topazcube 0.1.30 → 0.1.33

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 (96) hide show
  1. package/LICENSE.txt +0 -0
  2. package/README.md +0 -0
  3. package/dist/Renderer.cjs +18200 -0
  4. package/dist/Renderer.cjs.map +1 -0
  5. package/dist/Renderer.js +18183 -0
  6. package/dist/Renderer.js.map +1 -0
  7. package/dist/client.cjs +94 -260
  8. package/dist/client.cjs.map +1 -1
  9. package/dist/client.js +71 -215
  10. package/dist/client.js.map +1 -1
  11. package/dist/server.cjs +165 -432
  12. package/dist/server.cjs.map +1 -1
  13. package/dist/server.js +117 -370
  14. package/dist/server.js.map +1 -1
  15. package/dist/terminal.cjs +113 -200
  16. package/dist/terminal.cjs.map +1 -1
  17. package/dist/terminal.js +50 -51
  18. package/dist/terminal.js.map +1 -1
  19. package/dist/utils-CRhi1BDa.cjs +259 -0
  20. package/dist/utils-CRhi1BDa.cjs.map +1 -0
  21. package/dist/utils-D7tXt6-2.js +260 -0
  22. package/dist/utils-D7tXt6-2.js.map +1 -0
  23. package/package.json +19 -15
  24. package/src/{client.ts → network/client.js} +173 -403
  25. package/src/{compress-browser.ts → network/compress-browser.js} +2 -4
  26. package/src/{compress-node.ts → network/compress-node.js} +8 -14
  27. package/src/{server.ts → network/server.js} +229 -317
  28. package/src/{terminal.js → network/terminal.js} +0 -0
  29. package/src/{topazcube.ts → network/topazcube.js} +2 -2
  30. package/src/network/utils.js +375 -0
  31. package/src/renderer/Camera.js +191 -0
  32. package/src/renderer/DebugUI.js +572 -0
  33. package/src/renderer/Geometry.js +1049 -0
  34. package/src/renderer/Material.js +61 -0
  35. package/src/renderer/Mesh.js +211 -0
  36. package/src/renderer/Node.js +112 -0
  37. package/src/renderer/Pipeline.js +643 -0
  38. package/src/renderer/Renderer.js +1324 -0
  39. package/src/renderer/Skin.js +792 -0
  40. package/src/renderer/Texture.js +584 -0
  41. package/src/renderer/core/AssetManager.js +359 -0
  42. package/src/renderer/core/CullingSystem.js +307 -0
  43. package/src/renderer/core/EntityManager.js +541 -0
  44. package/src/renderer/core/InstanceManager.js +343 -0
  45. package/src/renderer/core/ParticleEmitter.js +358 -0
  46. package/src/renderer/core/ParticleSystem.js +564 -0
  47. package/src/renderer/core/SpriteSystem.js +349 -0
  48. package/src/renderer/gltf.js +546 -0
  49. package/src/renderer/math.js +161 -0
  50. package/src/renderer/rendering/HistoryBufferManager.js +333 -0
  51. package/src/renderer/rendering/ProbeCapture.js +1495 -0
  52. package/src/renderer/rendering/ReflectionProbeManager.js +352 -0
  53. package/src/renderer/rendering/RenderGraph.js +2064 -0
  54. package/src/renderer/rendering/passes/AOPass.js +308 -0
  55. package/src/renderer/rendering/passes/AmbientCapturePass.js +593 -0
  56. package/src/renderer/rendering/passes/BasePass.js +101 -0
  57. package/src/renderer/rendering/passes/BloomPass.js +417 -0
  58. package/src/renderer/rendering/passes/FogPass.js +419 -0
  59. package/src/renderer/rendering/passes/GBufferPass.js +706 -0
  60. package/src/renderer/rendering/passes/HiZPass.js +714 -0
  61. package/src/renderer/rendering/passes/LightingPass.js +739 -0
  62. package/src/renderer/rendering/passes/ParticlePass.js +835 -0
  63. package/src/renderer/rendering/passes/PlanarReflectionPass.js +456 -0
  64. package/src/renderer/rendering/passes/PostProcessPass.js +282 -0
  65. package/src/renderer/rendering/passes/ReflectionPass.js +157 -0
  66. package/src/renderer/rendering/passes/RenderPostPass.js +364 -0
  67. package/src/renderer/rendering/passes/SSGIPass.js +265 -0
  68. package/src/renderer/rendering/passes/SSGITilePass.js +296 -0
  69. package/src/renderer/rendering/passes/ShadowPass.js +1822 -0
  70. package/src/renderer/rendering/passes/TransparentPass.js +831 -0
  71. package/src/renderer/rendering/shaders/ao.wgsl +182 -0
  72. package/src/renderer/rendering/shaders/bloom.wgsl +97 -0
  73. package/src/renderer/rendering/shaders/bloom_blur.wgsl +80 -0
  74. package/src/renderer/rendering/shaders/depth_copy.wgsl +17 -0
  75. package/src/renderer/rendering/shaders/geometry.wgsl +550 -0
  76. package/src/renderer/rendering/shaders/hiz_reduce.wgsl +114 -0
  77. package/src/renderer/rendering/shaders/light_culling.wgsl +204 -0
  78. package/src/renderer/rendering/shaders/lighting.wgsl +932 -0
  79. package/src/renderer/rendering/shaders/lighting_common.wgsl +143 -0
  80. package/src/renderer/rendering/shaders/particle_render.wgsl +525 -0
  81. package/src/renderer/rendering/shaders/particle_simulate.wgsl +440 -0
  82. package/src/renderer/rendering/shaders/postproc.wgsl +272 -0
  83. package/src/renderer/rendering/shaders/render_post.wgsl +289 -0
  84. package/src/renderer/rendering/shaders/shadow.wgsl +76 -0
  85. package/src/renderer/rendering/shaders/ssgi.wgsl +266 -0
  86. package/src/renderer/rendering/shaders/ssgi_accumulate.wgsl +114 -0
  87. package/src/renderer/rendering/shaders/ssgi_propagate.wgsl +132 -0
  88. package/src/renderer/utils/BoundingSphere.js +439 -0
  89. package/src/renderer/utils/Frustum.js +281 -0
  90. package/dist/client.d.cts +0 -211
  91. package/dist/client.d.ts +0 -211
  92. package/dist/server.d.cts +0 -120
  93. package/dist/server.d.ts +0 -120
  94. package/dist/terminal.d.cts +0 -64
  95. package/dist/terminal.d.ts +0 -64
  96. package/src/utils.ts +0 -403
@@ -0,0 +1,61 @@
1
+ var _UID = 10001
2
+
3
+ class Material {
4
+
5
+ constructor(textures = [], uniforms = {}, name = null, engine = null) {
6
+ this.uid = _UID++
7
+ this.name = name || `Material_${this.uid}`
8
+ this.uniforms = uniforms
9
+ this._textures = textures
10
+
11
+ this.engine = engine
12
+ // If any textures have .engine, use that
13
+ for (const tex of textures) {
14
+ if (tex && tex.engine) {
15
+ this.engine = tex.engine
16
+ break
17
+ }
18
+ }
19
+
20
+ // Transparency settings
21
+ this.transparent = false // True for alpha blended materials (glass, water)
22
+ this.opacity = 1.0 // Base opacity value (0-1)
23
+ this.opacityTexture = null // Optional opacity texture
24
+
25
+ // Alpha hashing settings (for cutout transparency like leaves)
26
+ this.alphaHash = false
27
+ this.alphaHashScale = 1.0
28
+
29
+ // Alpha source settings
30
+ this.luminanceToAlpha = false // Use base color luminance as alpha (black=transparent)
31
+
32
+ // Force emissive: use base color (albedo) as emission
33
+ this.forceEmissive = false
34
+
35
+ // Specular boost: enables 3 additional specular lights for shiny materials (0-1, default 0 = disabled)
36
+ this.specularBoost = 0
37
+ }
38
+
39
+ /**
40
+ * Get textures array, substituting albedo for emission if forceEmissive is true
41
+ * Texture order: [albedo, normal, ambient, rm, emission]
42
+ */
43
+ get textures() {
44
+ if (this.forceEmissive && this._textures.length >= 5 && this._textures[0]) {
45
+ // Return copy with albedo texture as emission (index 4)
46
+ const result = [...this._textures]
47
+ result[4] = this._textures[0] // Use albedo as emission
48
+ return result
49
+ }
50
+ return this._textures
51
+ }
52
+
53
+ /**
54
+ * Set textures array directly
55
+ */
56
+ set textures(value) {
57
+ this._textures = value
58
+ }
59
+ }
60
+
61
+ export { Material }
@@ -0,0 +1,211 @@
1
+ import { mat4, vec3 } from "./math.js"
2
+
3
+ var _UID = 20001
4
+
5
+ class Mesh {
6
+ constructor(geometry, material, name = null) {
7
+ this.engine = geometry.engine || material.engine
8
+ this.uid = _UID++
9
+ this.name = name || `Mesh_${this.uid}`
10
+ this.geometry = geometry
11
+ this.material = material
12
+
13
+ // Cache for rotation to avoid recalculating from matrix
14
+ this._rotation = { yaw: 0, pitch: 0, roll: 0 }
15
+ this._scale = [1, 1, 1]
16
+ }
17
+
18
+ /**
19
+ * Add an instance with position and optional bounding sphere radius
20
+ * @param {Array} position - Position [x, y, z] or bounding sphere center
21
+ * @param {number} radius - Bounding sphere radius (default 1)
22
+ * @param {Array} uvTransform - UV transform [offsetX, offsetY, scaleX, scaleY] (default [0,0,1,1])
23
+ * @param {Array} color - RGBA color tint (default [1,1,1,1])
24
+ */
25
+ addInstance(position, radius = 1, uvTransform = [0, 0, 1, 1], color = [1, 1, 1, 1]) {
26
+ this.geometry.addInstance(position, radius, uvTransform, color)
27
+ }
28
+
29
+ updateInstance(index, matrix) {
30
+ this.geometry.updateInstance(index, matrix)
31
+ }
32
+
33
+ /**
34
+ * Get position of the first instance (legacy mesh)
35
+ * @returns {[number, number, number]} Position [x, y, z]
36
+ */
37
+ get position() {
38
+ const data = this.geometry.instanceData
39
+ if (!data) return [0, 0, 0]
40
+ return [data[12], data[13], data[14]]
41
+ }
42
+
43
+ /**
44
+ * Set position of the first instance (legacy mesh)
45
+ * @param {[number, number, number]} pos - Position [x, y, z]
46
+ */
47
+ set position(pos) {
48
+ const data = this.geometry.instanceData
49
+ if (!data) return
50
+ data[12] = pos[0]
51
+ data[13] = pos[1]
52
+ data[14] = pos[2]
53
+ this.geometry._instanceDataDirty = true
54
+ }
55
+
56
+ /**
57
+ * Get rotation of the first instance as euler angles
58
+ * @returns {{yaw: number, pitch: number, roll: number}} Rotation in radians
59
+ */
60
+ get rotation() {
61
+ const data = this.geometry.instanceData
62
+ if (!data) return { yaw: 0, pitch: 0, roll: 0 }
63
+
64
+ // Extract rotation from matrix (assuming no shear)
65
+ // Matrix layout: column-major [m0,m1,m2,m3, m4,m5,m6,m7, m8,m9,m10,m11, m12,m13,m14,m15]
66
+ // Column 0: [m0,m1,m2] = right * scaleX
67
+ // Column 1: [m4,m5,m6] = up * scaleY
68
+ // Column 2: [m8,m9,m10] = forward * scaleZ
69
+
70
+ // Get scale to normalize rotation matrix
71
+ const scaleX = Math.sqrt(data[0]*data[0] + data[1]*data[1] + data[2]*data[2])
72
+ const scaleY = Math.sqrt(data[4]*data[4] + data[5]*data[5] + data[6]*data[6])
73
+ const scaleZ = Math.sqrt(data[8]*data[8] + data[9]*data[9] + data[10]*data[10])
74
+
75
+ // Normalized rotation matrix elements
76
+ const m00 = data[0] / scaleX, m01 = data[4] / scaleY, m02 = data[8] / scaleZ
77
+ const m10 = data[1] / scaleX, m11 = data[5] / scaleY, m12 = data[9] / scaleZ
78
+ const m20 = data[2] / scaleX, m21 = data[6] / scaleY, m22 = data[10] / scaleZ
79
+
80
+ // Extract euler angles (YXZ order: yaw, pitch, roll)
81
+ let pitch, yaw, roll
82
+
83
+ if (Math.abs(m12) < 0.99999) {
84
+ pitch = Math.asin(-m12)
85
+ yaw = Math.atan2(m02, m22)
86
+ roll = Math.atan2(m10, m11)
87
+ } else {
88
+ // Gimbal lock
89
+ pitch = m12 < 0 ? Math.PI / 2 : -Math.PI / 2
90
+ yaw = Math.atan2(-m20, m00)
91
+ roll = 0
92
+ }
93
+
94
+ return { yaw, pitch, roll }
95
+ }
96
+
97
+ /**
98
+ * Set rotation of the first instance using euler angles
99
+ * Rebuilds the transform matrix preserving position and scale
100
+ * @param {{yaw?: number, pitch?: number, roll?: number}} rot - Rotation in radians
101
+ */
102
+ set rotation(rot) {
103
+ const data = this.geometry.instanceData
104
+ if (!data) return
105
+
106
+ // Get current position
107
+ const pos = [data[12], data[13], data[14]]
108
+
109
+ // Get current scale
110
+ const scaleX = Math.sqrt(data[0]*data[0] + data[1]*data[1] + data[2]*data[2])
111
+ const scaleY = Math.sqrt(data[4]*data[4] + data[5]*data[5] + data[6]*data[6])
112
+ const scaleZ = Math.sqrt(data[8]*data[8] + data[9]*data[9] + data[10]*data[10])
113
+
114
+ // Update cached rotation
115
+ const yaw = rot.yaw ?? this._rotation.yaw
116
+ const pitch = rot.pitch ?? this._rotation.pitch
117
+ const roll = rot.roll ?? this._rotation.roll
118
+ this._rotation = { yaw, pitch, roll }
119
+
120
+ // Build rotation matrix (YXZ order)
121
+ const cy = Math.cos(yaw), sy = Math.sin(yaw)
122
+ const cp = Math.cos(pitch), sp = Math.sin(pitch)
123
+ const cr = Math.cos(roll), sr = Math.sin(roll)
124
+
125
+ // Combined rotation matrix R = Ry * Rx * Rz
126
+ const m00 = cy * cr + sy * sp * sr
127
+ const m01 = -cy * sr + sy * sp * cr
128
+ const m02 = sy * cp
129
+ const m10 = cp * sr
130
+ const m11 = cp * cr
131
+ const m12 = -sp
132
+ const m20 = -sy * cr + cy * sp * sr
133
+ const m21 = sy * sr + cy * sp * cr
134
+ const m22 = cy * cp
135
+
136
+ // Apply scale and write to instance data
137
+ data[0] = m00 * scaleX; data[1] = m10 * scaleX; data[2] = m20 * scaleX; data[3] = 0
138
+ data[4] = m01 * scaleY; data[5] = m11 * scaleY; data[6] = m21 * scaleY; data[7] = 0
139
+ data[8] = m02 * scaleZ; data[9] = m12 * scaleZ; data[10] = m22 * scaleZ; data[11] = 0
140
+ data[12] = pos[0]; data[13] = pos[1]; data[14] = pos[2]; data[15] = 1
141
+
142
+ this.geometry._instanceDataDirty = true
143
+ }
144
+
145
+ /**
146
+ * Get scale of the first instance
147
+ * @returns {[number, number, number]} Scale [x, y, z]
148
+ */
149
+ get scale() {
150
+ const data = this.geometry.instanceData
151
+ if (!data) return [1, 1, 1]
152
+
153
+ const scaleX = Math.sqrt(data[0]*data[0] + data[1]*data[1] + data[2]*data[2])
154
+ const scaleY = Math.sqrt(data[4]*data[4] + data[5]*data[5] + data[6]*data[6])
155
+ const scaleZ = Math.sqrt(data[8]*data[8] + data[9]*data[9] + data[10]*data[10])
156
+
157
+ return [scaleX, scaleY, scaleZ]
158
+ }
159
+
160
+ /**
161
+ * Set scale of the first instance
162
+ * Rebuilds the transform matrix preserving position and rotation
163
+ * @param {[number, number, number]} s - Scale [x, y, z]
164
+ */
165
+ set scale(s) {
166
+ const data = this.geometry.instanceData
167
+ if (!data) return
168
+
169
+ // Get current scale to compute ratio
170
+ const oldScaleX = Math.sqrt(data[0]*data[0] + data[1]*data[1] + data[2]*data[2])
171
+ const oldScaleY = Math.sqrt(data[4]*data[4] + data[5]*data[5] + data[6]*data[6])
172
+ const oldScaleZ = Math.sqrt(data[8]*data[8] + data[9]*data[9] + data[10]*data[10])
173
+
174
+ // Scale ratio
175
+ const rx = oldScaleX > 0 ? s[0] / oldScaleX : s[0]
176
+ const ry = oldScaleY > 0 ? s[1] / oldScaleY : s[1]
177
+ const rz = oldScaleZ > 0 ? s[2] / oldScaleZ : s[2]
178
+
179
+ // Apply new scale to rotation columns
180
+ data[0] *= rx; data[1] *= rx; data[2] *= rx
181
+ data[4] *= ry; data[5] *= ry; data[6] *= ry
182
+ data[8] *= rz; data[9] *= rz; data[10] *= rz
183
+
184
+ this.geometry._instanceDataDirty = true
185
+ }
186
+
187
+ /**
188
+ * Get the full transform matrix of the first instance
189
+ * @returns {Float32Array} 4x4 transform matrix (16 floats)
190
+ */
191
+ get matrix() {
192
+ const data = this.geometry.instanceData
193
+ if (!data) return mat4.create()
194
+ return new Float32Array(data.buffer, data.byteOffset, 16)
195
+ }
196
+
197
+ /**
198
+ * Set the full transform matrix of the first instance
199
+ * @param {Float32Array|Array} m - 4x4 transform matrix
200
+ */
201
+ set matrix(m) {
202
+ const data = this.geometry.instanceData
203
+ if (!data) return
204
+ for (let i = 0; i < 16; i++) {
205
+ data[i] = m[i]
206
+ }
207
+ this.geometry._instanceDataDirty = true
208
+ }
209
+ }
210
+
211
+ export { Mesh }
@@ -0,0 +1,112 @@
1
+ import { fromEuler, toEuler, UP, RIGHT, FORWARD, V_T, V_T2 } from "./math.js"
2
+
3
+ class Node {
4
+
5
+ constructor() {
6
+ this.name = null
7
+ this.position = vec3.create()
8
+ this.rotation = quat.create()
9
+ this.scale = vec3.fromValues(1, 1, 1)
10
+ this.children = []
11
+
12
+ // calculated matrices
13
+ this.matrix = mat4.create()
14
+ this.world = mat4.create()
15
+ this.inv = mat4.create()
16
+ this.normal = mat4.create()
17
+ }
18
+
19
+ fromEuler(euler) {
20
+ //console.log('before fromEuler', this.rotation)
21
+ fromEuler(euler, this.rotation)
22
+ //console.log('after fromEuler', this.rotation)
23
+ }
24
+
25
+ get yaw() {
26
+ toEuler(this.rotation, V_T)
27
+ //console.log('get yaw', V_T[0])
28
+ return V_T[1]
29
+ }
30
+
31
+ set yaw(yaw) {
32
+ //console.log('--- set yaw', yaw)
33
+ //console.log('--- set before rotation', this.rotation)
34
+ toEuler(this.rotation, V_T2)
35
+ //console.log('toEuler', V_T2)
36
+ V_T2[1] = yaw
37
+ this.fromEuler(V_T2)
38
+ }
39
+
40
+ rotateYaw(yaw) {
41
+ this.yaw += yaw
42
+ }
43
+
44
+ get pitch() {
45
+ toEuler(this.rotation, V_T)
46
+ return V_T[0]
47
+ }
48
+
49
+ set pitch(pitch) {
50
+ toEuler(this.rotation, V_T2)
51
+ V_T2[0] = pitch
52
+ this.fromEuler(V_T2)
53
+ }
54
+
55
+ rotatePitch(pitch) {
56
+ this.pitch += pitch
57
+ }
58
+
59
+ limitPitch() {
60
+ // Convert current pitch to degrees
61
+ let pitchDegrees = this.pitch * (180 / Math.PI);
62
+
63
+ // Clamp pitch between -89.9 and 89.9 degrees
64
+ pitchDegrees = Math.max(-89, Math.min(89, pitchDegrees));
65
+
66
+ // Convert back to radians and set the pitch
67
+ this.pitch = pitchDegrees * (Math.PI / 180);
68
+ }
69
+
70
+ get roll() {
71
+ toEuler(this.rotation, V_T)
72
+ return V_T[2]
73
+ }
74
+
75
+ set roll(roll) {
76
+ toEuler(this.rotation, V_T2)
77
+ V_T2[2] = roll
78
+ this.fromEuler(V_T2)
79
+ }
80
+
81
+ rotateRoll(roll) {
82
+ this.roll += roll
83
+ }
84
+
85
+ updateMatrix(parentMatrix) {
86
+ mat4.fromRotationTranslationScale(this.matrix, this.rotation, this.position, this.scale)
87
+ mat4.identity(this.world)
88
+ mat4.multiply(this.world, this.world, this.matrix)
89
+ if (parentMatrix) {
90
+ mat4.multiply(this.world, this.world, parentMatrix)
91
+ }
92
+ mat4.invert(this.inv, this.world)
93
+ mat4.transpose(this.normal, this.inv)
94
+ if (this.direction) {
95
+ vec3.set(this.direction, 0, 0, -1)
96
+ vec3.transformQuat(this.direction, this.direction, this.rotation)
97
+ }
98
+ if (this.right) {
99
+ vec3.set(this.right, 1, 0, 0)
100
+ vec3.transformQuat(this.right, this.right, this.rotation)
101
+ }
102
+ for (let child of this.children) {
103
+ child.updateMatrix(this.world)
104
+ }
105
+ }
106
+
107
+ addChild(child) {
108
+ this.children.push(child)
109
+ }
110
+ }
111
+
112
+ export { Node, toEuler, fromEuler }