@thanhthbm/scene-editor 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +169 -0
  2. package/dist/index.css +921 -0
  3. package/dist/index.js +14076 -0
  4. package/package.json +49 -0
  5. package/src/editor/css/main.css +1030 -0
  6. package/src/editor/js/Animation.js +618 -0
  7. package/src/editor/js/AnimationResizer.js +73 -0
  8. package/src/editor/js/Command.js +40 -0
  9. package/src/editor/js/Config.js +86 -0
  10. package/src/editor/js/Editor.js +1006 -0
  11. package/src/editor/js/EditorControls.js +489 -0
  12. package/src/editor/js/GLTFImportDialog.js +112 -0
  13. package/src/editor/js/History.js +321 -0
  14. package/src/editor/js/Loader.js +1162 -0
  15. package/src/editor/js/LoaderUtils.js +90 -0
  16. package/src/editor/js/Menubar.Add.js +559 -0
  17. package/src/editor/js/Menubar.Edit.js +155 -0
  18. package/src/editor/js/Menubar.File.js +585 -0
  19. package/src/editor/js/Menubar.Help.js +73 -0
  20. package/src/editor/js/Menubar.Render.js +858 -0
  21. package/src/editor/js/Menubar.Status.js +51 -0
  22. package/src/editor/js/Menubar.View.js +193 -0
  23. package/src/editor/js/Menubar.js +29 -0
  24. package/src/editor/js/Player.js +53 -0
  25. package/src/editor/js/Resizer.js +65 -0
  26. package/src/editor/js/Script.js +532 -0
  27. package/src/editor/js/Selector.js +129 -0
  28. package/src/editor/js/Sidebar.Geometry.BoxGeometry.js +121 -0
  29. package/src/editor/js/Sidebar.Geometry.BufferGeometry.js +124 -0
  30. package/src/editor/js/Sidebar.Geometry.CapsuleGeometry.js +109 -0
  31. package/src/editor/js/Sidebar.Geometry.CircleGeometry.js +97 -0
  32. package/src/editor/js/Sidebar.Geometry.CylinderGeometry.js +121 -0
  33. package/src/editor/js/Sidebar.Geometry.DodecahedronGeometry.js +73 -0
  34. package/src/editor/js/Sidebar.Geometry.ExtrudeGeometry.js +196 -0
  35. package/src/editor/js/Sidebar.Geometry.IcosahedronGeometry.js +73 -0
  36. package/src/editor/js/Sidebar.Geometry.LatheGeometry.js +98 -0
  37. package/src/editor/js/Sidebar.Geometry.Modifiers.js +73 -0
  38. package/src/editor/js/Sidebar.Geometry.OctahedronGeometry.js +74 -0
  39. package/src/editor/js/Sidebar.Geometry.PlaneGeometry.js +97 -0
  40. package/src/editor/js/Sidebar.Geometry.RingGeometry.js +121 -0
  41. package/src/editor/js/Sidebar.Geometry.ShapeGeometry.js +76 -0
  42. package/src/editor/js/Sidebar.Geometry.SphereGeometry.js +133 -0
  43. package/src/editor/js/Sidebar.Geometry.TetrahedronGeometry.js +74 -0
  44. package/src/editor/js/Sidebar.Geometry.TextGeometry.js +136 -0
  45. package/src/editor/js/Sidebar.Geometry.TorusGeometry.js +109 -0
  46. package/src/editor/js/Sidebar.Geometry.TorusKnotGeometry.js +121 -0
  47. package/src/editor/js/Sidebar.Geometry.TubeGeometry.js +135 -0
  48. package/src/editor/js/Sidebar.Geometry.js +471 -0
  49. package/src/editor/js/Sidebar.Material.BooleanProperty.js +60 -0
  50. package/src/editor/js/Sidebar.Material.ColorProperty.js +87 -0
  51. package/src/editor/js/Sidebar.Material.ConstantProperty.js +62 -0
  52. package/src/editor/js/Sidebar.Material.MapProperty.js +277 -0
  53. package/src/editor/js/Sidebar.Material.NumberProperty.js +60 -0
  54. package/src/editor/js/Sidebar.Material.Program.js +73 -0
  55. package/src/editor/js/Sidebar.Material.RangeValueProperty.js +63 -0
  56. package/src/editor/js/Sidebar.Material.js +751 -0
  57. package/src/editor/js/Sidebar.Object.js +892 -0
  58. package/src/editor/js/Sidebar.Project.App.js +218 -0
  59. package/src/editor/js/Sidebar.Project.Materials.js +82 -0
  60. package/src/editor/js/Sidebar.Project.Renderer.js +193 -0
  61. package/src/editor/js/Sidebar.Project.Resources.js +242 -0
  62. package/src/editor/js/Sidebar.Project.js +21 -0
  63. package/src/editor/js/Sidebar.Properties.js +73 -0
  64. package/src/editor/js/Sidebar.Scene.js +643 -0
  65. package/src/editor/js/Sidebar.Script.js +129 -0
  66. package/src/editor/js/Sidebar.Settings.History.js +146 -0
  67. package/src/editor/js/Sidebar.Settings.Shortcuts.js +198 -0
  68. package/src/editor/js/Sidebar.Settings.js +58 -0
  69. package/src/editor/js/Sidebar.js +41 -0
  70. package/src/editor/js/Storage.js +98 -0
  71. package/src/editor/js/Strings.js +2718 -0
  72. package/src/editor/js/TextureParametersDialog.js +293 -0
  73. package/src/editor/js/Toolbar.js +75 -0
  74. package/src/editor/js/Viewport.Controls.js +98 -0
  75. package/src/editor/js/Viewport.Info.js +144 -0
  76. package/src/editor/js/Viewport.Pathtracer.js +27 -0
  77. package/src/editor/js/Viewport.ViewHelper.js +41 -0
  78. package/src/editor/js/Viewport.XR.js +7 -0
  79. package/src/editor/js/Viewport.js +982 -0
  80. package/src/editor/js/commands/AddObjectCommand.js +68 -0
  81. package/src/editor/js/commands/AddScriptCommand.js +75 -0
  82. package/src/editor/js/commands/Commands.js +24 -0
  83. package/src/editor/js/commands/MoveObjectCommand.js +117 -0
  84. package/src/editor/js/commands/MultiCmdsCommand.js +85 -0
  85. package/src/editor/js/commands/RemoveObjectCommand.js +88 -0
  86. package/src/editor/js/commands/RemoveScriptCommand.js +81 -0
  87. package/src/editor/js/commands/SetColorCommand.js +73 -0
  88. package/src/editor/js/commands/SetGeometryCommand.js +86 -0
  89. package/src/editor/js/commands/SetGeometryValueCommand.js +70 -0
  90. package/src/editor/js/commands/SetMaterialColorCommand.js +87 -0
  91. package/src/editor/js/commands/SetMaterialCommand.js +80 -0
  92. package/src/editor/js/commands/SetMaterialMapCommand.js +144 -0
  93. package/src/editor/js/commands/SetMaterialRangeCommand.js +92 -0
  94. package/src/editor/js/commands/SetMaterialValueCommand.js +91 -0
  95. package/src/editor/js/commands/SetMaterialVectorCommand.js +88 -0
  96. package/src/editor/js/commands/SetPositionCommand.js +84 -0
  97. package/src/editor/js/commands/SetRotationCommand.js +84 -0
  98. package/src/editor/js/commands/SetScaleCommand.js +84 -0
  99. package/src/editor/js/commands/SetSceneCommand.js +104 -0
  100. package/src/editor/js/commands/SetScriptValueCommand.js +80 -0
  101. package/src/editor/js/commands/SetShadowValueCommand.js +73 -0
  102. package/src/editor/js/commands/SetTextureParametersCommand.js +143 -0
  103. package/src/editor/js/commands/SetUuidCommand.js +70 -0
  104. package/src/editor/js/commands/SetValueCommand.js +75 -0
  105. package/src/editor/js/libs/acorn/acorn.js +3236 -0
  106. package/src/editor/js/libs/acorn/acorn_loose.js +1299 -0
  107. package/src/editor/js/libs/acorn/walk.js +344 -0
  108. package/src/editor/js/libs/app/index.html +51 -0
  109. package/src/editor/js/libs/app.js +14 -0
  110. package/src/editor/js/libs/codemirror/addon/dialog.css +32 -0
  111. package/src/editor/js/libs/codemirror/addon/dialog.js +163 -0
  112. package/src/editor/js/libs/codemirror/addon/show-hint.css +36 -0
  113. package/src/editor/js/libs/codemirror/addon/show-hint.js +529 -0
  114. package/src/editor/js/libs/codemirror/addon/tern.css +87 -0
  115. package/src/editor/js/libs/codemirror/addon/tern.js +750 -0
  116. package/src/editor/js/libs/codemirror/codemirror.css +344 -0
  117. package/src/editor/js/libs/codemirror/codemirror.js +9849 -0
  118. package/src/editor/js/libs/codemirror/mode/glsl.js +233 -0
  119. package/src/editor/js/libs/codemirror/mode/javascript.js +959 -0
  120. package/src/editor/js/libs/codemirror/theme/monokai.css +41 -0
  121. package/src/editor/js/libs/esprima.js +6401 -0
  122. package/src/editor/js/libs/jsonlint.js +453 -0
  123. package/src/editor/js/libs/signals.min.js +14 -0
  124. package/src/editor/js/libs/tern-threejs/build-defs.js +233 -0
  125. package/src/editor/js/libs/ternjs/comment.js +87 -0
  126. package/src/editor/js/libs/ternjs/def.js +588 -0
  127. package/src/editor/js/libs/ternjs/doc_comment.js +401 -0
  128. package/src/editor/js/libs/ternjs/infer.js +1635 -0
  129. package/src/editor/js/libs/ternjs/polyfill.js +80 -0
  130. package/src/editor/js/libs/ternjs/signal.js +26 -0
  131. package/src/editor/js/libs/ternjs/tern.js +993 -0
  132. package/src/editor/js/libs/ui.js +1305 -0
  133. package/src/editor/js/libs/ui.three.js +946 -0
  134. package/src/events.js +273 -0
  135. package/src/index.js +284 -0
  136. package/src/presets/machines.js +239 -0
@@ -0,0 +1,293 @@
1
+ import * as THREE from 'three';
2
+
3
+ import { UIButton, UICheckbox, UIDiv, UINumber, UIRow, UISelect, UIText } from './libs/ui.js';
4
+ import { renderToCanvas } from './libs/ui.three.js';
5
+
6
+ class TextureParametersDialog {
7
+
8
+ constructor( editor, texture ) {
9
+
10
+ this.editor = editor;
11
+
12
+ this.strings = editor.strings;
13
+ this.texture = texture;
14
+
15
+ const dom = new UIDiv();
16
+ dom.setClass( 'Dialog' );
17
+ this.dom = dom.dom;
18
+
19
+ const background = new UIDiv();
20
+ background.setClass( 'Dialog-background' );
21
+ background.dom.addEventListener( 'click', () => this.cancel() );
22
+ dom.add( background );
23
+
24
+ const content = new UIDiv();
25
+ content.setClass( 'Dialog-content TextureParametersDialog-content' );
26
+ dom.add( content );
27
+
28
+ // Title
29
+
30
+ const titleBar = new UIDiv();
31
+ titleBar.setClass( 'Dialog-title' );
32
+ titleBar.setTextContent( this.strings.getKey( 'dialog/texture/title' ) );
33
+ content.add( titleBar );
34
+
35
+ // Body (split into preview + form)
36
+
37
+ const body = new UIDiv();
38
+ body.setClass( 'Dialog-body TextureParametersDialog-body' );
39
+ content.add( body );
40
+
41
+ const split = new UIDiv();
42
+ split.setClass( 'TextureParametersDialog-split' );
43
+ body.add( split );
44
+
45
+ // Preview
46
+
47
+ const previewWrapper = new UIDiv();
48
+ previewWrapper.setClass( 'TextureParametersDialog-preview' );
49
+ split.add( previewWrapper );
50
+
51
+ previewWrapper.add( createGroupHeading( this.strings.getKey( 'dialog/texture/group/preview' ) ) );
52
+
53
+ const previewCanvas = document.createElement( 'canvas' );
54
+ previewCanvas.width = 400;
55
+ previewCanvas.height = 400;
56
+ previewWrapper.dom.appendChild( previewCanvas );
57
+
58
+ this.previewCanvas = previewCanvas;
59
+ this.previewContext = previewCanvas.getContext( '2d' );
60
+ this.previewTexture = texture.clone();
61
+
62
+ const updatePreview = () => this.updatePreview();
63
+
64
+ // Form
65
+
66
+ const form = new UIDiv();
67
+ form.setClass( 'TextureParametersDialog-form' );
68
+ split.add( form );
69
+
70
+ // Mapping group
71
+
72
+ form.add( createGroupHeading( this.strings.getKey( 'dialog/texture/group/mapping' ) ) );
73
+
74
+ this.mapping = new UISelect().setOptions( {
75
+ [ THREE.UVMapping ]: 'UV',
76
+ [ THREE.EquirectangularReflectionMapping ]: 'Equirectangular Reflection',
77
+ [ THREE.EquirectangularRefractionMapping ]: 'Equirectangular Refraction',
78
+ [ THREE.CubeReflectionMapping ]: 'Cube Reflection',
79
+ [ THREE.CubeRefractionMapping ]: 'Cube Refraction',
80
+ [ THREE.CubeUVReflectionMapping ]: 'CubeUV Reflection'
81
+ } ).setValue( texture.mapping ).onChange( updatePreview );
82
+ form.add( createRow( this.strings.getKey( 'dialog/texture/mapping' ), this.mapping ) );
83
+
84
+ const wrapOptions = {
85
+ [ THREE.RepeatWrapping ]: 'Repeat',
86
+ [ THREE.ClampToEdgeWrapping ]: 'Clamp To Edge',
87
+ [ THREE.MirroredRepeatWrapping ]: 'Mirrored Repeat'
88
+ };
89
+
90
+ this.wrapS = new UISelect().setOptions( wrapOptions ).setValue( texture.wrapS ).onChange( updatePreview );
91
+ form.add( createRow( this.strings.getKey( 'dialog/texture/wrapS' ), this.wrapS ) );
92
+
93
+ this.wrapT = new UISelect().setOptions( wrapOptions ).setValue( texture.wrapT ).onChange( updatePreview );
94
+ form.add( createRow( this.strings.getKey( 'dialog/texture/wrapT' ), this.wrapT ) );
95
+
96
+ // Filtering group
97
+
98
+ form.add( createGroupHeading( this.strings.getKey( 'dialog/texture/group/filtering' ) ) );
99
+
100
+ this.minFilter = new UISelect().setOptions( {
101
+ [ THREE.NearestFilter ]: 'Nearest',
102
+ [ THREE.NearestMipmapNearestFilter ]: 'Nearest Mipmap Nearest',
103
+ [ THREE.NearestMipmapLinearFilter ]: 'Nearest Mipmap Linear',
104
+ [ THREE.LinearFilter ]: 'Linear',
105
+ [ THREE.LinearMipmapNearestFilter ]: 'Linear Mipmap Nearest',
106
+ [ THREE.LinearMipmapLinearFilter ]: 'Linear Mipmap Linear'
107
+ } ).setValue( texture.minFilter ).onChange( updatePreview );
108
+ form.add( createRow( this.strings.getKey( 'dialog/texture/minFilter' ), this.minFilter ) );
109
+
110
+ this.magFilter = new UISelect().setOptions( {
111
+ [ THREE.NearestFilter ]: 'Nearest',
112
+ [ THREE.LinearFilter ]: 'Linear'
113
+ } ).setValue( texture.magFilter ).onChange( updatePreview );
114
+ form.add( createRow( this.strings.getKey( 'dialog/texture/magFilter' ), this.magFilter ) );
115
+
116
+ this.anisotropy = new UINumber( texture.anisotropy ).setPrecision( 0 ).setRange( 1, 16 ).setNudge( 1 ).setStep( 1 ).setWidth( '60px' ).onChange( updatePreview );
117
+ form.add( createRow( this.strings.getKey( 'dialog/texture/anisotropy' ), this.anisotropy ) );
118
+
119
+ // Transform group
120
+
121
+ form.add( createGroupHeading( this.strings.getKey( 'dialog/texture/group/transform' ) ) );
122
+
123
+ this.offsetX = new UINumber( texture.offset.x ).setWidth( '60px' ).onChange( updatePreview );
124
+ this.offsetY = new UINumber( texture.offset.y ).setWidth( '60px' ).onChange( updatePreview );
125
+ form.add( createRow( this.strings.getKey( 'dialog/texture/offset' ), this.offsetX, this.offsetY ) );
126
+
127
+ this.repeatX = new UINumber( texture.repeat.x ).setWidth( '60px' ).onChange( updatePreview );
128
+ this.repeatY = new UINumber( texture.repeat.y ).setWidth( '60px' ).onChange( updatePreview );
129
+ form.add( createRow( this.strings.getKey( 'dialog/texture/repeat' ), this.repeatX, this.repeatY ) );
130
+
131
+ this.centerX = new UINumber( texture.center.x ).setWidth( '60px' ).onChange( updatePreview );
132
+ this.centerY = new UINumber( texture.center.y ).setWidth( '60px' ).onChange( updatePreview );
133
+ form.add( createRow( this.strings.getKey( 'dialog/texture/center' ), this.centerX, this.centerY ) );
134
+
135
+ this.rotation = new UINumber( texture.rotation * THREE.MathUtils.RAD2DEG ).setStep( 10 ).setNudge( 0.1 ).setUnit( '°' ).setWidth( '60px' ).onChange( updatePreview );
136
+ form.add( createRow( this.strings.getKey( 'dialog/texture/rotation' ), this.rotation ) );
137
+
138
+ // Color group
139
+
140
+ form.add( createGroupHeading( this.strings.getKey( 'dialog/texture/group/color' ) ) );
141
+
142
+ this.premultiplyAlpha = new UICheckbox( texture.premultiplyAlpha ).onChange( updatePreview );
143
+ form.add( createRow( this.strings.getKey( 'dialog/texture/premultiplyAlpha' ), this.premultiplyAlpha ) );
144
+
145
+ this.colorSpace = new UISelect().setOptions( {
146
+ [ THREE.NoColorSpace ]: 'No Color Space',
147
+ [ THREE.SRGBColorSpace ]: 'sRGB',
148
+ [ THREE.LinearSRGBColorSpace ]: 'Linear sRGB'
149
+ } ).setValue( texture.colorSpace ).onChange( updatePreview );
150
+ form.add( createRow( this.strings.getKey( 'dialog/texture/colorSpace' ), this.colorSpace ) );
151
+
152
+ updatePreview();
153
+
154
+ // Buttons
155
+
156
+ const buttonsRow = new UIDiv();
157
+ buttonsRow.setClass( 'Dialog-buttons' );
158
+ body.add( buttonsRow );
159
+
160
+ const okButton = new UIButton( this.strings.getKey( 'dialog/ok' ) );
161
+ okButton.setWidth( '80px' );
162
+ okButton.onClick( () => this.confirm() );
163
+ buttonsRow.add( okButton );
164
+
165
+ const cancelButton = new UIButton( this.strings.getKey( 'dialog/cancel' ) );
166
+ cancelButton.setWidth( '80px' );
167
+ cancelButton.setMarginLeft( '8px' );
168
+ cancelButton.onClick( () => this.cancel() );
169
+ buttonsRow.add( cancelButton );
170
+
171
+ // Promise handlers
172
+
173
+ this.resolve = null;
174
+ this.reject = null;
175
+
176
+ }
177
+
178
+ show() {
179
+
180
+ document.body.appendChild( this.dom );
181
+
182
+ return new Promise( ( resolve, reject ) => {
183
+
184
+ this.resolve = resolve;
185
+ this.reject = reject;
186
+
187
+ } );
188
+
189
+ }
190
+
191
+ getCurrentParameters() {
192
+
193
+ return {
194
+ mapping: parseInt( this.mapping.getValue() ),
195
+ wrapS: parseInt( this.wrapS.getValue() ),
196
+ wrapT: parseInt( this.wrapT.getValue() ),
197
+ magFilter: parseInt( this.magFilter.getValue() ),
198
+ minFilter: parseInt( this.minFilter.getValue() ),
199
+ anisotropy: this.anisotropy.getValue(),
200
+ offset: { x: this.offsetX.getValue(), y: this.offsetY.getValue() },
201
+ repeat: { x: this.repeatX.getValue(), y: this.repeatY.getValue() },
202
+ center: { x: this.centerX.getValue(), y: this.centerY.getValue() },
203
+ rotation: this.rotation.getValue() * THREE.MathUtils.DEG2RAD,
204
+ premultiplyAlpha: this.premultiplyAlpha.getValue(),
205
+ colorSpace: this.colorSpace.getValue()
206
+ };
207
+
208
+ }
209
+
210
+ updatePreview() {
211
+
212
+ applyParameters( this.previewTexture, this.getCurrentParameters() );
213
+
214
+ const rendered = renderToCanvas( this.previewTexture );
215
+
216
+ const canvas = this.previewCanvas;
217
+ const context = this.previewContext;
218
+ context.clearRect( 0, 0, canvas.width, canvas.height );
219
+
220
+ if ( rendered.width === 0 || rendered.height === 0 ) return;
221
+
222
+ const scale = Math.min( canvas.width / rendered.width, canvas.height / rendered.height );
223
+ const w = rendered.width * scale;
224
+ const h = rendered.height * scale;
225
+ context.drawImage( rendered, ( canvas.width - w ) / 2, ( canvas.height - h ) / 2, w, h );
226
+
227
+ }
228
+
229
+ confirm() {
230
+
231
+ const result = this.getCurrentParameters();
232
+
233
+ this.previewTexture.dispose();
234
+ this.dom.remove();
235
+
236
+ if ( this.resolve ) this.resolve( result );
237
+
238
+ }
239
+
240
+ cancel() {
241
+
242
+ this.previewTexture.dispose();
243
+ this.dom.remove();
244
+
245
+ if ( this.reject ) this.reject( new Error( 'Texture parameters edit cancelled' ) );
246
+
247
+ }
248
+
249
+ }
250
+
251
+ function createRow( label, ...inputs ) {
252
+
253
+ const row = new UIRow();
254
+ row.add( new UIText( label ).setClass( 'Label' ) );
255
+
256
+ for ( const input of inputs ) {
257
+
258
+ row.add( input );
259
+
260
+ }
261
+
262
+ return row;
263
+
264
+ }
265
+
266
+ function createGroupHeading( label ) {
267
+
268
+ const heading = new UIText( label );
269
+ heading.setClass( 'TextureParametersDialog-groupHeading' );
270
+ heading.setStyle( 'display', [ 'block' ] );
271
+ return heading;
272
+
273
+ }
274
+
275
+ function applyParameters( texture, p ) {
276
+
277
+ texture.mapping = p.mapping;
278
+ texture.wrapS = p.wrapS;
279
+ texture.wrapT = p.wrapT;
280
+ texture.magFilter = p.magFilter;
281
+ texture.minFilter = p.minFilter;
282
+ texture.anisotropy = p.anisotropy;
283
+ texture.offset.set( p.offset.x, p.offset.y );
284
+ texture.repeat.set( p.repeat.x, p.repeat.y );
285
+ texture.center.set( p.center.x, p.center.y );
286
+ texture.rotation = p.rotation;
287
+ texture.premultiplyAlpha = p.premultiplyAlpha;
288
+ texture.colorSpace = p.colorSpace;
289
+ texture.needsUpdate = true;
290
+
291
+ }
292
+
293
+ export { TextureParametersDialog };
@@ -0,0 +1,75 @@
1
+ import { UIPanel, UIButton } from './libs/ui.js';
2
+
3
+ function Toolbar( editor ) {
4
+
5
+ const signals = editor.signals;
6
+ const strings = editor.strings;
7
+
8
+ const container = new UIPanel();
9
+ container.setId( 'toolbar' );
10
+
11
+ // translate / rotate / scale
12
+
13
+ const translateIcon = document.createElement( 'img' );
14
+ translateIcon.title = strings.getKey( 'toolbar/translate' );
15
+ translateIcon.src = 'images/translate.svg';
16
+
17
+ const translate = new UIButton();
18
+ translate.dom.className = 'Button selected';
19
+ translate.dom.appendChild( translateIcon );
20
+ translate.onClick( function () {
21
+
22
+ signals.transformModeChanged.dispatch( 'translate' );
23
+
24
+ } );
25
+ container.add( translate );
26
+
27
+ const rotateIcon = document.createElement( 'img' );
28
+ rotateIcon.title = strings.getKey( 'toolbar/rotate' );
29
+ rotateIcon.src = 'images/rotate.svg';
30
+
31
+ const rotate = new UIButton();
32
+ rotate.dom.appendChild( rotateIcon );
33
+ rotate.onClick( function () {
34
+
35
+ signals.transformModeChanged.dispatch( 'rotate' );
36
+
37
+ } );
38
+ container.add( rotate );
39
+
40
+ const scaleIcon = document.createElement( 'img' );
41
+ scaleIcon.title = strings.getKey( 'toolbar/scale' );
42
+ scaleIcon.src = 'images/scale.svg';
43
+
44
+ const scale = new UIButton();
45
+ scale.dom.appendChild( scaleIcon );
46
+ scale.onClick( function () {
47
+
48
+ signals.transformModeChanged.dispatch( 'scale' );
49
+
50
+ } );
51
+ container.add( scale );
52
+
53
+ //
54
+
55
+ signals.transformModeChanged.add( function ( mode ) {
56
+
57
+ translate.dom.classList.remove( 'selected' );
58
+ rotate.dom.classList.remove( 'selected' );
59
+ scale.dom.classList.remove( 'selected' );
60
+
61
+ switch ( mode ) {
62
+
63
+ case 'translate': translate.dom.classList.add( 'selected' ); break;
64
+ case 'rotate': rotate.dom.classList.add( 'selected' ); break;
65
+ case 'scale': scale.dom.classList.add( 'selected' ); break;
66
+
67
+ }
68
+
69
+ } );
70
+
71
+ return container;
72
+
73
+ }
74
+
75
+ export { Toolbar };
@@ -0,0 +1,98 @@
1
+ import { UIPanel, UISelect } from './libs/ui.js';
2
+
3
+ function ViewportControls( editor ) {
4
+
5
+ const signals = editor.signals;
6
+
7
+ const container = new UIPanel();
8
+ container.setPosition( 'absolute' );
9
+ container.setRight( '10px' );
10
+ container.setTop( '10px' );
11
+
12
+ // camera
13
+
14
+ const cameraSelect = new UISelect();
15
+ cameraSelect.setMarginRight( '10px' );
16
+ cameraSelect.onChange( function () {
17
+
18
+ editor.setViewportCamera( this.getValue() );
19
+
20
+ } );
21
+ container.add( cameraSelect );
22
+
23
+ signals.cameraAdded.add( update );
24
+ signals.cameraRemoved.add( update );
25
+ signals.objectChanged.add( function ( object ) {
26
+
27
+ if ( object.isCamera ) {
28
+
29
+ updateCameraList();
30
+
31
+ }
32
+
33
+ } );
34
+
35
+ // shading
36
+
37
+ const shadingSelect = new UISelect();
38
+ shadingSelect.setOptions( { 'realistic': 'realistic', 'solid': 'solid', 'normals': 'normals', 'wireframe': 'wireframe' } );
39
+ shadingSelect.setValue( 'solid' );
40
+ shadingSelect.onChange( function () {
41
+
42
+ editor.setViewportShading( this.getValue() );
43
+
44
+ } );
45
+ container.add( shadingSelect );
46
+
47
+ signals.editorCleared.add( function () {
48
+
49
+ editor.setViewportCamera( editor.camera.uuid );
50
+
51
+ shadingSelect.setValue( 'solid' );
52
+ editor.setViewportShading( shadingSelect.getValue() );
53
+
54
+ } );
55
+
56
+ signals.cameraResetted.add( update );
57
+
58
+ update();
59
+
60
+ //
61
+
62
+ function updateCameraList() {
63
+
64
+ const options = {};
65
+
66
+ const cameras = editor.cameras;
67
+
68
+ for ( const key in cameras ) {
69
+
70
+ const camera = cameras[ key ];
71
+ options[ camera.uuid ] = camera.name;
72
+
73
+ }
74
+
75
+ cameraSelect.setOptions( options );
76
+
77
+ const selectedCamera = ( editor.viewportCamera.uuid in options )
78
+ ? editor.viewportCamera
79
+ : editor.camera;
80
+
81
+ cameraSelect.setValue( selectedCamera.uuid );
82
+
83
+ return selectedCamera;
84
+
85
+ }
86
+
87
+ function update() {
88
+
89
+ const selectedCamera = updateCameraList();
90
+ editor.setViewportCamera( selectedCamera.uuid );
91
+
92
+ }
93
+
94
+ return container;
95
+
96
+ }
97
+
98
+ export { ViewportControls };
@@ -0,0 +1,144 @@
1
+ import { UIPanel, UIBreak, UIText } from './libs/ui.js';
2
+
3
+ function ViewportInfo( editor ) {
4
+
5
+ const signals = editor.signals;
6
+ const strings = editor.strings;
7
+
8
+ const container = new UIPanel();
9
+ container.setId( 'info' );
10
+ container.setPosition( 'absolute' );
11
+ container.setLeft( '10px' );
12
+ container.setBottom( '50px' );
13
+ container.setFontSize( '12px' );
14
+ container.setColor( '#fff' );
15
+ container.setTextTransform( 'lowercase' );
16
+
17
+ const objectsText = new UIText( '0' ).setTextAlign( 'right' ).setWidth( '60px' ).setMarginRight( '6px' );
18
+ const verticesText = new UIText( '0' ).setTextAlign( 'right' ).setWidth( '60px' ).setMarginRight( '6px' );
19
+ const trianglesText = new UIText( '0' ).setTextAlign( 'right' ).setWidth( '60px' ).setMarginRight( '6px' );
20
+ const frametimeText = new UIText( '0' ).setTextAlign( 'right' ).setWidth( '60px' ).setMarginRight( '6px' );
21
+ const samplesText = new UIText( '0' ).setTextAlign( 'right' ).setWidth( '60px' ).setMarginRight( '6px' ).setHidden( true );
22
+
23
+ const objectsUnitText = new UIText( strings.getKey( 'viewport/info/objects' ) );
24
+ const verticesUnitText = new UIText( strings.getKey( 'viewport/info/vertices' ) );
25
+ const trianglesUnitText = new UIText( strings.getKey( 'viewport/info/triangles' ) );
26
+ const samplesUnitText = new UIText( strings.getKey( 'viewport/info/samples' ) ).setHidden( true );
27
+
28
+ container.add( objectsText, objectsUnitText, new UIBreak() );
29
+ container.add( verticesText, verticesUnitText, new UIBreak() );
30
+ container.add( trianglesText, trianglesUnitText, new UIBreak() );
31
+ container.add( frametimeText, new UIText( strings.getKey( 'viewport/info/rendertime' ) ), new UIBreak() );
32
+ container.add( samplesText, samplesUnitText, new UIBreak() );
33
+
34
+ signals.objectAdded.add( update );
35
+ signals.objectRemoved.add( update );
36
+ signals.objectChanged.add( update );
37
+ signals.geometryChanged.add( update );
38
+ signals.sceneRendered.add( updateFrametime );
39
+
40
+ //
41
+
42
+ const pluralRules = new Intl.PluralRules( editor.config.getKey( 'language' ) );
43
+
44
+ //
45
+
46
+ function update() {
47
+
48
+ const scene = editor.scene;
49
+
50
+ let objects = 0, vertices = 0, triangles = 0;
51
+
52
+ for ( let i = 0, l = scene.children.length; i < l; i ++ ) {
53
+
54
+ const object = scene.children[ i ];
55
+
56
+ object.traverseVisible( function ( object ) {
57
+
58
+ objects ++;
59
+
60
+ if ( object.isMesh || object.isPoints ) {
61
+
62
+ const geometry = object.geometry;
63
+ const positionAttribute = geometry.attributes.position;
64
+
65
+ // update counts only if vertex data are defined
66
+
67
+ if ( positionAttribute !== undefined && positionAttribute !== null ) {
68
+
69
+ vertices += positionAttribute.count;
70
+
71
+ }
72
+
73
+ if ( object.isMesh ) {
74
+
75
+ if ( geometry.index !== null ) {
76
+
77
+ triangles += geometry.index.count / 3;
78
+
79
+ } else if ( positionAttribute !== undefined && positionAttribute !== null ) {
80
+
81
+ triangles += positionAttribute.count / 3;
82
+
83
+ }
84
+
85
+ }
86
+
87
+ }
88
+
89
+ } );
90
+
91
+ }
92
+
93
+ objectsText.setValue( editor.utils.formatNumber( objects ) );
94
+ verticesText.setValue( editor.utils.formatNumber( vertices ) );
95
+ trianglesText.setValue( editor.utils.formatNumber( triangles ) );
96
+
97
+ const pluralRules = new Intl.PluralRules( editor.config.getKey( 'language' ) );
98
+
99
+ const objectsStringKey = ( pluralRules.select( objects ) === 'one' ) ? 'viewport/info/object' : 'viewport/info/objects';
100
+ objectsUnitText.setValue( strings.getKey( objectsStringKey ) );
101
+
102
+ const verticesStringKey = ( pluralRules.select( vertices ) === 'one' ) ? 'viewport/info/vertex' : 'viewport/info/vertices';
103
+ verticesUnitText.setValue( strings.getKey( verticesStringKey ) );
104
+
105
+ const trianglesStringKey = ( pluralRules.select( triangles ) === 'one' ) ? 'viewport/info/triangle' : 'viewport/info/triangles';
106
+ trianglesUnitText.setValue( strings.getKey( trianglesStringKey ) );
107
+
108
+ }
109
+
110
+ function updateFrametime( frametime ) {
111
+
112
+ frametimeText.setValue( Number( frametime ).toFixed( 2 ) );
113
+
114
+ }
115
+
116
+ //
117
+
118
+ editor.signals.pathTracerUpdated.add( function ( samples ) {
119
+
120
+ samples = Math.floor( samples );
121
+
122
+ samplesText.setValue( samples );
123
+
124
+ const samplesStringKey = ( pluralRules.select( samples ) === 'one' ) ? 'viewport/info/sample' : 'viewport/info/samples';
125
+ samplesUnitText.setValue( strings.getKey( samplesStringKey ) );
126
+
127
+ } );
128
+
129
+ editor.signals.viewportShadingChanged.add( function () {
130
+
131
+ const isRealisticShading = ( editor.viewportShading === 'realistic' );
132
+
133
+ samplesText.setHidden( ! isRealisticShading );
134
+ samplesUnitText.setHidden( ! isRealisticShading );
135
+
136
+ container.setBottom( isRealisticShading ? '62px' : '50px' );
137
+
138
+ } );
139
+
140
+ return container;
141
+
142
+ }
143
+
144
+ export { ViewportInfo };
@@ -0,0 +1,27 @@
1
+ class ViewportPathtracer {
2
+
3
+ constructor( renderer ) {}
4
+
5
+ init( scene, camera ) {}
6
+
7
+ reset() {}
8
+
9
+ setSize( width, height ) {}
10
+
11
+ setBackground( background, blurriness ) {}
12
+
13
+ setEnvironment( environment ) {}
14
+
15
+ updateMaterials() {}
16
+
17
+ update() {}
18
+
19
+ getSamples() {
20
+
21
+ return 0;
22
+
23
+ }
24
+
25
+ }
26
+
27
+ export { ViewportPathtracer };
@@ -0,0 +1,41 @@
1
+ import { UIPanel } from './libs/ui.js';
2
+
3
+ import { ViewHelper as ViewHelperBase } from 'three/addons/helpers/ViewHelper.js';
4
+
5
+ class ViewHelper extends ViewHelperBase {
6
+
7
+ constructor( editorCamera, container ) {
8
+
9
+ super( editorCamera, container.dom );
10
+
11
+ this.location.top = 30;
12
+
13
+ const panel = new UIPanel();
14
+ panel.setId( 'viewHelper' );
15
+ panel.setPosition( 'absolute' );
16
+ panel.setRight( '0px' );
17
+ panel.setTop( '30px' );
18
+ panel.setHeight( '128px' );
19
+ panel.setWidth( '128px' );
20
+
21
+ panel.dom.addEventListener( 'pointerup', ( event ) => {
22
+
23
+ event.stopPropagation();
24
+
25
+ this.handleClick( event );
26
+
27
+ } );
28
+
29
+ panel.dom.addEventListener( 'pointerdown', function ( event ) {
30
+
31
+ event.stopPropagation();
32
+
33
+ } );
34
+
35
+ container.add( panel );
36
+
37
+ }
38
+
39
+ }
40
+
41
+ export { ViewHelper };
@@ -0,0 +1,7 @@
1
+ function XR( editor, controls ) {
2
+
3
+ // WebXR module is optional and not bundled in this library build.
4
+
5
+ }
6
+
7
+ export { XR };