@zephyr3d/scene 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 (236) hide show
  1. package/dist/animation/animation.js +173 -0
  2. package/dist/animation/animation.js.map +1 -0
  3. package/dist/animation/animationset.js +95 -0
  4. package/dist/animation/animationset.js.map +1 -0
  5. package/dist/animation/animationtrack.js +38 -0
  6. package/dist/animation/animationtrack.js.map +1 -0
  7. package/dist/animation/eulerrotationtrack.js +33 -0
  8. package/dist/animation/eulerrotationtrack.js.map +1 -0
  9. package/dist/animation/rotationtrack.js +37 -0
  10. package/dist/animation/rotationtrack.js.map +1 -0
  11. package/dist/animation/scaletrack.js +36 -0
  12. package/dist/animation/scaletrack.js.map +1 -0
  13. package/dist/animation/skeleton.js +97 -0
  14. package/dist/animation/skeleton.js.map +1 -0
  15. package/dist/animation/translationtrack.js +36 -0
  16. package/dist/animation/translationtrack.js.map +1 -0
  17. package/dist/animation/usertrack.js +47 -0
  18. package/dist/animation/usertrack.js.map +1 -0
  19. package/dist/app.js +173 -0
  20. package/dist/app.js.map +1 -0
  21. package/dist/asset/assetmanager.js +476 -0
  22. package/dist/asset/assetmanager.js.map +1 -0
  23. package/dist/asset/builtin.js +373 -0
  24. package/dist/asset/builtin.js.map +1 -0
  25. package/dist/asset/loaders/dds/dds.js +472 -0
  26. package/dist/asset/loaders/dds/dds.js.map +1 -0
  27. package/dist/asset/loaders/dds/dds_loader.js +38 -0
  28. package/dist/asset/loaders/dds/dds_loader.js.map +1 -0
  29. package/dist/asset/loaders/gltf/gltf_loader.js +981 -0
  30. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -0
  31. package/dist/asset/loaders/gltf/helpers.js +314 -0
  32. package/dist/asset/loaders/gltf/helpers.js.map +1 -0
  33. package/dist/asset/loaders/hdr/hdr.js +175 -0
  34. package/dist/asset/loaders/hdr/hdr.js.map +1 -0
  35. package/dist/asset/loaders/image/tga_Loader.js +117 -0
  36. package/dist/asset/loaders/image/tga_Loader.js.map +1 -0
  37. package/dist/asset/loaders/image/webimage_loader.js +50 -0
  38. package/dist/asset/loaders/image/webimage_loader.js.map +1 -0
  39. package/dist/asset/loaders/loader.js +45 -0
  40. package/dist/asset/loaders/loader.js.map +1 -0
  41. package/dist/asset/model.js +264 -0
  42. package/dist/asset/model.js.map +1 -0
  43. package/dist/blitter/blitter.js +389 -0
  44. package/dist/blitter/blitter.js.map +1 -0
  45. package/dist/blitter/box.js +118 -0
  46. package/dist/blitter/box.js.map +1 -0
  47. package/dist/blitter/copy.js +22 -0
  48. package/dist/blitter/copy.js.map +1 -0
  49. package/dist/blitter/depthlimitedgaussion.js +166 -0
  50. package/dist/blitter/depthlimitedgaussion.js.map +1 -0
  51. package/dist/blitter/gaussianblur.js +229 -0
  52. package/dist/blitter/gaussianblur.js.map +1 -0
  53. package/dist/camera/base.js +90 -0
  54. package/dist/camera/base.js.map +1 -0
  55. package/dist/camera/camera.js +358 -0
  56. package/dist/camera/camera.js.map +1 -0
  57. package/dist/camera/fps.js +246 -0
  58. package/dist/camera/fps.js.map +1 -0
  59. package/dist/camera/orbit.js +157 -0
  60. package/dist/camera/orbit.js.map +1 -0
  61. package/dist/camera/orthocamera.js +126 -0
  62. package/dist/camera/orthocamera.js.map +1 -0
  63. package/dist/camera/perspectivecamera.js +133 -0
  64. package/dist/camera/perspectivecamera.js.map +1 -0
  65. package/dist/index.d.ts +8402 -0
  66. package/dist/index.js +87 -0
  67. package/dist/index.js.map +1 -0
  68. package/dist/input/inputmgr.js +242 -0
  69. package/dist/input/inputmgr.js.map +1 -0
  70. package/dist/material/blinn.js +75 -0
  71. package/dist/material/blinn.js.map +1 -0
  72. package/dist/material/grassmaterial.js +221 -0
  73. package/dist/material/grassmaterial.js.map +1 -0
  74. package/dist/material/lambert.js +52 -0
  75. package/dist/material/lambert.js.map +1 -0
  76. package/dist/material/lightmodel.js +2074 -0
  77. package/dist/material/lightmodel.js.map +1 -0
  78. package/dist/material/lit.js +578 -0
  79. package/dist/material/lit.js.map +1 -0
  80. package/dist/material/material.js +458 -0
  81. package/dist/material/material.js.map +1 -0
  82. package/dist/material/meshmaterial.js +311 -0
  83. package/dist/material/meshmaterial.js.map +1 -0
  84. package/dist/material/mixins/albedocolor.js +130 -0
  85. package/dist/material/mixins/albedocolor.js.map +1 -0
  86. package/dist/material/mixins/texture.js +110 -0
  87. package/dist/material/mixins/texture.js.map +1 -0
  88. package/dist/material/mixins/vertexcolor.js +45 -0
  89. package/dist/material/mixins/vertexcolor.js.map +1 -0
  90. package/dist/material/pbr.js +27 -0
  91. package/dist/material/pbr.js.map +1 -0
  92. package/dist/material/standard.js +282 -0
  93. package/dist/material/standard.js.map +1 -0
  94. package/dist/material/terrainlightmodel.js +259 -0
  95. package/dist/material/terrainlightmodel.js.map +1 -0
  96. package/dist/material/terrainmaterial.js +139 -0
  97. package/dist/material/terrainmaterial.js.map +1 -0
  98. package/dist/material/unlit.js +29 -0
  99. package/dist/material/unlit.js.map +1 -0
  100. package/dist/posteffect/bloom.js +398 -0
  101. package/dist/posteffect/bloom.js.map +1 -0
  102. package/dist/posteffect/compositor.js +264 -0
  103. package/dist/posteffect/compositor.js.map +1 -0
  104. package/dist/posteffect/fxaa.js +291 -0
  105. package/dist/posteffect/fxaa.js.map +1 -0
  106. package/dist/posteffect/grayscale.js +87 -0
  107. package/dist/posteffect/grayscale.js.map +1 -0
  108. package/dist/posteffect/posteffect.js +165 -0
  109. package/dist/posteffect/posteffect.js.map +1 -0
  110. package/dist/posteffect/sao.js +327 -0
  111. package/dist/posteffect/sao.js.map +1 -0
  112. package/dist/posteffect/tonemap.js +112 -0
  113. package/dist/posteffect/tonemap.js.map +1 -0
  114. package/dist/posteffect/water.js +535 -0
  115. package/dist/posteffect/water.js.map +1 -0
  116. package/dist/render/clipmap.js +462 -0
  117. package/dist/render/clipmap.js.map +1 -0
  118. package/dist/render/cluster_light.js +329 -0
  119. package/dist/render/cluster_light.js.map +1 -0
  120. package/dist/render/cull_visitor.js +124 -0
  121. package/dist/render/cull_visitor.js.map +1 -0
  122. package/dist/render/depth_pass.js +47 -0
  123. package/dist/render/depth_pass.js.map +1 -0
  124. package/dist/render/envlight.js +282 -0
  125. package/dist/render/envlight.js.map +1 -0
  126. package/dist/render/forward.js +186 -0
  127. package/dist/render/forward.js.map +1 -0
  128. package/dist/render/forward_pass.js +137 -0
  129. package/dist/render/forward_pass.js.map +1 -0
  130. package/dist/render/helper.js +38 -0
  131. package/dist/render/helper.js.map +1 -0
  132. package/dist/render/primitive.js +246 -0
  133. package/dist/render/primitive.js.map +1 -0
  134. package/dist/render/render_queue.js +163 -0
  135. package/dist/render/render_queue.js.map +1 -0
  136. package/dist/render/renderpass.js +151 -0
  137. package/dist/render/renderpass.js.map +1 -0
  138. package/dist/render/renderscheme.js +61 -0
  139. package/dist/render/renderscheme.js.map +1 -0
  140. package/dist/render/scatteringlut.js +634 -0
  141. package/dist/render/scatteringlut.js.map +1 -0
  142. package/dist/render/shadowmap_pass.js +70 -0
  143. package/dist/render/shadowmap_pass.js.map +1 -0
  144. package/dist/render/sky.js +881 -0
  145. package/dist/render/sky.js.map +1 -0
  146. package/dist/render/temporalcache.js +222 -0
  147. package/dist/render/temporalcache.js.map +1 -0
  148. package/dist/render/watermesh.js +835 -0
  149. package/dist/render/watermesh.js.map +1 -0
  150. package/dist/scene/environment.js +146 -0
  151. package/dist/scene/environment.js.map +1 -0
  152. package/dist/scene/graph_node.js +69 -0
  153. package/dist/scene/graph_node.js.map +1 -0
  154. package/dist/scene/light.js +436 -0
  155. package/dist/scene/light.js.map +1 -0
  156. package/dist/scene/mesh.js +215 -0
  157. package/dist/scene/mesh.js.map +1 -0
  158. package/dist/scene/model.js +111 -0
  159. package/dist/scene/model.js.map +1 -0
  160. package/dist/scene/octree.js +651 -0
  161. package/dist/scene/octree.js.map +1 -0
  162. package/dist/scene/octree_update_visitor.js +16 -0
  163. package/dist/scene/octree_update_visitor.js.map +1 -0
  164. package/dist/scene/raycast_visitor.js +72 -0
  165. package/dist/scene/raycast_visitor.js.map +1 -0
  166. package/dist/scene/scene.js +225 -0
  167. package/dist/scene/scene.js.map +1 -0
  168. package/dist/scene/scene_node.js +299 -0
  169. package/dist/scene/scene_node.js.map +1 -0
  170. package/dist/scene/terrain/grass.js +277 -0
  171. package/dist/scene/terrain/grass.js.map +1 -0
  172. package/dist/scene/terrain/heightfield.js +391 -0
  173. package/dist/scene/terrain/heightfield.js.map +1 -0
  174. package/dist/scene/terrain/patch.js +530 -0
  175. package/dist/scene/terrain/patch.js.map +1 -0
  176. package/dist/scene/terrain/quadtree.js +430 -0
  177. package/dist/scene/terrain/quadtree.js.map +1 -0
  178. package/dist/scene/terrain/terrain.js +258 -0
  179. package/dist/scene/terrain/terrain.js.map +1 -0
  180. package/dist/scene/xform.js +224 -0
  181. package/dist/scene/xform.js.map +1 -0
  182. package/dist/shaders/builtins.js +110 -0
  183. package/dist/shaders/builtins.js.map +1 -0
  184. package/dist/shaders/framework.js +709 -0
  185. package/dist/shaders/framework.js.map +1 -0
  186. package/dist/shaders/lighting.js +335 -0
  187. package/dist/shaders/lighting.js.map +1 -0
  188. package/dist/shaders/misc.js +405 -0
  189. package/dist/shaders/misc.js.map +1 -0
  190. package/dist/shaders/noise.js +157 -0
  191. package/dist/shaders/noise.js.map +1 -0
  192. package/dist/shaders/pbr.js +132 -0
  193. package/dist/shaders/pbr.js.map +1 -0
  194. package/dist/shaders/shadow.js +642 -0
  195. package/dist/shaders/shadow.js.map +1 -0
  196. package/dist/shaders/water.js +630 -0
  197. package/dist/shaders/water.js.map +1 -0
  198. package/dist/shadow/esm.js +235 -0
  199. package/dist/shadow/esm.js.map +1 -0
  200. package/dist/shadow/pcf_opt.js +182 -0
  201. package/dist/shadow/pcf_opt.js.map +1 -0
  202. package/dist/shadow/pcf_pd.js +190 -0
  203. package/dist/shadow/pcf_pd.js.map +1 -0
  204. package/dist/shadow/shadow_impl.js +15 -0
  205. package/dist/shadow/shadow_impl.js.map +1 -0
  206. package/dist/shadow/shadowmapper.js +709 -0
  207. package/dist/shadow/shadowmapper.js.map +1 -0
  208. package/dist/shadow/ssm.js +194 -0
  209. package/dist/shadow/ssm.js.map +1 -0
  210. package/dist/shadow/vsm.js +298 -0
  211. package/dist/shadow/vsm.js.map +1 -0
  212. package/dist/shapes/box.js +313 -0
  213. package/dist/shapes/box.js.map +1 -0
  214. package/dist/shapes/cylinder.js +74 -0
  215. package/dist/shapes/cylinder.js.map +1 -0
  216. package/dist/shapes/plane.js +48 -0
  217. package/dist/shapes/plane.js.map +1 -0
  218. package/dist/shapes/shape.js +33 -0
  219. package/dist/shapes/shape.js.map +1 -0
  220. package/dist/shapes/sphere.js +91 -0
  221. package/dist/shapes/sphere.js.map +1 -0
  222. package/dist/shapes/torus.js +100 -0
  223. package/dist/shapes/torus.js.map +1 -0
  224. package/dist/utility/aabbtree.js +390 -0
  225. package/dist/utility/aabbtree.js.map +1 -0
  226. package/dist/utility/bounding_volume.js +78 -0
  227. package/dist/utility/bounding_volume.js.map +1 -0
  228. package/dist/utility/panorama.js +163 -0
  229. package/dist/utility/panorama.js.map +1 -0
  230. package/dist/utility/pmrem.js +345 -0
  231. package/dist/utility/pmrem.js.map +1 -0
  232. package/dist/utility/shprojection.js +448 -0
  233. package/dist/utility/shprojection.js.map +1 -0
  234. package/dist/values.js +48 -0
  235. package/dist/values.js.map +1 -0
  236. package/package.json +70 -0
@@ -0,0 +1,72 @@
1
+ import { Ray, Vector3 } from '@zephyr3d/base';
2
+ import { OctreeNode } from './octree.js';
3
+
4
+ /** @internal */ class RaycastVisitor {
5
+ /** @internal */ _ray;
6
+ /** @internal */ _rayLocal;
7
+ /** @internal */ _intersected;
8
+ /** @internal */ _intersectedDist;
9
+ constructor(ray, length){
10
+ this._ray = ray;
11
+ this._rayLocal = new Ray();
12
+ this._intersected = null;
13
+ this._intersectedDist = length;
14
+ }
15
+ get intersected() {
16
+ return this._intersected;
17
+ }
18
+ get intersectedDist() {
19
+ return this._intersectedDist;
20
+ }
21
+ get intersectedPoint() {
22
+ return Vector3.add(this._ray.origin, Vector3.scale(this._ray.direction, this._intersectedDist));
23
+ }
24
+ visit(target) {
25
+ if (target instanceof OctreeNode) {
26
+ return this.visitOctreeNode(target);
27
+ }
28
+ if (target.isMesh()) {
29
+ return this.visitMesh(target);
30
+ } else if (target.isTerrain()) {
31
+ return this.visitTerrain(target);
32
+ }
33
+ return false;
34
+ }
35
+ visitTerrain(node) {
36
+ if (!node.hidden && node.pickable) {
37
+ this._ray.transform(node.invWorldMatrix, this._rayLocal);
38
+ const d = node.rayIntersect(this._rayLocal); // this._rayLocal.bboxIntersectionTestEx(node.getBoundingVolume().toAABB());
39
+ if (d !== null && d < this._intersectedDist) {
40
+ this._intersectedDist = d;
41
+ this._intersected = node;
42
+ return true;
43
+ }
44
+ }
45
+ return false;
46
+ }
47
+ visitMesh(node) {
48
+ if (!node.hidden && node.pickable) {
49
+ this._ray.transform(node.invWorldMatrix, this._rayLocal);
50
+ const d = node.primitive.raycast(this._rayLocal);
51
+ if (d !== null && d < this._intersectedDist) {
52
+ this._intersectedDist = d;
53
+ this._intersected = node.getPickTarget() ?? node;
54
+ return true;
55
+ }
56
+ }
57
+ return false;
58
+ }
59
+ visitOctreeNode(node) {
60
+ if (node.getLevel() === 0 || this._ray.bboxIntersectionTest(node.getBoxLoosed()) !== null) {
61
+ const nodes = node.getNodes();
62
+ for(let i = 0; i < nodes.length; i++){
63
+ this.visit(nodes[i]);
64
+ }
65
+ return true;
66
+ }
67
+ return false;
68
+ }
69
+ }
70
+
71
+ export { RaycastVisitor };
72
+ //# sourceMappingURL=raycast_visitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"raycast_visitor.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,225 @@
1
+ import { makeEventTarget, Vector4, Vector3, Ray, nextPowerOf2 } from '@zephyr3d/base';
2
+ import { SceneNode } from './scene_node.js';
3
+ import { Octree } from './octree.js';
4
+ import { OctreeUpdateVisitor } from './octree_update_visitor.js';
5
+ import { Material } from '../material/material.js';
6
+ import '@zephyr3d/device';
7
+ import '../shaders/framework.js';
8
+ import { Application } from '../app.js';
9
+ import '../render/scatteringlut.js';
10
+ import '../material/lambert.js';
11
+ import '../material/blinn.js';
12
+ import '../material/unlit.js';
13
+ import '../material/lightmodel.js';
14
+ import { RaycastVisitor } from './raycast_visitor.js';
15
+ import { Environment } from './environment.js';
16
+
17
+ /**
18
+ * Event that will be fired when the scene needs to be updated
19
+ * @public
20
+ */ class SceneUpdateEvent {
21
+ static NAME = 'sceneupdate';
22
+ scene;
23
+ type = SceneUpdateEvent.NAME;
24
+ constructor(scene){
25
+ this.scene = scene;
26
+ }
27
+ }
28
+ /**
29
+ * Presents a world that manages a couple of objects that will be rendered
30
+ * @public
31
+ */ class Scene extends makeEventTarget(Object)() {
32
+ /** @internal */ static _nextId = 0;
33
+ /** @internal */ _rootNode;
34
+ /** @internal */ _octree;
35
+ /** @internal */ _nodePlaceList;
36
+ /** @internal */ _env;
37
+ /** @internal */ _updateEvent;
38
+ /** @internal */ _updateFrame;
39
+ /** @internal */ _worldUnit;
40
+ /** @internal */ _animationSet;
41
+ /** @internal */ _id;
42
+ /**
43
+ * Creates an instance of scene
44
+ */ constructor(){
45
+ super();
46
+ this._id = ++Scene._nextId;
47
+ this._octree = new Octree(this, 2048, 64);
48
+ this._nodePlaceList = new Set();
49
+ this._env = new Environment();
50
+ this._updateEvent = new SceneUpdateEvent(this);
51
+ this._updateFrame = -1;
52
+ this._worldUnit = 1;
53
+ this._animationSet = [];
54
+ this._rootNode = new SceneNode(this);
55
+ }
56
+ /** @internal */ get animationSet() {
57
+ return this._animationSet;
58
+ }
59
+ /**
60
+ * Gets the unique identifier of the scene
61
+ */ get id() {
62
+ return this._id;
63
+ }
64
+ /** How many meters a unit corresponds to. */ get worldUnit() {
65
+ return this._worldUnit;
66
+ }
67
+ set worldUnit(val) {
68
+ this._worldUnit = val;
69
+ }
70
+ /**
71
+ * Gets the root scene node of the scene
72
+ */ get rootNode() {
73
+ return this._rootNode;
74
+ }
75
+ /**
76
+ * Gets the octree
77
+ */ get octree() {
78
+ // Make sure the octree state is up to date
79
+ this.updateNodePlacement(this._octree, this._nodePlaceList);
80
+ return this._octree;
81
+ }
82
+ /**
83
+ * Gets the bounding box of the scene
84
+ */ get boundingBox() {
85
+ this.updateNodePlacement(this._octree, this._nodePlaceList);
86
+ // this._syncBVChangedList();
87
+ return this._octree.getRootNode().getBox() || this._octree.getRootNode().getBoxLoosed();
88
+ }
89
+ /**
90
+ * The environment of the scene
91
+ */ get env() {
92
+ return this._env;
93
+ }
94
+ /**
95
+ * Disposes the scene
96
+ */ dispose() {
97
+ this._rootNode = null;
98
+ }
99
+ /**
100
+ * Cast a ray into the scene to get the closest object hit by the ray
101
+ * @param camera - The camera used to compute the ray
102
+ * @param screenX - The x position on screen
103
+ * @param screenY - The y position on screen
104
+ * @returns The closest object hit by the ray
105
+ */ raycast(camera, screenX, screenY) {
106
+ const width = camera.viewport ? camera.viewport[2] : Application.instance.device.getViewport().width;
107
+ const height = camera.viewport ? camera.viewport[3] : Application.instance.device.getViewport().height;
108
+ const ray = this.constructRay(camera, width, height, screenX, screenY);
109
+ const raycastVisitor = new RaycastVisitor(ray, camera.getFarPlane());
110
+ this.octree.getRootNode().traverse(raycastVisitor);
111
+ return raycastVisitor.intersected ? {
112
+ node: raycastVisitor.intersected,
113
+ dist: raycastVisitor.intersectedDist,
114
+ point: raycastVisitor.intersectedPoint
115
+ } : null;
116
+ }
117
+ /**
118
+ * Constructs a ray by a given camera and the position on screen
119
+ * @param camera - The camera used to compute the ray
120
+ * @param viewportWidth - Width of the viewport
121
+ * @param viewportHeight - Height of the viewport
122
+ * @param screenX - The x position on screen
123
+ * @param screenY - The y position on screen
124
+ * @param invModelMatrix - A matrix used to transform the ray
125
+ * @returns The constructed ray
126
+ */ constructRay(camera, viewportWidth, viewportHeight, screenX, screenY, invModelMatrix) {
127
+ const vClip = new Vector4(2 * screenX / viewportWidth - 1, 1 - 2 * screenY / viewportHeight, 1, 1);
128
+ const vWorld = camera.invViewProjectionMatrix.transform(vClip);
129
+ vWorld.scaleBy(1 / vWorld.w);
130
+ let vEye = camera.getWorldPosition();
131
+ let vDir = Vector3.sub(vWorld.xyz(), vEye).inplaceNormalize();
132
+ if (invModelMatrix) {
133
+ vEye = invModelMatrix.transformPointAffine(vEye);
134
+ vDir = invModelMatrix.transformVectorAffine(vDir);
135
+ }
136
+ return new Ray(vEye, vDir);
137
+ }
138
+ /** @internal */ invalidateNodePlacement(node) {
139
+ this._nodePlaceList.add(node);
140
+ }
141
+ /** @internal */ _xformChanged(node) {
142
+ this._nodePlaceList.add(node);
143
+ }
144
+ /** @internal */ frameUpdate() {
145
+ const frameInfo = Application.instance.device.frameInfo;
146
+ if (frameInfo.frameCounter !== this._updateFrame) {
147
+ this._updateFrame = frameInfo.frameCounter;
148
+ // uniform buffer garbage collect
149
+ if (!Material.getGCOptions().disabled) {
150
+ Material.garbageCollect(frameInfo.frameTimestamp);
151
+ }
152
+ for (const an of this._animationSet){
153
+ an.update();
154
+ }
155
+ // check environment lighting
156
+ if (this.env.light.type === 'ibl') {
157
+ if (!this.env.light.radianceMap) {
158
+ if (this.env.sky.skyType !== 'none') {
159
+ this.env.light.radianceMap = this.env.sky.radianceMap;
160
+ }
161
+ } else if (this.env.light.radianceMap === this.env.sky.radianceMap) {
162
+ if (this.env.sky.skyType === 'none') {
163
+ this.env.light.radianceMap = null;
164
+ }
165
+ }
166
+ if (!this.env.light.irradianceMap) {
167
+ if (this.env.sky.skyType !== 'none') {
168
+ this.env.light.irradianceMap = this.env.sky.irradianceMap;
169
+ }
170
+ } else if (this.env.light.irradianceMap === this.env.sky.irradianceMap) {
171
+ if (this.env.sky.skyType === 'none') {
172
+ this.env.light.irradianceMap = null;
173
+ }
174
+ }
175
+ }
176
+ // update scene objects first
177
+ this.dispatchEvent(this._updateEvent);
178
+ this.updateNodePlacement(this._octree, this._nodePlaceList);
179
+ }
180
+ }
181
+ /**
182
+ * Update node placement in the octree
183
+ */ updateNodePlacement(octree, list) {
184
+ function placeNode(node, attached) {
185
+ if (node.isGraphNode()) {
186
+ if (attached && !node.hidden) {
187
+ octree.placeNode(node);
188
+ } else {
189
+ octree.removeNode(node);
190
+ }
191
+ }
192
+ for (const child of node.children){
193
+ if (child.isGraphNode()) {
194
+ placeNode(child, attached);
195
+ }
196
+ }
197
+ list.delete(node);
198
+ }
199
+ if (list.size > 0) {
200
+ while(list.size > 0){
201
+ const node = list.keys().next().value;
202
+ if (octree) {
203
+ placeNode(node, node.attached);
204
+ } else {
205
+ list.delete(node);
206
+ }
207
+ }
208
+ if (octree) {
209
+ const worldBox = octree.getRootNode().getBox();
210
+ if (worldBox) {
211
+ const radius = Math.max(Math.abs(worldBox.minPoint.x), Math.abs(worldBox.minPoint.y), Math.abs(worldBox.minPoint.z), Math.abs(worldBox.maxPoint.x), Math.abs(worldBox.maxPoint.y), Math.abs(worldBox.maxPoint.z));
212
+ const rootSize = nextPowerOf2(radius * 2);
213
+ if (rootSize > octree.getRootSize()) {
214
+ octree.initialize(rootSize, octree.getLeafSize());
215
+ const v = new OctreeUpdateVisitor(octree);
216
+ this._rootNode.traverse(v);
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+ }
223
+
224
+ export { Scene, SceneUpdateEvent };
225
+ //# sourceMappingURL=scene.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -0,0 +1,299 @@
1
+ import { XForm } from './xform.js';
2
+
3
+ /**
4
+ * The base class for any kind of scene objects
5
+ *
6
+ * @remarks
7
+ * We use a data structure called SceneGraph to store scenes,
8
+ * which consists of a couple of scene objects forming a
9
+ * hierarchical structure. This is the base class for any kind
10
+ * of the scene object, which contains the basic properties such
11
+ * as position, rotation, and scale of the object.
12
+ *
13
+ * @public
14
+ */ class SceneNode extends XForm {
15
+ static CLIP_INHERITED = -1;
16
+ static CLIP_DISABLED = 0;
17
+ static CLIP_ENABLED = 1;
18
+ static SHOW_INHERITED = -1;
19
+ static SHOW_HIDE = 0;
20
+ static SHOW_DEFAULT = 1;
21
+ static PICK_INHERITED = -1;
22
+ static PICK_DISABLED = 0;
23
+ static PICK_ENABLED = 1;
24
+ static BBOXDRAW_INHERITED = -1;
25
+ static BBOXDRAW_DISABLED = 0;
26
+ static BBOXDRAW_LOCAL = 1;
27
+ static BBOXDRAW_WORLD = 2;
28
+ /** @internal */ _clipMode;
29
+ /** @internal */ _renderOrder;
30
+ /** @internal */ _boxDrawMode;
31
+ /** @internal */ _visible;
32
+ /** @internal */ _pickMode;
33
+ /** @internal */ _name;
34
+ /** @internal */ _scene;
35
+ /** @internal */ _bv;
36
+ /** @internal */ _bvDirty;
37
+ /** @internal */ _bvWorld;
38
+ /**
39
+ * Creates a new scene node
40
+ * @param scene - Which scene the node belongs to
41
+ */ constructor(scene){
42
+ super();
43
+ this._scene = scene;
44
+ this._name = '';
45
+ this._bv = null;
46
+ this._bvWorld = null;
47
+ this._bvDirty = true;
48
+ this._clipMode = SceneNode.CLIP_ENABLED;
49
+ this._boxDrawMode = SceneNode.BBOXDRAW_DISABLED;
50
+ this._visible = SceneNode.SHOW_DEFAULT;
51
+ this._pickMode = SceneNode.PICK_DISABLED;
52
+ if (scene && this !== scene.rootNode) {
53
+ this.reparent(scene.rootNode);
54
+ }
55
+ }
56
+ /**
57
+ * Name of the scene node
58
+ */ get name() {
59
+ return this._name;
60
+ }
61
+ set name(val) {
62
+ this._name = val || '';
63
+ }
64
+ /** The scene to which the node belongs */ get scene() {
65
+ return this._scene;
66
+ }
67
+ /** true if the node is attached to the scene node, false otherwise */ get attached() {
68
+ return !!this._scene?.rootNode?.isParentOf(this);
69
+ }
70
+ /**
71
+ * Check if given node is a direct child of the node
72
+ * @param child - The node to be checked
73
+ * @returns true if the given node is a direct child of this node, false otherwise
74
+ */ hasChild(child) {
75
+ return this._children.indexOf(child) >= 0;
76
+ }
77
+ /**
78
+ * Removes all children from this node
79
+ */ removeChildren() {
80
+ while(this._children.length){
81
+ this._children[0].remove();
82
+ }
83
+ }
84
+ /**
85
+ * Checks if this node is the direct parent or indirect parent of a given node
86
+ * @param child - The node to be checked
87
+ * @returns true if this node is the direct parent or indirect parent of the given node, false otherwise
88
+ */ isParentOf(child) {
89
+ while(child && child !== this){
90
+ child = child.parent;
91
+ }
92
+ return child === this;
93
+ }
94
+ /**
95
+ * Removes this node from it's parent
96
+ * @returns self
97
+ */ remove() {
98
+ this.parent = null;
99
+ return this;
100
+ }
101
+ /**
102
+ * Traverse the entire subtree of this node by a visitor
103
+ * @param v - The visitor that will travel the subtree of this node
104
+ * @param inverse - true if traversing from bottom to top, otherwise top to bottom
105
+ */ traverse(v, inverse) {
106
+ if (inverse) {
107
+ for(let i = this._children.length - 1; i >= 0; i--){
108
+ this._children[i].traverse(v, inverse);
109
+ }
110
+ v.visit(this);
111
+ } else {
112
+ v.visit(this);
113
+ for (const child of this._children){
114
+ child.traverse(v);
115
+ }
116
+ }
117
+ }
118
+ /**
119
+ * Iterate self and all of the children
120
+ * @param callback - callback function that will be called on each node
121
+ */ iterate(callback) {
122
+ callback(this);
123
+ for (const child of this._children){
124
+ child.iterate(callback);
125
+ }
126
+ }
127
+ /** true if this is a graph node, false otherwise */ isGraphNode() {
128
+ return false;
129
+ }
130
+ /** true if this is a light node, false otherwise */ isLight() {
131
+ return false;
132
+ }
133
+ /** true if this is a mesh node, false otherwise */ isMesh() {
134
+ return false;
135
+ }
136
+ /** true if this is a terrain node, false otherwise */ isTerrain() {
137
+ return false;
138
+ }
139
+ /** true if this is a camera node, false otherwise */ isCamera() {
140
+ return false;
141
+ }
142
+ /** true if this is a punctual light node, false otherwise */ isPunctualLight() {
143
+ return false;
144
+ }
145
+ /** Disposes the node */ dispose() {
146
+ this.remove();
147
+ this.removeChildren();
148
+ }
149
+ /**
150
+ * Computes the bounding volume of the node
151
+ * @param bv - The output bounding volume
152
+ * @returns The output bounding volume
153
+ */ computeBoundingVolume(bv) {
154
+ return bv;
155
+ }
156
+ /**
157
+ * Gets the bounding volume of the node
158
+ * @returns The bounding volume of the node
159
+ */ getBoundingVolume() {
160
+ if (this._bvDirty) {
161
+ this._bv = this.computeBoundingVolume(this._bv) || null;
162
+ this._bvDirty = false;
163
+ }
164
+ return this._bv;
165
+ }
166
+ /**
167
+ * Sets the bounding volume of the node
168
+ * @param bv - The bounding volume to set
169
+ */ setBoundingVolume(bv) {
170
+ if (bv !== this._bv) {
171
+ this._bv = bv;
172
+ this.invalidateBoundingVolume();
173
+ }
174
+ }
175
+ /**
176
+ * Gets the world space bounding volume of the node
177
+ * @returns The world space bounding volume of the node
178
+ */ getWorldBoundingVolume() {
179
+ if (!this._bvWorld) {
180
+ this._bvWorld = this.getBoundingVolume()?.transform(this.worldMatrix) ?? null;
181
+ }
182
+ return this._bvWorld;
183
+ }
184
+ /**
185
+ * Force the bounding volume to be recalculated
186
+ */ invalidateBoundingVolume() {
187
+ this._bvDirty = true;
188
+ this.invalidateWorldBoundingVolume();
189
+ }
190
+ /** Force the world space bounding volume to be recalculated */ invalidateWorldBoundingVolume() {
191
+ this._bvWorld = null;
192
+ this._scene?.invalidateNodePlacement(this);
193
+ }
194
+ /**
195
+ * Computed value of clip mode
196
+ */ get computedClipMode() {
197
+ if (this._clipMode === SceneNode.CLIP_INHERITED) {
198
+ let parent = this.parent;
199
+ while(parent && !parent.isGraphNode()){
200
+ parent = parent.parent;
201
+ }
202
+ return parent?.computedClipMode ?? SceneNode.CLIP_ENABLED;
203
+ }
204
+ return this._clipMode;
205
+ }
206
+ /** Clip mode */ get clipMode() {
207
+ return this._clipMode;
208
+ }
209
+ set clipMode(val) {
210
+ this._clipMode = val;
211
+ }
212
+ /** Computed value of show state */ get hidden() {
213
+ if (this._visible === SceneNode.SHOW_INHERITED) {
214
+ let parent = this.parent;
215
+ while(parent && !parent.isGraphNode()){
216
+ parent = parent.parent;
217
+ }
218
+ return parent?.hidden ?? false;
219
+ }
220
+ return this._visible === SceneNode.SHOW_HIDE;
221
+ }
222
+ /** Show state */ get showState() {
223
+ return this._visible;
224
+ }
225
+ set showState(val) {
226
+ if (val !== this._visible) {
227
+ const prevHidden = this.hidden;
228
+ this._visible = val;
229
+ if (prevHidden !== this.hidden) {
230
+ this.notifyHiddenChanged();
231
+ }
232
+ }
233
+ }
234
+ /** Computed value of pick mode */ get pickable() {
235
+ if (this._pickMode === SceneNode.PICK_INHERITED) {
236
+ let parent = this.parent;
237
+ while(parent && !parent.isGraphNode()){
238
+ parent = parent.parent;
239
+ }
240
+ return parent?.pickable ?? false;
241
+ }
242
+ return this._pickMode !== SceneNode.PICK_DISABLED;
243
+ }
244
+ /** Pick mode */ get pickMode() {
245
+ return this._pickMode;
246
+ }
247
+ set pickMode(val) {
248
+ this._pickMode = val;
249
+ }
250
+ /** Computed value for bounding box draw mode */ get computedBoundingBoxDrawMode() {
251
+ if (this._boxDrawMode === SceneNode.BBOXDRAW_INHERITED) {
252
+ let parent = this.parent;
253
+ while(parent && !parent.isGraphNode()){
254
+ parent = parent.parent;
255
+ }
256
+ return parent?.computedBoundingBoxDrawMode ?? SceneNode.BBOXDRAW_DISABLED;
257
+ }
258
+ return this._boxDrawMode;
259
+ }
260
+ /** Bounding box draw mode */ get boundingBoxDrawMode() {
261
+ return this._boxDrawMode;
262
+ }
263
+ set boundingBoxDrawMode(mode) {
264
+ this._boxDrawMode = mode;
265
+ }
266
+ /** @internal */ _setParent(p) {
267
+ if (p !== this._parent) {
268
+ const sceneLast = this.attached ? this.scene : null;
269
+ const sceneNew = p?.attached ? p.scene : null;
270
+ const willDetach = sceneLast && sceneLast !== sceneNew;
271
+ const willAttach = sceneNew && sceneLast !== sceneNew;
272
+ willDetach && this._willDetach();
273
+ willAttach && this._willAttach();
274
+ super._setParent(p);
275
+ willDetach && this._detached();
276
+ willAttach && this._attached();
277
+ }
278
+ }
279
+ /** @internal */ _onTransformChanged(invalidateLocal) {
280
+ super._onTransformChanged(invalidateLocal);
281
+ this.invalidateWorldBoundingVolume();
282
+ }
283
+ /** @internal */ _willAttach() {}
284
+ /** @internal */ _attached() {}
285
+ /** @internal */ _willDetach() {}
286
+ /** @internal */ _detached() {}
287
+ /** @internal */ notifyHiddenChanged() {
288
+ this._visibleChanged();
289
+ for (const child of this._children){
290
+ if (child.isGraphNode() && child.showState === SceneNode.SHOW_INHERITED) {
291
+ child.notifyHiddenChanged();
292
+ }
293
+ }
294
+ }
295
+ /** @internal */ _visibleChanged() {}
296
+ }
297
+
298
+ export { SceneNode };
299
+ //# sourceMappingURL=scene_node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene_node.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}