@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.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +71 -2
  3. package/dist/db.d.ts +12 -0
  4. package/dist/db.js +134 -0
  5. package/dist/db.js.map +1 -0
  6. package/dist/details.d.ts +42 -0
  7. package/dist/details.js +210 -0
  8. package/dist/details.js.map +1 -0
  9. package/dist/export.d.ts +38 -0
  10. package/dist/export.js +241 -0
  11. package/dist/export.js.map +1 -0
  12. package/dist/games/cop.d.ts +7 -0
  13. package/dist/games/cop.js +11 -0
  14. package/dist/games/cop.js.map +1 -0
  15. package/dist/games/cs.d.ts +7 -0
  16. package/dist/games/cs.js +11 -0
  17. package/dist/games/cs.js.map +1 -0
  18. package/dist/games/sdk.d.ts +7 -0
  19. package/dist/games/sdk.js +10 -0
  20. package/dist/games/sdk.js.map +1 -0
  21. package/dist/games/soc.d.ts +9 -0
  22. package/dist/games/soc.js +13 -0
  23. package/dist/games/soc.js.map +1 -0
  24. package/dist/i18n.d.ts +2 -0
  25. package/dist/i18n.js +48 -0
  26. package/dist/i18n.js.map +1 -0
  27. package/dist/index.d.ts +5 -0
  28. package/dist/index.js +131 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/level.d.ts +39 -0
  31. package/dist/level.js +234 -0
  32. package/dist/level.js.map +1 -0
  33. package/dist/load.d.ts +5 -0
  34. package/dist/load.js +126 -0
  35. package/dist/load.js.map +1 -0
  36. package/dist/lzhuf.d.ts +2 -0
  37. package/dist/lzhuf.js +136 -0
  38. package/dist/lzhuf.js.map +1 -0
  39. package/dist/motion.d.ts +28 -0
  40. package/dist/motion.js +20 -0
  41. package/dist/motion.js.map +1 -0
  42. package/dist/object.d.ts +138 -0
  43. package/dist/object.js +361 -0
  44. package/dist/object.js.map +1 -0
  45. package/dist/ogf.d.ts +93 -0
  46. package/dist/ogf.js +418 -0
  47. package/dist/ogf.js.map +1 -0
  48. package/dist/scene.d.ts +28 -0
  49. package/dist/scene.js +141 -0
  50. package/dist/scene.js.map +1 -0
  51. package/dist/skeleton.d.ts +34 -0
  52. package/dist/skeleton.js +252 -0
  53. package/dist/skeleton.js.map +1 -0
  54. package/dist/smotion.d.ts +44 -0
  55. package/dist/smotion.js +283 -0
  56. package/dist/smotion.js.map +1 -0
  57. package/dist/soc-key.d.ts +18 -0
  58. package/dist/soc-key.js +125 -0
  59. package/dist/soc-key.js.map +1 -0
  60. package/dist/thm.d.ts +26 -0
  61. package/dist/thm.js +69 -0
  62. package/dist/thm.js.map +1 -0
  63. package/dist/write-object.d.ts +31 -0
  64. package/dist/write-object.js +228 -0
  65. package/dist/write-object.js.map +1 -0
  66. package/dist/write-omf.d.ts +47 -0
  67. package/dist/write-scene.d.ts +26 -0
  68. package/dist/write-scene.js +114 -0
  69. package/dist/write-scene.js.map +1 -0
  70. 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.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
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
+ }