@opsydyn/effect-three 0.0.0-stage → 0.2.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 (166) hide show
  1. package/CHANGELOG.md +69 -0
  2. package/LICENSE +21 -0
  3. package/README.md +189 -2
  4. package/dist/index-01kwfekm.js +5118 -0
  5. package/dist/index-01kwfekm.js.map +40 -0
  6. package/dist/index-4045wme0.js +129 -0
  7. package/dist/index-4045wme0.js.map +10 -0
  8. package/dist/index.d.ts +12 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +1361 -0
  11. package/dist/index.js.map +14 -0
  12. package/dist/kernel/animation.d.ts +14 -0
  13. package/dist/kernel/animation.d.ts.map +1 -0
  14. package/dist/kernel/behaviours.d.ts +16 -0
  15. package/dist/kernel/behaviours.d.ts.map +1 -0
  16. package/dist/kernel/bodies.d.ts +60 -0
  17. package/dist/kernel/bodies.d.ts.map +1 -0
  18. package/dist/kernel/bodySources.d.ts +47 -0
  19. package/dist/kernel/bodySources.d.ts.map +1 -0
  20. package/dist/kernel/build.d.ts +564 -0
  21. package/dist/kernel/build.d.ts.map +1 -0
  22. package/dist/kernel/cameraMotion.d.ts +39 -0
  23. package/dist/kernel/cameraMotion.d.ts.map +1 -0
  24. package/dist/kernel/clock.d.ts +17 -0
  25. package/dist/kernel/clock.d.ts.map +1 -0
  26. package/dist/kernel/contactShadowPasses.d.ts +47 -0
  27. package/dist/kernel/contactShadowPasses.d.ts.map +1 -0
  28. package/dist/kernel/description.d.ts +1120 -0
  29. package/dist/kernel/description.d.ts.map +1 -0
  30. package/dist/kernel/diff.d.ts +90 -0
  31. package/dist/kernel/diff.d.ts.map +1 -0
  32. package/dist/kernel/environmentPresets.d.ts +30 -0
  33. package/dist/kernel/environmentPresets.d.ts.map +1 -0
  34. package/dist/kernel/equality.d.ts +64 -0
  35. package/dist/kernel/equality.d.ts.map +1 -0
  36. package/dist/kernel/frames.d.ts +55 -0
  37. package/dist/kernel/frames.d.ts.map +1 -0
  38. package/dist/kernel/index.d.ts +37 -0
  39. package/dist/kernel/index.d.ts.map +1 -0
  40. package/dist/kernel/index.js +335 -0
  41. package/dist/kernel/index.js.map +9 -0
  42. package/dist/kernel/instances.d.ts +26 -0
  43. package/dist/kernel/instances.d.ts.map +1 -0
  44. package/dist/kernel/labels.d.ts +51 -0
  45. package/dist/kernel/labels.d.ts.map +1 -0
  46. package/dist/kernel/loop.d.ts +49 -0
  47. package/dist/kernel/loop.d.ts.map +1 -0
  48. package/dist/kernel/materials.d.ts +24 -0
  49. package/dist/kernel/materials.d.ts.map +1 -0
  50. package/dist/kernel/motion.d.ts +36 -0
  51. package/dist/kernel/motion.d.ts.map +1 -0
  52. package/dist/kernel/orbit.d.ts +127 -0
  53. package/dist/kernel/orbit.d.ts.map +1 -0
  54. package/dist/kernel/overlays.d.ts +16 -0
  55. package/dist/kernel/overlays.d.ts.map +1 -0
  56. package/dist/kernel/performance.d.ts +41 -0
  57. package/dist/kernel/performance.d.ts.map +1 -0
  58. package/dist/kernel/physics.d.ts +166 -0
  59. package/dist/kernel/physics.d.ts.map +1 -0
  60. package/dist/kernel/physicsDebug.d.ts +18 -0
  61. package/dist/kernel/physicsDebug.d.ts.map +1 -0
  62. package/dist/kernel/pointer.d.ts +357 -0
  63. package/dist/kernel/pointer.d.ts.map +1 -0
  64. package/dist/kernel/renderKit.d.ts +49 -0
  65. package/dist/kernel/renderKit.d.ts.map +1 -0
  66. package/dist/kernel/renderer.d.ts +83 -0
  67. package/dist/kernel/renderer.d.ts.map +1 -0
  68. package/dist/kernel/resources.d.ts +112 -0
  69. package/dist/kernel/resources.d.ts.map +1 -0
  70. package/dist/kernel/sceneGraph.d.ts +155 -0
  71. package/dist/kernel/sceneGraph.d.ts.map +1 -0
  72. package/dist/kernel/sceneIndex.d.ts +90 -0
  73. package/dist/kernel/sceneIndex.d.ts.map +1 -0
  74. package/dist/kernel/stage.d.ts +87 -0
  75. package/dist/kernel/stage.d.ts.map +1 -0
  76. package/dist/kernel/textLayout.d.ts +29 -0
  77. package/dist/kernel/textLayout.d.ts.map +1 -0
  78. package/dist/kernel/tween.d.ts +35 -0
  79. package/dist/kernel/tween.d.ts.map +1 -0
  80. package/dist/kernel/xrInput.d.ts +107 -0
  81. package/dist/kernel/xrInput.d.ts.map +1 -0
  82. package/dist/kernel/xrLocomotion.d.ts +38 -0
  83. package/dist/kernel/xrLocomotion.d.ts.map +1 -0
  84. package/dist/runtime/FrameSource.d.ts +29 -0
  85. package/dist/runtime/FrameSource.d.ts.map +1 -0
  86. package/dist/runtime/ResourceRegistry.d.ts +18 -0
  87. package/dist/runtime/ResourceRegistry.d.ts.map +1 -0
  88. package/dist/runtime/SceneRuntime.d.ts +68 -0
  89. package/dist/runtime/SceneRuntime.d.ts.map +1 -0
  90. package/dist/runtime/SceneSchema.d.ts +2536 -0
  91. package/dist/runtime/SceneSchema.d.ts.map +1 -0
  92. package/dist/runtime/errors.d.ts +19 -0
  93. package/dist/runtime/errors.d.ts.map +1 -0
  94. package/dist/runtime/index.d.ts +11 -0
  95. package/dist/runtime/index.d.ts.map +1 -0
  96. package/dist/webgl/contactShadows.d.ts +5 -0
  97. package/dist/webgl/contactShadows.d.ts.map +1 -0
  98. package/dist/webgl/index.d.ts +11 -0
  99. package/dist/webgl/index.d.ts.map +1 -0
  100. package/dist/webgl/index.js +239 -0
  101. package/dist/webgl/index.js.map +13 -0
  102. package/dist/webgl/shaderGrid.d.ts +27 -0
  103. package/dist/webgl/shaderGrid.d.ts.map +1 -0
  104. package/dist/webgl/sky.d.ts +4 -0
  105. package/dist/webgl/sky.d.ts.map +1 -0
  106. package/dist/webgpu/contactShadows.d.ts +5 -0
  107. package/dist/webgpu/contactShadows.d.ts.map +1 -0
  108. package/dist/webgpu/index.d.ts +10 -0
  109. package/dist/webgpu/index.d.ts.map +1 -0
  110. package/dist/webgpu/index.js +216 -0
  111. package/dist/webgpu/index.js.map +13 -0
  112. package/dist/webgpu/shaderGrid.d.ts +5 -0
  113. package/dist/webgpu/shaderGrid.d.ts.map +1 -0
  114. package/dist/webgpu/sky.d.ts +4 -0
  115. package/dist/webgpu/sky.d.ts.map +1 -0
  116. package/package.json +82 -4
  117. package/src/index.ts +11 -0
  118. package/src/kernel/animation.ts +24 -0
  119. package/src/kernel/behaviours.ts +36 -0
  120. package/src/kernel/bodies.ts +338 -0
  121. package/src/kernel/bodySources.ts +203 -0
  122. package/src/kernel/build.ts +1325 -0
  123. package/src/kernel/cameraMotion.ts +202 -0
  124. package/src/kernel/clock.ts +35 -0
  125. package/src/kernel/contactShadowPasses.ts +207 -0
  126. package/src/kernel/description.ts +1197 -0
  127. package/src/kernel/diff.ts +383 -0
  128. package/src/kernel/environmentPresets.ts +38 -0
  129. package/src/kernel/equality.ts +604 -0
  130. package/src/kernel/frames.ts +124 -0
  131. package/src/kernel/index.ts +274 -0
  132. package/src/kernel/instances.ts +97 -0
  133. package/src/kernel/labels.ts +54 -0
  134. package/src/kernel/loop.ts +248 -0
  135. package/src/kernel/materials.ts +258 -0
  136. package/src/kernel/motion.ts +75 -0
  137. package/src/kernel/orbit.ts +554 -0
  138. package/src/kernel/overlays.ts +130 -0
  139. package/src/kernel/performance.ts +101 -0
  140. package/src/kernel/physics.ts +361 -0
  141. package/src/kernel/physicsDebug.ts +68 -0
  142. package/src/kernel/pointer.ts +785 -0
  143. package/src/kernel/renderKit.ts +54 -0
  144. package/src/kernel/renderer.ts +136 -0
  145. package/src/kernel/resources.ts +504 -0
  146. package/src/kernel/sceneGraph.ts +1442 -0
  147. package/src/kernel/sceneIndex.ts +219 -0
  148. package/src/kernel/stage.ts +157 -0
  149. package/src/kernel/textLayout.ts +102 -0
  150. package/src/kernel/tween.ts +80 -0
  151. package/src/kernel/xrInput.ts +230 -0
  152. package/src/kernel/xrLocomotion.ts +72 -0
  153. package/src/runtime/FrameSource.ts +41 -0
  154. package/src/runtime/ResourceRegistry.ts +24 -0
  155. package/src/runtime/SceneRuntime.ts +229 -0
  156. package/src/runtime/SceneSchema.ts +983 -0
  157. package/src/runtime/errors.ts +18 -0
  158. package/src/runtime/index.ts +10 -0
  159. package/src/webgl/contactShadows.ts +67 -0
  160. package/src/webgl/index.ts +19 -0
  161. package/src/webgl/shaderGrid.ts +196 -0
  162. package/src/webgl/sky.ts +42 -0
  163. package/src/webgpu/contactShadows.ts +83 -0
  164. package/src/webgpu/index.ts +19 -0
  165. package/src/webgpu/shaderGrid.ts +158 -0
  166. package/src/webgpu/sky.ts +35 -0
@@ -0,0 +1,203 @@
1
+ /**
2
+ * What the body host needs from each body in a scene: where it is, where the description
3
+ * puts it, what its colliders are made from, and how to put a simulated pose back. A body
4
+ * sits on a mesh, group or borrowed model, or on each instance of an instances node (as
5
+ * react-three-rapier's `InstancedRigidBodies`, `ae5c3fe`).
6
+ *
7
+ * @module
8
+ */
9
+ import { Euler, type InstancedMesh, Matrix4, type Object3D, Quaternion, Vector3 } from 'three';
10
+
11
+ import type {
12
+ Body,
13
+ BorrowedNode,
14
+ GroupNode,
15
+ Instance,
16
+ InstancesNode,
17
+ MeshNode,
18
+ Rotation,
19
+ } from './description.ts';
20
+ import {
21
+ type BodyPose,
22
+ type Collider,
23
+ colliderFor,
24
+ colliderSignature,
25
+ collidersFor,
26
+ describedColliders,
27
+ } from './physics.ts';
28
+
29
+ /** The id of a node's body (`instance` null) or an instance's, in the physics world. */
30
+ export const bodyId = (key: string, instance: string | null): string =>
31
+ instance === null ? key : `${key}\u0000${instance}`;
32
+
33
+ /** A node a body can sit on directly. */
34
+ export type BodiedNode = MeshNode | GroupNode | BorrowedNode;
35
+
36
+ /** One body, as the body host sees it. */
37
+ export type BodySource = {
38
+ /** The body's id in the physics world. */
39
+ readonly id: string;
40
+ /** The node's key, and for an instance its key, as collisions report them. */
41
+ readonly key: string;
42
+ readonly instance?: string;
43
+ readonly body: Body;
44
+ /** What it lives on (a hosted object, or an instances node's entry): a new one means a new body. */
45
+ readonly holder: object;
46
+ /** Where the description puts it, as text: a change teleports a non-kinematic body. */
47
+ readonly placement: string;
48
+ /** What its colliders are made from: a change remakes them. */
49
+ readonly signature: () => string;
50
+ readonly colliders: () => ReadonlyArray<Collider>;
51
+ /** Where it is now, in world space. */
52
+ readonly pose: () => BodyPose;
53
+ /** Where the description puts it, in world space. */
54
+ readonly described: () => BodyPose;
55
+ /** Puts it at a world pose (a simulated one). */
56
+ readonly place: (pose: BodyPose) => void;
57
+ };
58
+
59
+ const position = new Vector3();
60
+ const quaternion = new Quaternion();
61
+ const scale = new Vector3();
62
+ const matrix = new Matrix4();
63
+ const local = new Matrix4();
64
+ const inverse = new Matrix4();
65
+ const euler = new Euler();
66
+ const ownScale = new Vector3();
67
+
68
+ const toPose = (from: Matrix4): BodyPose => {
69
+ from.decompose(position, quaternion, scale);
70
+ return {
71
+ position: [position.x, position.y, position.z],
72
+ quaternion: [quaternion.x, quaternion.y, quaternion.z, quaternion.w],
73
+ };
74
+ };
75
+
76
+ /** A world matrix's scale. */
77
+ const worldScale = (from: Matrix4): Vector3 => {
78
+ from.decompose(position, quaternion, ownScale);
79
+ return ownScale;
80
+ };
81
+
82
+ /** A world matrix's scale as text, to five places (a turning body's matrix rounds). */
83
+ const scaleText = (from: Matrix4): string =>
84
+ worldScale(from)
85
+ .toArray()
86
+ .map((value) => (Math.round(value * 1e5) / 1e5 || 0).toString())
87
+ .join(',');
88
+
89
+ const rotationText = (rotation: Rotation): string =>
90
+ rotation._tag === 'Fixed' ? rotation.euler.join(',') : 'spin';
91
+
92
+ /** A world pose written to an object in its parent's space, keeping its scale. */
93
+ export const placeObject = (object: Object3D, pose: BodyPose): void => {
94
+ object.matrixWorld.decompose(position, quaternion, scale);
95
+ matrix.compose(position.fromArray(pose.position), quaternion.fromArray(pose.quaternion), scale);
96
+ if (object.parent !== null) matrix.premultiply(inverse.copy(object.parent.matrixWorld).invert());
97
+ matrix.decompose(object.position, object.quaternion, scale);
98
+ };
99
+
100
+ /** The body on a mesh, group or borrowed model, if it has one. */
101
+ export const nodeSource = (
102
+ key: string,
103
+ node: BodiedNode,
104
+ object: Object3D,
105
+ ): BodySource | undefined => {
106
+ const { body } = node;
107
+ if (body === null) return undefined;
108
+ return {
109
+ id: key,
110
+ key,
111
+ body,
112
+ holder: object,
113
+ placement: `${node.position.join(',')}|${rotationText(node.rotation)}`,
114
+ // Colliders of its own depend on its scale only; others, on its meshes.
115
+ signature: () =>
116
+ body.colliders === null ? colliderSignature(object) : `own:${scaleText(object.matrixWorld)}`,
117
+ colliders: () =>
118
+ body.colliders === null
119
+ ? collidersFor(object, body.collider)
120
+ : describedColliders(body.colliders, worldScale(object.matrixWorld)),
121
+ pose: () => toPose(object.matrixWorld),
122
+ described: () => {
123
+ position.fromArray(node.position);
124
+ if (node.rotation._tag === 'Fixed') {
125
+ quaternion.setFromEuler(euler.fromArray([...node.rotation.euler]));
126
+ } else quaternion.copy(object.quaternion);
127
+ matrix.compose(position, quaternion, object.scale);
128
+ if (object.parent !== null) matrix.premultiply(object.parent.matrixWorld);
129
+ return toPose(matrix);
130
+ },
131
+ place: (pose) => placeObject(object, pose),
132
+ };
133
+ };
134
+
135
+ /** An instance's matrix in its mesh, from its description. */
136
+ const instanceMatrix = (instance: Instance): Matrix4 =>
137
+ local.compose(
138
+ position.fromArray(instance.position),
139
+ quaternion.setFromEuler(euler.fromArray([...instance.rotation])),
140
+ scale.fromArray(instance.scale),
141
+ );
142
+
143
+ /** The body on one instance of an instances node with a body. */
144
+ const instanceSource = (
145
+ key: string,
146
+ body: Body,
147
+ holder: object,
148
+ mesh: InstancedMesh,
149
+ instance: Instance,
150
+ slot: number,
151
+ ): BodySource => ({
152
+ id: bodyId(key, instance.key),
153
+ key,
154
+ instance: instance.key,
155
+ body,
156
+ holder,
157
+ placement: `${instance.position.join(',')}|${instance.rotation.join(',')}`,
158
+ signature: () => `${mesh.geometry.uuid}:${instance.scale.join(',')}`,
159
+ colliders: () => {
160
+ mesh.matrixWorld.decompose(position, quaternion, ownScale);
161
+ ownScale.multiply(scale.fromArray(instance.scale));
162
+ return body.colliders === null
163
+ ? [colliderFor(mesh.geometry, body.collider, ownScale)]
164
+ : describedColliders(body.colliders, ownScale);
165
+ },
166
+ pose: () => {
167
+ mesh.getMatrixAt(slot, local);
168
+ return toPose(matrix.copy(mesh.matrixWorld).multiply(local));
169
+ },
170
+ described: () => toPose(matrix.copy(mesh.matrixWorld).multiply(instanceMatrix(instance))),
171
+ place: (pose) => {
172
+ mesh.matrixWorld.decompose(position, quaternion, ownScale);
173
+ ownScale.multiply(scale.fromArray(instance.scale));
174
+ matrix.compose(
175
+ position.fromArray(pose.position),
176
+ quaternion.fromArray(pose.quaternion),
177
+ ownScale,
178
+ );
179
+ matrix.premultiply(inverse.copy(mesh.matrixWorld).invert());
180
+ mesh.setMatrixAt(slot, matrix);
181
+ mesh.instanceMatrix.needsUpdate = true;
182
+ // Picking and culling recompute these from the moved instances.
183
+ mesh.boundingSphere = null;
184
+ mesh.boundingBox = null;
185
+ },
186
+ });
187
+
188
+ /**
189
+ * A body per instance of an instances node with a body. `holder` outlives the mesh, which
190
+ * is swapped for a larger one as instances are added: the bodies stay.
191
+ */
192
+ export const instanceSources = (
193
+ key: string,
194
+ node: InstancesNode,
195
+ holder: object,
196
+ mesh: InstancedMesh,
197
+ ): ReadonlyArray<BodySource> => {
198
+ const { body } = node;
199
+ if (body === null) return [];
200
+ return node.instances.map((instance, slot) =>
201
+ instanceSource(key, body, holder, mesh, instance, slot),
202
+ );
203
+ };