@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,358 @@
|
|
|
1
|
+
import { Matrix4x4, Vector4, Frustum } from '@zephyr3d/base';
|
|
2
|
+
import { SceneNode } from '../scene/scene_node.js';
|
|
3
|
+
import { Application } from '../app.js';
|
|
4
|
+
import '../scene/octree.js';
|
|
5
|
+
import '../material/material.js';
|
|
6
|
+
import '@zephyr3d/device';
|
|
7
|
+
import '../shaders/framework.js';
|
|
8
|
+
import '../render/scatteringlut.js';
|
|
9
|
+
import '../material/lambert.js';
|
|
10
|
+
import '../material/blinn.js';
|
|
11
|
+
import '../material/unlit.js';
|
|
12
|
+
import '../material/lightmodel.js';
|
|
13
|
+
import { ForwardRenderScheme } from '../render/forward.js';
|
|
14
|
+
import '../render/sky.js';
|
|
15
|
+
import '../render/clipmap.js';
|
|
16
|
+
import '../render/watermesh.js';
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The camera node class
|
|
20
|
+
* @public
|
|
21
|
+
*/ class Camera extends SceneNode {
|
|
22
|
+
/** @internal */ _projMatrix;
|
|
23
|
+
/** @internal */ _viewMatrix;
|
|
24
|
+
/** @internal */ _viewProjMatrix;
|
|
25
|
+
/** @internal */ _rotationMatrix;
|
|
26
|
+
/** @internal */ _invViewProjMatrix;
|
|
27
|
+
/** @internal */ _clipPlane;
|
|
28
|
+
/** @internal */ _controller;
|
|
29
|
+
/** @internal */ _frustum;
|
|
30
|
+
/** @internal */ _frustumV;
|
|
31
|
+
/** @internal */ _dirty;
|
|
32
|
+
/** @internal */ _sampleCount;
|
|
33
|
+
/** @internal */ _framebuffer;
|
|
34
|
+
/** @internal */ _viewport;
|
|
35
|
+
/** @internal */ _scissor;
|
|
36
|
+
/** @internal */ _clearColor;
|
|
37
|
+
/** @internal */ _clipMask;
|
|
38
|
+
/**
|
|
39
|
+
* Creates a new camera node
|
|
40
|
+
* @param scene - The scene that the camera belongs to
|
|
41
|
+
* @param projectionMatrix - Projection matrix for this camera
|
|
42
|
+
*/ constructor(scene, projectionMatrix){
|
|
43
|
+
super(scene);
|
|
44
|
+
this._projMatrix = projectionMatrix || Matrix4x4.identity();
|
|
45
|
+
this._viewMatrix = Matrix4x4.identity();
|
|
46
|
+
this._viewProjMatrix = Matrix4x4.identity();
|
|
47
|
+
this._invViewProjMatrix = Matrix4x4.identity();
|
|
48
|
+
this._clipPlane = null;
|
|
49
|
+
this._dirty = true;
|
|
50
|
+
this._controller = null;
|
|
51
|
+
this._framebuffer = null;
|
|
52
|
+
this._viewport = null;
|
|
53
|
+
this._scissor = null;
|
|
54
|
+
this._clearColor = new Vector4(0, 0, 0, 1);
|
|
55
|
+
this._clipMask = 0;
|
|
56
|
+
this._sampleCount = 1;
|
|
57
|
+
this._frustum = null;
|
|
58
|
+
this._frustumV = null;
|
|
59
|
+
}
|
|
60
|
+
/** Clip plane in camera space */ get clipPlane() {
|
|
61
|
+
return this._clipPlane;
|
|
62
|
+
}
|
|
63
|
+
set clipPlane(plane) {
|
|
64
|
+
this._clipPlane = plane;
|
|
65
|
+
this._invalidate(false);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Sample count for MSAA
|
|
69
|
+
*
|
|
70
|
+
* @remarks
|
|
71
|
+
* If greater than one, force the scene to be rendered using multisampled framebuffer
|
|
72
|
+
*/ get sampleCount() {
|
|
73
|
+
return this._sampleCount;
|
|
74
|
+
}
|
|
75
|
+
set sampleCount(val) {
|
|
76
|
+
if (val !== 1 && val !== 4) {
|
|
77
|
+
console.error(`Invalid sample count: ${val}`);
|
|
78
|
+
} else {
|
|
79
|
+
this._sampleCount = val;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Clip plane mask */ get clipMask() {
|
|
83
|
+
return this._clipMask;
|
|
84
|
+
}
|
|
85
|
+
set clipMask(val) {
|
|
86
|
+
this._clipMask = val;
|
|
87
|
+
}
|
|
88
|
+
/** Framebuffer object into which the scene will be rendered */ get framebuffer() {
|
|
89
|
+
return this._framebuffer;
|
|
90
|
+
}
|
|
91
|
+
set framebuffer(fb) {
|
|
92
|
+
this._framebuffer = fb ?? null;
|
|
93
|
+
}
|
|
94
|
+
/** Viewport used for rendering, if null, use full framebuffer size */ get viewport() {
|
|
95
|
+
return this._viewport ? [
|
|
96
|
+
...this._viewport
|
|
97
|
+
] : null;
|
|
98
|
+
}
|
|
99
|
+
set viewport(rect) {
|
|
100
|
+
this._viewport = rect?.slice() ?? null;
|
|
101
|
+
}
|
|
102
|
+
/** Scissor rectangle used for rendering, if null, use viewport value */ get scissor() {
|
|
103
|
+
return this._scissor ? [
|
|
104
|
+
...this._scissor
|
|
105
|
+
] : null;
|
|
106
|
+
}
|
|
107
|
+
set scissor(rect) {
|
|
108
|
+
this._scissor = rect?.slice() ?? null;
|
|
109
|
+
}
|
|
110
|
+
/** Color value used to clear color buffer before rendering, if null, color buffer will not be cleared */ get clearColor() {
|
|
111
|
+
return this._clearColor;
|
|
112
|
+
}
|
|
113
|
+
set clearColor(val) {
|
|
114
|
+
if (!val) {
|
|
115
|
+
this._clearColor = null;
|
|
116
|
+
} else {
|
|
117
|
+
this._clearColor.set(val);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Handle input events
|
|
122
|
+
* @param ev - input event object
|
|
123
|
+
* @param type - event type, default to ev.type
|
|
124
|
+
* @returns Boolean value indicates whether the event was handled.
|
|
125
|
+
*/ handleEvent(ev, type) {
|
|
126
|
+
let handled = false;
|
|
127
|
+
if (this._controller) {
|
|
128
|
+
type = type ?? ev.type;
|
|
129
|
+
if (type === 'pointerdown') {
|
|
130
|
+
handled = this._controller.onMouseDown(ev);
|
|
131
|
+
} else if (type === 'pointerup') {
|
|
132
|
+
handled = this._controller.onMouseUp(ev);
|
|
133
|
+
} else if (type === 'pointermove') {
|
|
134
|
+
handled = this._controller.onMouseMove(ev);
|
|
135
|
+
} else if (type === 'wheel') {
|
|
136
|
+
handled = this._controller.onMouseWheel(ev);
|
|
137
|
+
} else if (type === 'keydown') {
|
|
138
|
+
handled = this._controller.onKeyDown(ev);
|
|
139
|
+
} else if (type === 'keyup') {
|
|
140
|
+
handled = this._controller.onKeyUp(ev);
|
|
141
|
+
}
|
|
142
|
+
if (handled) {
|
|
143
|
+
ev.preventDefault();
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return handled;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Place the camera by specifying the camera position and the target point
|
|
150
|
+
* @param eye - The camera position
|
|
151
|
+
* @param target - The target point to look at
|
|
152
|
+
* @param up - The up vector
|
|
153
|
+
* @returns self
|
|
154
|
+
*/ lookAt(eye, target, up) {
|
|
155
|
+
return this.setLocalTransform(Matrix4x4.lookAt(eye, target, up));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Place the camera to look at a given cube face at a given camera position
|
|
159
|
+
* @param face - The cube face to look at
|
|
160
|
+
* @param position - The camera position
|
|
161
|
+
* @returns self
|
|
162
|
+
*/ lookAtCubeFace(face, position) {
|
|
163
|
+
return this.setLocalTransform(Matrix4x4.lookAtCubeFace(face, position ?? this.position));
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Setup a perspective projection matrix for the camera
|
|
167
|
+
* @param fovY - The vertical field of view in radians.
|
|
168
|
+
* @param aspect - The aspect ratio
|
|
169
|
+
* @param zNear - The near clip plane
|
|
170
|
+
* @param zFar - The far clip plane
|
|
171
|
+
* @returns self
|
|
172
|
+
*/ setPerspective(fovY, aspect, zNear, zFar) {
|
|
173
|
+
this._projMatrix.perspective(fovY, aspect, zNear, zFar);
|
|
174
|
+
this._invalidate(true);
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Setup a orthogonal projection matrix for the camera
|
|
179
|
+
* @param left - Left bound of the frustum
|
|
180
|
+
* @param right - Right bound of the frustum
|
|
181
|
+
* @param bottom - Bottom bound of the frustum
|
|
182
|
+
* @param top - Top bound of the frustum
|
|
183
|
+
* @param near - Near bound of the frustum.
|
|
184
|
+
* @param far - Far bound of the frustum.
|
|
185
|
+
* @returns self
|
|
186
|
+
*/ setOrtho(left, right, bottom, top, near, far) {
|
|
187
|
+
this._projMatrix.ortho(left, right, bottom, top, near, far);
|
|
188
|
+
this._invalidate(true);
|
|
189
|
+
return this;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Setup a projection matrix for the camera
|
|
193
|
+
* @param matrix - The projection matrix
|
|
194
|
+
*/ setProjectionMatrix(matrix) {
|
|
195
|
+
if (matrix && matrix !== this._projMatrix) {
|
|
196
|
+
this._projMatrix.set(matrix);
|
|
197
|
+
this._invalidate(true);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Gets the projection matrix of the camera
|
|
202
|
+
* @returns The projection matrix
|
|
203
|
+
*/ getProjectionMatrix() {
|
|
204
|
+
if (this._dirty) {
|
|
205
|
+
this._dirty = false;
|
|
206
|
+
this._compute();
|
|
207
|
+
}
|
|
208
|
+
return this._projMatrix;
|
|
209
|
+
}
|
|
210
|
+
getRotationMatrix() {
|
|
211
|
+
const rotationMatrix = new Matrix4x4();
|
|
212
|
+
this.worldMatrix.decompose(null, rotationMatrix, null);
|
|
213
|
+
const xAxis = rotationMatrix.getRow(0).xyz().scaleBy(-1);
|
|
214
|
+
const yAxis = rotationMatrix.getRow(1).xyz();
|
|
215
|
+
const zAxis = rotationMatrix.getRow(2).xyz().scaleBy(-1);
|
|
216
|
+
rotationMatrix.setRow(0, new Vector4(xAxis.x, xAxis.y, xAxis.z, 0));
|
|
217
|
+
rotationMatrix.setRow(1, new Vector4(yAxis.x, yAxis.y, yAxis.z, 0));
|
|
218
|
+
rotationMatrix.setRow(2, new Vector4(zAxis.x, zAxis.y, zAxis.z, 0));
|
|
219
|
+
return rotationMatrix;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* View matrix of the camera
|
|
223
|
+
*
|
|
224
|
+
* @remarks
|
|
225
|
+
* Camera's view matrix will transform a point from the world space to the camera space
|
|
226
|
+
*/ get viewMatrix() {
|
|
227
|
+
if (this._dirty) {
|
|
228
|
+
this._dirty = false;
|
|
229
|
+
this._compute();
|
|
230
|
+
}
|
|
231
|
+
return this._viewMatrix;
|
|
232
|
+
}
|
|
233
|
+
get viewProjectionMatrix() {
|
|
234
|
+
if (this._dirty) {
|
|
235
|
+
this._dirty = false;
|
|
236
|
+
this._compute();
|
|
237
|
+
}
|
|
238
|
+
return this._viewProjMatrix;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* The inverse-view-projection matrix of the camera
|
|
242
|
+
*
|
|
243
|
+
* @remarks
|
|
244
|
+
* The inverse-view-projection matrix transforms a point from the clip space to the camera space
|
|
245
|
+
*/ get invViewProjectionMatrix() {
|
|
246
|
+
if (this._dirty) {
|
|
247
|
+
this._dirty = false;
|
|
248
|
+
this._compute();
|
|
249
|
+
}
|
|
250
|
+
return this._invViewProjMatrix;
|
|
251
|
+
}
|
|
252
|
+
/** Gets the frustum of the camera */ get frustum() {
|
|
253
|
+
if (this._dirty) {
|
|
254
|
+
this._dirty = false;
|
|
255
|
+
this._compute();
|
|
256
|
+
}
|
|
257
|
+
return this._frustum;
|
|
258
|
+
}
|
|
259
|
+
get frustumViewSpace() {
|
|
260
|
+
if (this._dirty) {
|
|
261
|
+
this._dirty = false;
|
|
262
|
+
this._compute();
|
|
263
|
+
}
|
|
264
|
+
if (!this._frustumV) {
|
|
265
|
+
this._frustumV = new Frustum(this._projMatrix);
|
|
266
|
+
}
|
|
267
|
+
return this._frustumV;
|
|
268
|
+
}
|
|
269
|
+
/** The camera controller */ get controller() {
|
|
270
|
+
return this._controller || null;
|
|
271
|
+
}
|
|
272
|
+
set controller(controller) {
|
|
273
|
+
this.setController(controller);
|
|
274
|
+
}
|
|
275
|
+
/** {@inheritDoc SceneNode.isCamera} */ isCamera() {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
/** Gets the near clip plane of the camera */ getNearPlane() {
|
|
279
|
+
return this._projMatrix.getNearPlane();
|
|
280
|
+
}
|
|
281
|
+
/** Gets the far clip plane of the camera */ getFarPlane() {
|
|
282
|
+
return this._projMatrix.getFarPlane();
|
|
283
|
+
}
|
|
284
|
+
/** Gets the vertical field of view of the camera */ getFOV() {
|
|
285
|
+
return this._projMatrix.getFov();
|
|
286
|
+
}
|
|
287
|
+
/** Gets the tangent of half of the vertical field of view */ getTanHalfFovy() {
|
|
288
|
+
return this._projMatrix.getTanHalfFov();
|
|
289
|
+
}
|
|
290
|
+
/** Gets the aspect ratio */ getAspect() {
|
|
291
|
+
return this._projMatrix.getAspect();
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Renders a scene
|
|
295
|
+
* @param scene - The scene to be rendered
|
|
296
|
+
* @param compositor - Compositor instance that will be used to apply postprocess effects
|
|
297
|
+
*/ render(scene, compositor, logger) {
|
|
298
|
+
const device = Application.instance.device;
|
|
299
|
+
device.pushDeviceStates();
|
|
300
|
+
device.reverseVertexWindingOrder(false);
|
|
301
|
+
device.setFramebuffer(this._framebuffer);
|
|
302
|
+
ForwardRenderScheme.setClearColor(this._clearColor);
|
|
303
|
+
ForwardRenderScheme.renderScene(scene, this, compositor, logger);
|
|
304
|
+
device.popDeviceStates();
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* Updates the controller state
|
|
308
|
+
*/ updateController() {
|
|
309
|
+
this._controller?.update();
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Reset the controller
|
|
313
|
+
*/ resetController() {
|
|
314
|
+
this._controller?.reset();
|
|
315
|
+
}
|
|
316
|
+
/** @internal */ setController(controller) {
|
|
317
|
+
if (this._controller !== controller) {
|
|
318
|
+
if (controller && controller._getCamera() && controller._getCamera() !== this) {
|
|
319
|
+
throw new Error('Camera.setController failed: one camera controller object cannot be assigned to multiple camera');
|
|
320
|
+
}
|
|
321
|
+
this._controller?._setCamera(null);
|
|
322
|
+
this._controller = controller;
|
|
323
|
+
this._controller?._setCamera(this);
|
|
324
|
+
}
|
|
325
|
+
return this;
|
|
326
|
+
}
|
|
327
|
+
/** @internal */ _invalidate(projectMatrixChanged) {
|
|
328
|
+
this._dirty = true;
|
|
329
|
+
if (projectMatrixChanged) {
|
|
330
|
+
this._frustumV = null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/** @internal */ _compute() {
|
|
334
|
+
this._computeProj();
|
|
335
|
+
Matrix4x4.invertAffine(this.worldMatrix, this._viewMatrix);
|
|
336
|
+
Matrix4x4.multiply(this._projMatrix, this._viewMatrix, this._viewProjMatrix);
|
|
337
|
+
Matrix4x4.invert(this._viewProjMatrix, this._invViewProjMatrix);
|
|
338
|
+
if (!this._frustum) {
|
|
339
|
+
this._frustum = new Frustum(this._viewProjMatrix);
|
|
340
|
+
} else {
|
|
341
|
+
this._frustum.initWithMatrix(this._viewProjMatrix);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
/** @internal */ _computeProj() {}
|
|
345
|
+
/** @internal */ _onTransformChanged(invalidateLocal) {
|
|
346
|
+
super._onTransformChanged(invalidateLocal);
|
|
347
|
+
this._invalidate(false);
|
|
348
|
+
}
|
|
349
|
+
/** {@inheritdoc SceneNode.dispose} */ dispose() {
|
|
350
|
+
this.setController(null);
|
|
351
|
+
this._projMatrix = null;
|
|
352
|
+
this._viewMatrix = null;
|
|
353
|
+
this._viewProjMatrix = null;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
export { Camera };
|
|
358
|
+
//# sourceMappingURL=camera.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"camera.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
import { Vector3, Quaternion, Matrix3x3, Matrix4x4 } from '@zephyr3d/base';
|
|
2
|
+
import { BaseCameraController } from './base.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* FPS camera controller
|
|
6
|
+
* @public
|
|
7
|
+
*/ class FPSCameraController extends BaseCameraController {
|
|
8
|
+
/** @internal */ options;
|
|
9
|
+
/** @internal */ mouseDown;
|
|
10
|
+
/** @internal */ lastMouseX;
|
|
11
|
+
/** @internal */ lastMouseY;
|
|
12
|
+
/** @internal */ keyUp;
|
|
13
|
+
/** @internal */ keyDown;
|
|
14
|
+
/** @internal */ keyLeft;
|
|
15
|
+
/** @internal */ keyRight;
|
|
16
|
+
/** @internal */ keyForward;
|
|
17
|
+
/** @internal */ keyBackward;
|
|
18
|
+
/**
|
|
19
|
+
* Creates an instance of FPSCameraController
|
|
20
|
+
* @param options - The creation options
|
|
21
|
+
*/ constructor(options){
|
|
22
|
+
super();
|
|
23
|
+
this.options = Object.assign({
|
|
24
|
+
controlKeys: {
|
|
25
|
+
up: 'KeyQ',
|
|
26
|
+
down: 'KeyE',
|
|
27
|
+
forward: 'KeyW',
|
|
28
|
+
backward: 'KeyS',
|
|
29
|
+
left: 'KeyA',
|
|
30
|
+
right: 'KeyD'
|
|
31
|
+
},
|
|
32
|
+
moveSpeed: 0.2,
|
|
33
|
+
rotateSpeed: 0.01
|
|
34
|
+
}, options || {});
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* {@inheritDoc BaseCameraController.reset}
|
|
38
|
+
* @override
|
|
39
|
+
*/ reset() {
|
|
40
|
+
this.mouseDown = false;
|
|
41
|
+
this.lastMouseX = 0;
|
|
42
|
+
this.lastMouseY = 0;
|
|
43
|
+
this.keyUp = false;
|
|
44
|
+
this.keyDown = false;
|
|
45
|
+
this.keyLeft = false;
|
|
46
|
+
this.keyRight = false;
|
|
47
|
+
this.keyForward = false;
|
|
48
|
+
this.keyBackward = false;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* {@inheritDoc BaseCameraController._onMouseDown}
|
|
52
|
+
* @override
|
|
53
|
+
*/ _onMouseDown(evt) {
|
|
54
|
+
if (evt.button === 0) {
|
|
55
|
+
this.mouseDown = true;
|
|
56
|
+
this.lastMouseX = evt.offsetX;
|
|
57
|
+
this.lastMouseY = evt.offsetY;
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* {@inheritDoc BaseCameraController._onMouseUp}
|
|
64
|
+
* @override
|
|
65
|
+
*/ _onMouseUp(evt) {
|
|
66
|
+
if (evt.button === 0 && this.mouseDown) {
|
|
67
|
+
this.mouseDown = false;
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* {@inheritDoc BaseCameraController._onMouseMove}
|
|
74
|
+
* @override
|
|
75
|
+
*/ _onMouseMove(evt) {
|
|
76
|
+
if (this.mouseDown) {
|
|
77
|
+
const dx = evt.offsetX - this.lastMouseX;
|
|
78
|
+
const dy = evt.offsetY - this.lastMouseY;
|
|
79
|
+
this.lastMouseX = evt.offsetX;
|
|
80
|
+
this.lastMouseY = evt.offsetY;
|
|
81
|
+
const zAxis = this._getCamera().worldMatrix.getRow(2).xyz();
|
|
82
|
+
const alpha = Math.atan2(zAxis.z, zAxis.x) + dx * this.options.rotateSpeed;
|
|
83
|
+
const beta = Math.min(Math.PI / 2.1, Math.max(-Math.PI / 2.1, Math.asin(zAxis.y) + dy * this.options.rotateSpeed));
|
|
84
|
+
const newY = Math.sin(beta);
|
|
85
|
+
const r = Math.sqrt(Math.max(0, 1 - newY * newY));
|
|
86
|
+
const newZ = Math.sin(alpha) * r;
|
|
87
|
+
const newX = Math.cos(alpha) * r;
|
|
88
|
+
zAxis.setXYZ(newX, newY, newZ).inplaceNormalize();
|
|
89
|
+
const XAxis = Vector3.cross(Vector3.axisPY(), zAxis).inplaceNormalize();
|
|
90
|
+
const YAxis = Vector3.cross(zAxis, XAxis).inplaceNormalize();
|
|
91
|
+
const rotation = Quaternion.fromRotationMatrix(new Matrix3x3([
|
|
92
|
+
XAxis.x,
|
|
93
|
+
XAxis.y,
|
|
94
|
+
XAxis.z,
|
|
95
|
+
YAxis.x,
|
|
96
|
+
YAxis.y,
|
|
97
|
+
YAxis.z,
|
|
98
|
+
zAxis.x,
|
|
99
|
+
zAxis.y,
|
|
100
|
+
zAxis.z
|
|
101
|
+
]));
|
|
102
|
+
if (!this._getCamera().parent) {
|
|
103
|
+
this._getCamera().rotation.set(rotation);
|
|
104
|
+
} else {
|
|
105
|
+
const pos = new Vector3();
|
|
106
|
+
const scale = new Vector3();
|
|
107
|
+
this._getCamera().worldMatrix.decompose(scale, null, pos);
|
|
108
|
+
const newWorldMatrix = Matrix4x4.scaling(scale).rotateLeft(rotation).translateLeft(pos);
|
|
109
|
+
const newLocalMatrix = this._getCamera().parent ? newWorldMatrix.multiplyLeftAffine(Matrix4x4.invertAffine(this._getCamera().parent.worldMatrix)) : newWorldMatrix;
|
|
110
|
+
newLocalMatrix.decompose(scale, rotation, pos);
|
|
111
|
+
this._getCamera().position.set(pos);
|
|
112
|
+
this._getCamera().scale.set(scale);
|
|
113
|
+
this._getCamera().rotation.set(rotation);
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* {@inheritDoc BaseCameraController._onKeyDown}
|
|
121
|
+
* @override
|
|
122
|
+
*/ _onKeyDown(evt) {
|
|
123
|
+
switch(evt.code){
|
|
124
|
+
case this.options.controlKeys.up:
|
|
125
|
+
this.keyUp = true;
|
|
126
|
+
break;
|
|
127
|
+
case this.options.controlKeys.down:
|
|
128
|
+
this.keyDown = true;
|
|
129
|
+
break;
|
|
130
|
+
case this.options.controlKeys.left:
|
|
131
|
+
this.keyLeft = true;
|
|
132
|
+
break;
|
|
133
|
+
case this.options.controlKeys.right:
|
|
134
|
+
this.keyRight = true;
|
|
135
|
+
break;
|
|
136
|
+
case this.options.controlKeys.forward:
|
|
137
|
+
this.keyForward = true;
|
|
138
|
+
break;
|
|
139
|
+
case this.options.controlKeys.backward:
|
|
140
|
+
this.keyBackward = true;
|
|
141
|
+
break;
|
|
142
|
+
default:
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* {@inheritDoc BaseCameraController._onKeyUp}
|
|
149
|
+
* @override
|
|
150
|
+
*/ _onKeyUp(evt) {
|
|
151
|
+
switch(evt.code){
|
|
152
|
+
case this.options.controlKeys.up:
|
|
153
|
+
this.keyUp = false;
|
|
154
|
+
break;
|
|
155
|
+
case this.options.controlKeys.down:
|
|
156
|
+
this.keyDown = false;
|
|
157
|
+
break;
|
|
158
|
+
case this.options.controlKeys.left:
|
|
159
|
+
this.keyLeft = false;
|
|
160
|
+
break;
|
|
161
|
+
case this.options.controlKeys.right:
|
|
162
|
+
this.keyRight = false;
|
|
163
|
+
break;
|
|
164
|
+
case this.options.controlKeys.forward:
|
|
165
|
+
this.keyForward = false;
|
|
166
|
+
break;
|
|
167
|
+
case this.options.controlKeys.backward:
|
|
168
|
+
this.keyBackward = false;
|
|
169
|
+
break;
|
|
170
|
+
default:
|
|
171
|
+
return false;
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Set options
|
|
177
|
+
* @param opt - options
|
|
178
|
+
*/ setOptions(opt) {
|
|
179
|
+
opt && Object.assign(this.options, opt);
|
|
180
|
+
this.reset();
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* {@inheritDoc BaseCameraController.update}
|
|
184
|
+
* @override
|
|
185
|
+
*/ update() {
|
|
186
|
+
const x = this._getCamera().worldMatrix.getRow(0).xyz();
|
|
187
|
+
x.y = 0;
|
|
188
|
+
x.inplaceNormalize();
|
|
189
|
+
if (x.isNaN()) {
|
|
190
|
+
console.log(`Camera error 1: ${x.toString()}`);
|
|
191
|
+
}
|
|
192
|
+
const z = this._getCamera().worldMatrix.getRow(2).xyz().inplaceNormalize();
|
|
193
|
+
if (z.isNaN()) {
|
|
194
|
+
console.log(`Camera error 2: ${z.toString()}`);
|
|
195
|
+
}
|
|
196
|
+
const move = new Vector3(0, 0, 0);
|
|
197
|
+
let changed = false;
|
|
198
|
+
if (this.keyForward) {
|
|
199
|
+
changed = true;
|
|
200
|
+
move.subBy(Vector3.scale(z, this.options.moveSpeed));
|
|
201
|
+
}
|
|
202
|
+
if (this.keyBackward) {
|
|
203
|
+
changed = true;
|
|
204
|
+
move.addBy(Vector3.scale(z, this.options.moveSpeed));
|
|
205
|
+
}
|
|
206
|
+
if (this.keyUp) {
|
|
207
|
+
changed = true;
|
|
208
|
+
move.y += this.options.moveSpeed;
|
|
209
|
+
}
|
|
210
|
+
if (this.keyDown) {
|
|
211
|
+
changed = true;
|
|
212
|
+
move.y -= this.options.moveSpeed;
|
|
213
|
+
}
|
|
214
|
+
if (this.keyLeft) {
|
|
215
|
+
changed = true;
|
|
216
|
+
move.subBy(Vector3.scale(x, this.options.moveSpeed));
|
|
217
|
+
}
|
|
218
|
+
if (this.keyRight) {
|
|
219
|
+
changed = true;
|
|
220
|
+
move.addBy(Vector3.scale(x, this.options.moveSpeed));
|
|
221
|
+
}
|
|
222
|
+
if (changed) {
|
|
223
|
+
if (this._getCamera().parent) {
|
|
224
|
+
const pos = new Vector3();
|
|
225
|
+
const scale = new Vector3();
|
|
226
|
+
const rotation = new Quaternion();
|
|
227
|
+
this._getCamera().worldMatrix.decompose(scale, rotation, pos);
|
|
228
|
+
pos.addBy(move);
|
|
229
|
+
const newWorldMatrix = Matrix4x4.scaling(scale).rotateLeft(rotation).translateLeft(pos);
|
|
230
|
+
const newLocalMatrix = newWorldMatrix.multiplyLeftAffine(Matrix4x4.invertAffine(this._getCamera().parent.worldMatrix));
|
|
231
|
+
newLocalMatrix.decompose(scale, rotation, pos);
|
|
232
|
+
if (scale.isNaN() || rotation.isNaN() || pos.isNaN()) {
|
|
233
|
+
console.log(`Camera error 3: ${scale.toString()} ${rotation.toString()} ${pos.toString()}`);
|
|
234
|
+
}
|
|
235
|
+
this._getCamera().position.set(pos);
|
|
236
|
+
this._getCamera().scale.set(scale);
|
|
237
|
+
this._getCamera().rotation.set(rotation);
|
|
238
|
+
} else {
|
|
239
|
+
this._getCamera().moveBy(move);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
export { FPSCameraController };
|
|
246
|
+
//# sourceMappingURL=fps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fps.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|