@galfus/engine 0.0.0-stage → 0.31.0-alpha

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 (80) hide show
  1. package/README.md +190 -2
  2. package/package.json +59 -4
  3. package/src/anchors/cache.ts +101 -0
  4. package/src/anchors/component.ts +123 -0
  5. package/src/anchors/hierarchy.ts +192 -0
  6. package/src/anchors/index.ts +8 -0
  7. package/src/anchors/solver.ts +247 -0
  8. package/src/anchors/strategy.ts +142 -0
  9. package/src/animation/blending.ts +163 -0
  10. package/src/animation/clip.ts +132 -0
  11. package/src/animation/coordinator.ts +568 -0
  12. package/src/animation/index.ts +7 -0
  13. package/src/animation/native-targets.ts +37 -0
  14. package/src/animation/player.ts +287 -0
  15. package/src/audio/index.ts +4 -0
  16. package/src/audio/manager.ts +371 -0
  17. package/src/collision/components.ts +211 -0
  18. package/src/collision/index.ts +16 -0
  19. package/src/collision/query2d.ts +167 -0
  20. package/src/collision/query3d.ts +170 -0
  21. package/src/ecs/component.ts +130 -0
  22. package/src/ecs/entity.ts +75 -0
  23. package/src/ecs/index.ts +9 -0
  24. package/src/ecs/intent.ts +162 -0
  25. package/src/ecs/metadata.ts +44 -0
  26. package/src/ecs/system.ts +224 -0
  27. package/src/ecs/world.ts +291 -0
  28. package/src/index.ts +19 -0
  29. package/src/interaction/focus.ts +327 -0
  30. package/src/interaction/index.ts +9 -0
  31. package/src/interaction/listener.ts +58 -0
  32. package/src/interaction/snapshot2d.ts +210 -0
  33. package/src/interaction/snapshot3d.ts +214 -0
  34. package/src/interaction/system.ts +544 -0
  35. package/src/interaction/types.ts +27 -0
  36. package/src/math/common.ts +67 -0
  37. package/src/math/index.ts +17 -0
  38. package/src/math/mat2d.ts +320 -0
  39. package/src/math/mat4.ts +576 -0
  40. package/src/math/quat.ts +438 -0
  41. package/src/math/vec2.ts +161 -0
  42. package/src/math/vec3.ts +242 -0
  43. package/src/math/vec4.ts +171 -0
  44. package/src/multiverse/coordinator.ts +540 -0
  45. package/src/multiverse/index.ts +13 -0
  46. package/src/multiverse/presentation-graph.ts +306 -0
  47. package/src/multiverse/presentation-links.ts +134 -0
  48. package/src/multiverse/realm.ts +49 -0
  49. package/src/platform/index.ts +2 -0
  50. package/src/platform/platform.ts +149 -0
  51. package/src/platform/window.ts +181 -0
  52. package/src/realm2d/components.ts +254 -0
  53. package/src/realm2d/index.ts +12 -0
  54. package/src/realm2d/presets/index.ts +36 -0
  55. package/src/realm2d/realm.ts +522 -0
  56. package/src/realm2d/sync.ts +284 -0
  57. package/src/realm2d/utils/index.ts +32 -0
  58. package/src/realm3d/components.ts +341 -0
  59. package/src/realm3d/geometry.ts +224 -0
  60. package/src/realm3d/index.ts +12 -0
  61. package/src/realm3d/presets/index.ts +67 -0
  62. package/src/realm3d/realm.ts +588 -0
  63. package/src/realm3d/resource-ids.ts +62 -0
  64. package/src/realm3d/skinning.ts +128 -0
  65. package/src/realm3d/sync.ts +442 -0
  66. package/src/realm3d/utils/index.ts +26 -0
  67. package/src/resources/index.ts +4 -0
  68. package/src/resources/manager.ts +92 -0
  69. package/src/runtime.ts +588 -0
  70. package/src/spatial/dirty_registry.ts +217 -0
  71. package/src/spatial/flags.ts +14 -0
  72. package/src/spatial/index.ts +6 -0
  73. package/src/spatial/metrics.ts +124 -0
  74. package/src/text/editor.ts +224 -0
  75. package/src/text/encoding.ts +38 -0
  76. package/src/text/index.ts +13 -0
  77. package/src/text/input.ts +160 -0
  78. package/src/text/keyboard.ts +50 -0
  79. package/src/text/svg-decorations.ts +147 -0
  80. package/src/types.ts +85 -0
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Semantic 3D Geometry definitions, vertex packing, and morph target utilities for Galfus Engine.
3
+ */
4
+ export interface GeometryData {
5
+ /** 3 float components per vertex: [x, y, z, ...] (Required) */
6
+ positions: Float32Array;
7
+ /** 3 float components per vertex: [nx, ny, nz, ...] (Optional, fallback: [0, 1, 0]) */
8
+ normals?: Float32Array;
9
+ /** 2 float components per vertex: [u, v, ...] (Optional, primary UV0, fallback: [0, 0]) */
10
+ uvs?: Float32Array;
11
+ /** 2 float components per vertex: [u, v, ...] (Optional, secondary UV1, fallback: [0, 0]) */
12
+ uv1?: Float32Array;
13
+ /** 4 float components per vertex: [x, y, z, w] (Optional, tangent with bitangent sign, fallback: [1, 0, 0, 1]) */
14
+ tangents?: Float32Array;
15
+ /** 4 float components per vertex: [r, g, b, a] (Optional, linear vertex color, fallback: [1, 1, 1, 1]) */
16
+ colors?: Float32Array;
17
+ /** 4 bone indices per vertex: [j0, j1, j2, j3] (Optional, primary 4 joints, fallback: [0, 0, 0, 0]) */
18
+ joints0?: Uint32Array | Uint16Array;
19
+ /** 4 bone influence weights per vertex: [w0, w1, w2, w3] (Optional, primary 4 weights, fallback: [0, 0, 0, 0]) */
20
+ weights0?: Float32Array;
21
+ /** 4 bone indices per vertex: [j4, j5, j6, j7] (Optional, secondary 4 joints, fallback: [0, 0, 0, 0]) */
22
+ joints1?: Uint32Array | Uint16Array;
23
+ /** 4 bone influence weights per vertex: [w4, w5, w6, w7] (Optional, secondary 4 weights, fallback: [0, 0, 0, 0]) */
24
+ weights1?: Float32Array;
25
+ /** Index buffer (Optional. If omitted, sequential indices [0..N-1] are generated) */
26
+ indices?: Uint32Array | Uint16Array;
27
+ /** Primitive topology: 0 = Points, 1 = Lines, 2 = LineStrip, 3 = Triangles, 4 = TriangleStrip. Default: 3 */
28
+ topology?: number;
29
+ }
30
+
31
+ export const VERTEX_STRIDE_BYTES = 136;
32
+ export const MORPH_VERTEX_STRIDE_BYTES = 48;
33
+
34
+ /**
35
+ * Packs separate semantic attribute arrays into the canonical 136-byte packed layout.
36
+ */
37
+ export function packGeometryData(data: GeometryData): {
38
+ topology: number;
39
+ vertexData: Uint8Array;
40
+ indices: Uint32Array;
41
+ } {
42
+ const vertexCount = Math.floor(data.positions.length / 3);
43
+ const vertexData = new Uint8Array(vertexCount * VERTEX_STRIDE_BYTES);
44
+ const view = new DataView(vertexData.buffer);
45
+
46
+ for (let i = 0; i < vertexCount; i++) {
47
+ const offset = i * VERTEX_STRIDE_BYTES;
48
+
49
+ // Position (Float32x3 at offset 0..12)
50
+ view.setFloat32(offset + 0, data.positions[i * 3 + 0] ?? 0, true);
51
+ view.setFloat32(offset + 4, data.positions[i * 3 + 1] ?? 0, true);
52
+ view.setFloat32(offset + 8, data.positions[i * 3 + 2] ?? 0, true);
53
+
54
+ // Normal (Float32x3 at offset 12..24)
55
+ if (data.normals) {
56
+ view.setFloat32(offset + 12, data.normals[i * 3 + 0] ?? 0, true);
57
+ view.setFloat32(offset + 16, data.normals[i * 3 + 1] ?? 1, true);
58
+ view.setFloat32(offset + 20, data.normals[i * 3 + 2] ?? 0, true);
59
+ } else {
60
+ view.setFloat32(offset + 16, 1, true); // default normal +Y
61
+ }
62
+
63
+ // UV0 (Float32x2 at offset 24..32)
64
+ if (data.uvs) {
65
+ view.setFloat32(offset + 24, data.uvs[i * 2 + 0] ?? 0, true);
66
+ view.setFloat32(offset + 28, data.uvs[i * 2 + 1] ?? 0, true);
67
+ }
68
+
69
+ // UV1 (Float32x2 at offset 32..40)
70
+ if (data.uv1) {
71
+ view.setFloat32(offset + 32, data.uv1[i * 2 + 0] ?? 0, true);
72
+ view.setFloat32(offset + 36, data.uv1[i * 2 + 1] ?? 0, true);
73
+ }
74
+
75
+ // Tangent (Float32x4 at offset 40..56) - default [1.0, 0.0, 0.0, 1.0]
76
+ if (data.tangents) {
77
+ view.setFloat32(offset + 40, data.tangents[i * 4 + 0] ?? 1, true);
78
+ view.setFloat32(offset + 44, data.tangents[i * 4 + 1] ?? 0, true);
79
+ view.setFloat32(offset + 48, data.tangents[i * 4 + 2] ?? 0, true);
80
+ view.setFloat32(offset + 52, data.tangents[i * 4 + 3] ?? 1, true);
81
+ } else {
82
+ view.setFloat32(offset + 40, 1, true);
83
+ view.setFloat32(offset + 52, 1, true);
84
+ }
85
+
86
+ // Color (Float32x4 linear RGBA at offset 56..72) - default [1.0, 1.0, 1.0, 1.0]
87
+ if (data.colors) {
88
+ view.setFloat32(offset + 56, data.colors[i * 4 + 0] ?? 1, true);
89
+ view.setFloat32(offset + 60, data.colors[i * 4 + 1] ?? 1, true);
90
+ view.setFloat32(offset + 64, data.colors[i * 4 + 2] ?? 1, true);
91
+ view.setFloat32(offset + 68, data.colors[i * 4 + 3] ?? 1, true);
92
+ } else {
93
+ view.setFloat32(offset + 56, 1, true);
94
+ view.setFloat32(offset + 60, 1, true);
95
+ view.setFloat32(offset + 64, 1, true);
96
+ view.setFloat32(offset + 68, 1, true);
97
+ }
98
+
99
+ // Joints0 (Uint32x4 at offset 72..88)
100
+ if (data.joints0) {
101
+ view.setUint32(offset + 72, data.joints0[i * 4 + 0] ?? 0, true);
102
+ view.setUint32(offset + 76, data.joints0[i * 4 + 1] ?? 0, true);
103
+ view.setUint32(offset + 80, data.joints0[i * 4 + 2] ?? 0, true);
104
+ view.setUint32(offset + 84, data.joints0[i * 4 + 3] ?? 0, true);
105
+ }
106
+
107
+ // Weights0 (Float32x4 at offset 88..104)
108
+ if (data.weights0) {
109
+ view.setFloat32(offset + 88, data.weights0[i * 4 + 0] ?? 0, true);
110
+ view.setFloat32(offset + 92, data.weights0[i * 4 + 1] ?? 0, true);
111
+ view.setFloat32(offset + 96, data.weights0[i * 4 + 2] ?? 0, true);
112
+ view.setFloat32(offset + 100, data.weights0[i * 4 + 3] ?? 0, true);
113
+ }
114
+
115
+ // Joints1 (Uint32x4 at offset 104..120)
116
+ if (data.joints1) {
117
+ view.setUint32(offset + 104, data.joints1[i * 4 + 0] ?? 0, true);
118
+ view.setUint32(offset + 108, data.joints1[i * 4 + 1] ?? 0, true);
119
+ view.setUint32(offset + 112, data.joints1[i * 4 + 2] ?? 0, true);
120
+ view.setUint32(offset + 116, data.joints1[i * 4 + 3] ?? 0, true);
121
+ }
122
+
123
+ // Weights1 (Float32x4 at offset 120..136)
124
+ if (data.weights1) {
125
+ view.setFloat32(offset + 120, data.weights1[i * 4 + 0] ?? 0, true);
126
+ view.setFloat32(offset + 124, data.weights1[i * 4 + 1] ?? 0, true);
127
+ view.setFloat32(offset + 128, data.weights1[i * 4 + 2] ?? 0, true);
128
+ view.setFloat32(offset + 132, data.weights1[i * 4 + 3] ?? 0, true);
129
+ }
130
+ }
131
+
132
+ let indices: Uint32Array;
133
+ if (data.indices) {
134
+ indices = data.indices instanceof Uint32Array ? data.indices : new Uint32Array(data.indices);
135
+ } else {
136
+ indices = new Uint32Array(vertexCount);
137
+ for (let k = 0; k < vertexCount; k++) {
138
+ indices[k] = k;
139
+ }
140
+ }
141
+
142
+ return {
143
+ topology: data.topology ?? 3,
144
+ vertexData,
145
+ indices
146
+ };
147
+ }
148
+
149
+ /**
150
+ * Morph target per-vertex deltas for position, normal, and tangent.
151
+ */
152
+ export interface MorphTargetData {
153
+ /** 3 float components per vertex delta: [dx, dy, dz, ...] */
154
+ positions?: Float32Array;
155
+ /** 3 float components per vertex delta: [nx, ny, nz, ...] */
156
+ normals?: Float32Array;
157
+ /** 3 float components per vertex delta: [tx, ty, tz, ...] */
158
+ tangents?: Float32Array;
159
+ }
160
+
161
+ /**
162
+ * Packs morph target deltas into contiguous 48-byte records (target-major).
163
+ */
164
+ export function packMorphTargets(
165
+ targets: MorphTargetData[],
166
+ vertexCount: number
167
+ ): { targetData: Uint8Array; targetCount: number } {
168
+ const targetCount = targets.length;
169
+ const targetData = new Uint8Array(targetCount * vertexCount * MORPH_VERTEX_STRIDE_BYTES);
170
+ const view = new DataView(targetData.buffer);
171
+
172
+ for (let t = 0; t < targetCount; t++) {
173
+ const target = targets[t];
174
+ const targetBase = t * vertexCount * MORPH_VERTEX_STRIDE_BYTES;
175
+
176
+ for (let i = 0; i < vertexCount; i++) {
177
+ const offset = targetBase + i * MORPH_VERTEX_STRIDE_BYTES;
178
+
179
+ // Position delta [dx, dy, dz, 0.0] (offset 0..16)
180
+ if (target?.positions) {
181
+ view.setFloat32(offset + 0, target.positions[i * 3 + 0] ?? 0, true);
182
+ view.setFloat32(offset + 4, target.positions[i * 3 + 1] ?? 0, true);
183
+ view.setFloat32(offset + 8, target.positions[i * 3 + 2] ?? 0, true);
184
+ }
185
+ view.setFloat32(offset + 12, 0.0, true);
186
+
187
+ // Normal delta [nx, ny, nz, 0.0] (offset 16..32)
188
+ if (target?.normals) {
189
+ view.setFloat32(offset + 16, target.normals[i * 3 + 0] ?? 0, true);
190
+ view.setFloat32(offset + 20, target.normals[i * 3 + 1] ?? 0, true);
191
+ view.setFloat32(offset + 24, target.normals[i * 3 + 2] ?? 0, true);
192
+ }
193
+ view.setFloat32(offset + 28, 0.0, true);
194
+
195
+ // Tangent delta [tx, ty, tz, 0.0] (offset 32..48)
196
+ if (target?.tangents) {
197
+ view.setFloat32(offset + 32, target.tangents[i * 3 + 0] ?? 0, true);
198
+ view.setFloat32(offset + 36, target.tangents[i * 3 + 1] ?? 0, true);
199
+ view.setFloat32(offset + 40, target.tangents[i * 3 + 2] ?? 0, true);
200
+ }
201
+ view.setFloat32(offset + 44, 0.0, true);
202
+ }
203
+ }
204
+
205
+ return { targetData, targetCount };
206
+ }
207
+
208
+ /** Validates and packs morph targets for a registered custom geometry. */
209
+ export function prepareMorphTargets(
210
+ targetData: Uint8Array | MorphTargetData[],
211
+ vertexCount: number | undefined,
212
+ vertexDataByteLength?: number
213
+ ): { data: Uint8Array; count: number } {
214
+ const count =
215
+ vertexCount ??
216
+ (vertexDataByteLength === undefined ? undefined : vertexDataByteLength / VERTEX_STRIDE_BYTES);
217
+ if (!count || !Number.isInteger(count)) throw new Error('Morph targets require a vertex count');
218
+ const packed =
219
+ targetData instanceof Uint8Array
220
+ ? { targetData, targetCount: targetData.byteLength / (count * MORPH_VERTEX_STRIDE_BYTES) }
221
+ : packMorphTargets(targetData, count);
222
+ if (!Number.isInteger(packed.targetCount)) throw new Error('Invalid morph target data length');
223
+ return { data: packed.targetData, count: packed.targetCount };
224
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Subpath export for Realm3D subsystem.
3
+ */
4
+ export * from './components';
5
+ export * from './geometry';
6
+ export * as presets3D from './presets/index';
7
+ export * from './realm';
8
+ export * from './skinning';
9
+ export * from './sync';
10
+ export * as utils3D from './utils/index';
11
+
12
+ export { Collider3DComponent, createCollider3D } from '../collision/components';
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Realm 3D presets for camera and lighting configurations.
3
+ */
4
+
5
+ import type { Camera3DDesc, Light3DDesc, Material3DDesc } from '@galfus/transport-types';
6
+
7
+ export function createPerspectiveCamera3DPreset(
8
+ options: {
9
+ fovY?: number;
10
+ near?: number;
11
+ far?: number;
12
+ cameraSlot?: number;
13
+ } = {}
14
+ ): Camera3DDesc {
15
+ return {
16
+ kind: 'perspective',
17
+ fovY: options.fovY ?? 60.0,
18
+ near: options.near ?? 0.1,
19
+ far: options.far ?? 1000.0,
20
+ cameraSlot: options.cameraSlot ?? 0
21
+ };
22
+ }
23
+
24
+ export function createPointLight3DPreset(
25
+ options: {
26
+ color?: [number, number, number];
27
+ intensity?: number;
28
+ range?: number;
29
+ } = {}
30
+ ): Light3DDesc {
31
+ return {
32
+ kind: 'point',
33
+ range: options.range ?? 20.0,
34
+ color: options.color ?? [1.0, 1.0, 1.0],
35
+ intensity: options.intensity ?? 3.0
36
+ };
37
+ }
38
+
39
+ export function createDirectionalLight3DPreset(
40
+ options: {
41
+ color?: [number, number, number];
42
+ intensity?: number;
43
+ castShadow?: boolean;
44
+ } = {}
45
+ ): Light3DDesc {
46
+ return {
47
+ kind: 'directional',
48
+ color: options.color ?? [1.0, 1.0, 1.0],
49
+ intensity: options.intensity ?? 2.5,
50
+ castShadow: options.castShadow ?? false
51
+ };
52
+ }
53
+
54
+ export function createPbrMaterialPreset(
55
+ options: {
56
+ baseColor?: [number, number, number, number];
57
+ roughness?: number;
58
+ metallic?: number;
59
+ } = {}
60
+ ): Material3DDesc {
61
+ return {
62
+ surfaceType: 'opaque',
63
+ baseColor: options.baseColor ?? [1.0, 1.0, 1.0, 1.0],
64
+ roughness: options.roughness ?? 0.5,
65
+ metallic: options.metallic ?? 0.0
66
+ };
67
+ }