spoint 0.1.0 → 0.1.11

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 (204) hide show
  1. package/README.md +134 -209
  2. package/SKILL.md +95 -0
  3. package/apps/environment/index.js +200 -1
  4. package/apps/environment/models/decorative/.gitkeep +0 -0
  5. package/apps/environment/models/hazards/.gitkeep +0 -0
  6. package/apps/environment/models/interactive/.gitkeep +0 -0
  7. package/apps/environment/models/structures/.gitkeep +0 -0
  8. package/apps/environment/smartObjects.js +114 -0
  9. package/apps/interactable/index.js +155 -0
  10. package/apps/physics-crate/index.js +15 -9
  11. package/apps/power-crate/index.js +18 -12
  12. package/apps/tps-game/$GDUPI.vrm +0 -0
  13. package/apps/tps-game/Cleetus.vrm +0 -0
  14. package/apps/tps-game/index.js +185 -27
  15. package/apps/world/index.js +68 -22
  16. package/bin/create-app.js +337 -0
  17. package/client/ARControls.js +301 -0
  18. package/client/LoadingManager.js +117 -0
  19. package/client/MobileControls.js +1122 -0
  20. package/client/anim-lib.glb +0 -0
  21. package/client/animation.js +306 -0
  22. package/client/app.js +1341 -65
  23. package/client/camera.js +191 -33
  24. package/client/createLoadingScreen.js +69 -0
  25. package/client/editor/bridge.js +113 -0
  26. package/client/editor/css/main.css +794 -0
  27. package/client/editor/images/rotate.svg +4 -0
  28. package/client/editor/images/scale.svg +4 -0
  29. package/client/editor/images/translate.svg +4 -0
  30. package/client/editor/index.html +103 -0
  31. package/client/editor/js/Command.js +41 -0
  32. package/client/editor/js/Config.js +81 -0
  33. package/client/editor/js/Editor.js +785 -0
  34. package/client/editor/js/EditorControls.js +438 -0
  35. package/client/editor/js/History.js +321 -0
  36. package/client/editor/js/Loader.js +987 -0
  37. package/client/editor/js/LoaderUtils.js +90 -0
  38. package/client/editor/js/Menubar.Add.js +510 -0
  39. package/client/editor/js/Menubar.Edit.js +145 -0
  40. package/client/editor/js/Menubar.File.js +466 -0
  41. package/client/editor/js/Menubar.Help.js +73 -0
  42. package/client/editor/js/Menubar.Status.js +51 -0
  43. package/client/editor/js/Menubar.View.js +183 -0
  44. package/client/editor/js/Menubar.js +27 -0
  45. package/client/editor/js/Player.js +53 -0
  46. package/client/editor/js/Resizer.js +58 -0
  47. package/client/editor/js/Script.js +503 -0
  48. package/client/editor/js/Selector.js +102 -0
  49. package/client/editor/js/Sidebar.Geometry.BoxGeometry.js +121 -0
  50. package/client/editor/js/Sidebar.Geometry.BufferGeometry.js +115 -0
  51. package/client/editor/js/Sidebar.Geometry.CapsuleGeometry.js +97 -0
  52. package/client/editor/js/Sidebar.Geometry.CircleGeometry.js +97 -0
  53. package/client/editor/js/Sidebar.Geometry.CylinderGeometry.js +121 -0
  54. package/client/editor/js/Sidebar.Geometry.DodecahedronGeometry.js +73 -0
  55. package/client/editor/js/Sidebar.Geometry.ExtrudeGeometry.js +196 -0
  56. package/client/editor/js/Sidebar.Geometry.IcosahedronGeometry.js +73 -0
  57. package/client/editor/js/Sidebar.Geometry.LatheGeometry.js +98 -0
  58. package/client/editor/js/Sidebar.Geometry.Modifiers.js +73 -0
  59. package/client/editor/js/Sidebar.Geometry.OctahedronGeometry.js +74 -0
  60. package/client/editor/js/Sidebar.Geometry.PlaneGeometry.js +97 -0
  61. package/client/editor/js/Sidebar.Geometry.RingGeometry.js +121 -0
  62. package/client/editor/js/Sidebar.Geometry.ShapeGeometry.js +76 -0
  63. package/client/editor/js/Sidebar.Geometry.SphereGeometry.js +133 -0
  64. package/client/editor/js/Sidebar.Geometry.TetrahedronGeometry.js +74 -0
  65. package/client/editor/js/Sidebar.Geometry.TorusGeometry.js +109 -0
  66. package/client/editor/js/Sidebar.Geometry.TorusKnotGeometry.js +121 -0
  67. package/client/editor/js/Sidebar.Geometry.TubeGeometry.js +135 -0
  68. package/client/editor/js/Sidebar.Geometry.js +332 -0
  69. package/client/editor/js/Sidebar.Material.BooleanProperty.js +60 -0
  70. package/client/editor/js/Sidebar.Material.ColorProperty.js +87 -0
  71. package/client/editor/js/Sidebar.Material.ConstantProperty.js +62 -0
  72. package/client/editor/js/Sidebar.Material.MapProperty.js +249 -0
  73. package/client/editor/js/Sidebar.Material.NumberProperty.js +60 -0
  74. package/client/editor/js/Sidebar.Material.Program.js +73 -0
  75. package/client/editor/js/Sidebar.Material.RangeValueProperty.js +63 -0
  76. package/client/editor/js/Sidebar.Material.js +751 -0
  77. package/client/editor/js/Sidebar.Object.Animation.js +102 -0
  78. package/client/editor/js/Sidebar.Object.js +898 -0
  79. package/client/editor/js/Sidebar.Project.App.js +165 -0
  80. package/client/editor/js/Sidebar.Project.Image.js +225 -0
  81. package/client/editor/js/Sidebar.Project.Materials.js +82 -0
  82. package/client/editor/js/Sidebar.Project.Renderer.js +144 -0
  83. package/client/editor/js/Sidebar.Project.Video.js +242 -0
  84. package/client/editor/js/Sidebar.Project.js +31 -0
  85. package/client/editor/js/Sidebar.Properties.js +73 -0
  86. package/client/editor/js/Sidebar.Scene.js +585 -0
  87. package/client/editor/js/Sidebar.Script.js +129 -0
  88. package/client/editor/js/Sidebar.Settings.History.js +146 -0
  89. package/client/editor/js/Sidebar.Settings.Shortcuts.js +175 -0
  90. package/client/editor/js/Sidebar.Settings.js +60 -0
  91. package/client/editor/js/Sidebar.js +41 -0
  92. package/client/editor/js/Storage.js +98 -0
  93. package/client/editor/js/Strings.js +2028 -0
  94. package/client/editor/js/Toolbar.js +84 -0
  95. package/client/editor/js/Viewport.Controls.js +92 -0
  96. package/client/editor/js/Viewport.Info.js +136 -0
  97. package/client/editor/js/Viewport.Pathtracer.js +91 -0
  98. package/client/editor/js/Viewport.ViewHelper.js +39 -0
  99. package/client/editor/js/Viewport.XR.js +222 -0
  100. package/client/editor/js/Viewport.js +900 -0
  101. package/client/editor/js/commands/AddObjectCommand.js +68 -0
  102. package/client/editor/js/commands/AddScriptCommand.js +75 -0
  103. package/client/editor/js/commands/Commands.js +23 -0
  104. package/client/editor/js/commands/MoveObjectCommand.js +111 -0
  105. package/client/editor/js/commands/MultiCmdsCommand.js +85 -0
  106. package/client/editor/js/commands/RemoveObjectCommand.js +88 -0
  107. package/client/editor/js/commands/RemoveScriptCommand.js +81 -0
  108. package/client/editor/js/commands/SetColorCommand.js +73 -0
  109. package/client/editor/js/commands/SetGeometryCommand.js +87 -0
  110. package/client/editor/js/commands/SetGeometryValueCommand.js +70 -0
  111. package/client/editor/js/commands/SetMaterialColorCommand.js +86 -0
  112. package/client/editor/js/commands/SetMaterialCommand.js +79 -0
  113. package/client/editor/js/commands/SetMaterialMapCommand.js +143 -0
  114. package/client/editor/js/commands/SetMaterialRangeCommand.js +91 -0
  115. package/client/editor/js/commands/SetMaterialValueCommand.js +90 -0
  116. package/client/editor/js/commands/SetMaterialVectorCommand.js +79 -0
  117. package/client/editor/js/commands/SetPositionCommand.js +84 -0
  118. package/client/editor/js/commands/SetRotationCommand.js +84 -0
  119. package/client/editor/js/commands/SetScaleCommand.js +84 -0
  120. package/client/editor/js/commands/SetSceneCommand.js +103 -0
  121. package/client/editor/js/commands/SetScriptValueCommand.js +80 -0
  122. package/client/editor/js/commands/SetShadowValueCommand.js +73 -0
  123. package/client/editor/js/commands/SetUuidCommand.js +70 -0
  124. package/client/editor/js/commands/SetValueCommand.js +75 -0
  125. package/client/editor/js/libs/acorn/acorn.js +3236 -0
  126. package/client/editor/js/libs/acorn/acorn_loose.js +1299 -0
  127. package/client/editor/js/libs/acorn/walk.js +344 -0
  128. package/client/editor/js/libs/app/index.html +57 -0
  129. package/client/editor/js/libs/app.js +251 -0
  130. package/client/editor/js/libs/codemirror/addon/dialog.css +32 -0
  131. package/client/editor/js/libs/codemirror/addon/dialog.js +163 -0
  132. package/client/editor/js/libs/codemirror/addon/show-hint.css +36 -0
  133. package/client/editor/js/libs/codemirror/addon/show-hint.js +529 -0
  134. package/client/editor/js/libs/codemirror/addon/tern.css +87 -0
  135. package/client/editor/js/libs/codemirror/addon/tern.js +750 -0
  136. package/client/editor/js/libs/codemirror/codemirror.css +344 -0
  137. package/client/editor/js/libs/codemirror/codemirror.js +9849 -0
  138. package/client/editor/js/libs/codemirror/mode/glsl.js +233 -0
  139. package/client/editor/js/libs/codemirror/mode/javascript.js +959 -0
  140. package/client/editor/js/libs/codemirror/theme/monokai.css +41 -0
  141. package/client/editor/js/libs/esprima.js +6401 -0
  142. package/client/editor/js/libs/jsonlint.js +453 -0
  143. package/client/editor/js/libs/signals.min.js +14 -0
  144. package/client/editor/js/libs/tern-threejs/threejs.js +5031 -0
  145. package/client/editor/js/libs/ternjs/comment.js +87 -0
  146. package/client/editor/js/libs/ternjs/def.js +588 -0
  147. package/client/editor/js/libs/ternjs/doc_comment.js +401 -0
  148. package/client/editor/js/libs/ternjs/infer.js +1635 -0
  149. package/client/editor/js/libs/ternjs/polyfill.js +80 -0
  150. package/client/editor/js/libs/ternjs/signal.js +26 -0
  151. package/client/editor/js/libs/ternjs/tern.js +993 -0
  152. package/client/editor/js/libs/ui.js +1346 -0
  153. package/client/editor/js/libs/ui.three.js +855 -0
  154. package/client/facial-animation.js +455 -0
  155. package/client/index.html +7 -4
  156. package/client/loading.css +147 -0
  157. package/client/loading.html +25 -0
  158. package/client/style.css +251 -0
  159. package/package.json +7 -3
  160. package/server.js +9 -1
  161. package/src/apps/AppContext.js +1 -1
  162. package/src/apps/AppLoader.js +50 -37
  163. package/src/apps/AppRuntime.js +32 -8
  164. package/src/client/InputHandler.js +233 -0
  165. package/src/client/JitterBuffer.js +207 -0
  166. package/src/client/KalmanFilter.js +125 -0
  167. package/src/client/MessageHandler.js +101 -0
  168. package/src/client/PhysicsNetworkClient.js +141 -68
  169. package/src/client/ReconnectManager.js +62 -0
  170. package/src/client/SmoothInterpolation.js +127 -0
  171. package/src/client/SnapshotProcessor.js +144 -0
  172. package/src/connection/ConnectionManager.js +21 -3
  173. package/src/connection/SessionStore.js +13 -3
  174. package/src/index.client.js +4 -6
  175. package/src/netcode/EventLog.js +29 -15
  176. package/src/netcode/LagCompensator.js +25 -26
  177. package/src/netcode/NetworkState.js +4 -1
  178. package/src/netcode/PhysicsIntegration.js +20 -6
  179. package/src/netcode/PlayerManager.js +10 -2
  180. package/src/netcode/SnapshotEncoder.js +66 -19
  181. package/src/netcode/TickSystem.js +13 -4
  182. package/src/physics/World.js +66 -13
  183. package/src/protocol/msgpack.js +90 -63
  184. package/src/sdk/ReloadHandlers.js +12 -2
  185. package/src/sdk/ReloadManager.js +5 -0
  186. package/src/sdk/ServerHandlers.js +50 -11
  187. package/src/sdk/StaticHandler.js +22 -6
  188. package/src/sdk/TickHandler.js +101 -34
  189. package/src/sdk/scaffold.js +31 -0
  190. package/src/sdk/server.js +59 -33
  191. package/src/shared/movement.js +2 -1
  192. package/src/spatial/Octree.js +5 -0
  193. package/apps/interactive-door/index.js +0 -33
  194. package/apps/patrol-npc/index.js +0 -37
  195. package/src/connection/QualityMonitor.js +0 -46
  196. package/src/debug/StateInspector.js +0 -42
  197. package/src/index.js +0 -1
  198. package/src/index.server.js +0 -27
  199. package/src/protocol/Codec.js +0 -60
  200. package/src/protocol/SequenceTracker.js +0 -71
  201. package/src/sdk/ClientMessageHandler.js +0 -80
  202. package/src/sdk/client.js +0 -122
  203. package/world/kaira.glb +0 -0
  204. package/world/schwust.glb +0 -0
@@ -0,0 +1,900 @@
1
+ import * as THREE from 'three';
2
+
3
+ import { TransformControls } from 'three/addons/controls/TransformControls.js';
4
+
5
+ import { UIPanel } from './libs/ui.js';
6
+
7
+ import { EditorControls } from './EditorControls.js';
8
+
9
+ import { ViewportControls } from './Viewport.Controls.js';
10
+ import { ViewportInfo } from './Viewport.Info.js';
11
+
12
+ import { ViewHelper } from './Viewport.ViewHelper.js';
13
+ import { XR } from './Viewport.XR.js';
14
+
15
+ import { SetPositionCommand } from './commands/SetPositionCommand.js';
16
+ import { SetRotationCommand } from './commands/SetRotationCommand.js';
17
+ import { SetScaleCommand } from './commands/SetScaleCommand.js';
18
+
19
+ import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
20
+ import { ViewportPathtracer } from './Viewport.Pathtracer.js';
21
+
22
+ function Viewport( editor ) {
23
+
24
+ const selector = editor.selector;
25
+ const signals = editor.signals;
26
+
27
+ const container = new UIPanel();
28
+ container.setId( 'viewport' );
29
+ container.setPosition( 'absolute' );
30
+
31
+ container.add( new ViewportControls( editor ) );
32
+ container.add( new ViewportInfo( editor ) );
33
+
34
+ //
35
+
36
+ let renderer = null;
37
+ let pmremGenerator = null;
38
+ let pathtracer = null;
39
+
40
+ const camera = editor.camera;
41
+ const scene = editor.scene;
42
+ const sceneHelpers = editor.sceneHelpers;
43
+
44
+ // helpers
45
+
46
+ const GRID_COLORS_LIGHT = [ 0x999999, 0x777777 ];
47
+ const GRID_COLORS_DARK = [ 0x555555, 0x888888 ];
48
+
49
+ const grid = new THREE.Group();
50
+
51
+ const grid1 = new THREE.GridHelper( 30, 30 );
52
+ grid1.material.color.setHex( GRID_COLORS_LIGHT[ 0 ] );
53
+ grid1.material.vertexColors = false;
54
+ grid.add( grid1 );
55
+
56
+ const grid2 = new THREE.GridHelper( 30, 6 );
57
+ grid2.material.color.setHex( GRID_COLORS_LIGHT[ 1 ] );
58
+ grid2.material.vertexColors = false;
59
+ grid.add( grid2 );
60
+
61
+ const viewHelper = new ViewHelper( camera, container );
62
+
63
+ //
64
+
65
+ const box = new THREE.Box3();
66
+
67
+ const selectionBox = new THREE.Box3Helper( box );
68
+ selectionBox.material.depthTest = false;
69
+ selectionBox.material.transparent = true;
70
+ selectionBox.visible = false;
71
+ sceneHelpers.add( selectionBox );
72
+
73
+ let objectPositionOnDown = null;
74
+ let objectRotationOnDown = null;
75
+ let objectScaleOnDown = null;
76
+
77
+ const transformControls = new TransformControls( camera, container.dom );
78
+ transformControls.addEventListener( 'axis-changed', function () {
79
+
80
+ if ( editor.viewportShading !== 'realistic' ) render();
81
+
82
+ } );
83
+ transformControls.addEventListener( 'objectChange', function () {
84
+
85
+ signals.objectChanged.dispatch( transformControls.object );
86
+
87
+ } );
88
+ transformControls.addEventListener( 'mouseDown', function () {
89
+
90
+ const object = transformControls.object;
91
+
92
+ objectPositionOnDown = object.position.clone();
93
+ objectRotationOnDown = object.rotation.clone();
94
+ objectScaleOnDown = object.scale.clone();
95
+
96
+ controls.enabled = false;
97
+
98
+ } );
99
+ transformControls.addEventListener( 'mouseUp', function () {
100
+
101
+ const object = transformControls.object;
102
+
103
+ if ( object !== undefined ) {
104
+
105
+ switch ( transformControls.getMode() ) {
106
+
107
+ case 'translate':
108
+
109
+ if ( ! objectPositionOnDown.equals( object.position ) ) {
110
+
111
+ editor.execute( new SetPositionCommand( editor, object, object.position, objectPositionOnDown ) );
112
+
113
+ }
114
+
115
+ break;
116
+
117
+ case 'rotate':
118
+
119
+ if ( ! objectRotationOnDown.equals( object.rotation ) ) {
120
+
121
+ editor.execute( new SetRotationCommand( editor, object, object.rotation, objectRotationOnDown ) );
122
+
123
+ }
124
+
125
+ break;
126
+
127
+ case 'scale':
128
+
129
+ if ( ! objectScaleOnDown.equals( object.scale ) ) {
130
+
131
+ editor.execute( new SetScaleCommand( editor, object, object.scale, objectScaleOnDown ) );
132
+
133
+ }
134
+
135
+ break;
136
+
137
+ }
138
+
139
+ }
140
+
141
+ controls.enabled = true;
142
+
143
+ } );
144
+
145
+ sceneHelpers.add( transformControls.getHelper() );
146
+
147
+ //
148
+
149
+ const xr = new XR( editor, transformControls ); // eslint-disable-line no-unused-vars
150
+
151
+ // events
152
+
153
+ function updateAspectRatio() {
154
+
155
+ for ( const uuid in editor.cameras ) {
156
+
157
+ const camera = editor.cameras[ uuid ];
158
+
159
+ const aspect = container.dom.offsetWidth / container.dom.offsetHeight;
160
+
161
+ if ( camera.isPerspectiveCamera ) {
162
+
163
+ camera.aspect = aspect;
164
+
165
+ } else {
166
+
167
+ camera.left = - aspect;
168
+ camera.right = aspect;
169
+
170
+ }
171
+
172
+ camera.updateProjectionMatrix();
173
+
174
+ const cameraHelper = editor.helpers[ camera.id ];
175
+ if ( cameraHelper ) cameraHelper.update();
176
+
177
+ }
178
+
179
+ }
180
+
181
+ const onDownPosition = new THREE.Vector2();
182
+ const onUpPosition = new THREE.Vector2();
183
+ const onDoubleClickPosition = new THREE.Vector2();
184
+
185
+ function getMousePosition( dom, x, y ) {
186
+
187
+ const rect = dom.getBoundingClientRect();
188
+ return [ ( x - rect.left ) / rect.width, ( y - rect.top ) / rect.height ];
189
+
190
+ }
191
+
192
+ function handleClick() {
193
+
194
+ if ( onDownPosition.distanceTo( onUpPosition ) === 0 ) {
195
+
196
+ const intersects = selector.getPointerIntersects( onUpPosition, camera );
197
+ signals.intersectionsDetected.dispatch( intersects );
198
+
199
+ render();
200
+
201
+ }
202
+
203
+ }
204
+
205
+ function onMouseDown( event ) {
206
+
207
+ // event.preventDefault();
208
+
209
+ if ( event.target !== renderer.domElement ) return;
210
+
211
+ const array = getMousePosition( container.dom, event.clientX, event.clientY );
212
+ onDownPosition.fromArray( array );
213
+
214
+ document.addEventListener( 'mouseup', onMouseUp );
215
+
216
+ }
217
+
218
+ function onMouseUp( event ) {
219
+
220
+ const array = getMousePosition( container.dom, event.clientX, event.clientY );
221
+ onUpPosition.fromArray( array );
222
+
223
+ handleClick();
224
+
225
+ document.removeEventListener( 'mouseup', onMouseUp );
226
+
227
+ }
228
+
229
+ function onTouchStart( event ) {
230
+
231
+ const touch = event.changedTouches[ 0 ];
232
+
233
+ const array = getMousePosition( container.dom, touch.clientX, touch.clientY );
234
+ onDownPosition.fromArray( array );
235
+
236
+ document.addEventListener( 'touchend', onTouchEnd );
237
+
238
+ }
239
+
240
+ function onTouchEnd( event ) {
241
+
242
+ const touch = event.changedTouches[ 0 ];
243
+
244
+ const array = getMousePosition( container.dom, touch.clientX, touch.clientY );
245
+ onUpPosition.fromArray( array );
246
+
247
+ handleClick();
248
+
249
+ document.removeEventListener( 'touchend', onTouchEnd );
250
+
251
+ }
252
+
253
+ function onDoubleClick( event ) {
254
+
255
+ const array = getMousePosition( container.dom, event.clientX, event.clientY );
256
+ onDoubleClickPosition.fromArray( array );
257
+
258
+ const intersects = selector.getPointerIntersects( onDoubleClickPosition, camera );
259
+
260
+ if ( intersects.length > 0 ) {
261
+
262
+ const intersect = intersects[ 0 ];
263
+
264
+ signals.objectFocused.dispatch( intersect.object );
265
+
266
+ }
267
+
268
+ }
269
+
270
+ container.dom.addEventListener( 'mousedown', onMouseDown );
271
+ container.dom.addEventListener( 'touchstart', onTouchStart, { passive: false } );
272
+ container.dom.addEventListener( 'dblclick', onDoubleClick );
273
+
274
+ // controls need to be added *after* main logic,
275
+ // otherwise controls.enabled doesn't work.
276
+
277
+ const controls = new EditorControls( camera, container.dom );
278
+ controls.addEventListener( 'change', function () {
279
+
280
+ signals.cameraChanged.dispatch( camera );
281
+ signals.refreshSidebarObject3D.dispatch( camera );
282
+
283
+ } );
284
+ viewHelper.center = controls.center;
285
+
286
+ // signals
287
+
288
+ signals.editorCleared.add( function () {
289
+
290
+ controls.center.set( 0, 0, 0 );
291
+ pathtracer.reset();
292
+
293
+ initPT();
294
+ render();
295
+
296
+ } );
297
+
298
+ signals.transformModeChanged.add( function ( mode ) {
299
+
300
+ transformControls.setMode( mode );
301
+
302
+ render();
303
+
304
+ } );
305
+
306
+ signals.snapChanged.add( function ( dist ) {
307
+
308
+ transformControls.setTranslationSnap( dist );
309
+
310
+ } );
311
+
312
+ signals.spaceChanged.add( function ( space ) {
313
+
314
+ transformControls.setSpace( space );
315
+
316
+ render();
317
+
318
+ } );
319
+
320
+ signals.rendererUpdated.add( function () {
321
+
322
+ scene.traverse( function ( child ) {
323
+
324
+ if ( child.material !== undefined ) {
325
+
326
+ child.material.needsUpdate = true;
327
+
328
+ }
329
+
330
+ } );
331
+
332
+ render();
333
+
334
+ } );
335
+
336
+ signals.rendererCreated.add( function ( newRenderer ) {
337
+
338
+ if ( renderer !== null ) {
339
+
340
+ renderer.setAnimationLoop( null );
341
+ renderer.dispose();
342
+ pmremGenerator.dispose();
343
+
344
+ container.dom.removeChild( renderer.domElement );
345
+
346
+ }
347
+
348
+ renderer = newRenderer;
349
+
350
+ renderer.setAnimationLoop( animate );
351
+ renderer.setClearColor( 0xaaaaaa );
352
+
353
+ if ( window.matchMedia ) {
354
+
355
+ const mediaQuery = window.matchMedia( '(prefers-color-scheme: dark)' );
356
+ mediaQuery.addEventListener( 'change', function ( event ) {
357
+
358
+ renderer.setClearColor( event.matches ? 0x333333 : 0xaaaaaa );
359
+ updateGridColors( grid1, grid2, event.matches ? GRID_COLORS_DARK : GRID_COLORS_LIGHT );
360
+
361
+ render();
362
+
363
+ } );
364
+
365
+ renderer.setClearColor( mediaQuery.matches ? 0x333333 : 0xaaaaaa );
366
+ updateGridColors( grid1, grid2, mediaQuery.matches ? GRID_COLORS_DARK : GRID_COLORS_LIGHT );
367
+
368
+ }
369
+
370
+ renderer.setPixelRatio( window.devicePixelRatio );
371
+ renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
372
+
373
+ pmremGenerator = new THREE.PMREMGenerator( renderer );
374
+ pmremGenerator.compileEquirectangularShader();
375
+
376
+ pathtracer = new ViewportPathtracer( renderer );
377
+
378
+ container.dom.appendChild( renderer.domElement );
379
+
380
+ render();
381
+
382
+ } );
383
+
384
+ signals.rendererDetectKTX2Support.add( function ( ktx2Loader ) {
385
+
386
+ ktx2Loader.detectSupport( renderer );
387
+
388
+ } );
389
+
390
+ signals.sceneGraphChanged.add( function () {
391
+
392
+ initPT();
393
+ render();
394
+
395
+ } );
396
+
397
+ signals.cameraChanged.add( function () {
398
+
399
+ pathtracer.reset();
400
+
401
+ render();
402
+
403
+ } );
404
+
405
+ signals.objectSelected.add( function ( object ) {
406
+
407
+ selectionBox.visible = false;
408
+ transformControls.detach();
409
+
410
+ if ( object !== null && object !== scene && object !== camera ) {
411
+
412
+ box.setFromObject( object, true );
413
+
414
+ if ( box.isEmpty() === false ) {
415
+
416
+ selectionBox.visible = true;
417
+
418
+ }
419
+
420
+ transformControls.attach( object );
421
+
422
+ }
423
+
424
+ render();
425
+
426
+ } );
427
+
428
+ signals.objectFocused.add( function ( object ) {
429
+
430
+ controls.focus( object );
431
+
432
+ } );
433
+
434
+ signals.geometryChanged.add( function ( object ) {
435
+
436
+ if ( object !== undefined ) {
437
+
438
+ box.setFromObject( object, true );
439
+
440
+ }
441
+
442
+ initPT();
443
+ render();
444
+
445
+ } );
446
+
447
+ signals.objectChanged.add( function ( object ) {
448
+
449
+ if ( editor.selected === object ) {
450
+
451
+ box.setFromObject( object, true );
452
+
453
+ }
454
+
455
+ if ( object.isPerspectiveCamera ) {
456
+
457
+ object.updateProjectionMatrix();
458
+
459
+ }
460
+
461
+ const helper = editor.helpers[ object.id ];
462
+
463
+ if ( helper !== undefined && helper.isSkeletonHelper !== true ) {
464
+
465
+ helper.update();
466
+
467
+ }
468
+
469
+ initPT();
470
+ render();
471
+
472
+ } );
473
+
474
+ signals.objectRemoved.add( function ( object ) {
475
+
476
+ controls.enabled = true; // see #14180
477
+
478
+ if ( object === transformControls.object ) {
479
+
480
+ transformControls.detach();
481
+
482
+ }
483
+
484
+ } );
485
+
486
+ signals.materialChanged.add( function () {
487
+
488
+ updatePTMaterials();
489
+ render();
490
+
491
+ } );
492
+
493
+ // background
494
+
495
+ signals.sceneBackgroundChanged.add( function ( backgroundType, backgroundColor, backgroundTexture, backgroundEquirectangularTexture, backgroundBlurriness, backgroundIntensity, backgroundRotation ) {
496
+
497
+ scene.background = null;
498
+
499
+ switch ( backgroundType ) {
500
+
501
+ case 'Color':
502
+
503
+ scene.background = new THREE.Color( backgroundColor );
504
+
505
+ break;
506
+
507
+ case 'Texture':
508
+
509
+ if ( backgroundTexture ) {
510
+
511
+ scene.background = backgroundTexture;
512
+
513
+ }
514
+
515
+ break;
516
+
517
+ case 'Equirectangular':
518
+
519
+ if ( backgroundEquirectangularTexture ) {
520
+
521
+ backgroundEquirectangularTexture.mapping = THREE.EquirectangularReflectionMapping;
522
+
523
+ scene.background = backgroundEquirectangularTexture;
524
+ scene.backgroundBlurriness = backgroundBlurriness;
525
+ scene.backgroundIntensity = backgroundIntensity;
526
+ scene.backgroundRotation.y = backgroundRotation * THREE.MathUtils.DEG2RAD;
527
+
528
+ if ( useBackgroundAsEnvironment ) {
529
+
530
+ scene.environment = scene.background;
531
+ scene.environmentRotation.y = backgroundRotation * THREE.MathUtils.DEG2RAD;
532
+
533
+ }
534
+
535
+
536
+ }
537
+
538
+ break;
539
+
540
+ }
541
+
542
+ updatePTBackground();
543
+ render();
544
+
545
+ } );
546
+
547
+ // environment
548
+
549
+ let useBackgroundAsEnvironment = false;
550
+
551
+ signals.sceneEnvironmentChanged.add( function ( environmentType, environmentEquirectangularTexture ) {
552
+
553
+ scene.environment = null;
554
+
555
+ useBackgroundAsEnvironment = false;
556
+
557
+ switch ( environmentType ) {
558
+
559
+
560
+ case 'Background':
561
+
562
+ useBackgroundAsEnvironment = true;
563
+
564
+ if ( scene.background !== null && scene.background.isTexture ) {
565
+
566
+ scene.environment = scene.background;
567
+ scene.environment.mapping = THREE.EquirectangularReflectionMapping;
568
+ scene.environmentRotation.y = scene.backgroundRotation.y;
569
+
570
+ }
571
+
572
+ break;
573
+
574
+ case 'Equirectangular':
575
+
576
+ if ( environmentEquirectangularTexture ) {
577
+
578
+ scene.environment = environmentEquirectangularTexture;
579
+ scene.environment.mapping = THREE.EquirectangularReflectionMapping;
580
+
581
+ }
582
+
583
+ break;
584
+
585
+ case 'ModelViewer':
586
+
587
+ scene.environment = pmremGenerator.fromScene( new RoomEnvironment(), 0.04 ).texture;
588
+
589
+ break;
590
+
591
+ }
592
+
593
+ updatePTEnvironment();
594
+ render();
595
+
596
+ } );
597
+
598
+ // fog
599
+
600
+ signals.sceneFogChanged.add( function ( fogType, fogColor, fogNear, fogFar, fogDensity ) {
601
+
602
+ switch ( fogType ) {
603
+
604
+ case 'None':
605
+ scene.fog = null;
606
+ break;
607
+ case 'Fog':
608
+ scene.fog = new THREE.Fog( fogColor, fogNear, fogFar );
609
+ break;
610
+ case 'FogExp2':
611
+ scene.fog = new THREE.FogExp2( fogColor, fogDensity );
612
+ break;
613
+
614
+ }
615
+
616
+ render();
617
+
618
+ } );
619
+
620
+ signals.sceneFogSettingsChanged.add( function ( fogType, fogColor, fogNear, fogFar, fogDensity ) {
621
+
622
+ switch ( fogType ) {
623
+
624
+ case 'Fog':
625
+ scene.fog.color.setHex( fogColor );
626
+ scene.fog.near = fogNear;
627
+ scene.fog.far = fogFar;
628
+ break;
629
+ case 'FogExp2':
630
+ scene.fog.color.setHex( fogColor );
631
+ scene.fog.density = fogDensity;
632
+ break;
633
+
634
+ }
635
+
636
+ render();
637
+
638
+ } );
639
+
640
+ signals.viewportCameraChanged.add( function () {
641
+
642
+ const viewportCamera = editor.viewportCamera;
643
+
644
+ if ( viewportCamera.isPerspectiveCamera || viewportCamera.isOrthographicCamera ) {
645
+
646
+ updateAspectRatio();
647
+
648
+ }
649
+
650
+ // disable EditorControls when setting a user camera
651
+
652
+ controls.enabled = ( viewportCamera === editor.camera );
653
+
654
+ initPT();
655
+ render();
656
+
657
+ } );
658
+
659
+ signals.viewportShadingChanged.add( function () {
660
+
661
+ const viewportShading = editor.viewportShading;
662
+
663
+ switch ( viewportShading ) {
664
+
665
+ case 'realistic':
666
+ pathtracer.init( scene, editor.viewportCamera );
667
+ break;
668
+
669
+ case 'solid':
670
+ scene.overrideMaterial = null;
671
+ break;
672
+
673
+ case 'normals':
674
+ scene.overrideMaterial = new THREE.MeshNormalMaterial();
675
+ break;
676
+
677
+ case 'wireframe':
678
+ scene.overrideMaterial = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true } );
679
+ break;
680
+
681
+ }
682
+
683
+ render();
684
+
685
+ } );
686
+
687
+ //
688
+
689
+ signals.windowResize.add( function () {
690
+
691
+ updateAspectRatio();
692
+
693
+ renderer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
694
+ pathtracer.setSize( container.dom.offsetWidth, container.dom.offsetHeight );
695
+
696
+ render();
697
+
698
+ } );
699
+
700
+ signals.showHelpersChanged.add( function ( appearanceStates ) {
701
+
702
+ grid.visible = appearanceStates.gridHelper;
703
+
704
+ sceneHelpers.traverse( function ( object ) {
705
+
706
+ switch ( object.type ) {
707
+
708
+ case 'CameraHelper':
709
+
710
+ {
711
+
712
+ object.visible = appearanceStates.cameraHelpers;
713
+ break;
714
+
715
+ }
716
+
717
+ case 'PointLightHelper':
718
+ case 'DirectionalLightHelper':
719
+ case 'SpotLightHelper':
720
+ case 'HemisphereLightHelper':
721
+
722
+ {
723
+
724
+ object.visible = appearanceStates.lightHelpers;
725
+ break;
726
+
727
+ }
728
+
729
+ case 'SkeletonHelper':
730
+
731
+ {
732
+
733
+ object.visible = appearanceStates.skeletonHelpers;
734
+ break;
735
+
736
+ }
737
+
738
+ default:
739
+
740
+ {
741
+
742
+ // not a helper, skip.
743
+
744
+ }
745
+
746
+ }
747
+
748
+ } );
749
+
750
+
751
+ render();
752
+
753
+ } );
754
+
755
+ signals.cameraResetted.add( updateAspectRatio );
756
+
757
+ // animations
758
+
759
+ let prevActionsInUse = 0;
760
+
761
+ const clock = new THREE.Clock(); // only used for animations
762
+
763
+ function animate() {
764
+
765
+ const mixer = editor.mixer;
766
+ const delta = clock.getDelta();
767
+
768
+ let needsUpdate = false;
769
+
770
+ // Animations
771
+
772
+ const actions = mixer.stats.actions;
773
+
774
+ if ( actions.inUse > 0 || prevActionsInUse > 0 ) {
775
+
776
+ prevActionsInUse = actions.inUse;
777
+
778
+ mixer.update( delta );
779
+ needsUpdate = true;
780
+
781
+ if ( editor.selected !== null ) {
782
+
783
+ editor.selected.updateWorldMatrix( false, true ); // avoid frame late effect for certain skinned meshes (e.g. Michelle.glb)
784
+ selectionBox.box.setFromObject( editor.selected, true ); // selection box should reflect current animation state
785
+
786
+ }
787
+
788
+ }
789
+
790
+ // View Helper
791
+
792
+ if ( viewHelper.animating === true ) {
793
+
794
+ viewHelper.update( delta );
795
+ needsUpdate = true;
796
+
797
+ }
798
+
799
+ if ( renderer.xr.isPresenting === true ) {
800
+
801
+ needsUpdate = true;
802
+
803
+ }
804
+
805
+ if ( needsUpdate === true ) render();
806
+
807
+ updatePT();
808
+
809
+ }
810
+
811
+ function initPT() {
812
+
813
+ if ( editor.viewportShading === 'realistic' ) {
814
+
815
+ pathtracer.init( scene, editor.viewportCamera );
816
+
817
+ }
818
+
819
+ }
820
+
821
+ function updatePTBackground() {
822
+
823
+ if ( editor.viewportShading === 'realistic' ) {
824
+
825
+ pathtracer.setBackground( scene.background, scene.backgroundBlurriness );
826
+
827
+ }
828
+
829
+ }
830
+
831
+ function updatePTEnvironment() {
832
+
833
+ if ( editor.viewportShading === 'realistic' ) {
834
+
835
+ pathtracer.setEnvironment( scene.environment );
836
+
837
+ }
838
+
839
+ }
840
+
841
+ function updatePTMaterials() {
842
+
843
+ if ( editor.viewportShading === 'realistic' ) {
844
+
845
+ pathtracer.updateMaterials();
846
+
847
+ }
848
+
849
+ }
850
+
851
+ function updatePT() {
852
+
853
+ if ( editor.viewportShading === 'realistic' ) {
854
+
855
+ pathtracer.update();
856
+ editor.signals.pathTracerUpdated.dispatch( pathtracer.getSamples() );
857
+
858
+ }
859
+
860
+ }
861
+
862
+ //
863
+
864
+ let startTime = 0;
865
+ let endTime = 0;
866
+
867
+ function render() {
868
+
869
+ startTime = performance.now();
870
+
871
+ renderer.setViewport( 0, 0, container.dom.offsetWidth, container.dom.offsetHeight );
872
+ renderer.render( scene, editor.viewportCamera );
873
+
874
+ if ( camera === editor.viewportCamera ) {
875
+
876
+ renderer.autoClear = false;
877
+ if ( grid.visible === true ) renderer.render( grid, camera );
878
+ if ( sceneHelpers.visible === true ) renderer.render( sceneHelpers, camera );
879
+ if ( renderer.xr.isPresenting !== true ) viewHelper.render( renderer );
880
+ renderer.autoClear = true;
881
+
882
+ }
883
+
884
+ endTime = performance.now();
885
+ editor.signals.sceneRendered.dispatch( endTime - startTime );
886
+
887
+ }
888
+
889
+ return container;
890
+
891
+ }
892
+
893
+ function updateGridColors( grid1, grid2, colors ) {
894
+
895
+ grid1.material.color.setHex( colors[ 0 ] );
896
+ grid2.material.color.setHex( colors[ 1 ] );
897
+
898
+ }
899
+
900
+ export { Viewport };