@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.
- package/dist/animation/animation.js +173 -0
- package/dist/animation/animation.js.map +1 -0
- package/dist/animation/animationset.js +95 -0
- package/dist/animation/animationset.js.map +1 -0
- package/dist/animation/animationtrack.js +38 -0
- package/dist/animation/animationtrack.js.map +1 -0
- package/dist/animation/eulerrotationtrack.js +33 -0
- package/dist/animation/eulerrotationtrack.js.map +1 -0
- package/dist/animation/rotationtrack.js +37 -0
- package/dist/animation/rotationtrack.js.map +1 -0
- package/dist/animation/scaletrack.js +36 -0
- package/dist/animation/scaletrack.js.map +1 -0
- package/dist/animation/skeleton.js +97 -0
- package/dist/animation/skeleton.js.map +1 -0
- package/dist/animation/translationtrack.js +36 -0
- package/dist/animation/translationtrack.js.map +1 -0
- package/dist/animation/usertrack.js +47 -0
- package/dist/animation/usertrack.js.map +1 -0
- package/dist/app.js +173 -0
- package/dist/app.js.map +1 -0
- package/dist/asset/assetmanager.js +476 -0
- package/dist/asset/assetmanager.js.map +1 -0
- package/dist/asset/builtin.js +373 -0
- package/dist/asset/builtin.js.map +1 -0
- package/dist/asset/loaders/dds/dds.js +472 -0
- package/dist/asset/loaders/dds/dds.js.map +1 -0
- package/dist/asset/loaders/dds/dds_loader.js +38 -0
- package/dist/asset/loaders/dds/dds_loader.js.map +1 -0
- package/dist/asset/loaders/gltf/gltf_loader.js +981 -0
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -0
- package/dist/asset/loaders/gltf/helpers.js +314 -0
- package/dist/asset/loaders/gltf/helpers.js.map +1 -0
- package/dist/asset/loaders/hdr/hdr.js +175 -0
- package/dist/asset/loaders/hdr/hdr.js.map +1 -0
- package/dist/asset/loaders/image/tga_Loader.js +117 -0
- package/dist/asset/loaders/image/tga_Loader.js.map +1 -0
- package/dist/asset/loaders/image/webimage_loader.js +50 -0
- package/dist/asset/loaders/image/webimage_loader.js.map +1 -0
- package/dist/asset/loaders/loader.js +45 -0
- package/dist/asset/loaders/loader.js.map +1 -0
- package/dist/asset/model.js +264 -0
- package/dist/asset/model.js.map +1 -0
- package/dist/blitter/blitter.js +389 -0
- package/dist/blitter/blitter.js.map +1 -0
- package/dist/blitter/box.js +118 -0
- package/dist/blitter/box.js.map +1 -0
- package/dist/blitter/copy.js +22 -0
- package/dist/blitter/copy.js.map +1 -0
- package/dist/blitter/depthlimitedgaussion.js +166 -0
- package/dist/blitter/depthlimitedgaussion.js.map +1 -0
- package/dist/blitter/gaussianblur.js +229 -0
- package/dist/blitter/gaussianblur.js.map +1 -0
- package/dist/camera/base.js +90 -0
- package/dist/camera/base.js.map +1 -0
- package/dist/camera/camera.js +358 -0
- package/dist/camera/camera.js.map +1 -0
- package/dist/camera/fps.js +246 -0
- package/dist/camera/fps.js.map +1 -0
- package/dist/camera/orbit.js +157 -0
- package/dist/camera/orbit.js.map +1 -0
- package/dist/camera/orthocamera.js +126 -0
- package/dist/camera/orthocamera.js.map +1 -0
- package/dist/camera/perspectivecamera.js +133 -0
- package/dist/camera/perspectivecamera.js.map +1 -0
- package/dist/index.d.ts +8402 -0
- package/dist/index.js +87 -0
- package/dist/index.js.map +1 -0
- package/dist/input/inputmgr.js +242 -0
- package/dist/input/inputmgr.js.map +1 -0
- package/dist/material/blinn.js +75 -0
- package/dist/material/blinn.js.map +1 -0
- package/dist/material/grassmaterial.js +221 -0
- package/dist/material/grassmaterial.js.map +1 -0
- package/dist/material/lambert.js +52 -0
- package/dist/material/lambert.js.map +1 -0
- package/dist/material/lightmodel.js +2074 -0
- package/dist/material/lightmodel.js.map +1 -0
- package/dist/material/lit.js +578 -0
- package/dist/material/lit.js.map +1 -0
- package/dist/material/material.js +458 -0
- package/dist/material/material.js.map +1 -0
- package/dist/material/meshmaterial.js +311 -0
- package/dist/material/meshmaterial.js.map +1 -0
- package/dist/material/mixins/albedocolor.js +130 -0
- package/dist/material/mixins/albedocolor.js.map +1 -0
- package/dist/material/mixins/texture.js +110 -0
- package/dist/material/mixins/texture.js.map +1 -0
- package/dist/material/mixins/vertexcolor.js +45 -0
- package/dist/material/mixins/vertexcolor.js.map +1 -0
- package/dist/material/pbr.js +27 -0
- package/dist/material/pbr.js.map +1 -0
- package/dist/material/standard.js +282 -0
- package/dist/material/standard.js.map +1 -0
- package/dist/material/terrainlightmodel.js +259 -0
- package/dist/material/terrainlightmodel.js.map +1 -0
- package/dist/material/terrainmaterial.js +139 -0
- package/dist/material/terrainmaterial.js.map +1 -0
- package/dist/material/unlit.js +29 -0
- package/dist/material/unlit.js.map +1 -0
- package/dist/posteffect/bloom.js +398 -0
- package/dist/posteffect/bloom.js.map +1 -0
- package/dist/posteffect/compositor.js +264 -0
- package/dist/posteffect/compositor.js.map +1 -0
- package/dist/posteffect/fxaa.js +291 -0
- package/dist/posteffect/fxaa.js.map +1 -0
- package/dist/posteffect/grayscale.js +87 -0
- package/dist/posteffect/grayscale.js.map +1 -0
- package/dist/posteffect/posteffect.js +165 -0
- package/dist/posteffect/posteffect.js.map +1 -0
- package/dist/posteffect/sao.js +327 -0
- package/dist/posteffect/sao.js.map +1 -0
- package/dist/posteffect/tonemap.js +112 -0
- package/dist/posteffect/tonemap.js.map +1 -0
- package/dist/posteffect/water.js +535 -0
- package/dist/posteffect/water.js.map +1 -0
- package/dist/render/clipmap.js +462 -0
- package/dist/render/clipmap.js.map +1 -0
- package/dist/render/cluster_light.js +329 -0
- package/dist/render/cluster_light.js.map +1 -0
- package/dist/render/cull_visitor.js +124 -0
- package/dist/render/cull_visitor.js.map +1 -0
- package/dist/render/depth_pass.js +47 -0
- package/dist/render/depth_pass.js.map +1 -0
- package/dist/render/envlight.js +282 -0
- package/dist/render/envlight.js.map +1 -0
- package/dist/render/forward.js +186 -0
- package/dist/render/forward.js.map +1 -0
- package/dist/render/forward_pass.js +137 -0
- package/dist/render/forward_pass.js.map +1 -0
- package/dist/render/helper.js +38 -0
- package/dist/render/helper.js.map +1 -0
- package/dist/render/primitive.js +246 -0
- package/dist/render/primitive.js.map +1 -0
- package/dist/render/render_queue.js +163 -0
- package/dist/render/render_queue.js.map +1 -0
- package/dist/render/renderpass.js +151 -0
- package/dist/render/renderpass.js.map +1 -0
- package/dist/render/renderscheme.js +61 -0
- package/dist/render/renderscheme.js.map +1 -0
- package/dist/render/scatteringlut.js +634 -0
- package/dist/render/scatteringlut.js.map +1 -0
- package/dist/render/shadowmap_pass.js +70 -0
- package/dist/render/shadowmap_pass.js.map +1 -0
- package/dist/render/sky.js +881 -0
- package/dist/render/sky.js.map +1 -0
- package/dist/render/temporalcache.js +222 -0
- package/dist/render/temporalcache.js.map +1 -0
- package/dist/render/watermesh.js +835 -0
- package/dist/render/watermesh.js.map +1 -0
- package/dist/scene/environment.js +146 -0
- package/dist/scene/environment.js.map +1 -0
- package/dist/scene/graph_node.js +69 -0
- package/dist/scene/graph_node.js.map +1 -0
- package/dist/scene/light.js +436 -0
- package/dist/scene/light.js.map +1 -0
- package/dist/scene/mesh.js +215 -0
- package/dist/scene/mesh.js.map +1 -0
- package/dist/scene/model.js +111 -0
- package/dist/scene/model.js.map +1 -0
- package/dist/scene/octree.js +651 -0
- package/dist/scene/octree.js.map +1 -0
- package/dist/scene/octree_update_visitor.js +16 -0
- package/dist/scene/octree_update_visitor.js.map +1 -0
- package/dist/scene/raycast_visitor.js +72 -0
- package/dist/scene/raycast_visitor.js.map +1 -0
- package/dist/scene/scene.js +225 -0
- package/dist/scene/scene.js.map +1 -0
- package/dist/scene/scene_node.js +299 -0
- package/dist/scene/scene_node.js.map +1 -0
- package/dist/scene/terrain/grass.js +277 -0
- package/dist/scene/terrain/grass.js.map +1 -0
- package/dist/scene/terrain/heightfield.js +391 -0
- package/dist/scene/terrain/heightfield.js.map +1 -0
- package/dist/scene/terrain/patch.js +530 -0
- package/dist/scene/terrain/patch.js.map +1 -0
- package/dist/scene/terrain/quadtree.js +430 -0
- package/dist/scene/terrain/quadtree.js.map +1 -0
- package/dist/scene/terrain/terrain.js +258 -0
- package/dist/scene/terrain/terrain.js.map +1 -0
- package/dist/scene/xform.js +224 -0
- package/dist/scene/xform.js.map +1 -0
- package/dist/shaders/builtins.js +110 -0
- package/dist/shaders/builtins.js.map +1 -0
- package/dist/shaders/framework.js +709 -0
- package/dist/shaders/framework.js.map +1 -0
- package/dist/shaders/lighting.js +335 -0
- package/dist/shaders/lighting.js.map +1 -0
- package/dist/shaders/misc.js +405 -0
- package/dist/shaders/misc.js.map +1 -0
- package/dist/shaders/noise.js +157 -0
- package/dist/shaders/noise.js.map +1 -0
- package/dist/shaders/pbr.js +132 -0
- package/dist/shaders/pbr.js.map +1 -0
- package/dist/shaders/shadow.js +642 -0
- package/dist/shaders/shadow.js.map +1 -0
- package/dist/shaders/water.js +630 -0
- package/dist/shaders/water.js.map +1 -0
- package/dist/shadow/esm.js +235 -0
- package/dist/shadow/esm.js.map +1 -0
- package/dist/shadow/pcf_opt.js +182 -0
- package/dist/shadow/pcf_opt.js.map +1 -0
- package/dist/shadow/pcf_pd.js +190 -0
- package/dist/shadow/pcf_pd.js.map +1 -0
- package/dist/shadow/shadow_impl.js +15 -0
- package/dist/shadow/shadow_impl.js.map +1 -0
- package/dist/shadow/shadowmapper.js +709 -0
- package/dist/shadow/shadowmapper.js.map +1 -0
- package/dist/shadow/ssm.js +194 -0
- package/dist/shadow/ssm.js.map +1 -0
- package/dist/shadow/vsm.js +298 -0
- package/dist/shadow/vsm.js.map +1 -0
- package/dist/shapes/box.js +313 -0
- package/dist/shapes/box.js.map +1 -0
- package/dist/shapes/cylinder.js +74 -0
- package/dist/shapes/cylinder.js.map +1 -0
- package/dist/shapes/plane.js +48 -0
- package/dist/shapes/plane.js.map +1 -0
- package/dist/shapes/shape.js +33 -0
- package/dist/shapes/shape.js.map +1 -0
- package/dist/shapes/sphere.js +91 -0
- package/dist/shapes/sphere.js.map +1 -0
- package/dist/shapes/torus.js +100 -0
- package/dist/shapes/torus.js.map +1 -0
- package/dist/utility/aabbtree.js +390 -0
- package/dist/utility/aabbtree.js.map +1 -0
- package/dist/utility/bounding_volume.js +78 -0
- package/dist/utility/bounding_volume.js.map +1 -0
- package/dist/utility/panorama.js +163 -0
- package/dist/utility/panorama.js.map +1 -0
- package/dist/utility/pmrem.js +345 -0
- package/dist/utility/pmrem.js.map +1 -0
- package/dist/utility/shprojection.js +448 -0
- package/dist/utility/shprojection.js.map +1 -0
- package/dist/values.js +48 -0
- package/dist/values.js.map +1 -0
- 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|