@gmvjs/xray-v1 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +71 -2
- package/dist/db.d.ts +12 -0
- package/dist/db.js +134 -0
- package/dist/db.js.map +1 -0
- package/dist/details.d.ts +42 -0
- package/dist/details.js +210 -0
- package/dist/details.js.map +1 -0
- package/dist/export.d.ts +38 -0
- package/dist/export.js +241 -0
- package/dist/export.js.map +1 -0
- package/dist/games/cop.d.ts +7 -0
- package/dist/games/cop.js +11 -0
- package/dist/games/cop.js.map +1 -0
- package/dist/games/cs.d.ts +7 -0
- package/dist/games/cs.js +11 -0
- package/dist/games/cs.js.map +1 -0
- package/dist/games/sdk.d.ts +7 -0
- package/dist/games/sdk.js +10 -0
- package/dist/games/sdk.js.map +1 -0
- package/dist/games/soc.d.ts +9 -0
- package/dist/games/soc.js +13 -0
- package/dist/games/soc.js.map +1 -0
- package/dist/i18n.d.ts +2 -0
- package/dist/i18n.js +48 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +131 -0
- package/dist/index.js.map +1 -0
- package/dist/level.d.ts +39 -0
- package/dist/level.js +234 -0
- package/dist/level.js.map +1 -0
- package/dist/load.d.ts +5 -0
- package/dist/load.js +126 -0
- package/dist/load.js.map +1 -0
- package/dist/lzhuf.d.ts +2 -0
- package/dist/lzhuf.js +136 -0
- package/dist/lzhuf.js.map +1 -0
- package/dist/motion.d.ts +28 -0
- package/dist/motion.js +20 -0
- package/dist/motion.js.map +1 -0
- package/dist/object.d.ts +138 -0
- package/dist/object.js +361 -0
- package/dist/object.js.map +1 -0
- package/dist/ogf.d.ts +93 -0
- package/dist/ogf.js +418 -0
- package/dist/ogf.js.map +1 -0
- package/dist/scene.d.ts +28 -0
- package/dist/scene.js +141 -0
- package/dist/scene.js.map +1 -0
- package/dist/skeleton.d.ts +34 -0
- package/dist/skeleton.js +252 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/smotion.d.ts +44 -0
- package/dist/smotion.js +283 -0
- package/dist/smotion.js.map +1 -0
- package/dist/soc-key.d.ts +18 -0
- package/dist/soc-key.js +125 -0
- package/dist/soc-key.js.map +1 -0
- package/dist/thm.d.ts +26 -0
- package/dist/thm.js +69 -0
- package/dist/thm.js.map +1 -0
- package/dist/write-object.d.ts +31 -0
- package/dist/write-object.js +228 -0
- package/dist/write-object.js.map +1 -0
- package/dist/write-omf.d.ts +47 -0
- package/dist/write-scene.d.ts +26 -0
- package/dist/write-scene.js +114 -0
- package/dist/write-scene.js.map +1 -0
- package/package.json +70 -4
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { EOBJ, EMESH } from "./object.js";
|
|
2
|
+
class W {
|
|
3
|
+
buf = new Uint8Array(1 << 16);
|
|
4
|
+
dv = new DataView(this.buf.buffer);
|
|
5
|
+
pos = 0;
|
|
6
|
+
need(n) {
|
|
7
|
+
if (this.pos + n <= this.buf.length) return;
|
|
8
|
+
let s = this.buf.length * 2;
|
|
9
|
+
while (s < this.pos + n) s *= 2;
|
|
10
|
+
const b = new Uint8Array(s);
|
|
11
|
+
b.set(this.buf);
|
|
12
|
+
this.buf = b;
|
|
13
|
+
this.dv = new DataView(b.buffer);
|
|
14
|
+
}
|
|
15
|
+
b(v) {
|
|
16
|
+
this.need(1);
|
|
17
|
+
this.dv.setUint8(this.pos++, v);
|
|
18
|
+
return this;
|
|
19
|
+
}
|
|
20
|
+
w(v) {
|
|
21
|
+
this.need(2);
|
|
22
|
+
this.dv.setUint16(this.pos, v, true);
|
|
23
|
+
this.pos += 2;
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
d(v) {
|
|
27
|
+
this.need(4);
|
|
28
|
+
this.dv.setUint32(this.pos, v >>> 0, true);
|
|
29
|
+
this.pos += 4;
|
|
30
|
+
return this;
|
|
31
|
+
}
|
|
32
|
+
f(v) {
|
|
33
|
+
this.need(4);
|
|
34
|
+
this.dv.setFloat32(this.pos, v, true);
|
|
35
|
+
this.pos += 4;
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
sz(s) {
|
|
39
|
+
const e = encode1251(s);
|
|
40
|
+
this.need(e.length + 1);
|
|
41
|
+
this.buf.set(e, this.pos);
|
|
42
|
+
this.pos += e.length;
|
|
43
|
+
return this.b(0);
|
|
44
|
+
}
|
|
45
|
+
bytes(u) {
|
|
46
|
+
this.need(u.length);
|
|
47
|
+
this.buf.set(u, this.pos);
|
|
48
|
+
this.pos += u.length;
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
/** Чанк: id, затем размер, заполняемый после тела. */
|
|
52
|
+
chunk(id, body) {
|
|
53
|
+
this.d(id);
|
|
54
|
+
const at = this.pos;
|
|
55
|
+
this.d(0);
|
|
56
|
+
body(this);
|
|
57
|
+
this.dv.setUint32(at, this.pos - at - 4, true);
|
|
58
|
+
return this;
|
|
59
|
+
}
|
|
60
|
+
done() {
|
|
61
|
+
return this.buf.slice(0, this.pos);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function encode1251(s) {
|
|
65
|
+
const out = new Uint8Array(s.length);
|
|
66
|
+
for (let i = 0; i < s.length; i++) {
|
|
67
|
+
const c = s.charCodeAt(i);
|
|
68
|
+
out[i] = c < 128 ? c : c >= 1040 && c <= 1103 ? c - 848 : c === 1025 ? 168 : c === 1105 ? 184 : 63;
|
|
69
|
+
}
|
|
70
|
+
return out;
|
|
71
|
+
}
|
|
72
|
+
function build(m, hardCos) {
|
|
73
|
+
const P = m.pos, I = m.indices, nt = Math.floor(I.length / 3);
|
|
74
|
+
const pointOf = /* @__PURE__ */ new Map(), vpoint = new Int32Array(P.length / 3), points = [], N0 = m.nor;
|
|
75
|
+
const q = (x) => Math.round(x * 1e3);
|
|
76
|
+
for (let v = 0; v < P.length / 3; v++) {
|
|
77
|
+
const k = `${P[v * 3]}|${P[v * 3 + 1]}|${P[v * 3 + 2]}` + (N0 ? `|${q(N0[v * 3])}|${q(N0[v * 3 + 1])}|${q(N0[v * 3 + 2])}` : "");
|
|
78
|
+
let p = pointOf.get(k);
|
|
79
|
+
if (p === void 0) {
|
|
80
|
+
p = points.length / 3;
|
|
81
|
+
pointOf.set(k, p);
|
|
82
|
+
points.push(P[v * 3], P[v * 3 + 1], P[v * 3 + 2]);
|
|
83
|
+
}
|
|
84
|
+
vpoint[v] = p;
|
|
85
|
+
}
|
|
86
|
+
const np = points.length / 3, base = new Array(np * 2).fill(NaN), poly = [];
|
|
87
|
+
const vmrefs = [], vmrefOf = /* @__PURE__ */ new Map(), faces = [];
|
|
88
|
+
const ref = (vm, idx) => {
|
|
89
|
+
const k = `${vm}|${idx}`;
|
|
90
|
+
let r = vmrefOf.get(k);
|
|
91
|
+
if (r === void 0) {
|
|
92
|
+
r = vmrefs.length;
|
|
93
|
+
vmrefOf.set(k, r);
|
|
94
|
+
vmrefs.push([vm, idx]);
|
|
95
|
+
}
|
|
96
|
+
return r;
|
|
97
|
+
};
|
|
98
|
+
const sfaces = /* @__PURE__ */ new Map();
|
|
99
|
+
const surf = (t) => typeof m.surface === "number" ? m.surface : m.surface[t] ?? 0;
|
|
100
|
+
for (let t = 0; t < nt; t++) for (let k = 0; k < 3; k++) {
|
|
101
|
+
const v = I[t * 3 + k], p = vpoint[v];
|
|
102
|
+
if (Number.isNaN(base[p * 2])) {
|
|
103
|
+
base[p * 2] = m.uv[v * 2];
|
|
104
|
+
base[p * 2 + 1] = m.uv[v * 2 + 1];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (let t = 0; t < nt; t++) {
|
|
108
|
+
for (let k = 0; k < 3; k++) {
|
|
109
|
+
const v = I[t * 3 + k], p = vpoint[v], u = m.uv[v * 2], w = m.uv[v * 2 + 1];
|
|
110
|
+
let r;
|
|
111
|
+
if (u === base[p * 2] && w === base[p * 2 + 1]) r = ref(0, p);
|
|
112
|
+
else {
|
|
113
|
+
r = ref(1, poly.length);
|
|
114
|
+
poly.push({ u, v: w, point: p, face: t });
|
|
115
|
+
}
|
|
116
|
+
faces.push(p, r);
|
|
117
|
+
}
|
|
118
|
+
const s = surf(t);
|
|
119
|
+
(sfaces.get(s) ?? sfaces.set(s, []).get(s)).push(t);
|
|
120
|
+
}
|
|
121
|
+
const fn = (t) => {
|
|
122
|
+
const a = vpoint[I[t * 3]] * 3, b = vpoint[I[t * 3 + 1]] * 3, c = vpoint[I[t * 3 + 2]] * 3;
|
|
123
|
+
const ux = points[b] - points[a], uy = points[b + 1] - points[a + 1], uz = points[b + 2] - points[a + 2], vx = points[c] - points[a], vy = points[c + 1] - points[a + 1], vz = points[c + 2] - points[a + 2];
|
|
124
|
+
const n = [uy * vz - uz * vy, uz * vx - ux * vz, ux * vy - uy * vx], l = Math.hypot(n[0], n[1], n[2]) || 1;
|
|
125
|
+
return [n[0] / l, n[1] / l, n[2] / l];
|
|
126
|
+
};
|
|
127
|
+
const edgeFaces = /* @__PURE__ */ new Map();
|
|
128
|
+
for (let t = 0; t < nt; t++) for (let k = 0; k < 3; k++) {
|
|
129
|
+
const a = vpoint[I[t * 3 + k]], b = vpoint[I[t * 3 + (k + 1) % 3]], key = a < b ? `${a}_${b}` : `${b}_${a}`;
|
|
130
|
+
(edgeFaces.get(key) ?? edgeFaces.set(key, []).get(key)).push([t, k]);
|
|
131
|
+
}
|
|
132
|
+
const sg = new Array(nt).fill(0);
|
|
133
|
+
const N = m.nor;
|
|
134
|
+
const vnor = (t, k) => {
|
|
135
|
+
const v = I[t * 3 + k];
|
|
136
|
+
return [N[v * 3], N[v * 3 + 1], N[v * 3 + 2]];
|
|
137
|
+
};
|
|
138
|
+
const dot = (a, b) => a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
139
|
+
for (const list of edgeFaces.values()) {
|
|
140
|
+
if (list.length !== 2) {
|
|
141
|
+
for (const [t, k] of list) sg[t] |= 1 << k;
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
const [[t1, k1], [t2, k2]] = list;
|
|
145
|
+
let hard;
|
|
146
|
+
if (N) {
|
|
147
|
+
const p1 = vpoint[I[t1 * 3 + k1]], cornerIn = (t, p) => [0, 1, 2].find((k) => vpoint[I[t * 3 + k]] === p);
|
|
148
|
+
const q1 = vpoint[I[t1 * 3 + (k1 + 1) % 3]];
|
|
149
|
+
hard = dot(vnor(t1, k1), vnor(t2, cornerIn(t2, p1))) < 0.999 || dot(vnor(t1, (k1 + 1) % 3), vnor(t2, cornerIn(t2, q1))) < 0.999;
|
|
150
|
+
} else hard = dot(fn(t1), fn(t2)) < hardCos;
|
|
151
|
+
if (hard) {
|
|
152
|
+
sg[t1] |= 1 << k1;
|
|
153
|
+
sg[t2] |= 1 << k2;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const lo = [Infinity, Infinity, Infinity], hi = [-Infinity, -Infinity, -Infinity];
|
|
157
|
+
for (let i = 0; i < points.length; i++) {
|
|
158
|
+
lo[i % 3] = Math.min(lo[i % 3], points[i]);
|
|
159
|
+
hi[i % 3] = Math.max(hi[i % 3], points[i]);
|
|
160
|
+
}
|
|
161
|
+
return { points, faces, sg, vmrefs, base, poly, sfaces, bbox: [lo, hi] };
|
|
162
|
+
}
|
|
163
|
+
function writeObject(o) {
|
|
164
|
+
const hardCos = Math.cos((o.hardAngleDeg ?? 60) * Math.PI / 180), now = Math.floor(Date.now() / 1e3), w = new W();
|
|
165
|
+
const sname = (i) => o.surfaces[i]?.name ?? `surface_${i}`;
|
|
166
|
+
w.chunk(EOBJ.MAIN, (w2) => {
|
|
167
|
+
w2.chunk(EOBJ.VERSION, (w3) => w3.w(16));
|
|
168
|
+
w2.chunk(EOBJ.USERDATA, (w3) => w3.sz(""));
|
|
169
|
+
w2.chunk(EOBJ.LOD_REF, (w3) => w3.sz(""));
|
|
170
|
+
w2.chunk(EOBJ.FLAGS, (w3) => w3.d(o.dynamic ? 1 : 0));
|
|
171
|
+
w2.chunk(EOBJ.MESHES, (w3) => {
|
|
172
|
+
o.meshes.forEach((m, mi) => w3.chunk(mi, (w4) => {
|
|
173
|
+
const b = build(m, hardCos), np = b.points.length / 3, nt = b.faces.length / 6;
|
|
174
|
+
w4.chunk(EMESH.VERSION, (w5) => w5.w(17));
|
|
175
|
+
w4.chunk(EMESH.NAME, (w5) => w5.sz(m.name || `mesh_${mi}`));
|
|
176
|
+
w4.chunk(EMESH.BBOX, (w5) => {
|
|
177
|
+
for (const v of [...b.bbox[0], ...b.bbox[1]]) w5.f(np ? v : 0);
|
|
178
|
+
});
|
|
179
|
+
w4.chunk(EMESH.FLAGS, (w5) => w5.b(1));
|
|
180
|
+
w4.chunk(EMESH.OPTIONS, (w5) => w5.d(0).d(0));
|
|
181
|
+
w4.chunk(EMESH.VERTS, (w5) => {
|
|
182
|
+
w5.d(np);
|
|
183
|
+
for (const v of b.points) w5.f(v);
|
|
184
|
+
});
|
|
185
|
+
w4.chunk(EMESH.FACES, (w5) => {
|
|
186
|
+
w5.d(nt);
|
|
187
|
+
for (const v of b.faces) w5.d(v);
|
|
188
|
+
});
|
|
189
|
+
w4.chunk(EMESH.SG, (w5) => {
|
|
190
|
+
for (const v of b.sg) w5.d(v);
|
|
191
|
+
});
|
|
192
|
+
w4.chunk(EMESH.VMREFS, (w5) => {
|
|
193
|
+
w5.d(b.vmrefs.length);
|
|
194
|
+
for (const [vm, i] of b.vmrefs) w5.b(1).d(vm).d(i);
|
|
195
|
+
});
|
|
196
|
+
w4.chunk(EMESH.SFACE, (w5) => {
|
|
197
|
+
w5.w(b.sfaces.size);
|
|
198
|
+
for (const [s, list] of b.sfaces) {
|
|
199
|
+
w5.sz(sname(s)).d(list.length);
|
|
200
|
+
for (const f of list) w5.d(f);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
w4.chunk(EMESH.VMAPS2, (w5) => {
|
|
204
|
+
w5.d(b.poly.length ? 2 : 1);
|
|
205
|
+
w5.sz("Texture").b(2).b(0).b(0).d(np);
|
|
206
|
+
for (let p = 0; p < np; p++) w5.f(b.base[p * 2]).f(b.base[p * 2 + 1]);
|
|
207
|
+
for (let p = 0; p < np; p++) w5.d(p);
|
|
208
|
+
if (b.poly.length) {
|
|
209
|
+
w5.sz("Texture").b(2).b(1).b(0).d(b.poly.length);
|
|
210
|
+
for (const e of b.poly) w5.f(e.u).f(e.v);
|
|
211
|
+
for (const e of b.poly) w5.d(e.point);
|
|
212
|
+
for (const e of b.poly) w5.d(e.face);
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}));
|
|
216
|
+
});
|
|
217
|
+
w2.chunk(EOBJ.SURFACES3, (w3) => {
|
|
218
|
+
w3.d(o.surfaces.length);
|
|
219
|
+
for (const s of o.surfaces) w3.sz(s.name).sz(s.eshader ?? "default").sz(s.cshader ?? "default").sz(s.gamemtl ?? "default").sz(s.texture).sz("Texture").d(s.twoSided ? 1 : 0).d(274).d(1);
|
|
220
|
+
});
|
|
221
|
+
w2.chunk(EOBJ.REVISION, (w3) => w3.sz(o.owner ?? "gmv").d(now).sz(o.owner ?? "gmv").d(now));
|
|
222
|
+
});
|
|
223
|
+
return w.done();
|
|
224
|
+
}
|
|
225
|
+
export {
|
|
226
|
+
writeObject
|
|
227
|
+
};
|
|
228
|
+
//# sourceMappingURL=write-object.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-object.js","sources":["../src/write-object.ts"],"sourcesContent":["// Запись исходного объекта X-Ray SDK (.object, версия 0x10, сглаживание рёбрами как в SDK 0.7 ЗП).\n// Вход — треугольники в координатах X-Ray (левосторонние, Y вверх, внешняя нормаль = (b − a) × (c − a)).\nimport { EMESH, EOBJ } from './object';\n\nexport interface ObjectSurfaceIn {\n name: string;\n /** Текстура без расширения относительно gamedata/textures, например «wall\\\\wall_stucco_05». */\n texture: string;\n /** Шейдер движка (eshader), по умолчанию «default». */\n eshader?: string;\n /** Шейдер компилятора (cshader), по умолчанию «default». */\n cshader?: string;\n /** Игровой материал, по умолчанию «default». */\n gamemtl?: string;\n twoSided?: boolean;\n}\nexport interface ObjectMeshIn {\n name: string;\n pos: ArrayLike<number>;\n /** Нормали вершин: по их разрывам находятся жёсткие рёбра. Нет — жёсткие рёбра по углу. */\n nor?: ArrayLike<number> | null;\n uv: ArrayLike<number>;\n indices: ArrayLike<number>;\n /** Номер поверхности для каждого треугольника или одна на весь меш. */\n surface: number | ArrayLike<number>;\n}\nexport interface ObjectIn { meshes: ObjectMeshIn[]; surfaces: ObjectSurfaceIn[]; owner?: string; dynamic?: boolean; hardAngleDeg?: number }\n\nclass W {\n private buf = new Uint8Array(1 << 16);\n private dv = new DataView(this.buf.buffer);\n pos = 0;\n private need(n: number) {\n if (this.pos + n <= this.buf.length) return;\n let s = this.buf.length * 2;\n while (s < this.pos + n) s *= 2;\n const b = new Uint8Array(s);\n b.set(this.buf);\n this.buf = b; this.dv = new DataView(b.buffer);\n }\n b(v: number) { this.need(1); this.dv.setUint8(this.pos++, v); return this; }\n w(v: number) { this.need(2); this.dv.setUint16(this.pos, v, true); this.pos += 2; return this; }\n d(v: number) { this.need(4); this.dv.setUint32(this.pos, v >>> 0, true); this.pos += 4; return this; }\n f(v: number) { this.need(4); this.dv.setFloat32(this.pos, v, true); this.pos += 4; return this; }\n sz(s: string) { const e = encode1251(s); this.need(e.length + 1); this.buf.set(e, this.pos); this.pos += e.length; return this.b(0); }\n bytes(u: Uint8Array) { this.need(u.length); this.buf.set(u, this.pos); this.pos += u.length; return this; }\n /** Чанк: id, затем размер, заполняемый после тела. */\n chunk(id: number, body: (w: W) => void) {\n this.d(id);\n const at = this.pos;\n this.d(0);\n body(this);\n this.dv.setUint32(at, this.pos - at - 4, true);\n return this;\n }\n done() { return this.buf.slice(0, this.pos); }\n}\n\n/** Строки SDK — в кодировке Windows-1251 (имена текстур и материалов бывают русскими). */\nfunction encode1251(s: string): Uint8Array {\n const out = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i);\n out[i] = c < 128 ? c : c >= 0x410 && c <= 0x44f ? c - 0x350 : c === 0x401 ? 0xa8 : c === 0x451 ? 0xb8 : 0x3f;\n }\n return out;\n}\n\ninterface Built {\n points: number[]; faces: number[]; sg: number[]; vmrefs: Array<[number, number]>;\n base: number[]; poly: Array<{ u: number; v: number; point: number; face: number }>;\n sfaces: Map<number, number[]>; bbox: [number[], number[]];\n}\n\nfunction build(m: ObjectMeshIn, hardCos: number): Built {\n const P = m.pos, I = m.indices, nt = Math.floor(I.length / 3);\n // сварка вершин: одна точка .object на позицию и нормаль. Углы с разными нормалями остаются разными точками,\n // поэтому SDK не сгладит то, что в исходнике было жёстким (и не потянет сглаживание через шов в соседний «веер»)\n const pointOf = new Map<string, number>(), vpoint = new Int32Array(P.length / 3), points: number[] = [], N0 = m.nor;\n const q = (x: number) => Math.round(x * 1000);\n for (let v = 0; v < P.length / 3; v++) {\n const k = `${P[v * 3]}|${P[v * 3 + 1]}|${P[v * 3 + 2]}` + (N0 ? `|${q(N0[v * 3]!)}|${q(N0[v * 3 + 1]!)}|${q(N0[v * 3 + 2]!)}` : '');\n let p = pointOf.get(k);\n if (p === undefined) { p = points.length / 3; pointOf.set(k, p); points.push(P[v * 3]!, P[v * 3 + 1]!, P[v * 3 + 2]!); }\n vpoint[v] = p;\n }\n const np = points.length / 3, base = new Array<number>(np * 2).fill(NaN), poly: Built['poly'] = [];\n const vmrefs: Array<[number, number]> = [], vmrefOf = new Map<string, number>(), faces: number[] = [];\n const ref = (vm: number, idx: number) => { const k = `${vm}|${idx}`; let r = vmrefOf.get(k); if (r === undefined) { r = vmrefs.length; vmrefOf.set(k, r); vmrefs.push([vm, idx]); } return r; };\n const sfaces = new Map<number, number[]>();\n const surf = (t: number) => (typeof m.surface === 'number' ? m.surface : m.surface[t] ?? 0);\n // базовая UV точки — из первого угла; отличающиеся углы — в «поли»-карту (разрывы UV)\n for (let t = 0; t < nt; t++) for (let k = 0; k < 3; k++) { const v = I[t * 3 + k]!, p = vpoint[v]!; if (Number.isNaN(base[p * 2])) { base[p * 2] = m.uv[v * 2]!; base[p * 2 + 1] = m.uv[v * 2 + 1]!; } }\n for (let t = 0; t < nt; t++) {\n for (let k = 0; k < 3; k++) {\n const v = I[t * 3 + k]!, p = vpoint[v]!, u = m.uv[v * 2]!, w = m.uv[v * 2 + 1]!;\n let r: number;\n if (u === base[p * 2] && w === base[p * 2 + 1]) r = ref(0, p);\n else { r = ref(1, poly.length); poly.push({ u, v: w, point: p, face: t }); }\n faces.push(p, r);\n }\n const s = surf(t);\n (sfaces.get(s) ?? sfaces.set(s, []).get(s)!).push(t);\n }\n // жёсткие рёбра (бит k — ребро k→k+1): нормали вершин по разные стороны ребра различаются, или угол граней больше порога\n const fn = (t: number) => {\n const a = vpoint[I[t * 3]!]! * 3, b = vpoint[I[t * 3 + 1]!]! * 3, c = vpoint[I[t * 3 + 2]!]! * 3;\n const ux = points[b]! - points[a]!, uy = points[b + 1]! - points[a + 1]!, uz = points[b + 2]! - points[a + 2]!, vx = points[c]! - points[a]!, vy = points[c + 1]! - points[a + 1]!, vz = points[c + 2]! - points[a + 2]!;\n const n = [uy * vz - uz * vy, uz * vx - ux * vz, ux * vy - uy * vx], l = Math.hypot(n[0]!, n[1]!, n[2]!) || 1;\n return [n[0]! / l, n[1]! / l, n[2]! / l];\n };\n const edgeFaces = new Map<string, Array<[number, number]>>();\n for (let t = 0; t < nt; t++) for (let k = 0; k < 3; k++) {\n const a = vpoint[I[t * 3 + k]!]!, b = vpoint[I[t * 3 + ((k + 1) % 3)]!]!, key = a < b ? `${a}_${b}` : `${b}_${a}`;\n (edgeFaces.get(key) ?? edgeFaces.set(key, []).get(key)!).push([t, k]);\n }\n const sg = new Array<number>(nt).fill(0);\n const N = m.nor;\n const vnor = (t: number, k: number) => { const v = I[t * 3 + k]!; return [N![v * 3]!, N![v * 3 + 1]!, N![v * 3 + 2]!]; };\n const dot = (a: number[], b: number[]) => a[0]! * b[0]! + a[1]! * b[1]! + a[2]! * b[2]!;\n for (const list of edgeFaces.values()) {\n if (list.length !== 2) { for (const [t, k] of list) sg[t]! |= 1 << k; continue; } // край или неманифолд — жёстко\n const [[t1, k1], [t2, k2]] = list as [[number, number], [number, number]];\n let hard: boolean;\n if (N) {\n // концы ребра: в грани t1 — углы k1 и k1+1, в t2 те же точки\n const p1 = vpoint[I[t1 * 3 + k1]!]!, cornerIn = (t: number, p: number) => [0, 1, 2].find((k) => vpoint[I[t * 3 + k]!] === p)!;\n const q1 = vpoint[I[t1 * 3 + ((k1 + 1) % 3)]!]!;\n hard = dot(vnor(t1, k1), vnor(t2, cornerIn(t2, p1))) < 0.999 || dot(vnor(t1, (k1 + 1) % 3), vnor(t2, cornerIn(t2, q1))) < 0.999;\n } else hard = dot(fn(t1), fn(t2)) < hardCos;\n if (hard) { sg[t1]! |= 1 << k1; sg[t2]! |= 1 << k2; }\n }\n const lo = [Infinity, Infinity, Infinity], hi = [-Infinity, -Infinity, -Infinity];\n for (let i = 0; i < points.length; i++) { lo[i % 3] = Math.min(lo[i % 3]!, points[i]!); hi[i % 3] = Math.max(hi[i % 3]!, points[i]!); }\n return { points, faces, sg, vmrefs, base, poly, sfaces, bbox: [lo, hi] };\n}\n\n/** Записать .object. Возвращает байты файла. */\nexport function writeObject(o: ObjectIn): Uint8Array {\n const hardCos = Math.cos(((o.hardAngleDeg ?? 60) * Math.PI) / 180), now = Math.floor(Date.now() / 1000), w = new W();\n const sname = (i: number) => o.surfaces[i]?.name ?? `surface_${i}`;\n w.chunk(EOBJ.MAIN, (w) => {\n w.chunk(EOBJ.VERSION, (w) => w.w(0x10));\n w.chunk(EOBJ.USERDATA, (w) => w.sz(''));\n w.chunk(EOBJ.LOD_REF, (w) => w.sz(''));\n w.chunk(EOBJ.FLAGS, (w) => w.d(o.dynamic ? 1 : 0));\n w.chunk(EOBJ.MESHES, (w) => {\n o.meshes.forEach((m, mi) => w.chunk(mi, (w) => {\n const b = build(m, hardCos), np = b.points.length / 3, nt = b.faces.length / 6;\n w.chunk(EMESH.VERSION, (w) => w.w(0x11));\n w.chunk(EMESH.NAME, (w) => w.sz(m.name || `mesh_${mi}`));\n w.chunk(EMESH.BBOX, (w) => { for (const v of [...b.bbox[0], ...b.bbox[1]]) w.f(np ? v : 0); });\n w.chunk(EMESH.FLAGS, (w) => w.b(1)); // виден\n w.chunk(EMESH.OPTIONS, (w) => w.d(0).d(0));\n w.chunk(EMESH.VERTS, (w) => { w.d(np); for (const v of b.points) w.f(v); });\n w.chunk(EMESH.FACES, (w) => { w.d(nt); for (const v of b.faces) w.d(v); });\n w.chunk(EMESH.SG, (w) => { for (const v of b.sg) w.d(v); });\n w.chunk(EMESH.VMREFS, (w) => { w.d(b.vmrefs.length); for (const [vm, i] of b.vmrefs) w.b(1).d(vm).d(i); });\n w.chunk(EMESH.SFACE, (w) => {\n w.w(b.sfaces.size);\n for (const [s, list] of b.sfaces) { w.sz(sname(s)).d(list.length); for (const f of list) w.d(f); }\n });\n w.chunk(EMESH.VMAPS2, (w) => {\n w.d(b.poly.length ? 2 : 1);\n w.sz('Texture').b(2).b(0).b(0).d(np);\n for (let p = 0; p < np; p++) w.f(b.base[p * 2]!).f(b.base[p * 2 + 1]!);\n for (let p = 0; p < np; p++) w.d(p);\n if (b.poly.length) {\n w.sz('Texture').b(2).b(1).b(0).d(b.poly.length);\n for (const e of b.poly) w.f(e.u).f(e.v);\n for (const e of b.poly) w.d(e.point);\n for (const e of b.poly) w.d(e.face);\n }\n });\n }));\n });\n w.chunk(EOBJ.SURFACES3, (w) => {\n w.d(o.surfaces.length);\n for (const s of o.surfaces) w.sz(s.name).sz(s.eshader ?? 'default').sz(s.cshader ?? 'default').sz(s.gamemtl ?? 'default').sz(s.texture).sz('Texture').d(s.twoSided ? 1 : 0).d(0x112).d(1);\n });\n w.chunk(EOBJ.REVISION, (w) => w.sz(o.owner ?? 'gmv').d(now).sz(o.owner ?? 'gmv').d(now));\n });\n return w.done();\n}\n"],"names":["w"],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { XrayMotion } from './motion';
|
|
2
|
+
export declare const ESM: {
|
|
3
|
+
readonly FX: 1;
|
|
4
|
+
readonly STOP_AT_END: 2;
|
|
5
|
+
readonly NO_MIX: 4;
|
|
6
|
+
readonly SYNC_PART: 8;
|
|
7
|
+
readonly USE_FOOT_STEPS: 16;
|
|
8
|
+
readonly ROOT_MOVER: 32;
|
|
9
|
+
readonly IDLE: 64;
|
|
10
|
+
readonly USE_WEAPON_BONE: 128;
|
|
11
|
+
};
|
|
12
|
+
export interface OmfMotionDef {
|
|
13
|
+
/** Флаги esm*. */
|
|
14
|
+
flags?: number;
|
|
15
|
+
/** Часть тела (номер в parts) для циклов или кость для FX. */
|
|
16
|
+
boneOrPart?: number;
|
|
17
|
+
speed?: number;
|
|
18
|
+
power?: number;
|
|
19
|
+
accrue?: number;
|
|
20
|
+
falloff?: number;
|
|
21
|
+
/** Метки (шаги и т. п.): имя и интервалы [начало, конец] в секундах. */
|
|
22
|
+
marks?: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
intervals: Array<[number, number]>;
|
|
25
|
+
}>;
|
|
26
|
+
/** Дополнительные имена того же движения. Движок X-Ray нумерует движения по порядку описаний (`m_cycle[name] = mot_i`,
|
|
27
|
+
* поле «номер движения» описания не читается), поэтому писатель разворачивает псевдонимы в полные копии движения
|
|
28
|
+
* (ключи дублируются в файле); описание-ссылка на чужие ключи движок читать не умеет (net1198). */
|
|
29
|
+
aliases?: string[];
|
|
30
|
+
}
|
|
31
|
+
export interface OmfInput {
|
|
32
|
+
/** Имена костей в порядке треков (порядок костей модели). */
|
|
33
|
+
bones: readonly string[];
|
|
34
|
+
/** Части тела; пусто - одна часть «default» со всеми костями. */
|
|
35
|
+
parts?: Array<{
|
|
36
|
+
name: string;
|
|
37
|
+
bones: string[];
|
|
38
|
+
}>;
|
|
39
|
+
motions: Array<{
|
|
40
|
+
motion: XrayMotion;
|
|
41
|
+
def?: OmfMotionDef;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
export declare function crc32(u: Uint8Array): number;
|
|
45
|
+
export declare function writeOMF(input0: OmfInput): Uint8Array;
|
|
46
|
+
/** Квантованный поворот из float-кватерниона (x, y, z, w) - для треков, построенных не из OMF. */
|
|
47
|
+
export declare function quantRot(q: readonly number[]): Int16Array;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface SceneObjectOut {
|
|
2
|
+
/** Имя экземпляра в сцене. */
|
|
3
|
+
name: string;
|
|
4
|
+
/** Путь объекта в rawdata/objects без расширения, например «gmv\\metro\\tunnel_01». */
|
|
5
|
+
reference: string;
|
|
6
|
+
position: number[];
|
|
7
|
+
/** Углы, как в part-файле (см. sceneRotation), либо матрица поворота 3×3 (строки-векторы). */
|
|
8
|
+
rotation?: number[];
|
|
9
|
+
matrix?: number[];
|
|
10
|
+
scale?: number[];
|
|
11
|
+
}
|
|
12
|
+
export interface SceneOut {
|
|
13
|
+
name: string;
|
|
14
|
+
objects: SceneObjectOut[];
|
|
15
|
+
owner?: string;
|
|
16
|
+
camera?: {
|
|
17
|
+
pos: number[];
|
|
18
|
+
hpb: number[];
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
/** Углы part-файла по матрице поворота (обратное к sceneRotation). */
|
|
22
|
+
export declare function sceneEuler(R: ArrayLike<number>): number[];
|
|
23
|
+
/** ini в стиле SDK: секции по алфавиту, ключи по алфавиту, «ключ = значение» с выравниванием, пустая строка из пробела. */
|
|
24
|
+
export declare function writeIni(sections: Record<string, Record<string, string>>): string;
|
|
25
|
+
/** Файлы сцены: путь (относительно rawdata/levels) -> байты. */
|
|
26
|
+
export declare function writeScene(sc: SceneOut): Map<string, Uint8Array>;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
function sceneEuler(R) {
|
|
2
|
+
const m = [R[0], R[3], R[6], R[1], R[4], R[7], R[2], R[5], R[8]];
|
|
3
|
+
const p = Math.asin(Math.max(-1, Math.min(1, m[5])));
|
|
4
|
+
let h, b;
|
|
5
|
+
if (Math.abs(m[5]) < 0.99999) {
|
|
6
|
+
h = Math.atan2(-m[2], m[8]);
|
|
7
|
+
b = Math.atan2(-m[3], m[4]);
|
|
8
|
+
} else {
|
|
9
|
+
h = 0;
|
|
10
|
+
b = Math.atan2(m[1], m[0]);
|
|
11
|
+
}
|
|
12
|
+
return [p, h, b];
|
|
13
|
+
}
|
|
14
|
+
const f6 = (v) => (Math.abs(v) < 5e-7 ? 0 : v).toFixed(6);
|
|
15
|
+
const vec = (a) => a.map(f6).join(", ");
|
|
16
|
+
function writeIni(sections) {
|
|
17
|
+
let s = "";
|
|
18
|
+
for (const name of Object.keys(sections).sort()) {
|
|
19
|
+
s += `[${name}]\r
|
|
20
|
+
`;
|
|
21
|
+
const sec = sections[name];
|
|
22
|
+
for (const k of Object.keys(sec).sort()) {
|
|
23
|
+
const v = sec[k];
|
|
24
|
+
s += ` ${k.padEnd(33)}=${v === "" ? "" : " " + v}\r
|
|
25
|
+
`;
|
|
26
|
+
}
|
|
27
|
+
s += " \r\n";
|
|
28
|
+
}
|
|
29
|
+
return s;
|
|
30
|
+
}
|
|
31
|
+
function encode1251(s) {
|
|
32
|
+
const out = new Uint8Array(s.length);
|
|
33
|
+
for (let i = 0; i < s.length; i++) {
|
|
34
|
+
const c = s.charCodeAt(i);
|
|
35
|
+
out[i] = c < 128 ? c : c >= 1040 && c <= 1103 ? c - 848 : c === 1025 ? 168 : c === 1105 ? 184 : 63;
|
|
36
|
+
}
|
|
37
|
+
return out;
|
|
38
|
+
}
|
|
39
|
+
const rnd64 = () => {
|
|
40
|
+
let v = 0n;
|
|
41
|
+
for (let i = 0; i < 8; i++) v = v << 8n | BigInt(Math.floor(Math.random() * 256));
|
|
42
|
+
return v.toString();
|
|
43
|
+
};
|
|
44
|
+
function writeScene(sc) {
|
|
45
|
+
const g0 = rnd64(), g1 = rnd64(), now = Math.floor(Date.now() / 1e3);
|
|
46
|
+
const objects = {};
|
|
47
|
+
sc.objects.forEach((o, i) => {
|
|
48
|
+
const rot = o.rotation ?? (o.matrix ? sceneEuler(o.matrix) : [0, 0, 0]);
|
|
49
|
+
objects[`object_${i}`] = {
|
|
50
|
+
clsid: "2",
|
|
51
|
+
co_flags: "0",
|
|
52
|
+
flags: "0",
|
|
53
|
+
name: o.name,
|
|
54
|
+
position: vec(o.position),
|
|
55
|
+
reference_name: o.reference,
|
|
56
|
+
rotation: vec(rot),
|
|
57
|
+
scale: vec(o.scale ?? [1, 1, 1]),
|
|
58
|
+
version: "18"
|
|
59
|
+
};
|
|
60
|
+
});
|
|
61
|
+
const part = writeIni({
|
|
62
|
+
appendrandom: { AppendRandomMaxRotation: vec([0, 0, 0]), AppendRandomMaxScale: vec([1, 1, 1]), AppendRandomMinRotation: vec([0, 0, 0]), AppendRandomMinScale: vec([1, 1, 1]), AppendRandomObjects_size: "0" },
|
|
63
|
+
guid: { guid_g0: g0, guid_g1: g1 },
|
|
64
|
+
main: { flags: "0", objects_count: String(sc.objects.length), version: "0" },
|
|
65
|
+
modif: { name: "", time: "0" },
|
|
66
|
+
...objects
|
|
67
|
+
});
|
|
68
|
+
let cam = sc.camera;
|
|
69
|
+
if (!cam) {
|
|
70
|
+
const c = [0, 0, 0];
|
|
71
|
+
for (const o of sc.objects) for (let k = 0; k < 3; k++) c[k] += o.position[k] / Math.max(1, sc.objects.length);
|
|
72
|
+
cam = { pos: [c[0], c[1] + 20, c[2] - 30], hpb: [0, -0.5, 0] };
|
|
73
|
+
}
|
|
74
|
+
const level = writeIni({
|
|
75
|
+
build_params: {
|
|
76
|
+
light_jitter_samples: "9",
|
|
77
|
+
light_pixel_per_meter: f6(20),
|
|
78
|
+
light_quality: "2",
|
|
79
|
+
light_quality_reserved: "29795",
|
|
80
|
+
light_rms: "4",
|
|
81
|
+
light_rms_zero: "4",
|
|
82
|
+
reserved_0: f6(0),
|
|
83
|
+
reserved_1: f6(0),
|
|
84
|
+
reserved_2: f6(0),
|
|
85
|
+
reserved_3: f6(0),
|
|
86
|
+
reserved_4: f6(0),
|
|
87
|
+
reserved_5: f6(0),
|
|
88
|
+
smooth_angle: f6(75),
|
|
89
|
+
weld_distance: f6(5e-3)
|
|
90
|
+
},
|
|
91
|
+
camera: { hpb: vec(cam.hpb), pos: vec(cam.pos) },
|
|
92
|
+
guid: { guid_g0: g0, guid_g1: g1 },
|
|
93
|
+
level_options: {
|
|
94
|
+
bop: '""',
|
|
95
|
+
game_type: "1",
|
|
96
|
+
level_path: sc.name,
|
|
97
|
+
level_prefix: sc.name,
|
|
98
|
+
light_hemi_quality: "3",
|
|
99
|
+
light_sun_quality: "0",
|
|
100
|
+
map_version: "1.0",
|
|
101
|
+
version: "12",
|
|
102
|
+
version_bp: "9"
|
|
103
|
+
},
|
|
104
|
+
level_tag: { create_time: String(now), owner: sc.owner ?? "gmv" },
|
|
105
|
+
version: { value: "5" }
|
|
106
|
+
});
|
|
107
|
+
return /* @__PURE__ */ new Map([[`${sc.name}.level`, encode1251(level)], [`${sc.name}/scene_object.part`, encode1251(part)]]);
|
|
108
|
+
}
|
|
109
|
+
export {
|
|
110
|
+
sceneEuler,
|
|
111
|
+
writeIni,
|
|
112
|
+
writeScene
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=write-scene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write-scene.js","sources":["../src/write-scene.ts"],"sourcesContent":["// Запись сцены уровня X-Ray SDK 0.7 (ЗП): <уровень>.level и <уровень>/scene_object.part (ini, CRLF, Windows-1251).\n// Остальные части (свет, секторы, порталы, спавн, AI-сетка) добавляются в LevelEditor.\n\nexport interface SceneObjectOut {\n /** Имя экземпляра в сцене. */\n name: string;\n /** Путь объекта в rawdata/objects без расширения, например «gmv\\\\metro\\\\tunnel_01». */\n reference: string;\n position: number[];\n /** Углы, как в part-файле (см. sceneRotation), либо матрица поворота 3×3 (строки-векторы). */\n rotation?: number[];\n matrix?: number[];\n scale?: number[];\n}\nexport interface SceneOut { name: string; objects: SceneObjectOut[]; owner?: string; camera?: { pos: number[]; hpb: number[] } }\n\n/** Углы part-файла по матрице поворота (обратное к sceneRotation). */\nexport function sceneEuler(R: ArrayLike<number>): number[] {\n // sceneRotation = transpose(setHPB(y, x, z)) -> m = transpose(R)\n const m = [R[0]!, R[3]!, R[6]!, R[1]!, R[4]!, R[7]!, R[2]!, R[5]!, R[8]!];\n const p = Math.asin(Math.max(-1, Math.min(1, m[5]!)));\n let h: number, b: number;\n if (Math.abs(m[5]!) < 0.99999) { h = Math.atan2(-m[2]!, m[8]!); b = Math.atan2(-m[3]!, m[4]!); }\n else { h = 0; b = Math.atan2(m[1]!, m[0]!); } // вырожденный случай (тангаж ±90°)\n return [p, h, b];\n}\n\nconst f6 = (v: number) => (Math.abs(v) < 5e-7 ? 0 : v).toFixed(6);\nconst vec = (a: number[]) => a.map(f6).join(', ');\n\n/** ini в стиле SDK: секции по алфавиту, ключи по алфавиту, «ключ = значение» с выравниванием, пустая строка из пробела. */\nexport function writeIni(sections: Record<string, Record<string, string>>): string {\n let s = '';\n for (const name of Object.keys(sections).sort()) {\n s += `[${name}]\\r\\n`;\n const sec = sections[name]!;\n for (const k of Object.keys(sec).sort()) { const v = sec[k]!; s += ` ${k.padEnd(33)}=${v === '' ? '' : ' ' + v}\\r\\n`; }\n s += ' \\r\\n';\n }\n return s;\n}\n\nfunction encode1251(s: string): Uint8Array {\n const out = new Uint8Array(s.length);\n for (let i = 0; i < s.length; i++) { const c = s.charCodeAt(i); out[i] = c < 128 ? c : c >= 0x410 && c <= 0x44f ? c - 0x350 : c === 0x401 ? 0xa8 : c === 0x451 ? 0xb8 : 0x3f; }\n return out;\n}\n\nconst rnd64 = () => { let v = 0n; for (let i = 0; i < 8; i++) v = (v << 8n) | BigInt(Math.floor(Math.random() * 256)); return v.toString(); };\n\n/** Файлы сцены: путь (относительно rawdata/levels) -> байты. */\nexport function writeScene(sc: SceneOut): Map<string, Uint8Array> {\n const g0 = rnd64(), g1 = rnd64(), now = Math.floor(Date.now() / 1000);\n const objects: Record<string, Record<string, string>> = {};\n sc.objects.forEach((o, i) => {\n const rot = o.rotation ?? (o.matrix ? sceneEuler(o.matrix) : [0, 0, 0]);\n objects[`object_${i}`] = {\n clsid: '2', co_flags: '0', flags: '0', name: o.name, position: vec(o.position), reference_name: o.reference,\n rotation: vec(rot), scale: vec(o.scale ?? [1, 1, 1]), version: '18',\n };\n });\n const part = writeIni({\n appendrandom: { AppendRandomMaxRotation: vec([0, 0, 0]), AppendRandomMaxScale: vec([1, 1, 1]), AppendRandomMinRotation: vec([0, 0, 0]), AppendRandomMinScale: vec([1, 1, 1]), AppendRandomObjects_size: '0' },\n guid: { guid_g0: g0, guid_g1: g1 },\n main: { flags: '0', objects_count: String(sc.objects.length), version: '0' },\n modif: { name: '', time: '0' },\n ...objects,\n });\n // камера: над центром сцены\n let cam = sc.camera;\n if (!cam) {\n const c = [0, 0, 0];\n for (const o of sc.objects) for (let k = 0; k < 3; k++) c[k] += o.position[k]! / Math.max(1, sc.objects.length);\n cam = { pos: [c[0]!, c[1]! + 20, c[2]! - 30], hpb: [0, -0.5, 0] };\n }\n const level = writeIni({\n build_params: {\n light_jitter_samples: '9', light_pixel_per_meter: f6(20), light_quality: '2', light_quality_reserved: '29795', light_rms: '4', light_rms_zero: '4',\n reserved_0: f6(0), reserved_1: f6(0), reserved_2: f6(0), reserved_3: f6(0), reserved_4: f6(0), reserved_5: f6(0), smooth_angle: f6(75), weld_distance: f6(0.005),\n },\n camera: { hpb: vec(cam.hpb), pos: vec(cam.pos) },\n guid: { guid_g0: g0, guid_g1: g1 },\n level_options: {\n bop: '\"\"', game_type: '1', level_path: sc.name, level_prefix: sc.name, light_hemi_quality: '3', light_sun_quality: '0', map_version: '1.0', version: '12', version_bp: '9',\n },\n level_tag: { create_time: String(now), owner: sc.owner ?? 'gmv' },\n version: { value: '5' },\n });\n return new Map([[`${sc.name}.level`, encode1251(level)], [`${sc.name}/scene_object.part`, encode1251(part)]]);\n}\n"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,72 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gmvjs/xray-v1",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "gmv: X-Ray Engine 1.x",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"gmv",
|
|
7
|
+
"x-ray-engine",
|
|
8
|
+
"stalker",
|
|
9
|
+
"ogf",
|
|
10
|
+
"omf"
|
|
11
|
+
],
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"author": "Alexander Shibisty",
|
|
14
|
+
"homepage": "https://github.com/shibisty/gmv/tree/main/packages/xray-v1#readme",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "git+https://github.com/shibisty/gmv.git",
|
|
18
|
+
"directory": "packages/xray-v1"
|
|
19
|
+
},
|
|
20
|
+
"bugs": {
|
|
21
|
+
"url": "https://github.com/shibisty/gmv/issues"
|
|
22
|
+
},
|
|
23
|
+
"type": "module",
|
|
24
|
+
"sideEffects": false,
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"gmv-source": "./src/index.ts",
|
|
28
|
+
"types": "./dist/index.d.ts",
|
|
29
|
+
"import": "./dist/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./cop": {
|
|
32
|
+
"gmv-source": "./src/games/cop.ts",
|
|
33
|
+
"types": "./dist/games/cop.d.ts",
|
|
34
|
+
"import": "./dist/games/cop.js"
|
|
35
|
+
},
|
|
36
|
+
"./cs": {
|
|
37
|
+
"gmv-source": "./src/games/cs.ts",
|
|
38
|
+
"types": "./dist/games/cs.d.ts",
|
|
39
|
+
"import": "./dist/games/cs.js"
|
|
40
|
+
},
|
|
41
|
+
"./sdk": {
|
|
42
|
+
"gmv-source": "./src/games/sdk.ts",
|
|
43
|
+
"types": "./dist/games/sdk.d.ts",
|
|
44
|
+
"import": "./dist/games/sdk.js"
|
|
45
|
+
},
|
|
46
|
+
"./soc": {
|
|
47
|
+
"gmv-source": "./src/games/soc.ts",
|
|
48
|
+
"types": "./dist/games/soc.d.ts",
|
|
49
|
+
"import": "./dist/games/soc.js"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"main": "./dist/index.js",
|
|
53
|
+
"types": "./dist/index.d.ts",
|
|
54
|
+
"files": [
|
|
55
|
+
"dist",
|
|
56
|
+
"README.md",
|
|
57
|
+
"LICENSE"
|
|
58
|
+
],
|
|
59
|
+
"scripts": {
|
|
60
|
+
"build": "node ../../scripts/build-package.mjs"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@gmvjs/codecs": "^0.1.0",
|
|
64
|
+
"@gmvjs/core": "^0.1.0"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@gmvjs/test-utils": "^0.1.0"
|
|
68
|
+
},
|
|
69
|
+
"publishConfig": {
|
|
70
|
+
"access": "public"
|
|
71
|
+
}
|
|
72
|
+
}
|