@gmvjs/xray-v1 0.0.0-stage → 0.1.1

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 +77 -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
+ /** Chunk: id, then a size filled in after the body. */
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":["// Writing an X-Ray SDK source object (.object, version 0x10, edge smoothing as in SDK 0.7 CoP).\n// Input: triangles in X-Ray coordinates (left-handed, Y up, outward normal = (b − a) × (c − a)).\nimport { EMESH, EOBJ } from './object';\n\nexport interface ObjectSurfaceIn {\n name: string;\n /** Texture without extension relative to gamedata/textures, for example \"wall\\\\wall_stucco_05\". */\n texture: string;\n /** Engine shader (eshader), \"default\" by default. */\n eshader?: string;\n /** Compiler shader (cshader), \"default\" by default. */\n cshader?: string;\n /** Game material, \"default\" by default. */\n gamemtl?: string;\n twoSided?: boolean;\n}\nexport interface ObjectMeshIn {\n name: string;\n pos: ArrayLike<number>;\n /** Vertex normals: hard edges are found from their discontinuities. Without them, hard edges by angle. */\n nor?: ArrayLike<number> | null;\n uv: ArrayLike<number>;\n indices: ArrayLike<number>;\n /** Surface number for every triangle, or one for the whole mesh. */\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 /** Chunk: id, then a size filled in after the body. */\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 strings are in Windows-1251 (texture and material names may be in Russian). */\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 // vertex welding: one .object point per position and normal. Corners with different normals stay different points,\n // so the SDK does not smooth what was hard in the source (and does not drag smoothing across a seam into the neighbouring \"fan\")\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 // a point's base UV comes from its first corner; differing corners go to the \"poly\" map (UV seams)\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 // hard edges (bit k = edge k→k+1): vertex normals differ on the two sides of the edge, or the face angle exceeds the threshold\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; } // a border or non-manifold edge: hard\n const [[t1, k1], [t2, k2]] = list as [[number, number], [number, number]];\n let hard: boolean;\n if (N) {\n // edge ends: corners k1 and k1+1 in face t1, the same points in 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/** Write a .object. Returns the file bytes. */\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)); // visible\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* flags. */
14
+ flags?: number;
15
+ /** Body part (an index in parts) for cycles, or a bone for FX. */
16
+ boneOrPart?: number;
17
+ speed?: number;
18
+ power?: number;
19
+ accrue?: number;
20
+ falloff?: number;
21
+ /** Marks (footsteps and the like): a name and [start, end] intervals in seconds. */
22
+ marks?: Array<{
23
+ name: string;
24
+ intervals: Array<[number, number]>;
25
+ }>;
26
+ /** Extra names of the same motion. The X-Ray engine numbers motions in description order (`m_cycle[name] = mot_i`,
27
+ * the description's "motion number" field is not read), so the writer expands aliases into full copies of the motion
28
+ * (keys are duplicated in the file); the engine cannot read a description pointing at another motion's keys (net1198). */
29
+ aliases?: string[];
30
+ }
31
+ export interface OmfInput {
32
+ /** Bone names in track order (the model bone order). */
33
+ bones: readonly string[];
34
+ /** Body parts; empty = one "default" part with all bones. */
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
+ /** Quantized rotation from a float quaternion (x, y, z, w), for tracks not built from OMF. */
47
+ export declare function quantRot(q: readonly number[]): Int16Array;
@@ -0,0 +1,26 @@
1
+ export interface SceneObjectOut {
2
+ /** Instance name in the scene. */
3
+ name: string;
4
+ /** Object path in rawdata/objects without extension, for example "gmv\\metro\\tunnel_01". */
5
+ reference: string;
6
+ position: number[];
7
+ /** Angles as in the part file (see sceneRotation), or a 3×3 rotation matrix (row vectors). */
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-file angles from a rotation matrix (the inverse of sceneRotation). */
22
+ export declare function sceneEuler(R: ArrayLike<number>): number[];
23
+ /** SDK-style ini: sections and keys sorted alphabetically, "key = value" aligned, an empty line made of a space. */
24
+ export declare function writeIni(sections: Record<string, Record<string, string>>): string;
25
+ /** Scene files: path (relative to rawdata/levels) -> bytes. */
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":["// Writing an X-Ray SDK 0.7 level scene (CoP): <level>.level and <level>/scene_object.part (ini, CRLF, Windows-1251).\n// The other parts (lights, sectors, portals, spawn, AI grid) are added in LevelEditor.\n\nexport interface SceneObjectOut {\n /** Instance name in the scene. */\n name: string;\n /** Object path in rawdata/objects without extension, for example \"gmv\\\\metro\\\\tunnel_01\". */\n reference: string;\n position: number[];\n /** Angles as in the part file (see sceneRotation), or a 3×3 rotation matrix (row vectors). */\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-file angles from a rotation matrix (the inverse of 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]!); } // degenerate case (pitch ±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/** SDK-style ini: sections and keys sorted alphabetically, \"key = value\" aligned, an empty line made of a space. */\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/** Scene files: path (relative to rawdata/levels) -> bytes. */\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 // camera: above the scene centre\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.1",
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.1",
64
+ "@gmvjs/core": "^0.1.1"
65
+ },
66
+ "devDependencies": {
67
+ "@gmvjs/test-utils": "^0.1.0"
68
+ },
69
+ "publishConfig": {
70
+ "access": "public"
71
+ }
72
+ }