├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── _config.yml
├── dist
├── EditControl.d.ts
├── EditControl.js
├── EditControl.js.map
├── EditControl.max.js
├── EditControl.max.js.LICENSE.txt
└── EditControl.max.js.map
├── edit.bat
├── flowchart.drawio
├── package-lock.json
├── package.json
├── src
└── EditControl.ts
├── tsconfig.json
├── tst
├── comprehensive.html
├── comprehensive.js
├── pointerlock.html
├── pointerlock.js
├── simple.html
├── simple.js
├── test.css
├── test.html
└── w3.css
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | nbproject
2 | node_modules
3 | *.bat
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | nbproject
2 | node_modules
3 | tst
4 | _config.yml
5 | tsconfig.json
6 | webpack.config.js
7 | *.bat
8 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # BabylonJS-EditControl
2 |
3 | An edit control for use in [BabylonJS](http://www.babylonjs.com/) (a 3D HTML Webgl framework) applications.
4 |
5 | ## About
6 |
7 | Many 3d editors provide, what is called, a widget/gizmo/transform control, to help translate, rotate or scale 3d objects in the editor.
8 | This EditControl is just that.
9 | You can embed this in your Babylonjs application to provide those same capabilities.
10 | It currently supports
11 |
12 | - Translate
13 | - Translate Snap
14 | - Rotate
15 | - Rotate Snap
16 | - Scale
17 | - Scale Snap
18 | - Local or Global Translation and Rotation. (Scaling only in local axis)
19 | - Create multiple instances in the same scene with each instance attached to a different mesh
20 | - Scale size of control
21 | - undo, redo
22 |
23 | For a demo, head on over to https://ssatguru.github.io/BabylonJS-EditControl-Samples/demo/Demo.html
24 |
25 | ### Limitations/Issues
26 |
27 | This currently does not handle properly, a right handed mesh in a left handed system (example gltf mesh in lhs babylon) or a left handed mesh in a right handed system.
28 | A right handed mesh in a right handed system or a left handed mesh in a left handed system is handled properly.
29 | A gltf mesh in a right handed babylon is handled properly.
30 | I would address this in a future release.
31 |
32 | For a list of other know issues, shortcomings and planned enhancements see https://github.com/ssatguru/BabylonJS-EditControl/issues
33 |
34 | ### 3.3.0 Major changes
35 |
36 | Moved the EditControl to the Babylonjs DefaultUtilityLayer scene.
37 | Because this scene is different from the main scene there is less interference with the main scene. Also makes it a bit faster.
38 | This is similar to how the native gizmos of Babylonjs work.
39 |
40 | Upgraded to latest version of Babylons js - 5.41.
41 | Replaced deprecated methods with new ones.
42 | Upgraded other dev dependenices to latest version - typescript, webpack etc.
43 |
44 | ### 3.20 Major and Breaking changes
45 |
46 | Version 3.2.0 converts the project from a plain vanilla JavaScript project to a module based JavaScript project.
47 | With this change, the way to load the application has changed.
48 | In JavaScript, instead of
49 |
50 | ```
51 | var EditControl = org.ssatguru.babylonjs.component.EditControl;
52 | editControl = new EditControl(box,camera, canvas, 0.75);
53 | ```
54 |
55 | now do
56 |
57 | ```
58 | var editControl = new EditControl(box,camera, canvas, 0.75);
59 | ```
60 |
61 | In TypeScript, instead of
62 |
63 | ```
64 | import EditControl = org.ssatguru.babylonjs.component.EditControl;
65 | ```
66 |
67 | now do
68 |
69 | ```
70 | import {EditControl} from "babaylonjs-editcontrol";
71 | ```
72 |
73 | See below for more details.
74 |
75 | ## Quick start
76 |
77 | 1. add the following dependencies
78 |
79 | ```
80 |
81 |
82 |
83 | ```
84 |
85 | See INSTALL below to find where you can get "EditControl.js".
86 |
87 | 2. a small javascript code snippet to get you up and running
88 |
89 | ```
90 | //------------------EDIT CONTROL -------------------------------------------------
91 | //create edit control (mesh to attach to, active camera, canvas, scale of editcontrol)
92 | var editControl = new EditControl(box,camera, canvas, 0.75);
93 | //to show translation controls
94 | editControl.enableTranslation();
95 | //set transalation snap value in meters
96 | editControl.setTransSnapValue(0.5
97 | ```
98 |
99 | see sample project here
100 | [https://github.com/ssatguru/BabylonJS-EditControl-Samples/tree/master/sample-global](https://github.com/ssatguru/BabylonJS-EditControl-Samples/tree/master/sample-global)
101 |
102 | ## INSTALL
103 |
104 | You can find the "EditControl.js" from its git repository "dist" folder or "releases" section
105 | [https://github.com/ssatguru/BabylonJS-EditControl/tree/master/dist](https://github.com/ssatguru/BabylonJS-EditControl/tree/master/dist)
106 | [https://github.com/ssatguru/BabylonJS-EditControl/releases](https://github.com/ssatguru/BabylonJS-EditControl/releases)
107 |
108 | You can also install this from npm
109 |
110 | ```
111 | npm install babylonjs-editcontrol
112 | ```
113 |
114 | ## USAGE
115 |
116 | This has been built as an UMD module which means you can use it as a CommonJS/NodeJS module, AMD module or as a global object
117 | loaded using the script tag.
118 |
119 | Project "BabylonJS-EditControl-Samples" [https://github.com/ssatguru/BabylonJS-EditControl-Samples](https://github.com/ssatguru/BabylonJS-EditControl-Samples) has a
120 | collection of sample projects to show how to use this from TypeScript, NodeJs, AMD or plain vanilla JavaScript applications.
121 |
122 | Below is a quick summary of how you can use this as different module types.
123 |
124 | CommonJS/NodeJS Module
125 |
126 | ```
127 | let BABYLON = require("babylonjs");
128 | let EditControl = require("babylonjs-editcontrol").EditControl;
129 | let engine = new BABYLON.Engine(canvas, true);
130 | ...
131 | let editControl = new EditControl(box,camera, canvas, 0.75);
132 | ...
133 |
134 | ```
135 |
136 | AMD Module
137 |
138 | ```
139 |
140 |
157 | ```
158 |
159 | Global Module
160 |
161 | ```
162 |
163 |
164 |
170 | ```
171 |
172 | ## DEPENDENCIES
173 |
174 | - pepjs
175 | - babylonjs
176 |
177 | The two can be installed from npm
178 |
179 | ```
180 | npm install babylonjs pepjs
181 | ```
182 |
183 | or via cdn
184 |
185 | ```
186 |
187 |
188 | ```
189 |
190 | ## API
191 |
192 | #### To Instantiate
193 |
194 | ```
195 | // JavaScript
196 | var editControl = new EditControl(mesh,camera, canvas, 0.75, true);
197 | ```
198 |
199 | ```
200 | // TypeScript
201 | import {EditControl} from "babaylonjs-editcontrol";
202 | let editControl:EditControl = new EditControl(mesh,camera, canvas, 0.75, true,0.02);
203 | ```
204 |
205 | This positions the edit control at the mesh pivot position and displays x,y,z axis.
206 | Takes five parms
207 |
208 | - mesh - the mesh to control using the editcontrol
209 | - camera - active camera
210 | - canvas - the mesh canvas
211 | - scale - number. Optional. Default 1. Determines how small or large the editcontrol should appear.
212 | - eulerian - true/false. Optional. Default false. True indicates that rotation of the mesh is in euler.If rotation is unresponsive then it is possible that the rotation may not have been initialized to either a eulerian or quaternion value.
213 | - pickWidth - number. Optional. Default 0.02. Determines how close to an axis should the pointer get before we can pick it
214 |
215 | #### To show Translation, Rotation or Scaling controls
216 |
217 | ```
218 | editControl.enableTranslation();
219 |
220 | editControl.enableRotation();
221 | editControl.setRotGuideFull(true/false) //This makes the rotation guides 360 degree(true) or 90 degree(false) .90 degree looks less cluttered.
222 | editControl.returnEuler(true); // Optional. This will return rotation in euler instead of quaternion. Quaternion is the default.
223 |
224 | editControl.enableScaling();
225 | ```
226 |
227 | #### To hide Translation, Rotation or Scaling controls (just displays x,y,z axis)
228 |
229 | ```
230 | editControl.disableTranslation();
231 | editControl.disableRotation();
232 | editControl.disableScaling();
233 | ```
234 |
235 | #### To check if Translation, Rotation or Scaling is enabled
236 |
237 | ```
238 | editControl.isTranslationEnabled();
239 | editControl.isRotationEnabled();
240 | editControl.isScalingEnabled();
241 | ```
242 |
243 | #### To turn on/off local/ global mode
244 |
245 | ```
246 | editControl.setLocal(boolean true/false);
247 | ```
248 |
249 | #### To check if local/ global mode
250 |
251 | ```
252 | editControl.isLocal();
253 | ```
254 |
255 | #### To turn on/off translation, rotation or scale snapping
256 |
257 | ```
258 | editControl.setTransSnap(boolean true/false);
259 | editControl.setRotSnap(boolean true/false);
260 | editControl.setScaleSnap(boolean true/false);
261 |
262 | editControl.isTransSnap();
263 | editControl.isRotSnap();
264 | editControl.isScaleSnap();
265 | ```
266 |
267 | #### To set/get translation, rotation or scale snap values
268 |
269 | ```
270 | editControl.setTransSnapValue(number n in meters);
271 | editControl.setRotSnapValue(number n in radians);
272 | editControl.setScaleSnapValue(number n a factor by which scale should increase);
273 |
274 | editControl.getTransSnapValue();
275 | editControl.getRotSnapValue();
276 | editControl.getScaleSnapValue();
277 | ```
278 |
279 | #### To bound translation, rotation or scaling
280 |
281 | This restricts tranlation, rotation,scaling between a minimum and maximum values
282 |
283 | ```
284 | setTransBounds(min?: Vector3,max?: Vector3) ;
285 | setRotBounds(min?: Vector3,max?: Vector3);
286 | setScaleBounds(min?: Vector3,max?: Vector3);
287 | ```
288 |
289 | ```
290 | removeTransBounds();
291 | removeRotBounds();
292 | removeScaleBounds();
293 | ```
294 |
295 | Note: rotation bounds has not been implemented. This is on TODO list.
296 |
297 | #### To undo or redo
298 |
299 | ```
300 | editControl.undo();
301 | editControl.redo();
302 | ```
303 |
304 | #### To set undo count
305 |
306 | By default does upto 10 undos
307 |
308 | ```
309 | editControl.setUndoCount(number count);
310 | ```
311 |
312 | #### To check if user editing (moving,translating or scaling object)
313 |
314 | ```
315 | editControl.isEditing();
316 | ```
317 |
318 | returns true if the use is in the process of editing
319 |
320 | #### To check if the pointer is over the edit control
321 |
322 | ```
323 | editControl.isPointeOver();
324 | ```
325 |
326 | returns true if the pointer is over the edit control
327 |
328 | #### To be called back whenever the user starts, takes or ends an action
329 |
330 | ```
331 | editControl.addActionStartListener(function(number actionType));
332 | editControl.addActionListener(function(number actionType));
333 | editControl.addActionEndListener(function(number actionType));
334 | ```
335 |
336 | Each of these take a function as a parameter.
337 | The ActionStartListener would be called when the user starts translating,rotating or scaling a mesh
338 | The ActionListener would be called when the user is translating,rotating or scaling a mesh
339 | The ActionEndListener would be called when the user ends translating,rotating or scaling a mesh
340 |
341 | When called, these listeners would be passed a number which would indicate the action being taken by the user.
342 | This number would have one of the following values
343 | 0 - ActionType.TRANS, Translation
344 | 1 - ActioneType.ROT, Rotation
345 | 2 - ActioneType.SCALE, Scaling
346 |
347 | To remove the listeners
348 |
349 | ```
350 | editControl.removeActionStartListener();
351 | editControl.removeActionListener();
352 | editControl.removeActionEndListener();
353 | editControl.removeAllActionListeners() // to remove all;
354 | ```
355 |
356 | #### To refresh mesh Bounding Info.
357 |
358 | EditControl uses mesh bounding info to provide the same smooth scaling experience for both small and large mesh. The bounding info changes when a mesh is baked. Use this method to refresh the bounding info if you baked the transform of the mesh.
359 |
360 | ```
361 | editControl.refreshBoundingInfo();
362 | ```
363 |
364 | #### To get position and rotaion of EditControl
365 |
366 | ```
367 | editControl.getPosition();//returns Vector3
368 | editControl.getRotationQuaternion(): //returns rotation in quaternion
369 | ```
370 |
371 | The postion and rotation of EditControl would be the same as that of the mesh to which it is attached
372 |
373 | #### To show/hide EditControl
374 |
375 | ```
376 | editControl.hide();
377 | editControl.isHidden(); //turns true or false
378 | editControl.show();
379 | ```
380 |
381 | #### To set visibililty (transparency)
382 |
383 | ```
384 | editControl.setVisibility(v:number);
385 | ```
386 |
387 | By default the visibility is set to 0.75
388 |
389 | #### To switch camera
390 |
391 | ```
392 | editControl.switchCamera(camera:Camera);
393 | ```
394 |
395 | The edit control uses the camera specified during instantiation to control how it is scaled or picked.
396 | Use this to swicth to a different camera after instantiation.
397 | You might want to use this for example when the active camera in your scene changes and you want to use the new one for the editcontrol.
398 |
399 | #### To switch edit control to another mesh
400 |
401 | ```
402 | editControl.switchTo(Mesh mesh, optional boolean isEuler );
403 | ```
404 |
405 | This quickly removes the edit control from one mesh and attaches it to another mesh.
406 |
407 | The translation, rotation, scaling mode is maintained.
408 |
409 | mesh : the mesh to which the control should switch to
410 | isEuler : true/false, optional, default false, true indicates that rotation of the mesh is in euler
411 |
412 | #### To detach from the mesh and clean up resources.
413 |
414 | ```
415 | editControl.detach();
416 | ```
417 |
418 | ## Build and Test
419 |
420 | If not already installed, install node js.
421 | Switch to the project folder.
422 | Run "npm install", once, to install all the dependencies.
423 |
424 | ### Build
425 |
426 | Run "npm run build" - this will compile the files in "src" and create a development module in the "dist" folder.
427 | Run "npm run build-prod" - this will compile and create a minified production module in the "dist" folder.
428 |
429 | ### To test
430 |
431 | Two ways to test.
432 |
433 | 1. using the webpack-dev-server.
434 | Start the development server
435 | "npm run start"
436 | This will start the live dev server on port 8080 (could be different if this port is already in use) and open the browser with the file http://localhost:8080/tst/test.html.
437 | The dev server will live compile your code any time you make changes.
438 | Note: The dev server does not write the build to disk, instead it serves it from memory. In our case the build, "EditControl.max.js", is served from location http://localhost:8080/dist. (see publicPath in wepack.config.js file).
439 |
440 | 2. using any other http server.
441 | Start the server , say http-server, from the project root folder (not from within "/tst " folder).
442 | Goto http://localhost:8080/tst/test.html (assuming the server was started on port 8080).
443 | Everytime you make changes you will have to build using "npm start build-dev".
444 |
445 | ## Note:
446 |
447 | The original version was written in Java and then transpiled to TypeScript/JavaScript using JSweet.
448 | It was originally written in Java, as at that time I wasn't very comfortable with the TypeScript language and its ecosystem.
449 | Over time I have become more comfortable with it.
450 | The new version is thus written in TypeScript.
451 | It is based on the initial TypeScript code generated by JSweet.
452 | Porting to Typescript was easy, as JSweet generates good human readable TypeScript which allows one to switch to TypeScript at any time.
453 | For those interested, the old java version is still available at [https://github.com/ssatguru/BabylonJS-EditControl.java](https://github.com/ssatguru/BabylonJS-EditControl.java)
454 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/dist/EditControl.d.ts:
--------------------------------------------------------------------------------
1 | import { AbstractMesh, Camera, Quaternion, Vector3, TransformNode } from 'babylonjs';
2 | /**
3 | * Draws a transform widget at the mesh's location (its pivot location).
4 | * The widget transforms(translates,rotates and scales) the mesh based on user
5 | * interactions with the widget.
6 | * The widget shows the mesh position and rotation at any time.
7 | * The widget follows the mesh constantly.
8 | * Note: An alternate approach would have been for the mesh to follow the widget.
9 | * The problem with the alternate approach - syncing the transforms
10 | * if the mesh was being transformed by entities other than the widget say physics
11 | * or script for example.
12 | *
13 | */
14 | export declare class EditControl {
15 | private _mesh;
16 | private _canvas;
17 | private _scene;
18 | private _utilLayer;
19 | private _mainCamera;
20 | private _ecRoot;
21 | private _local;
22 | private _snapT;
23 | private _snapR;
24 | private _transSnap;
25 | private _rotSnap;
26 | private _axesLen;
27 | private _axesScale;
28 | private _pickWidth;
29 | private _redMat;
30 | private _greenMat;
31 | private _blueMat;
32 | private _whiteMat;
33 | private _yellowMat;
34 | private _redCol;
35 | private _greenCol;
36 | private _blueCol;
37 | private _whiteCol;
38 | private _yellowCol;
39 | private _actHist;
40 | private _renderer;
41 | private _pointerdown;
42 | private _pointerup;
43 | private _pointermove;
44 | private _visibility;
45 | private _lhsRhs;
46 | constructor(mesh: TransformNode, camera: Camera, canvas: HTMLCanvasElement, scale?: number, eulerian?: boolean, pickWidth?: number);
47 | getRoot(): AbstractMesh;
48 | private _checkQuaternion;
49 | /**
50 | * checks if a have left hand , right hand issue.
51 | * In other words if a mesh is a LHS mesh in RHS system or
52 | * a RHS mesh in LHS system
53 | * The X axis will be reversed in such cases.
54 | * thus Cross product of X and Y should be inverse of Z.
55 | *
56 | * if no parent then we are ok.
57 | * If parent and parent has issue then we have issue.
58 | *
59 | */
60 | private _check_LHS_RHS;
61 | private _ecMatrix;
62 | private _ecTOcamera;
63 | private _renderLoopProcess;
64 | /**
65 | * sets rotaion of edit control to that of the mesh
66 | */
67 | private _setECRotation;
68 | /**
69 | * checks if any of the mesh's ancestors has non uniform scale
70 | */
71 | private _isScaleUnEqual;
72 | private _distFromCamera;
73 | private _cameraTOec;
74 | private _cameraNormal;
75 | private _setECScale;
76 | private _rotRotGuides;
77 | /**
78 | * rotate the planar guide so that they are facing the camera
79 | */
80 | private _rotPlanarGuides;
81 | switchTo(mesh: TransformNode, eulerian?: boolean): void;
82 | switchCamera(camera: Camera): void;
83 | setUndoCount(c: number): void;
84 | undo(): void;
85 | redo(): void;
86 | /**
87 | * detach the edit control from the mesh and dispose off all
88 | * resources created by the edit control
89 | */
90 | detach(): void;
91 | private _prevState;
92 | private _hidden;
93 | /**
94 | * hide the edit control. use show() to unhide the control.
95 | */
96 | hide(): void;
97 | private _hideCommonAxes;
98 | private _showCommonAxes;
99 | /**
100 | * unhide the editcontrol hidden using the hide() method
101 | */
102 | show(): void;
103 | /**
104 | * check if the editcontrol was hidden using the hide() methods
105 | */
106 | isHidden(): boolean;
107 | private _disposeAll;
108 | private _actionListener;
109 | private _actionStartListener;
110 | private _actionEndListener;
111 | addActionListener(actionListener: (actionType: number) => void): void;
112 | removeActionListener(): void;
113 | addActionStartListener(actionStartListener: (actionType: number) => void): void;
114 | removeActionStartListener(): void;
115 | addActionEndListener(actionEndListener: (actionType: number) => void): void;
116 | removeActionEndListener(): void;
117 | removeAllActionListeners(): void;
118 | private _pDown;
119 | private _axisPicked;
120 | private _onPointerDown;
121 | private _setEditing;
122 | isEditing(): boolean;
123 | /**
124 | * no camera movement during edit
125 | */
126 | private _detachCamera;
127 | private _prevOverMesh;
128 | private _pointerIsOver;
129 | isPointerOver(): boolean;
130 | private _savedMat;
131 | private _savedCol;
132 | private _onPointerOver;
133 | private _clearPrevOverMesh;
134 | private _restoreColor;
135 | private _editing;
136 | private _onPointerUp;
137 | private _actionType;
138 | private _setActionType;
139 | private _callActionListener;
140 | private _callActionStartListener;
141 | private _callActionEndListener;
142 | private _prevPos;
143 | private _onPointerMove;
144 | private _rotate2;
145 | private _getPickPlane;
146 | private _transBy;
147 | private _doTranslation;
148 | private _snapTV;
149 | private _transWithSnap;
150 | private _snapS;
151 | private _snapSV;
152 | private _scaleSnap;
153 | private _scale;
154 | private _doScaling;
155 | private _scaleWithSnap;
156 | private _localX;
157 | private _localY;
158 | private _localZ;
159 | private _setLocalAxes;
160 | private _boundingDimesion;
161 | private _getBoundingDimension;
162 | refreshBoundingInfo(): void;
163 | private _eulerian;
164 | private _snapRA;
165 | private _doRotation;
166 | private _getPosOnPickPlane;
167 | private _hideBaxis;
168 | getRotationQuaternion(): Quaternion;
169 | getPosition(): Vector3;
170 | private _transEnabled;
171 | isTranslationEnabled(): boolean;
172 | enableTranslation(): void;
173 | disableTranslation(): void;
174 | private _rotEnabled;
175 | isRotationEnabled(): boolean;
176 | returnEuler(euler: boolean): void;
177 | enableRotation(): void;
178 | disableRotation(): void;
179 | private _scaleEnabled;
180 | isScalingEnabled(): boolean;
181 | enableScaling(): void;
182 | disableScaling(): void;
183 | private _scaleBoundsMin;
184 | private _scaleBoundsMax;
185 | setScaleBounds(min?: Vector3, max?: Vector3): void;
186 | removeScaleBounds(): void;
187 | private _transBoundsMin;
188 | private _transBoundsMax;
189 | setTransBounds(min?: Vector3, max?: Vector3): void;
190 | removeTransBounds(): void;
191 | private _rotBoundsMin;
192 | private _rotBoundsMax;
193 | setRotBounds(min?: Vector3, max?: Vector3): void;
194 | removeRotBounds(): void;
195 | private _bXaxis;
196 | private _bYaxis;
197 | private _bZaxis;
198 | private _xaxis;
199 | private _yaxis;
200 | private _zaxis;
201 | private _createCommonAxes;
202 | private _pickedPlane;
203 | private _pALL;
204 | private _pXZ;
205 | private _pZY;
206 | private _pYX;
207 | private _createPickPlanes;
208 | private _tCtl;
209 | private _tX;
210 | private _tY;
211 | private _tZ;
212 | private _tXZ;
213 | private _tZY;
214 | private _tYX;
215 | private _tAll;
216 | private _all_t;
217 | private _tEndX;
218 | private _tEndY;
219 | private _tEndZ;
220 | private _tEndXZ;
221 | private _tEndZY;
222 | private _tEndYX;
223 | private _tEndAll;
224 | private _all_tEnd;
225 | private _createTransAxes;
226 | /**
227 | * pickable but invisible
228 | * a) 3 boxes around each of the 3 small axes lines
229 | * b) 3 small planes near origin for movement along a plane
230 | * @param r
231 | * @param l
232 | * @param tCtl
233 | * @param scene
234 | */
235 | private _createPickableTrans;
236 | private _createNonPickableTrans;
237 | private _rCtl;
238 | private _rX;
239 | private _rY;
240 | private _rZ;
241 | private _rAll;
242 | private _all_r;
243 | private _rEndX;
244 | private _rEndY;
245 | private _rEndZ;
246 | private _rEndAll;
247 | private _rEndAll2;
248 | private _all_rEnd;
249 | private _guideSize;
250 | setRotGuideFull(y: boolean): void;
251 | private _createRotAxes;
252 | private _createPickableRot;
253 | private _createNonPickableRot;
254 | private _setVisibility;
255 | private _setPickableFalse;
256 | private _setRenderingGroup;
257 | private _extrudeBox;
258 | private _createCircle;
259 | private _createTube;
260 | private _sCtl;
261 | private _sX;
262 | private _sY;
263 | private _sZ;
264 | private _sXZ;
265 | private _sZY;
266 | private _sYX;
267 | private _sAll;
268 | private _all_s;
269 | private _sEndX;
270 | private _sEndY;
271 | private _sEndZ;
272 | private _sEndXZ;
273 | private _sEndZY;
274 | private _sEndYX;
275 | private _sEndAll;
276 | private _all_sEnd;
277 | private _createScaleAxes;
278 | private _createPickableScale;
279 | private _createNonPickableScale;
280 | /**
281 | * checks if a have left hand , right hand issue.
282 | * In other words if a mesh is a LHS mesh in RHS system or
283 | * a RHS mesh in LHS system
284 | * The X axis will be reversed in such cases.
285 | * thus Cross product of X and Y should be inverse of Z.
286 | *
287 | */
288 | /**
289 | * set how transparent the axes are
290 | * 0 to 1
291 | * 0 - completely transparent
292 | * 1 - completely non transparent
293 | * default is 0.75
294 | */
295 | setVisibility(v: number): void;
296 | setLocal(l: boolean): void;
297 | isLocal(): boolean;
298 | setTransSnap(s: boolean): void;
299 | isTransSnap(): boolean;
300 | setRotSnap(s: boolean): void;
301 | isRotSnap(): boolean;
302 | setScaleSnap(s: boolean): void;
303 | isScaleSnap(): boolean;
304 | private _tSnap;
305 | setTransSnapValue(t: number): void;
306 | getTransSnapValue(): number;
307 | setRotSnapValue(r: number): void;
308 | getRotSnapValue(): number;
309 | setScaleSnapValue(r: number): void;
310 | getScaleSnapValue(): number;
311 | private _tv1;
312 | private _tv2;
313 | private _tv3;
314 | private _tm;
315 | private _getAngle2;
316 | /**
317 | * finds the angle subtended from points p1 to p2 around the point p
318 | * checks if the user was trying to rotate clockwise (+ve in LHS) or anticlockwise (-ve in LHS)
319 | * to figure this check the orientation of the user(camera)to ec vector with the rotation normal vector
320 | */
321 | private _getAngle;
322 | private static _getStandardMaterial;
323 | private _createMaterials;
324 | private _disposeMaterials;
325 | }
326 |
--------------------------------------------------------------------------------
/dist/EditControl.js:
--------------------------------------------------------------------------------
1 | !function(t,i){if("object"==typeof exports&&"object"==typeof module)module.exports=i(require("babylonjs"));else if("function"==typeof define&&define.amd)define(["babylonjs"],i);else{var s="object"==typeof exports?i(require("babylonjs")):i(t.BABYLON);for(var h in s)("object"==typeof exports?exports:t)[h]=s[h]}}(self,(t=>(()=>{"use strict";var i={247:i=>{i.exports=t}},s={};function h(t){var n=s[t];if(void 0!==n)return n.exports;var u=s[t]={exports:{}};return i[t](u,u.exports,h),u.exports}h.n=t=>{var i=t&&t.t?()=>t.default:()=>t;return h.d(i,{a:i}),i},h.d=(t,i)=>{for(var s in i)h.o(i,s)&&!h.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},h.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),h.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"t",{value:!0})};var n={};return(()=>{h.r(n),h.d(n,{EditControl:()=>s});var t,i=h(247);!function(t){t[t.TRANS=0]="TRANS",t[t.ROT=1]="ROT",t[t.SCALE=2]="SCALE"}(t||(t={}));var s=function(){function s(t,s,h,n,e,r){var o=this;this.i=!0,this.h=!1,this.u=!1,this.l=1,this.v=Math.PI/18,this.M=.4,this.p=1,this.L=.02,this.A=new i.Color3(1,.2,.2),this.j=new i.Color3(.2,1,.2),this.S=new i.Color3(.2,.2,1),this.O=new i.Color3(1,1,1),this.T=new i.Color3(1,1,.2),this.R=.75,this.g=!1,this.k=new i.Matrix,this.q=new i.Vector3(0,0,0),this.C=2,this._=new i.Vector3(0,0,0),this.B=new i.Vector3(0,0,0),this.N="",this.D=!1,this.F=null,this.G=null,this.H=null,this.I=!1,this.J=!1,this.K=!1,this.P=!1,this.U=new i.Vector3(0,0,0),this.V=new i.Vector3(0,0,0),this.W=!1,this.$=new i.Vector3(0,0,0),this.tt=.25,this.it=new i.Vector3(0,0,0),this.st=new i.Vector3(0,0,0),this.ht=new i.Vector3(0,0,0),this.nt=new i.Vector3(0,0,0),this.ut=!1,this.et=0,this.rt=!1,this.ot=!1,this.ft=!1,this.lt=180,this.ct=new i.Vector3(this.l,this.l,this.l),this.vt=new i.Vector3(0,0,0),this.wt=new i.Vector3(0,0,0),this.Mt=new i.Vector3(0,0,0),this.Xt=new i.Matrix,this.Yt=t,this.Zt=s,this.dt=h,null!=n&&(this.p=n),this.ut=null!==e&&e,this.bt(),null!=r&&(this.L=r),this.Lt=i.UtilityLayerRenderer.DefaultUtilityLayer,this.Lt.onlyCheckPointerDownEvents=!1,this.zt=this.Lt.utilityLayerScene,this.yt=new u(t,10),t.computeWorldMatrix(!0),this.At=this.jt(t),this.St(t),this.g=this.xt(t),console.log("lhs rhs issue "+this.g),this.Ot=new i.Mesh("",this.zt),this.Ot.rotationQuaternion=i.Quaternion.Identity(),this.Ot.visibility=0,this.Ot.isPickable=!1,this.Tt(this.zt),this.Et().parent=this.Ot,this.Rt().parent=this.Ot,this.gt=function(t){return o.kt(t)},this.qt=function(t){return o.Ct(t)},this._t=function(t){return o.Bt(t)},h.addEventListener("pointerdown",this.gt,!1),h.addEventListener("pointerup",this.qt,!1),h.addEventListener("pointermove",this._t,!1),this.Nt=function(){return o.Qt()},this.zt.registerBeforeRender(this.Nt)}return s.prototype.getRoot=function(){return this.Ot},s.prototype.bt=function(){if(!this.ut&&(null==this.Yt.rotationQuaternion||null==this.Yt.rotationQuaternion))throw"Error: Eulerian is set to false but the mesh's rotationQuaternion is not set."},s.prototype.xt=function(t){var s=!1,h=t.parent;if(null==h)return!1;this.St(h);var n=i.Vector3.Cross(this.st,this.ht);return s=i.Vector3.Dot(n,this.nt)<0,this.St(t),s},s.prototype.Qt=function(){this.Ot.position=this.Yt.getAbsolutePivotPoint(),this.Dt(),this.Ft(),this.i?(this.Ot.getWorldMatrix().invertToRef(this.k),i.Vector3.TransformCoordinatesToRef(this.Zt.position,this.k,this.q),this.Gt.lookAt(this.q,0,0,0,i.Space.LOCAL)):(this.Zt.position.subtractToRef(this.Ot.position,this.q),this.Gt.lookAt(this.Zt.position,0,0,0,i.Space.WORLD)),this.ot?this.Ht():this.rt?this.It(this.Jt,this.Kt,this.Pt):this.ft&&this.It(this.Ut,this.Vt,this.Wt)},s.prototype.Dt=function(){if(this.i)if(null==this.Yt.parent)if(this.ut){var t=this.Yt.rotation;i.Quaternion.RotationYawPitchRollToRef(t.y,t.x,t.z,this.Ot.rotationQuaternion)}else this.Ot.rotationQuaternion.copyFrom(this.Yt.rotationQuaternion);else{if(this.$t(this.Yt))return;this.Yt.getWorldMatrix().getRotationMatrixToRef(this.Xt),i.Quaternion.FromRotationMatrixToRef(this.Xt,this.Ot.rotationQuaternion)}},s.prototype.$t=function(t){if(null==t.parent)return!1;for(;null!=t.parent;){if(t.parent.scaling.x!=t.parent.scaling.y||t.parent.scaling.y!=t.parent.scaling.z)return!0;t=t.parent}return!1},s.prototype.Ft=function(){this.Ot.position.subtractToRef(this.Zt.position,this._),i.Vector3.FromArrayToRef(this.Zt.getWorldMatrix().asArray(),8,this.B);var t=i.Vector3.Dot(this._,this.B)/this.B.length(),s=Math.abs(t/this.C);i.Vector3.FromFloatsToRef(s,s,s,this.Ot.scaling)},s.prototype.Ht=function(){var t=Math.atan(this.q.y/this.q.z);this.q.z>=0?this.ti.rotation.x=-t:this.ti.rotation.x=-t-Math.PI;var i=Math.atan(this.q.x/this.q.z);this.q.z>=0?this.ii.rotation.y=i:this.ii.rotation.y=i+Math.PI;var s=Math.atan(this.q.x/this.q.y);this.q.y>=0?this.si.rotation.z=-s:this.si.rotation.z=-s-Math.PI},s.prototype.It=function(t,i,s){var h=this.q;t.rotation.x=0,t.rotation.y=0,t.rotation.z=0,i.rotation.x=0,i.rotation.y=0,i.rotation.z=0,s.rotation.x=0,s.rotation.y=0,s.rotation.z=0,h.x<=0&&h.y>=0&&h.z>=0?(t.rotation.z=3.14,s.rotation.y=3.14):h.x<=0&&h.y>=0&&h.z<=0?(t.rotation.y=3.14,i.rotation.y=3.14,s.rotation.y=3.14):h.x>=0&&h.y>=0&&h.z<=0?(t.rotation.x=3.14,i.rotation.y=3.14):h.x>=0&&h.y<=0&&h.z>=0?(i.rotation.z=3.14,s.rotation.x=3.14):h.x<=0&&h.y<=0&&h.z>=0?(t.rotation.z=3.14,i.rotation.z=3.14,s.rotation.z=3.14):h.x<=0&&h.y<=0&&h.z<=0?(t.rotation.y=3.14,i.rotation.x=3.14,s.rotation.z=3.14):h.x>=0&&h.y<=0&&h.z<=0&&(t.rotation.x=3.14,i.rotation.x=3.14,s.rotation.x=3.14)},s.prototype.switchTo=function(t,i){t.computeWorldMatrix(!0),this.Yt=t,null!=i&&(this.ut=i),this.bt(),this.St(t),this.yt=new u(t,10),this.g=this.xt(t),this.refreshBoundingInfo()},s.prototype.switchCamera=function(t){this.Zt=t},s.prototype.setUndoCount=function(t){this.yt.setCapacity(t)},s.prototype.undo=function(){var t=this.yt.undo();this.Yt.computeWorldMatrix(!0),this.St(this.Yt),this.hi(t),this.ni(t),this.ui(t)},s.prototype.redo=function(){var t=this.yt.redo();this.Yt.computeWorldMatrix(!0),this.St(this.Yt),this.hi(t),this.ni(t),this.ui(t)},s.prototype.detach=function(){this.dt.removeEventListener("pointerdown",this.gt,!1),this.dt.removeEventListener("pointerup",this.qt,!1),this.dt.removeEventListener("pointermove",this._t,!1),this.zt.unregisterBeforeRender(this.Nt),this.removeAllActionListeners(),this.ei()},s.prototype.hide=function(){this.D=!0,this.rt?(this.N="T",this.disableTranslation()):this.ot?(this.N="R",this.disableRotation()):this.ft&&(this.N="S",this.disableScaling()),this.ri()},s.prototype.ri=function(){this.oi.visibility=0,this.fi.visibility=0,this.li.visibility=0},s.prototype.ai=function(){this.oi.visibility=this.R,this.fi.visibility=this.R,this.li.visibility=this.R},s.prototype.show=function(){this.D=!1,this.ai(),"T"==this.N?this.enableTranslation():"R"==this.N?this.enableRotation():"S"==this.N&&this.enableScaling()},s.prototype.isHidden=function(){return this.D},s.prototype.ei=function(){this.Ot.dispose(),this.ci(),this.yt=null},s.prototype.addActionListener=function(t){this.F=t},s.prototype.removeActionListener=function(){this.F=null},s.prototype.addActionStartListener=function(t){this.G=t},s.prototype.removeActionStartListener=function(){this.G=null},s.prototype.addActionEndListener=function(t){this.H=t},s.prototype.removeActionEndListener=function(){this.H=null},s.prototype.removeAllActionListeners=function(){this.F=null,this.G=null,this.H=null},s.prototype.kt=function(t){var i=this;if(t.preventDefault(),this.I=!0,0==t.button){var s=this.zt.getEngine(),h=s.isPointerLock?.5*this.dt.width:this.zt.pointerX,n=s.isPointerLock?.5*this.dt.height:this.zt.pointerY,u=this.zt.pick(h,n,(function(t){if(i.rt){if(t==i.vi||t==i.wi||t==i.Mi||t==i.Jt||t==i.Kt||t==i.Pt||t==i.pi)return!0}else if(i.ot){if(t==i.ti||t==i.ii||t==i.si||t==i.Xi)return!0}else if(i.ft&&(t==i.Yi||t==i.Zi||t==i.di||t==i.Ut||t==i.Vt||t==i.Wt||t==i.bi))return!0;return!1}),!1,this.Zt);if(u.hit){this.Li=u.pickedMesh;var e=this.Li.getChildren();e.length>0?e[0].visibility=this.R:this.Li.visibility=this.R;var r=this.Li.name;"X"==r?this.zi.visibility=1:"Y"==r?this.yi.visibility=1:"Z"==r?this.Ai.visibility=1:"XZ"==r?(this.zi.visibility=1,this.Ai.visibility=1):"ZY"==r?(this.Ai.visibility=1,this.yi.visibility=1):"YX"==r?(this.yi.visibility=1,this.zi.visibility=1):"ALL"==r&&(this.zi.visibility=1,this.yi.visibility=1,this.Ai.visibility=1),this.mi(!0),this.ji=this.Si(this.Li),null!=this.ji?this.xi=this.Oi():this.xi=null,window.setTimeout((function(t,s){return i.Ti(t,s)}),0,this.Zt,this.dt)}}},s.prototype.mi=function(i){this.K=i,i?(this.Ei(),this.Ri==t.ROT&&(this.et=0),this.hi(this.Ri)):this.ui(this.Ri)},s.prototype.isEditing=function(){return this.K},s.prototype.Ti=function(t,i){var s=t,h=i;this.zt.getEngine().isPointerLock||s.detachControl(h)},s.prototype.isPointerOver=function(){return this.J},s.prototype.gi=function(){var t=this,i=this.zt.getEngine(),s=i.isPointerLock?.5*this.dt.width:this.zt.pointerX,h=i.isPointerLock?.5*this.dt.height:this.zt.pointerY,n=this.zt.pick(s,h,(function(i){if(t.rt){if(i==t.vi||i==t.wi||i==t.Mi||i==t.Jt||i==t.Kt||i==t.Pt||i==t.pi)return!0}else if(t.ot){if(i==t.ti||i==t.ii||i==t.si||i==t.Xi)return!0}else if(t.ft&&(i==t.Yi||i==t.Zi||i==t.di||i==t.Ut||i==t.Vt||i==t.Wt||i==t.bi))return!0;return!1}),!1,this.Zt);if(n.hit){if(n.pickedMesh!=this.ki){if(this.J=!0,this.qi(),this.ki=n.pickedMesh,this.ot)this.Ci=this.ki.getChildren()[0].color,this.ki.getChildren()[0].color=this.O;else{var u=this.ki.getChildren();u.length>0?(this._i=u[0].material,u[0].material=this.Bi):(this._i=this.ki.material,this.ki.material=this.Bi)}"X"==this.ki.name?this.oi.color=this.O:"Y"==this.ki.name?this.fi.color=this.O:"Z"==this.ki.name&&(this.li.color=this.O)}}else this.J=!1,null!=this.ki&&(this.Ni(this.ki),this.ki=null)},s.prototype.qi=function(){null!=this.ki&&(this.ki.visibility=0,this.Ni(this.ki))},s.prototype.Ni=function(t){switch(t.name){case"X":this.oi.color=this.A;break;case"Y":this.fi.color=this.j;break;case"Z":this.li.color=this.S}if(this.ot)t.getChildren()[0].color=this.Ci;else{var i=t.getChildren();i.length>0?i[0].material=this._i:t.material=this._i}},s.prototype.Ct=function(t){(this.I=!1,this.K)&&(this.zt.getEngine().isPointerLock||this.Zt.attachControl(!0),this.mi(!1),this.Qi(),null!=this.ki&&(this.Ni(this.ki),this.ki=null),this.yt.add(this.Ri))},s.prototype.Ei=function(){this.rt?this.Ri=t.TRANS:this.ot?this.Ri=t.ROT:this.ft&&(this.Ri=t.SCALE)},s.prototype.ni=function(t){null!=this.F&&this.F(t)},s.prototype.hi=function(t){null!=this.G&&this.G(t)},s.prototype.ui=function(t){null!=this.H&&this.H(t)},s.prototype.Bt=function(t){if(this.I){if(this.K&&null!=this.xi){var i=this.Oi();if(null!=i){if(this.ot)this.Di(this.Yt,this.Li,i,this.xi);else{var s=i.subtract(this.xi);if(0==s.x&&0==s.y&&0==s.z)return;this.rt?this.Fi(s):this.ft&&this.i&&this.Gi(s)}this.xi=i,this.ni(this.Ri)}}}else this.gi()},s.prototype.Si=function(t){var s=t.name;if(this.rt||this.ft){if("XZ"==s)return this.Hi;if("ZY"==s)return this.Ii;if("YX"==s)return this.Ji;if("ALL"==s)return this.Gt;this.Ot.getWorldMatrix().invertToRef(this.k),i.Vector3.TransformCoordinatesToRef(this.Zt.position,this.k,this.q);var h=this.q;if("X"===s)return Math.abs(h.y)>Math.abs(h.z)?this.Hi:this.Ji;if("Z"===s)return Math.abs(h.y)>Math.abs(h.x)?this.Hi:this.Ii;if("Y"===s)return Math.abs(h.z)>Math.abs(h.x)?this.Ji:this.Ii}else{if(!this.ot)return null;this.P=!1,this.Ot.getWorldMatrix().invertToRef(this.k),i.Vector3.TransformCoordinatesToRef(this.Zt.position,this.k,this.q);h=this.q;switch(s){case"X":return Math.abs(h.x)<.2?(this.P=!0,this.Gt):this.Ii;case"Y":return Math.abs(h.y)<.2?(this.P=!0,this.Gt):this.Hi;case"Z":return Math.abs(h.z)<.2?(this.P=!0,this.Gt):this.Ji;default:return this.Gt}}},s.prototype.Fi=function(t){null!=this.Yt.parent&&this.$t(this.Yt)?this.St(this.Ot):this.St(this.Yt);var s=this.Li.name;this.U.x=0,this.U.y=0,this.U.z=0,"X"!=s&&"XZ"!=s&&"YX"!=s&&"ALL"!=s||(this.i?this.U.x=i.Vector3.Dot(t,this.st)/this.st.length():this.U.x=t.x),"Y"!=s&&"ZY"!=s&&"YX"!=s&&"ALL"!=s||(this.i?this.U.y=i.Vector3.Dot(t,this.ht)/this.ht.length():this.U.y=t.y),"Z"!=s&&"XZ"!=s&&"ZY"!=s&&"ALL"!=s||(this.i?this.U.z=i.Vector3.Dot(t,this.nt)/this.nt.length():this.U.z=t.z),this.Ki(this.Yt,this.U,this.i),this.Pi&&(this.Yt.position.x=Math.max(this.Yt.position.x,this.Pi.x),this.Yt.position.y=Math.max(this.Yt.position.y,this.Pi.y),this.Yt.position.z=Math.max(this.Yt.position.z,this.Pi.z)),this.Ui&&(this.Yt.position.x=Math.min(this.Yt.position.x,this.Ui.x),this.Yt.position.y=Math.min(this.Yt.position.y,this.Ui.y),this.Yt.position.z=Math.min(this.Yt.position.z,this.Ui.z)),this.Yt.computeWorldMatrix(!0)},s.prototype.Ki=function(t,s,h){if(this.h){var n=!1;if(this.V.addInPlace(s),Math.abs(this.V.x)>this.ct.x&&(this.V.x>0?s.x=this.ct.x:s.x=-this.ct.x,n=!0),Math.abs(this.V.y)>this.ct.y&&(this.V.y>0?s.y=this.ct.y:s.y=-this.ct.y,n=!0),Math.abs(this.V.z)>this.ct.z&&(this.V.z>0?s.z=this.ct.z:s.z=-this.ct.z,n=!0),!n)return;Math.abs(s.x)!==this.ct.x&&(s.x=0),Math.abs(s.y)!==this.ct.y&&(s.y=0),Math.abs(s.z)!==this.ct.z&&(s.z=0),i.Vector3.FromFloatsToRef(0,0,0,this.V),n=!1}h?(this.st.normalizeToRef(this.vt),this.ht.normalizeToRef(this.wt),this.nt.normalizeToRef(this.Mt),this.Yt.translate(this.vt,s.x,i.Space.WORLD),this.Yt.translate(this.wt,s.y,i.Space.WORLD),this.Yt.translate(this.Mt,s.z,i.Space.WORLD)):null==this.Yt.parent?this.Yt.position.addInPlace(s):this.Yt.setAbsolutePosition(s.addInPlace(this.Yt.absolutePosition))},s.prototype.Gi=function(t){this.St(this.Yt),this.it.x=0,this.it.y=0,this.it.z=0;var s=this.Li.name;"X"!=s&&"XZ"!=s&&"YX"!=s||(this.it.x=i.Vector3.Dot(t,this.st)/this.st.length(),this.Yt.scaling.x<0&&(this.it.x=-this.it.x)),"Y"!=s&&"ZY"!=s&&"YX"!=s||(this.it.y=i.Vector3.Dot(t,this.ht)/this.ht.length(),this.Yt.scaling.y<0&&(this.it.y=-this.it.y)),"Z"!=s&&"XZ"!=s&&"ZY"!=s||(this.it.z=i.Vector3.Dot(t,this.nt)/this.nt.length(),this.Yt.scaling.z<0&&(this.it.z=-this.it.z));var h=this.At;if(this.it.x=this.it.x/h.x,this.it.y=this.it.y/h.y,this.it.z=this.it.z/h.z,"ALL"==s){var n=i.Vector3.Dot(t,this.Zt.upVector);n/=Math.max(h.x,h.y,h.z),this.it.copyFromFloats(n,n,n)}else{var u=!1;if("XZ"==s?(u=!0,Math.abs(this.it.x)>Math.abs(this.it.z)?this.it.z=this.it.x:this.it.x=this.it.z):"ZY"==s?(u=!0,Math.abs(this.it.z)>Math.abs(this.it.y)?this.it.y=this.it.z:this.it.z=this.it.y):"YX"==s&&(u=!0,Math.abs(this.it.y)>Math.abs(this.it.x)?this.it.x=this.it.y:this.it.y=this.it.x),u){this.Ot.position.subtractToRef(this.Zt.position,this._);n=i.Vector3.Dot(t,this._);this.it.x=Math.abs(this.it.x),this.it.y=Math.abs(this.it.y),this.it.z=Math.abs(this.it.z),n>0?(this.Yt.scaling.x>0&&(this.it.x=-this.it.x),this.Yt.scaling.y>0&&(this.it.y=-this.it.y),this.Yt.scaling.z>0&&(this.it.z=-this.it.z)):(this.Yt.scaling.x<0&&(this.it.x=-this.it.x),this.Yt.scaling.y<0&&(this.it.y=-this.it.y),this.Yt.scaling.z<0&&(this.it.z=-this.it.z))}}this.Vi(this.Yt,this.it),this.Wi&&(this.Yt.scaling.x=Math.max(this.Yt.scaling.x,this.Wi.x),this.Yt.scaling.y=Math.max(this.Yt.scaling.y,this.Wi.y),this.Yt.scaling.z=Math.max(this.Yt.scaling.z,this.Wi.z)),this.$i&&(this.Yt.scaling.x=Math.min(this.Yt.scaling.x,this.$i.x),this.Yt.scaling.y=Math.min(this.Yt.scaling.y,this.$i.y),this.Yt.scaling.z=Math.min(this.Yt.scaling.z,this.$i.z))},s.prototype.Vi=function(t,s){if(this.W){var h=!1;if(this.$.addInPlace(s),Math.abs(this.$.x)>this.tt&&(s.x>0?s.x=this.tt:s.x=-this.tt,h=!0),Math.abs(this.$.y)>this.tt&&(s.y>0?s.y=this.tt:s.y=-this.tt,h=!0),Math.abs(this.$.z)>this.tt&&(s.z>0?s.z=this.tt:s.z=-this.tt,h=!0),!h)return;Math.abs(s.x)!==this.tt&&0!==s.x&&(s.x=0),Math.abs(s.y)!==this.tt&&0!==s.y&&(s.y=0),Math.abs(s.z)!==this.tt&&0!==s.z&&(s.z=0),i.Vector3.FromFloatsToRef(0,0,0,this.$),h=!1}t.scaling.addInPlace(s)},s.prototype.St=function(t){var s=t.getWorldMatrix();i.Vector3.FromArrayToRef(s.m,0,this.st),i.Vector3.FromArrayToRef(s.m,4,this.ht),i.Vector3.FromArrayToRef(s.m,8,this.nt)},s.prototype.jt=function(t){if(t instanceof i.AbstractMesh){var s=t.getBoundingInfo().boundingBox,h=s.maximum.subtract(s.minimum);return 0==h.x&&(h.x=1),0==h.y&&(h.y=1),0==h.z&&(h.z=1),h}return new i.Vector3(1,1,1)},s.prototype.refreshBoundingInfo=function(){this.At=this.jt(this.Yt)},s.prototype.Di=function(t,s,h,n){this.i&&null!=this.Yt.parent&&this.$t(t)?this.St(this.Ot):this.St(t);var u,e=0;s==this.ti?u=this.i?this.st:i.Axis.X:s==this.ii?u=this.i?this.ht:i.Axis.Y:s==this.si&&(u=this.i?this.nt:i.Axis.Z),this.Ot.position.subtractToRef(this.Zt.position,this._),this.P?(e=this.ts(n,h,this.Zt.position,this._,u),this.zt.useRightHandedSystem&&(e=-e)):e=this.ss(n,h,t.getAbsolutePivotPoint(),this._),this.g&&(e=-e),this.u&&(this.et+=e,e=0,Math.abs(this.et)>=this.v&&(e=this.et>0?this.v:-this.v,this.et=0)),0!==e&&(this._.normalize(),s==this.Xi?t.rotate(this._,-e,i.Space.WORLD):(i.Vector3.Dot(u,this._)>=0&&(e=-e),t.rotate(u,e,i.Space.WORLD)),this.ut&&(t.rotation=t.rotationQuaternion.toEulerAngles(),t.rotationQuaternion=null),this.i&&(this.g&&(e=-e),null!=this.Yt.parent&&this.$t(t)&&(s==this.Xi?this.Ot.rotate(this._,-e,i.Space.WORLD):this.Ot.rotate(u,e,i.Space.WORLD))))},s.prototype.Oi=function(){var t=this,i=this.zt.getEngine(),s=i.isPointerLock?.5*this.dt.width:this.zt.pointerX,h=i.isPointerLock?.5*this.dt.height:this.zt.pointerY,n=this.zt.pick(s,h,(function(i){return i==t.ji}),null,this.Zt);return n.hit?n.pickedPoint:null},s.prototype.Qi=function(){this.zi.visibility=0,this.yi.visibility=0,this.Ai.visibility=0},s.prototype.getRotationQuaternion=function(){return this.Ot.rotationQuaternion},s.prototype.getPosition=function(){return this.Ot.position},s.prototype.isTranslationEnabled=function(){return this.rt},s.prototype.enableTranslation=function(){this.D||(null==this.vi&&(this.hs(),this.ns.parent=this.Ot),this.qi(),this.rt||(this.us(this.es,this.R),this.rt=!0,this.disableRotation(),this.disableScaling()))},s.prototype.disableTranslation=function(){this.rt&&(this.us(this.es,0),this.rt=!1)},s.prototype.isRotationEnabled=function(){return this.ot},s.prototype.returnEuler=function(t){this.ut=t},s.prototype.enableRotation=function(){this.D||(null==this.rs&&(this.os(),this.rs.parent=this.Ot),this.qi(),this.ot||(this.us(this.fs,this.R),this.ot=!0,this.disableTranslation(),this.disableScaling()))},s.prototype.disableRotation=function(){this.ot&&(this.us(this.fs,0),this.ot=!1)},s.prototype.isScalingEnabled=function(){return this.ft},s.prototype.enableScaling=function(){this.D||(null==this.Yi&&(this.ls(),this.cs.parent=this.Ot),this.qi(),this.ft||(this.us(this.vs,this.R),this.ft=!0,this.disableTranslation(),this.disableRotation()))},s.prototype.disableScaling=function(){this.ft&&(this.us(this.vs,0),this.ft=!1)},s.prototype.setScaleBounds=function(t,i){this.Wi=t||null,this.$i=i||null,null!=this.Wi&&(0==this.Wi.x&&(this.Wi.x=1e-8),0==this.Wi.y&&(this.Wi.y=1e-8),0==this.Wi.z&&(this.Wi.z=1e-8))},s.prototype.removeScaleBounds=function(){this.Wi=null,this.$i=null},s.prototype.setTransBounds=function(t,i){this.Pi=t||null,this.Ui=i||null},s.prototype.removeTransBounds=function(){this.Pi=null,this.Ui=null},s.prototype.setRotBounds=function(t,i){this.ws=t||null,this.Ms=i||null},s.prototype.removeRotBounds=function(){this.ws=null,this.Ms=null},s.prototype.Et=function(){var t=new i.Mesh("",this.zt);this.zi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(-100,0,0),new i.Vector3(100,0,0)]},this.zt),this.yi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,-100,0),new i.Vector3(0,100,0)]},this.zt),this.Ai=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,-100),new i.Vector3(0,0,100)]},this.zt),this.zi.isPickable=!1,this.yi.isPickable=!1,this.Ai.isPickable=!1,this.zi.parent=t,this.yi.parent=t,this.Ai.parent=t,this.zi.color=this.A,this.yi.color=this.j,this.Ai.color=this.S,this.Qi();var s=this.M*this.p*.75;return this.oi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,0),new i.Vector3(s,0,0)]},this.zt),this.fi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,0),new i.Vector3(0,s,0)]},this.zt),this.li=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,0),new i.Vector3(0,0,s)]},this.zt),this.oi.isPickable=!1,this.fi.isPickable=!1,this.li.isPickable=!1,this.oi.parent=t,this.fi.parent=t,this.li.parent=t,this.oi.color=this.A,this.fi.color=this.j,this.li.color=this.S,this.oi.renderingGroupId=1,this.fi.renderingGroupId=1,this.li.renderingGroupId=1,t},s.prototype.Rt=function(){this.Gt=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Hi=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Ii=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Ji=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Gt.isPickable=!1,this.Hi.isPickable=!1,this.Ii.isPickable=!1,this.Ji.isPickable=!1,this.Gt.visibility=0,this.Hi.visibility=0,this.Ii.visibility=0,this.Ji.visibility=0,this.Gt.renderingGroupId=1,this.Hi.renderingGroupId=1,this.Ii.renderingGroupId=1,this.Ji.renderingGroupId=1,this.Gt.lookAt(this.Zt.position),this.Hi.rotate(i.Axis.X,1.57),this.Ii.rotate(i.Axis.Y,1.57);var t=new i.Mesh("",this.zt);return this.Gt.parent=t,this.Hi.parent=t,this.Ii.parent=t,this.Ji.parent=t,t},s.prototype.hs=function(){var t=2*this.L*this.p,s=this.M*this.p;this.ns=new i.Mesh("",this.zt),this.ps(t,s,this.ns,this.zt),this.Xs(t,s,this.zt)},s.prototype.ps=function(t,s,h,n){var u=this.Ys(t/2,s);u.name="X";var e=u.clone("Y"),r=u.clone("Z"),o=2*t,f=i.MeshBuilder.CreatePlane("XZ",{size:o},n),l=i.MeshBuilder.CreatePlane("ZY",{size:o},n),a=i.MeshBuilder.CreatePlane("YX",{size:o},n);f.rotation.x=1.57,l.rotation.y=-1.57,f.position.x=2*t,f.position.z=2*t,l.position.z=2*t,l.position.y=2*t,a.position.y=2*t,a.position.x=2*t,f.bakeCurrentTransformIntoVertices(),l.bakeCurrentTransformIntoVertices(),a.bakeCurrentTransformIntoVertices();var c=i.MeshBuilder.CreateBox("ALL",{size:2*t},n);u.parent=h,e.parent=h,r.parent=h,f.parent=h,l.parent=h,a.parent=h,c.parent=h,u.rotation.y=1.57,e.rotation.x-=1.57,this.vi=u,this.wi=e,this.Mi=r,this.Jt=f,this.Kt=l,this.Pt=a,this.pi=c,this.Zs=[u,e,r,f,l,a,c],this.us(this.Zs,0),this.ds(this.Zs)},s.prototype.Xs=function(t,s,h){var n=s/5,u=i.MeshBuilder.CreateCylinder("",{height:n,diameterTop:0,diameterBottom:t,tessellation:6,subdivisions:1},h),e=u.clone(""),r=u.clone(""),o=2*t,f=i.MeshBuilder.CreatePlane("XZ",{size:o},h),l=i.MeshBuilder.CreatePlane("ZY",{size:o},h),a=i.MeshBuilder.CreatePlane("YX",{size:o},h),c=i.MeshBuilder.CreateBox("ALL",{size:t},h);u.rotation.x=1.57,e.rotation.x=1.57,r.rotation.x=1.57,f.rotation.x=1.57,l.rotation.y=1.57,f.position.x=o,f.position.z=o,l.position.z=o,l.position.y=o,a.position.y=o,a.position.x=o,u.parent=this.vi,e.parent=this.wi,r.parent=this.Mi,f.parent=this.Jt,l.parent=this.Kt,a.parent=this.Pt,c.parent=this.pi,u.position.z=s-n/2,e.position.z=s-n/2,r.position.z=s-n/2,u.material=this.bs,e.material=this.Ls,r.material=this.zs,f.material=this.Ls,l.material=this.bs,a.material=this.zs,c.material=this.ys,this.As=u,this.js=e,this.Ss=r,this.xs=f,this.Os=l,this.Ts=a,this.Es=c,this.es=[u,e,r,f,l,a,c],this.ds(this.es),this.Rs(this.es)},s.prototype.setRotGuideFull=function(t){this.lt=t?360:180,null!=this.rs&&(this.rs.dispose(),this.Xi.dispose(),this.rs=null,this.enableRotation())},s.prototype.os=function(){var t=this.M*this.p*2;this.rs=new i.Mesh("",this.zt),this.gs(t,this.rs),this.ks(t)},s.prototype.gs=function(t,i){var s=this.qs(t/2,this.lt),h=this.qs(t/2,this.lt),n=this.qs(t/2,this.lt),u=this.qs(t/1.75,360);s.name="X",h.name="Y",n.name="Z",u.name="ALL",s.rotation.z=1.57,n.rotation.x=-1.57,s.bakeCurrentTransformIntoVertices(),n.bakeCurrentTransformIntoVertices(),u.rotation.x=1.57,s.parent=i,h.parent=i,n.parent=i,u.parent=this.Gt,this.ti=s,this.ii=h,this.si=n,this.Xi=u,this.Cs=[s,h,n,u],this.us(this.Cs,0),this.ds(this.Cs)},s.prototype.ks=function(t){var s=this._s(t/2,this.lt,!1),h=s.clone(""),n=s.clone(""),u=this._s(t/1.75,360,!1),e=this._s(t/2,360,!1);s.parent=this.ti,h.parent=this.ii,n.parent=this.si,s.rotation.z=1.57,n.rotation.x=-1.57,u.parent=this.Xi,e.parent=this.Xi,s.color=this.A,h.color=this.j,n.color=this.S,u.color=this.T,e.color=i.Color3.Gray(),this.Bs=s,this.Ns=h,this.Qs=n,this.Ds=u,this.Fs=e,this.fs=[s,h,n,u,e],this.ds(this.fs),this.Rs(this.fs)},s.prototype.us=function(t,i){t.map((function(t){return t.visibility=i}))},s.prototype.ds=function(t){t.map((function(t){t.isPickable=!1}))},s.prototype.Rs=function(t){t.map((function(t){return t.renderingGroupId=2}))},s.prototype.Ys=function(t,s){var h=[new i.Vector3(t,t,0),new i.Vector3(-t,t,0),new i.Vector3(-t,-t,0),new i.Vector3(t,-t,0),new i.Vector3(t,t,0)],n=[new i.Vector3(0,0,0),new i.Vector3(0,0,s)];return i.MeshBuilder.ExtrudeShape("",{shape:h,path:n,scale:1,rotation:0,cap:2},this.zt)},s.prototype._s=function(t,s,h){null===s&&(s=360);for(var n,u,e=[],r=3.14/180,o=0,f=0;f<=s;f+=5)n=t*Math.cos(f*r),u=90==f?t:270==f?-t:t*Math.sin(f*r),e[o]=new i.Vector3(n,0,u),o++;if(h){t-=.04;for(f=0;f<=s;f+=5)n=t*Math.cos(f*r),u=90==f?t:270==f?-t:t*Math.sin(f*r),e[o]=new i.Vector3(n,0,u),o++}return i.MeshBuilder.CreateLines("",{points:e},this.zt)},s.prototype.qs=function(t,s){null===s&&(s=360);for(var h,n,u=[],e=3.14/180,r=0,o=0;o<=s;o+=30)h=t*Math.cos(o*e),n=90==o?t:270==o?-t:t*Math.sin(o*e),u[r]=new i.Vector3(h,0,n),r++;return i.MeshBuilder.CreateTube("",{path:u,radius:this.L*this.p*2,tessellation:3,cap:i.Mesh.NO_CAP},this.zt)},s.prototype.ls=function(){var t=2*this.L*this.p,s=this.M*this.p;this.cs=new i.Mesh("",this.zt),this.Gs(t,s,this.cs),this.Hs(t,s)},s.prototype.Gs=function(t,s,h){var n=this.Ys(t/2,s);n.name="X";var u=n.clone("Y"),e=n.clone("Z"),r=i.MeshBuilder.CreatePlane("XZ",{size:2*t},this.zt),o=i.MeshBuilder.CreatePlane("ZY",{size:2*t},this.zt),f=i.MeshBuilder.CreatePlane("YX",{size:2*t},this.zt);r.rotation.x=1.57,o.rotation.y=-1.57,r.position.x=2*t,r.position.z=2*t,o.position.z=2*t,o.position.y=2*t,f.position.y=2*t,f.position.x=2*t,r.bakeCurrentTransformIntoVertices(),o.bakeCurrentTransformIntoVertices(),f.bakeCurrentTransformIntoVertices();var l=i.MeshBuilder.CreateBox("ALL",{size:2*t},this.zt);n.parent=h,u.parent=h,e.parent=h,l.parent=h,r.parent=h,o.parent=h,f.parent=h,n.rotation.y=1.57,u.rotation.x-=1.57,this.Yi=n,this.Zi=u,this.di=e,this.Ut=r,this.Vt=o,this.Wt=f,this.bi=l,this.Is=[n,u,e,r,o,f,l],this.us(this.Is,0),this.ds(this.Is)},s.prototype.Hs=function(t,s){var h=i.MeshBuilder.CreateBox("",{size:t},this.zt),n=h.clone(""),u=h.clone(""),e=2*t,r=i.MeshBuilder.CreatePlane("XZ",{size:e},this.zt),o=i.MeshBuilder.CreatePlane("ZY",{size:e},this.zt),f=i.MeshBuilder.CreatePlane("YX",{size:e},this.zt),l=i.MeshBuilder.CreateBox("ALL",{size:t},this.zt);r.rotation.x=1.57,o.rotation.y=-1.57,r.position.x=e,r.position.z=e,o.position.z=e,o.position.y=e,f.position.y=e,f.position.x=e,h.parent=this.Yi,n.parent=this.Zi,u.parent=this.di,r.parent=this.Ut,o.parent=this.Vt,f.parent=this.Wt,l.parent=this.bi,h.position.z=s-t/2,n.position.z=s-t/2,u.position.z=s-t/2,h.material=this.bs,n.material=this.Ls,u.material=this.zs,r.material=this.Ls,o.material=this.bs,f.material=this.zs,l.material=this.ys,this.Js=h,this.Ks=n,this.Ps=u,this.Us=r,this.Vs=o,this.Ws=f,this.$s=l,this.vs=[h,n,u,r,o,f,l],this.ds(this.vs),this.Rs(this.vs)},s.prototype.setVisibility=function(t){this.R=t},s.prototype.setLocal=function(t){this.i!=t&&(this.i=t,t||(this.Ot.rotationQuaternion=i.Quaternion.Identity()))},s.prototype.isLocal=function(){return this.i},s.prototype.setTransSnap=function(t){this.h=t},s.prototype.isTransSnap=function(){return this.h},s.prototype.setRotSnap=function(t){this.u=t},s.prototype.isRotSnap=function(){return this.u},s.prototype.setScaleSnap=function(t){this.W=t},s.prototype.isScaleSnap=function(){return this.W},s.prototype.setTransSnapValue=function(t){this.ct.copyFromFloats(t,t,t),this.l=t},s.prototype.getTransSnapValue=function(){return this.l},s.prototype.setRotSnapValue=function(t){this.v=t},s.prototype.getRotSnapValue=function(){return this.v},s.prototype.setScaleSnapValue=function(t){this.tt=t},s.prototype.getScaleSnapValue=function(){return this.tt},s.prototype.ts=function(t,s,h,n,u){var e=i.Vector3.Dot(n,u);u.scaleToRef(e,this.vt),h.addToRef(this.vt,this.wt);var r=this.wt;this.Zt.getWorldMatrix().invertToRef(this.Xt),i.Vector3.TransformCoordinatesToRef(this.wt,this.Xt,this.wt);var o=0;r.x>=0&&r.y>=0?o=1:r.x<=0&&r.y>=0?o=2:r.x<=0&&r.y<=0?o=3:r.x>=0&&r.y<=0&&(o=4),i.Vector3.TransformCoordinatesToRef(t,this.Xt,this.vt),i.Vector3.TransformCoordinatesToRef(s,this.Xt,this.wt),this.wt.subtractInPlace(this.vt);var f=this.wt,l=f.length(),a="";f.x>=0&&f.y>=0?a=f.x>=f.y?"r":"u":f.x<=0&&f.y>=0?a=-f.x>=f.y?"l":"u":f.x<=0&&f.y<=0?a=-f.x>=-f.y?"l":"d":f.x>=0&&f.y<=0&&(a=f.x>=-f.y?"r":"d");var c=0;return"d"==a?c=1==o||4==o?1:-1:"u"==a?c=1==o||4==o?-1:1:"r"==a?c=2==o||1==o?1:-1:"l"==a&&(c=2==o||1==o?-1:1),c*l},s.prototype.ss=function(t,s,h,n){t.subtractToRef(h,this.vt),s.subtractToRef(h,this.wt),i.Vector3.CrossToRef(this.vt,this.wt,this.Mt);var u=Math.asin(this.Mt.length()/(this.vt.length()*this.wt.length()));return i.Vector3.Dot(this.Mt,n)>0&&(u*=-1),u},s.th=function(t,s){var h=new i.StandardMaterial("",s);return h.emissiveColor=t,h.diffuseColor=i.Color3.Black(),h.specularColor=i.Color3.Black(),h.backFaceCulling=!1,h},s.prototype.Tt=function(t){this.bs=s.th(this.A,t),this.Ls=s.th(this.j,t),this.zs=s.th(this.S,t),this.Bi=s.th(this.O,t),this.ys=s.th(this.T,t)},s.prototype.ci=function(){this.bs.dispose(),this.Ls.dispose(),this.zs.dispose(),this.Bi.dispose(),this.ys.dispose()},s}(),u=function(){function t(t,i){this.lastMax=10,this.acts=new Array,this.last=-1,this.current=-1,this.mesh=t,this.lastMax=i-1,this.add()}return t.prototype.setCapacity=function(t){0!=t?(this.lastMax=t-1,this.last=-1,this.current=-1,this.acts=new Array,this.add()):console.error("capacity should be more than zero")},t.prototype.add=function(t){void 0===t&&(t=null);var i=new e(this.mesh,t);this.current0){var t=this.acts[this.current].getActionType();return this.current--,this.acts[this.current].perform(this.mesh),t}},t.prototype.redo=function(){if(this.current(()=>{"use strict";var i={babylonjs:i=>{i.exports=t}},s={};function h(t){var n=s[t];if(void 0!==n)return n.exports;var u=s[t]={exports:{}};return i[t](u,u.exports,h),u.exports}h.n=t=>{var i=t&&t.t?()=>t.default:()=>t;return h.d(i,{a:i}),i},h.d=(t,i)=>{for(var s in i)h.o(i,s)&&!h.o(t,s)&&Object.defineProperty(t,s,{enumerable:!0,get:i[s]})},h.o=(t,i)=>Object.prototype.hasOwnProperty.call(t,i),h.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"t",{value:!0})};var n={};return(()=>{h.r(n),h.d(n,{EditControl:()=>s});var t,i=h("babylonjs");!function(t){t[t.TRANS=0]="TRANS",t[t.ROT=1]="ROT",t[t.SCALE=2]="SCALE"}(t||(t={}));var s=function(){function s(t,s,h,n,e,r){var o=this;this.i=!0,this.h=!1,this.u=!1,this.l=1,this.v=Math.PI/18,this.M=.4,this.p=1,this.L=.02,this.A=new i.Color3(1,.2,.2),this.j=new i.Color3(.2,1,.2),this.S=new i.Color3(.2,.2,1),this.O=new i.Color3(1,1,1),this.T=new i.Color3(1,1,.2),this.R=.75,this.g=!1,this.k=new i.Matrix,this.q=new i.Vector3(0,0,0),this.C=2,this._=new i.Vector3(0,0,0),this.B=new i.Vector3(0,0,0),this.N="",this.D=!1,this.F=null,this.G=null,this.H=null,this.I=!1,this.J=!1,this.K=!1,this.P=!1,this.U=new i.Vector3(0,0,0),this.V=new i.Vector3(0,0,0),this.W=!1,this.$=new i.Vector3(0,0,0),this.tt=.25,this.it=new i.Vector3(0,0,0),this.st=new i.Vector3(0,0,0),this.ht=new i.Vector3(0,0,0),this.nt=new i.Vector3(0,0,0),this.ut=!1,this.et=0,this.rt=!1,this.ot=!1,this.ft=!1,this.lt=180,this.ct=new i.Vector3(this.l,this.l,this.l),this.vt=new i.Vector3(0,0,0),this.wt=new i.Vector3(0,0,0),this.Mt=new i.Vector3(0,0,0),this.Xt=new i.Matrix,this.Yt=t,this.Zt=s,this.bt=h,null!=n&&(this.p=n),this.ut=null!==e&&e,this.dt(),null!=r&&(this.L=r),this.Lt=i.UtilityLayerRenderer.DefaultUtilityLayer,this.Lt.onlyCheckPointerDownEvents=!1,this.zt=this.Lt.utilityLayerScene,this.yt=new u(t,10),t.computeWorldMatrix(!0),this.At=this.jt(t),this.St(t),this.g=this.xt(t),console.log("lhs rhs issue "+this.g),this.Ot=new i.Mesh("",this.zt),this.Ot.rotationQuaternion=i.Quaternion.Identity(),this.Ot.visibility=0,this.Ot.isPickable=!1,this.Tt(this.zt),this.Et().parent=this.Ot,this.Rt().parent=this.Ot,this.gt=function(t){return o.kt(t)},this.qt=function(t){return o.Ct(t)},this._t=function(t){return o.Bt(t)},h.addEventListener("pointerdown",this.gt,!1),h.addEventListener("pointerup",this.qt,!1),h.addEventListener("pointermove",this._t,!1),this.Nt=function(){return o.Qt()},this.zt.registerBeforeRender(this.Nt)}return s.prototype.getRoot=function(){return this.Ot},s.prototype.dt=function(){if(!this.ut&&(null==this.Yt.rotationQuaternion||null==this.Yt.rotationQuaternion))throw"Error: Eulerian is set to false but the mesh's rotationQuaternion is not set."},s.prototype.xt=function(t){var s=!1,h=t.parent;if(null==h)return!1;this.St(h);var n=i.Vector3.Cross(this.st,this.ht);return s=i.Vector3.Dot(n,this.nt)<0,this.St(t),s},s.prototype.Qt=function(){this.Ot.position=this.Yt.getAbsolutePivotPoint(),this.Dt(),this.Ft(),this.i?(this.Ot.getWorldMatrix().invertToRef(this.k),i.Vector3.TransformCoordinatesToRef(this.Zt.position,this.k,this.q),this.Gt.lookAt(this.q,0,0,0,i.Space.LOCAL)):(this.Zt.position.subtractToRef(this.Ot.position,this.q),this.Gt.lookAt(this.Zt.position,0,0,0,i.Space.WORLD)),this.ot?this.Ht():this.rt?this.It(this.Jt,this.Kt,this.Pt):this.ft&&this.It(this.Ut,this.Vt,this.Wt)},s.prototype.Dt=function(){if(this.i)if(null==this.Yt.parent)if(this.ut){var t=this.Yt.rotation;i.Quaternion.RotationYawPitchRollToRef(t.y,t.x,t.z,this.Ot.rotationQuaternion)}else this.Ot.rotationQuaternion.copyFrom(this.Yt.rotationQuaternion);else{if(this.$t(this.Yt))return;this.Yt.getWorldMatrix().getRotationMatrixToRef(this.Xt),i.Quaternion.FromRotationMatrixToRef(this.Xt,this.Ot.rotationQuaternion)}},s.prototype.$t=function(t){if(null==t.parent)return!1;for(;null!=t.parent;){if(t.parent.scaling.x!=t.parent.scaling.y||t.parent.scaling.y!=t.parent.scaling.z)return!0;t=t.parent}return!1},s.prototype.Ft=function(){this.Ot.position.subtractToRef(this.Zt.position,this._),i.Vector3.FromArrayToRef(this.Zt.getWorldMatrix().asArray(),8,this.B);var t=i.Vector3.Dot(this._,this.B)/this.B.length(),s=Math.abs(t/this.C);i.Vector3.FromFloatsToRef(s,s,s,this.Ot.scaling)},s.prototype.Ht=function(){var t=Math.atan(this.q.y/this.q.z);this.q.z>=0?this.ti.rotation.x=-t:this.ti.rotation.x=-t-Math.PI;var i=Math.atan(this.q.x/this.q.z);this.q.z>=0?this.ii.rotation.y=i:this.ii.rotation.y=i+Math.PI;var s=Math.atan(this.q.x/this.q.y);this.q.y>=0?this.si.rotation.z=-s:this.si.rotation.z=-s-Math.PI},s.prototype.It=function(t,i,s){var h=this.q;t.rotation.x=0,t.rotation.y=0,t.rotation.z=0,i.rotation.x=0,i.rotation.y=0,i.rotation.z=0,s.rotation.x=0,s.rotation.y=0,s.rotation.z=0,h.x<=0&&h.y>=0&&h.z>=0?(t.rotation.z=3.14,s.rotation.y=3.14):h.x<=0&&h.y>=0&&h.z<=0?(t.rotation.y=3.14,i.rotation.y=3.14,s.rotation.y=3.14):h.x>=0&&h.y>=0&&h.z<=0?(t.rotation.x=3.14,i.rotation.y=3.14):h.x>=0&&h.y<=0&&h.z>=0?(i.rotation.z=3.14,s.rotation.x=3.14):h.x<=0&&h.y<=0&&h.z>=0?(t.rotation.z=3.14,i.rotation.z=3.14,s.rotation.z=3.14):h.x<=0&&h.y<=0&&h.z<=0?(t.rotation.y=3.14,i.rotation.x=3.14,s.rotation.z=3.14):h.x>=0&&h.y<=0&&h.z<=0&&(t.rotation.x=3.14,i.rotation.x=3.14,s.rotation.x=3.14)},s.prototype.switchTo=function(t,i){t.computeWorldMatrix(!0),this.Yt=t,null!=i&&(this.ut=i),this.dt(),this.St(t),this.yt=new u(t,10),this.g=this.xt(t),this.refreshBoundingInfo()},s.prototype.switchCamera=function(t){this.Zt=t},s.prototype.setUndoCount=function(t){this.yt.setCapacity(t)},s.prototype.undo=function(){var t=this.yt.undo();this.Yt.computeWorldMatrix(!0),this.St(this.Yt),this.hi(t),this.ni(t),this.ui(t)},s.prototype.redo=function(){var t=this.yt.redo();this.Yt.computeWorldMatrix(!0),this.St(this.Yt),this.hi(t),this.ni(t),this.ui(t)},s.prototype.detach=function(){this.bt.removeEventListener("pointerdown",this.gt,!1),this.bt.removeEventListener("pointerup",this.qt,!1),this.bt.removeEventListener("pointermove",this._t,!1),this.zt.unregisterBeforeRender(this.Nt),this.removeAllActionListeners(),this.ei()},s.prototype.hide=function(){this.D=!0,this.rt?(this.N="T",this.disableTranslation()):this.ot?(this.N="R",this.disableRotation()):this.ft&&(this.N="S",this.disableScaling()),this.ri()},s.prototype.ri=function(){this.oi.visibility=0,this.fi.visibility=0,this.li.visibility=0},s.prototype.ai=function(){this.oi.visibility=this.R,this.fi.visibility=this.R,this.li.visibility=this.R},s.prototype.show=function(){this.D=!1,this.ai(),"T"==this.N?this.enableTranslation():"R"==this.N?this.enableRotation():"S"==this.N&&this.enableScaling()},s.prototype.isHidden=function(){return this.D},s.prototype.ei=function(){this.Ot.dispose(),this.ci(),this.yt=null},s.prototype.addActionListener=function(t){this.F=t},s.prototype.removeActionListener=function(){this.F=null},s.prototype.addActionStartListener=function(t){this.G=t},s.prototype.removeActionStartListener=function(){this.G=null},s.prototype.addActionEndListener=function(t){this.H=t},s.prototype.removeActionEndListener=function(){this.H=null},s.prototype.removeAllActionListeners=function(){this.F=null,this.G=null,this.H=null},s.prototype.kt=function(t){var i=this;if(t.preventDefault(),this.I=!0,0==t.button){var s=this.zt.getEngine(),h=s.isPointerLock?.5*this.bt.width:this.zt.pointerX,n=s.isPointerLock?.5*this.bt.height:this.zt.pointerY,u=this.zt.pick(h,n,(function(t){if(i.rt){if(t==i.vi||t==i.wi||t==i.Mi||t==i.Jt||t==i.Kt||t==i.Pt||t==i.pi)return!0}else if(i.ot){if(t==i.ti||t==i.ii||t==i.si||t==i.Xi)return!0}else if(i.ft&&(t==i.Yi||t==i.Zi||t==i.bi||t==i.Ut||t==i.Vt||t==i.Wt||t==i.di))return!0;return!1}),!1,this.Zt);if(u.hit){this.Li=u.pickedMesh;var e=this.Li.getChildren();e.length>0?e[0].visibility=this.R:this.Li.visibility=this.R;var r=this.Li.name;"X"==r?this.zi.visibility=1:"Y"==r?this.yi.visibility=1:"Z"==r?this.Ai.visibility=1:"XZ"==r?(this.zi.visibility=1,this.Ai.visibility=1):"ZY"==r?(this.Ai.visibility=1,this.yi.visibility=1):"YX"==r?(this.yi.visibility=1,this.zi.visibility=1):"ALL"==r&&(this.zi.visibility=1,this.yi.visibility=1,this.Ai.visibility=1),this.ji(!0),this.mi=this.Si(this.Li),null!=this.mi?this.xi=this.Oi():this.xi=null,window.setTimeout((function(t,s){return i.Ti(t,s)}),0,this.Zt,this.bt)}}},s.prototype.ji=function(i){this.K=i,i?(this.Ei(),this.Ri==t.ROT&&(this.et=0),this.hi(this.Ri)):this.ui(this.Ri)},s.prototype.isEditing=function(){return this.K},s.prototype.Ti=function(t,i){var s=t,h=i;this.zt.getEngine().isPointerLock||s.detachControl(h)},s.prototype.isPointerOver=function(){return this.J},s.prototype.gi=function(){var t=this,i=this.zt.getEngine(),s=i.isPointerLock?.5*this.bt.width:this.zt.pointerX,h=i.isPointerLock?.5*this.bt.height:this.zt.pointerY,n=this.zt.pick(s,h,(function(i){if(t.rt){if(i==t.vi||i==t.wi||i==t.Mi||i==t.Jt||i==t.Kt||i==t.Pt||i==t.pi)return!0}else if(t.ot){if(i==t.ti||i==t.ii||i==t.si||i==t.Xi)return!0}else if(t.ft&&(i==t.Yi||i==t.Zi||i==t.bi||i==t.Ut||i==t.Vt||i==t.Wt||i==t.di))return!0;return!1}),!1,this.Zt);if(n.hit){if(n.pickedMesh!=this.ki){if(this.J=!0,this.qi(),this.ki=n.pickedMesh,this.ot)this.Ci=this.ki.getChildren()[0].color,this.ki.getChildren()[0].color=this.O;else{var u=this.ki.getChildren();u.length>0?(this._i=u[0].material,u[0].material=this.Bi):(this._i=this.ki.material,this.ki.material=this.Bi)}"X"==this.ki.name?this.oi.color=this.O:"Y"==this.ki.name?this.fi.color=this.O:"Z"==this.ki.name&&(this.li.color=this.O)}}else this.J=!1,null!=this.ki&&(this.Ni(this.ki),this.ki=null)},s.prototype.qi=function(){null!=this.ki&&(this.ki.visibility=0,this.Ni(this.ki))},s.prototype.Ni=function(t){switch(t.name){case"X":this.oi.color=this.A;break;case"Y":this.fi.color=this.j;break;case"Z":this.li.color=this.S}if(this.ot)t.getChildren()[0].color=this.Ci;else{var i=t.getChildren();i.length>0?i[0].material=this._i:t.material=this._i}},s.prototype.Ct=function(t){(this.I=!1,this.K)&&(this.zt.getEngine().isPointerLock||this.Zt.attachControl(!0),this.ji(!1),this.Qi(),null!=this.ki&&(this.Ni(this.ki),this.ki=null),this.yt.add(this.Ri))},s.prototype.Ei=function(){this.rt?this.Ri=t.TRANS:this.ot?this.Ri=t.ROT:this.ft&&(this.Ri=t.SCALE)},s.prototype.ni=function(t){null!=this.F&&this.F(t)},s.prototype.hi=function(t){null!=this.G&&this.G(t)},s.prototype.ui=function(t){null!=this.H&&this.H(t)},s.prototype.Bt=function(t){if(this.I){if(this.K&&null!=this.xi){var i=this.Oi();if(null!=i){if(this.ot)this.Di(this.Yt,this.Li,i,this.xi);else{var s=i.subtract(this.xi);if(0==s.x&&0==s.y&&0==s.z)return;this.rt?this.Fi(s):this.ft&&this.i&&this.Gi(s)}this.xi=i,this.ni(this.Ri)}}}else this.gi()},s.prototype.Si=function(t){var s=t.name;if(this.rt||this.ft){if("XZ"==s)return this.Hi;if("ZY"==s)return this.Ii;if("YX"==s)return this.Ji;if("ALL"==s)return this.Gt;this.Ot.getWorldMatrix().invertToRef(this.k),i.Vector3.TransformCoordinatesToRef(this.Zt.position,this.k,this.q);var h=this.q;if("X"===s)return Math.abs(h.y)>Math.abs(h.z)?this.Hi:this.Ji;if("Z"===s)return Math.abs(h.y)>Math.abs(h.x)?this.Hi:this.Ii;if("Y"===s)return Math.abs(h.z)>Math.abs(h.x)?this.Ji:this.Ii}else{if(!this.ot)return null;this.P=!1,this.Ot.getWorldMatrix().invertToRef(this.k),i.Vector3.TransformCoordinatesToRef(this.Zt.position,this.k,this.q);h=this.q;switch(s){case"X":return Math.abs(h.x)<.2?(this.P=!0,this.Gt):this.Ii;case"Y":return Math.abs(h.y)<.2?(this.P=!0,this.Gt):this.Hi;case"Z":return Math.abs(h.z)<.2?(this.P=!0,this.Gt):this.Ji;default:return this.Gt}}},s.prototype.Fi=function(t){null!=this.Yt.parent&&this.$t(this.Yt)?this.St(this.Ot):this.St(this.Yt);var s=this.Li.name;this.U.x=0,this.U.y=0,this.U.z=0,"X"!=s&&"XZ"!=s&&"YX"!=s&&"ALL"!=s||(this.i?this.U.x=i.Vector3.Dot(t,this.st)/this.st.length():this.U.x=t.x),"Y"!=s&&"ZY"!=s&&"YX"!=s&&"ALL"!=s||(this.i?this.U.y=i.Vector3.Dot(t,this.ht)/this.ht.length():this.U.y=t.y),"Z"!=s&&"XZ"!=s&&"ZY"!=s&&"ALL"!=s||(this.i?this.U.z=i.Vector3.Dot(t,this.nt)/this.nt.length():this.U.z=t.z),this.Ki(this.Yt,this.U,this.i),this.Pi&&(this.Yt.position.x=Math.max(this.Yt.position.x,this.Pi.x),this.Yt.position.y=Math.max(this.Yt.position.y,this.Pi.y),this.Yt.position.z=Math.max(this.Yt.position.z,this.Pi.z)),this.Ui&&(this.Yt.position.x=Math.min(this.Yt.position.x,this.Ui.x),this.Yt.position.y=Math.min(this.Yt.position.y,this.Ui.y),this.Yt.position.z=Math.min(this.Yt.position.z,this.Ui.z)),this.Yt.computeWorldMatrix(!0)},s.prototype.Ki=function(t,s,h){if(this.h){var n=!1;if(this.V.addInPlace(s),Math.abs(this.V.x)>this.ct.x&&(this.V.x>0?s.x=this.ct.x:s.x=-this.ct.x,n=!0),Math.abs(this.V.y)>this.ct.y&&(this.V.y>0?s.y=this.ct.y:s.y=-this.ct.y,n=!0),Math.abs(this.V.z)>this.ct.z&&(this.V.z>0?s.z=this.ct.z:s.z=-this.ct.z,n=!0),!n)return;Math.abs(s.x)!==this.ct.x&&(s.x=0),Math.abs(s.y)!==this.ct.y&&(s.y=0),Math.abs(s.z)!==this.ct.z&&(s.z=0),i.Vector3.FromFloatsToRef(0,0,0,this.V),n=!1}h?(this.st.normalizeToRef(this.vt),this.ht.normalizeToRef(this.wt),this.nt.normalizeToRef(this.Mt),this.Yt.translate(this.vt,s.x,i.Space.WORLD),this.Yt.translate(this.wt,s.y,i.Space.WORLD),this.Yt.translate(this.Mt,s.z,i.Space.WORLD)):null==this.Yt.parent?this.Yt.position.addInPlace(s):this.Yt.setAbsolutePosition(s.addInPlace(this.Yt.absolutePosition))},s.prototype.Gi=function(t){this.St(this.Yt),this.it.x=0,this.it.y=0,this.it.z=0;var s=this.Li.name;"X"!=s&&"XZ"!=s&&"YX"!=s||(this.it.x=i.Vector3.Dot(t,this.st)/this.st.length(),this.Yt.scaling.x<0&&(this.it.x=-this.it.x)),"Y"!=s&&"ZY"!=s&&"YX"!=s||(this.it.y=i.Vector3.Dot(t,this.ht)/this.ht.length(),this.Yt.scaling.y<0&&(this.it.y=-this.it.y)),"Z"!=s&&"XZ"!=s&&"ZY"!=s||(this.it.z=i.Vector3.Dot(t,this.nt)/this.nt.length(),this.Yt.scaling.z<0&&(this.it.z=-this.it.z));var h=this.At;if(this.it.x=this.it.x/h.x,this.it.y=this.it.y/h.y,this.it.z=this.it.z/h.z,"ALL"==s){var n=i.Vector3.Dot(t,this.Zt.upVector);n/=Math.max(h.x,h.y,h.z),this.it.copyFromFloats(n,n,n)}else{var u=!1;if("XZ"==s?(u=!0,Math.abs(this.it.x)>Math.abs(this.it.z)?this.it.z=this.it.x:this.it.x=this.it.z):"ZY"==s?(u=!0,Math.abs(this.it.z)>Math.abs(this.it.y)?this.it.y=this.it.z:this.it.z=this.it.y):"YX"==s&&(u=!0,Math.abs(this.it.y)>Math.abs(this.it.x)?this.it.x=this.it.y:this.it.y=this.it.x),u){this.Ot.position.subtractToRef(this.Zt.position,this._);n=i.Vector3.Dot(t,this._);this.it.x=Math.abs(this.it.x),this.it.y=Math.abs(this.it.y),this.it.z=Math.abs(this.it.z),n>0?(this.Yt.scaling.x>0&&(this.it.x=-this.it.x),this.Yt.scaling.y>0&&(this.it.y=-this.it.y),this.Yt.scaling.z>0&&(this.it.z=-this.it.z)):(this.Yt.scaling.x<0&&(this.it.x=-this.it.x),this.Yt.scaling.y<0&&(this.it.y=-this.it.y),this.Yt.scaling.z<0&&(this.it.z=-this.it.z))}}this.Vi(this.Yt,this.it),this.Wi&&(this.Yt.scaling.x=Math.max(this.Yt.scaling.x,this.Wi.x),this.Yt.scaling.y=Math.max(this.Yt.scaling.y,this.Wi.y),this.Yt.scaling.z=Math.max(this.Yt.scaling.z,this.Wi.z)),this.$i&&(this.Yt.scaling.x=Math.min(this.Yt.scaling.x,this.$i.x),this.Yt.scaling.y=Math.min(this.Yt.scaling.y,this.$i.y),this.Yt.scaling.z=Math.min(this.Yt.scaling.z,this.$i.z))},s.prototype.Vi=function(t,s){if(this.W){var h=!1;if(this.$.addInPlace(s),Math.abs(this.$.x)>this.tt&&(s.x>0?s.x=this.tt:s.x=-this.tt,h=!0),Math.abs(this.$.y)>this.tt&&(s.y>0?s.y=this.tt:s.y=-this.tt,h=!0),Math.abs(this.$.z)>this.tt&&(s.z>0?s.z=this.tt:s.z=-this.tt,h=!0),!h)return;Math.abs(s.x)!==this.tt&&0!==s.x&&(s.x=0),Math.abs(s.y)!==this.tt&&0!==s.y&&(s.y=0),Math.abs(s.z)!==this.tt&&0!==s.z&&(s.z=0),i.Vector3.FromFloatsToRef(0,0,0,this.$),h=!1}t.scaling.addInPlace(s)},s.prototype.St=function(t){var s=t.getWorldMatrix();i.Vector3.FromArrayToRef(s.m,0,this.st),i.Vector3.FromArrayToRef(s.m,4,this.ht),i.Vector3.FromArrayToRef(s.m,8,this.nt)},s.prototype.jt=function(t){if(t instanceof i.AbstractMesh){var s=t.getBoundingInfo().boundingBox,h=s.maximum.subtract(s.minimum);return 0==h.x&&(h.x=1),0==h.y&&(h.y=1),0==h.z&&(h.z=1),h}return new i.Vector3(1,1,1)},s.prototype.refreshBoundingInfo=function(){this.At=this.jt(this.Yt)},s.prototype.Di=function(t,s,h,n){this.i&&null!=this.Yt.parent&&this.$t(t)?this.St(this.Ot):this.St(t);var u,e=0;s==this.ti?u=this.i?this.st:i.Axis.X:s==this.ii?u=this.i?this.ht:i.Axis.Y:s==this.si&&(u=this.i?this.nt:i.Axis.Z),this.Ot.position.subtractToRef(this.Zt.position,this._),this.P?(e=this.ts(n,h,this.Zt.position,this._,u),this.zt.useRightHandedSystem&&(e=-e)):e=this.ss(n,h,t.getAbsolutePivotPoint(),this._),this.g&&(e=-e),this.u&&(this.et+=e,e=0,Math.abs(this.et)>=this.v&&(e=this.et>0?this.v:-this.v,this.et=0)),0!==e&&(this._.normalize(),s==this.Xi?t.rotate(this._,-e,i.Space.WORLD):(i.Vector3.Dot(u,this._)>=0&&(e=-e),t.rotate(u,e,i.Space.WORLD)),this.ut&&(t.rotation=t.rotationQuaternion.toEulerAngles(),t.rotationQuaternion=null),this.i&&(this.g&&(e=-e),null!=this.Yt.parent&&this.$t(t)&&(s==this.Xi?this.Ot.rotate(this._,-e,i.Space.WORLD):this.Ot.rotate(u,e,i.Space.WORLD))))},s.prototype.Oi=function(){var t=this,i=this.zt.getEngine(),s=i.isPointerLock?.5*this.bt.width:this.zt.pointerX,h=i.isPointerLock?.5*this.bt.height:this.zt.pointerY,n=this.zt.pick(s,h,(function(i){return i==t.mi}),null,this.Zt);return n.hit?n.pickedPoint:null},s.prototype.Qi=function(){this.zi.visibility=0,this.yi.visibility=0,this.Ai.visibility=0},s.prototype.getRotationQuaternion=function(){return this.Ot.rotationQuaternion},s.prototype.getPosition=function(){return this.Ot.position},s.prototype.isTranslationEnabled=function(){return this.rt},s.prototype.enableTranslation=function(){this.D||(null==this.vi&&(this.hs(),this.ns.parent=this.Ot),this.qi(),this.rt||(this.us(this.es,this.R),this.rt=!0,this.disableRotation(),this.disableScaling()))},s.prototype.disableTranslation=function(){this.rt&&(this.us(this.es,0),this.rt=!1)},s.prototype.isRotationEnabled=function(){return this.ot},s.prototype.returnEuler=function(t){this.ut=t},s.prototype.enableRotation=function(){this.D||(null==this.rs&&(this.os(),this.rs.parent=this.Ot),this.qi(),this.ot||(this.us(this.fs,this.R),this.ot=!0,this.disableTranslation(),this.disableScaling()))},s.prototype.disableRotation=function(){this.ot&&(this.us(this.fs,0),this.ot=!1)},s.prototype.isScalingEnabled=function(){return this.ft},s.prototype.enableScaling=function(){this.D||(null==this.Yi&&(this.ls(),this.cs.parent=this.Ot),this.qi(),this.ft||(this.us(this.vs,this.R),this.ft=!0,this.disableTranslation(),this.disableRotation()))},s.prototype.disableScaling=function(){this.ft&&(this.us(this.vs,0),this.ft=!1)},s.prototype.setScaleBounds=function(t,i){this.Wi=t||null,this.$i=i||null,null!=this.Wi&&(0==this.Wi.x&&(this.Wi.x=1e-8),0==this.Wi.y&&(this.Wi.y=1e-8),0==this.Wi.z&&(this.Wi.z=1e-8))},s.prototype.removeScaleBounds=function(){this.Wi=null,this.$i=null},s.prototype.setTransBounds=function(t,i){this.Pi=t||null,this.Ui=i||null},s.prototype.removeTransBounds=function(){this.Pi=null,this.Ui=null},s.prototype.setRotBounds=function(t,i){this.ws=t||null,this.Ms=i||null},s.prototype.removeRotBounds=function(){this.ws=null,this.Ms=null},s.prototype.Et=function(){var t=new i.Mesh("",this.zt);this.zi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(-100,0,0),new i.Vector3(100,0,0)]},this.zt),this.yi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,-100,0),new i.Vector3(0,100,0)]},this.zt),this.Ai=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,-100),new i.Vector3(0,0,100)]},this.zt),this.zi.isPickable=!1,this.yi.isPickable=!1,this.Ai.isPickable=!1,this.zi.parent=t,this.yi.parent=t,this.Ai.parent=t,this.zi.color=this.A,this.yi.color=this.j,this.Ai.color=this.S,this.Qi();var s=this.M*this.p*.75;return this.oi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,0),new i.Vector3(s,0,0)]},this.zt),this.fi=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,0),new i.Vector3(0,s,0)]},this.zt),this.li=i.MeshBuilder.CreateLines("",{points:[new i.Vector3(0,0,0),new i.Vector3(0,0,s)]},this.zt),this.oi.isPickable=!1,this.fi.isPickable=!1,this.li.isPickable=!1,this.oi.parent=t,this.fi.parent=t,this.li.parent=t,this.oi.color=this.A,this.fi.color=this.j,this.li.color=this.S,this.oi.renderingGroupId=1,this.fi.renderingGroupId=1,this.li.renderingGroupId=1,t},s.prototype.Rt=function(){this.Gt=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Hi=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Ii=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Ji=i.MeshBuilder.CreatePlane("",{size:5},this.zt),this.Gt.isPickable=!1,this.Hi.isPickable=!1,this.Ii.isPickable=!1,this.Ji.isPickable=!1,this.Gt.visibility=0,this.Hi.visibility=0,this.Ii.visibility=0,this.Ji.visibility=0,this.Gt.renderingGroupId=1,this.Hi.renderingGroupId=1,this.Ii.renderingGroupId=1,this.Ji.renderingGroupId=1,this.Gt.lookAt(this.Zt.position),this.Hi.rotate(i.Axis.X,1.57),this.Ii.rotate(i.Axis.Y,1.57);var t=new i.Mesh("",this.zt);return this.Gt.parent=t,this.Hi.parent=t,this.Ii.parent=t,this.Ji.parent=t,t},s.prototype.hs=function(){var t=2*this.L*this.p,s=this.M*this.p;this.ns=new i.Mesh("",this.zt),this.ps(t,s,this.ns,this.zt),this.Xs(t,s,this.zt)},s.prototype.ps=function(t,s,h,n){var u=this.Ys(t/2,s);u.name="X";var e=u.clone("Y"),r=u.clone("Z"),o=2*t,f=i.MeshBuilder.CreatePlane("XZ",{size:o},n),l=i.MeshBuilder.CreatePlane("ZY",{size:o},n),a=i.MeshBuilder.CreatePlane("YX",{size:o},n);f.rotation.x=1.57,l.rotation.y=-1.57,f.position.x=2*t,f.position.z=2*t,l.position.z=2*t,l.position.y=2*t,a.position.y=2*t,a.position.x=2*t,f.bakeCurrentTransformIntoVertices(),l.bakeCurrentTransformIntoVertices(),a.bakeCurrentTransformIntoVertices();var c=i.MeshBuilder.CreateBox("ALL",{size:2*t},n);u.parent=h,e.parent=h,r.parent=h,f.parent=h,l.parent=h,a.parent=h,c.parent=h,u.rotation.y=1.57,e.rotation.x-=1.57,this.vi=u,this.wi=e,this.Mi=r,this.Jt=f,this.Kt=l,this.Pt=a,this.pi=c,this.Zs=[u,e,r,f,l,a,c],this.us(this.Zs,0),this.bs(this.Zs)},s.prototype.Xs=function(t,s,h){var n=s/5,u=i.MeshBuilder.CreateCylinder("",{height:n,diameterTop:0,diameterBottom:t,tessellation:6,subdivisions:1},h),e=u.clone(""),r=u.clone(""),o=2*t,f=i.MeshBuilder.CreatePlane("XZ",{size:o},h),l=i.MeshBuilder.CreatePlane("ZY",{size:o},h),a=i.MeshBuilder.CreatePlane("YX",{size:o},h),c=i.MeshBuilder.CreateBox("ALL",{size:t},h);u.rotation.x=1.57,e.rotation.x=1.57,r.rotation.x=1.57,f.rotation.x=1.57,l.rotation.y=1.57,f.position.x=o,f.position.z=o,l.position.z=o,l.position.y=o,a.position.y=o,a.position.x=o,u.parent=this.vi,e.parent=this.wi,r.parent=this.Mi,f.parent=this.Jt,l.parent=this.Kt,a.parent=this.Pt,c.parent=this.pi,u.position.z=s-n/2,e.position.z=s-n/2,r.position.z=s-n/2,u.material=this.ds,e.material=this.Ls,r.material=this.zs,f.material=this.Ls,l.material=this.ds,a.material=this.zs,c.material=this.ys,this.As=u,this.js=e,this.Ss=r,this.xs=f,this.Os=l,this.Ts=a,this.Es=c,this.es=[u,e,r,f,l,a,c],this.bs(this.es),this.Rs(this.es)},s.prototype.setRotGuideFull=function(t){this.lt=t?360:180,null!=this.rs&&(this.rs.dispose(),this.Xi.dispose(),this.rs=null,this.enableRotation())},s.prototype.os=function(){var t=this.M*this.p*2;this.rs=new i.Mesh("",this.zt),this.gs(t,this.rs),this.ks(t)},s.prototype.gs=function(t,i){var s=this.qs(t/2,this.lt),h=this.qs(t/2,this.lt),n=this.qs(t/2,this.lt),u=this.qs(t/1.75,360);s.name="X",h.name="Y",n.name="Z",u.name="ALL",s.rotation.z=1.57,n.rotation.x=-1.57,s.bakeCurrentTransformIntoVertices(),n.bakeCurrentTransformIntoVertices(),u.rotation.x=1.57,s.parent=i,h.parent=i,n.parent=i,u.parent=this.Gt,this.ti=s,this.ii=h,this.si=n,this.Xi=u,this.Cs=[s,h,n,u],this.us(this.Cs,0),this.bs(this.Cs)},s.prototype.ks=function(t){var s=this._s(t/2,this.lt,!1),h=s.clone(""),n=s.clone(""),u=this._s(t/1.75,360,!1),e=this._s(t/2,360,!1);s.parent=this.ti,h.parent=this.ii,n.parent=this.si,s.rotation.z=1.57,n.rotation.x=-1.57,u.parent=this.Xi,e.parent=this.Xi,s.color=this.A,h.color=this.j,n.color=this.S,u.color=this.T,e.color=i.Color3.Gray(),this.Bs=s,this.Ns=h,this.Qs=n,this.Ds=u,this.Fs=e,this.fs=[s,h,n,u,e],this.bs(this.fs),this.Rs(this.fs)},s.prototype.us=function(t,i){t.map((function(t){return t.visibility=i}))},s.prototype.bs=function(t){t.map((function(t){t.isPickable=!1}))},s.prototype.Rs=function(t){t.map((function(t){return t.renderingGroupId=2}))},s.prototype.Ys=function(t,s){var h=[new i.Vector3(t,t,0),new i.Vector3(-t,t,0),new i.Vector3(-t,-t,0),new i.Vector3(t,-t,0),new i.Vector3(t,t,0)],n=[new i.Vector3(0,0,0),new i.Vector3(0,0,s)];return i.MeshBuilder.ExtrudeShape("",{shape:h,path:n,scale:1,rotation:0,cap:2},this.zt)},s.prototype._s=function(t,s,h){null===s&&(s=360);for(var n,u,e=[],r=3.14/180,o=0,f=0;f<=s;f+=5)n=t*Math.cos(f*r),u=90==f?t:270==f?-t:t*Math.sin(f*r),e[o]=new i.Vector3(n,0,u),o++;if(h){t-=.04;for(f=0;f<=s;f+=5)n=t*Math.cos(f*r),u=90==f?t:270==f?-t:t*Math.sin(f*r),e[o]=new i.Vector3(n,0,u),o++}return i.MeshBuilder.CreateLines("",{points:e},this.zt)},s.prototype.qs=function(t,s){null===s&&(s=360);for(var h,n,u=[],e=3.14/180,r=0,o=0;o<=s;o+=30)h=t*Math.cos(o*e),n=90==o?t:270==o?-t:t*Math.sin(o*e),u[r]=new i.Vector3(h,0,n),r++;return i.MeshBuilder.CreateTube("",{path:u,radius:this.L*this.p*2,tessellation:3,cap:i.Mesh.NO_CAP},this.zt)},s.prototype.ls=function(){var t=2*this.L*this.p,s=this.M*this.p;this.cs=new i.Mesh("",this.zt),this.Gs(t,s,this.cs),this.Hs(t,s)},s.prototype.Gs=function(t,s,h){var n=this.Ys(t/2,s);n.name="X";var u=n.clone("Y"),e=n.clone("Z"),r=i.MeshBuilder.CreatePlane("XZ",{size:2*t},this.zt),o=i.MeshBuilder.CreatePlane("ZY",{size:2*t},this.zt),f=i.MeshBuilder.CreatePlane("YX",{size:2*t},this.zt);r.rotation.x=1.57,o.rotation.y=-1.57,r.position.x=2*t,r.position.z=2*t,o.position.z=2*t,o.position.y=2*t,f.position.y=2*t,f.position.x=2*t,r.bakeCurrentTransformIntoVertices(),o.bakeCurrentTransformIntoVertices(),f.bakeCurrentTransformIntoVertices();var l=i.MeshBuilder.CreateBox("ALL",{size:2*t},this.zt);n.parent=h,u.parent=h,e.parent=h,l.parent=h,r.parent=h,o.parent=h,f.parent=h,n.rotation.y=1.57,u.rotation.x-=1.57,this.Yi=n,this.Zi=u,this.bi=e,this.Ut=r,this.Vt=o,this.Wt=f,this.di=l,this.Is=[n,u,e,r,o,f,l],this.us(this.Is,0),this.bs(this.Is)},s.prototype.Hs=function(t,s){var h=i.MeshBuilder.CreateBox("",{size:t},this.zt),n=h.clone(""),u=h.clone(""),e=2*t,r=i.MeshBuilder.CreatePlane("XZ",{size:e},this.zt),o=i.MeshBuilder.CreatePlane("ZY",{size:e},this.zt),f=i.MeshBuilder.CreatePlane("YX",{size:e},this.zt),l=i.MeshBuilder.CreateBox("ALL",{size:t},this.zt);r.rotation.x=1.57,o.rotation.y=-1.57,r.position.x=e,r.position.z=e,o.position.z=e,o.position.y=e,f.position.y=e,f.position.x=e,h.parent=this.Yi,n.parent=this.Zi,u.parent=this.bi,r.parent=this.Ut,o.parent=this.Vt,f.parent=this.Wt,l.parent=this.di,h.position.z=s-t/2,n.position.z=s-t/2,u.position.z=s-t/2,h.material=this.ds,n.material=this.Ls,u.material=this.zs,r.material=this.Ls,o.material=this.ds,f.material=this.zs,l.material=this.ys,this.Js=h,this.Ks=n,this.Ps=u,this.Us=r,this.Vs=o,this.Ws=f,this.$s=l,this.vs=[h,n,u,r,o,f,l],this.bs(this.vs),this.Rs(this.vs)},s.prototype.setVisibility=function(t){this.R=t},s.prototype.setLocal=function(t){this.i!=t&&(this.i=t,t||(this.Ot.rotationQuaternion=i.Quaternion.Identity()))},s.prototype.isLocal=function(){return this.i},s.prototype.setTransSnap=function(t){this.h=t},s.prototype.isTransSnap=function(){return this.h},s.prototype.setRotSnap=function(t){this.u=t},s.prototype.isRotSnap=function(){return this.u},s.prototype.setScaleSnap=function(t){this.W=t},s.prototype.isScaleSnap=function(){return this.W},s.prototype.setTransSnapValue=function(t){this.ct.copyFromFloats(t,t,t),this.l=t},s.prototype.getTransSnapValue=function(){return this.l},s.prototype.setRotSnapValue=function(t){this.v=t},s.prototype.getRotSnapValue=function(){return this.v},s.prototype.setScaleSnapValue=function(t){this.tt=t},s.prototype.getScaleSnapValue=function(){return this.tt},s.prototype.ts=function(t,s,h,n,u){var e=i.Vector3.Dot(n,u);u.scaleToRef(e,this.vt),h.addToRef(this.vt,this.wt);var r=this.wt;this.Zt.getWorldMatrix().invertToRef(this.Xt),i.Vector3.TransformCoordinatesToRef(this.wt,this.Xt,this.wt);var o=0;r.x>=0&&r.y>=0?o=1:r.x<=0&&r.y>=0?o=2:r.x<=0&&r.y<=0?o=3:r.x>=0&&r.y<=0&&(o=4),i.Vector3.TransformCoordinatesToRef(t,this.Xt,this.vt),i.Vector3.TransformCoordinatesToRef(s,this.Xt,this.wt),this.wt.subtractInPlace(this.vt);var f=this.wt,l=f.length(),a="";f.x>=0&&f.y>=0?a=f.x>=f.y?"r":"u":f.x<=0&&f.y>=0?a=-f.x>=f.y?"l":"u":f.x<=0&&f.y<=0?a=-f.x>=-f.y?"l":"d":f.x>=0&&f.y<=0&&(a=f.x>=-f.y?"r":"d");var c=0;return"d"==a?c=1==o||4==o?1:-1:"u"==a?c=1==o||4==o?-1:1:"r"==a?c=2==o||1==o?1:-1:"l"==a&&(c=2==o||1==o?-1:1),c*l},s.prototype.ss=function(t,s,h,n){t.subtractToRef(h,this.vt),s.subtractToRef(h,this.wt),i.Vector3.CrossToRef(this.vt,this.wt,this.Mt);var u=Math.asin(this.Mt.length()/(this.vt.length()*this.wt.length()));return i.Vector3.Dot(this.Mt,n)>0&&(u*=-1),u},s.th=function(t,s){var h=new i.StandardMaterial("",s);return h.emissiveColor=t,h.diffuseColor=i.Color3.Black(),h.specularColor=i.Color3.Black(),h.backFaceCulling=!1,h},s.prototype.Tt=function(t){this.ds=s.th(this.A,t),this.Ls=s.th(this.j,t),this.zs=s.th(this.S,t),this.Bi=s.th(this.O,t),this.ys=s.th(this.T,t)},s.prototype.ci=function(){this.ds.dispose(),this.Ls.dispose(),this.zs.dispose(),this.Bi.dispose(),this.ys.dispose()},s}(),u=function(){function t(t,i){this.lastMax=10,this.acts=new Array,this.last=-1,this.current=-1,this.mesh=t,this.lastMax=i-1,this.add()}return t.prototype.setCapacity=function(t){0!=t?(this.lastMax=t-1,this.last=-1,this.current=-1,this.acts=new Array,this.add()):console.error("capacity should be more than zero")},t.prototype.add=function(t){void 0===t&&(t=null);var i=new e(this.mesh,t);this.current0){var t=this.acts[this.current].getActionType();return this.current--,this.acts[this.current].perform(this.mesh),t}},t.prototype.redo=function(){if(this.current5VrLdpswEP0aL9PDyzhdxkmavs9p0ybtUjEKqBESlYRt+vXVgGSMAdtpG9MkG4NGAuF774xGAyP/NF1eCJQlH3iE6chzouXIPxt5nuv5nj6ApTAW1w0qSyxIZGy14ZL8wsboGGtOIiwbAxXnVJGsaZxxxvBMNWxICL5oDrvltDlrhmLcMlzOEG1br0mkksp67E1q+2tM4sTO7IYvq54U2cHmn8gERXyxZvLPR/6p4FxVZ+nyFFNAz+Jy/aa4pu/vwou3n+RP9HX67svHq6PqZq/uc8nqLwjM1L+9tV/deo5obvCKsQKKEqx/da9DucZSH3NGoGOuOeJC6jN+uxqXYpkYjFRhgRc8ZxGGyd2RP10kROHLDM2gd6G1pm2JSqnpvuVMGe24GthpTJEE4h19LpXgdyvyYPSKCejeExwD4hwLhZdr0jBgXWCeYiUKPcT2hoZ3o/xj01zUKnKtNJI1BQXGhqQF1N65JkefGH66ufo0Po6d4rxI+K+j0D3x5OIqOHLHLYxxpLVumlyohMecIXpeW6c1C4BVPeY955lB8wdWqjDgo1zxJjMaVVF8M9eXje/QeDG2zbPleudZ0aAFHnDDD/fjSfJczPA2NEwsQQIUu2Vc0M2ywBQpMm8+3b/nrO1gOtBpRefgRi0+5YKkFDG822F61LwvwP2q95qqD9qq95wO1YfOQ8neayMoMFI67oQoBVTYjcxKRJyMzO7gABDKgQPSDmq2qKWXm6BJjR8OHZHa4hY4JlJhAevDHA6nGhemD3kGAHDCqk48ByT0YyIWUSyePllBhyMdlqygRZbUwVOVoVBDLQiLnzwLY29oFpzeaAYJp2YB0afvDKsV5BA0dC6CkzYNCS4XD5pAcivKXyJlDusM1Y8zvdFxK4zh7EcuwW1kmSkj2JRQNLTv7MnQfRLgDdLcwX3HbZNmfWfG05TrdeZVud2EyZfPIAP4D/Yk7VXF+ovMEGvAH/7MYatcAnu0ME93oocETgWaHWD9bBe71TzaXE1VXdQifficOvjDnNobPxRtYb8n3ZD4EbtPz2bP3MbfyAaG9p6OVcjSIFNUXo+W5OkT4U6GZsJ1WyAftLZSl1O+j9arKX9cW9karXcWV0x82FlcmXSzfKDaSjuKoYz8h/F/s6Yy6cikOhcA338wvbdDD2bohuIvAjGJgD5YcB9f3Anvkz8Nnz4d99DwmavnQYE7eBHLfdnDAbxEeqRFkXtR0JWPHpYCO1lXIlQGJBuPnJOuvHT4CL+Z4Yd7p/gPVzbfsluGOjkoHJZ4gHeV8DuIRaNHXEBfey+7T012cN13vB2yHLFS7x1MzTh7flQNX3zyghbIz/ntq8kfd+4Q+mj+2y2CbtZfXpR9ax+w+Oe/AQ==
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "babylonjs-editcontrol",
3 | "version": "3.3.0",
4 | "description": "A transform control for Babylonjs mesh",
5 | "repository": {
6 | "type": "git",
7 | "url": "git://github.com/ssatguru/BabylonJS-EditControl.git"
8 | },
9 | "keywords": [
10 | "babylonjs",
11 | "transform control",
12 | "widget",
13 | "gizmo"
14 | ],
15 | "author": "satguru ",
16 | "license": "Apache-2.0",
17 | "contributors": [],
18 | "main": "dist/EditControl.js",
19 | "types": "dist/EditControl.d.ts",
20 | "dependencies": {},
21 | "devDependencies": {
22 | "babylonjs": "^5.41.0",
23 | "babylonjs-gui": "^5.41.0",
24 | "babylonjs-inspector": "^5.41.0",
25 | "pepjs": "^0.4.3",
26 | "terser-webpack-plugin": "^5.3.6",
27 | "ts-loader": "^9.4.2",
28 | "typescript": "^4.9.4",
29 | "webpack": "^5.75.0",
30 | "webpack-cli": "^5.0.1",
31 | "webpack-dev-server": "^4.11.1"
32 | },
33 | "scripts": {
34 | "build-prod": "webpack --mode production",
35 | "build": "webpack",
36 | "start": "webpack-dev-server --open /tst/test.html"
37 | }
38 | }
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "declaration":true,
4 | "target": "es5",
5 | "module": "es2015",
6 | "moduleResolution": "node",
7 | "sourceMap": true,
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "removeComments": false,
11 | "noImplicitAny": false,
12 | "outDir":"dist"
13 | },
14 | "include": ["src/EditControl.ts"]
15 | }
16 |
17 |
--------------------------------------------------------------------------------
/tst/comprehensive.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | EditControl Test
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | box1 is parent of box2 and box2 is parent of box3
27 |
28 |
29 |
30 |
31 | select
32 | box1 box2 box3
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
local global
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
snap translation
54 |
snap rotation
55 |
snap scale
56 |
57 |
58 |
bound translation
59 |
bound rotation
60 |
bound scale
61 |
62 |
63 |
64 |
full rotation guides
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
--------------------------------------------------------------------------------
/tst/comprehensive.js:
--------------------------------------------------------------------------------
1 | //import {EditControl} from 'babylonjs-editcontrol';
2 | //import * as BABYLON from 'babylonjs';
3 | var box, box1, box2, box3;
4 | var commonEC, ec1, ec2, ec3;
5 | //let camera;
6 | window.onload = function () {
7 | main();
8 | };
9 | var main = function () {
10 | var canvas = document.getElementById("renderCanvas");
11 | var engine = new BABYLON.Engine(canvas, true);
12 | var scene = addScene(engine);
13 | var camera = addCamera(scene, canvas);
14 | scene.debugLayer.show({ showExplorer: true, embedMode: true });
15 |
16 | addGrid(scene);
17 | addBoxes(scene);
18 | addEditControls(camera, canvas);
19 | setButtons(camera);
20 | engine.runRenderLoop(function () {
21 | scene.render();
22 | });
23 | window.addEventListener("resize", function () {
24 | engine.resize();
25 | });
26 | };
27 | var addScene = function (engine) {
28 | var scene = new BABYLON.Scene(engine);
29 | scene.clearColor = new BABYLON.Color4(0.75, 0.75, 0.75, 1);
30 | var light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
31 | light.intensity = 0.5;
32 | return scene;
33 | };
34 | var addCamera = function (scene, canvas) {
35 | var camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", Math.PI / 4, Math.PI / 4, 20, new BABYLON.Vector3(0, 0, 0), scene);
36 | camera.wheelPrecision = 15;
37 | camera.setTarget(BABYLON.Vector3.Zero());
38 | camera.attachControl(canvas, false);
39 | return camera;
40 | };
41 | var addGrid = function (scene) {
42 | var ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 10, scene);
43 | var gridMaterial = new BABYLON.StandardMaterial("Grid Material", scene);
44 | gridMaterial.wireframe = true;
45 | ground.material = gridMaterial;
46 | };
47 | var addBoxes = function (scene) {
48 | var mat1 = new BABYLON.StandardMaterial("mat", scene);
49 | var mat2 = new BABYLON.StandardMaterial("mat2", scene);
50 | var mat3 = new BABYLON.StandardMaterial("mat3", scene);
51 | mat1.diffuseColor = BABYLON.Color3.Red();
52 | mat2.diffuseColor = BABYLON.Color3.Teal();
53 | mat3.diffuseColor = BABYLON.Color3.Magenta();
54 | box1 = BABYLON.MeshBuilder.CreateBox("box1", { height: 5, width: 3, depth: 2 });
55 | box2 = BABYLON.MeshBuilder.CreateBox("box2", { height: 3, width: 2, depth: 1 });
56 | box3 = BABYLON.MeshBuilder.CreateBox("box3", { height: 2, width: 1, depth: 2 });
57 | box1.rotationQuaternion = BABYLON.Quaternion.Identity();
58 | box2.rotationQuaternion = BABYLON.Quaternion.Identity();
59 | box3.rotationQuaternion = BABYLON.Quaternion.Identity();
60 | box1.position = new BABYLON.Vector3(0, 1, 0);
61 | box2.position = new BABYLON.Vector3(-4, 0, 0);
62 | box3.position = new BABYLON.Vector3(-4, 0, 0);
63 | box1.material = mat1;
64 | box2.material = mat2;
65 | box3.material = mat3;
66 | box2.parent = box1;
67 | box3.parent = box2;
68 | };
69 | var addEditControls = function (camera, canvas) {
70 | ec1 = attachEditControl(box1, camera, canvas);
71 | ec2 = attachEditControl(box2, camera, canvas);
72 | ec3 = attachEditControl(box3, camera, canvas);
73 | box = box1;
74 | commonEC = ec1;
75 | };
76 | var attachEditControl = function (mesh, camera, canvas) {
77 | mesh.rotationQuaternion = BABYLON.Quaternion.Identity();
78 | var ec = new EditControl(mesh, camera, canvas, 0.5, false);
79 | ec.enableTranslation();
80 | ec.setRotSnapValue(3.14 / 18);
81 | ec.setTransSnapValue(0.5);
82 | ec.setScaleSnapValue(0.25);
83 | ec.addActionStartListener(actionStartListener);
84 | ec.addActionListener(actionListener);
85 | ec.addActionEndListener(actionEndListener);
86 | return ec;
87 | };
88 | var actionStartListener = function (actionType) {
89 | if (actionType === 0) {
90 | console.log("translation started");
91 | } else if (actionType === 1) {
92 | console.log("rotation started");
93 | } else if (actionType === 2) {
94 | console.log("scaling started");
95 | }
96 | };
97 | var actionListener = function (actionType) {
98 | if (actionType === 0) {
99 | console.log("translating");
100 | } else if (actionType === 1) {
101 | //console.log("rotating");
102 | } else if (actionType === 2) {
103 | console.log("scaling");
104 | }
105 | };
106 | var actionEndListener = function (actionType) {
107 | if (actionType === 0) {
108 | console.log("translation done");
109 | } else if (actionType === 1) {
110 | console.log("rotation done");
111 | } else if (actionType === 2) {
112 | console.log("scaling done");
113 | }
114 | };
115 | var setButtons = function (camera) {
116 | var hideButton = document.getElementById("hide");
117 | hideButton.onclick = function () {
118 | if (commonEC.isHidden()) {
119 | commonEC.show();
120 | } else commonEC.hide();
121 | };
122 | var transButton = document.getElementById("trans");
123 | var rotButton = document.getElementById("rotate");
124 | var scaleButton = document.getElementById("scale");
125 | transButton.onclick = function () {
126 | commonEC.enableTranslation();
127 | };
128 | rotButton.onclick = function () {
129 | commonEC.enableRotation();
130 | };
131 | scaleButton.onclick = function () {
132 | commonEC.enableScaling();
133 | if (!commonEC.isLocal()) {
134 | alert("Please note that you cannot scale in global mode");
135 | }
136 | };
137 | var snapTButton = document.getElementById("snaptrans");
138 | var snapRButton = document.getElementById("snaprot");
139 | var snapSButton = document.getElementById("snapscale");
140 | snapTButton.checked = false;
141 | snapRButton.checked = false;
142 | snapSButton.checked = false;
143 | snapTButton.onclick = function () {
144 | commonEC.setTransSnap(snapTButton.checked);
145 | };
146 | snapRButton.onclick = function () {
147 | commonEC.setRotSnap(snapRButton.checked);
148 | };
149 | snapSButton.onclick = function () {
150 | commonEC.setScaleSnap(snapSButton.checked);
151 | };
152 | var boundTButton = document.getElementById("boundTrans");
153 | var boundRButton = document.getElementById("boundRot");
154 | var boundSButton = document.getElementById("boundScale");
155 | boundTButton.checked = false;
156 | boundRButton.checked = false;
157 | boundSButton.checked = false;
158 | boundTButton.onclick = function () {
159 | if (boundTButton.checked) {
160 | commonEC.setTransBounds(
161 | new BABYLON.Vector3(-5, -5, -5), // min
162 | new BABYLON.Vector3(5, 5, 5) // max
163 | );
164 | } else {
165 | commonEC.removeTransBounds();
166 | }
167 | };
168 | boundRButton.onclick = function () {
169 | alert("Rotation Bounds has not been implemented yet");
170 | };
171 | boundSButton.onclick = function () {
172 | if (boundSButton.checked) {
173 | commonEC.setScaleBounds(
174 | // new BABYLON.Vector3(0.00000001,0.00000001,0.00000001), // works
175 | new BABYLON.Vector3(0, 0, 0), // causes bug
176 | new BABYLON.Vector3(2, 2, 2) // max
177 | );
178 | } else {
179 | commonEC.removeScaleBounds();
180 | }
181 | };
182 | var rotGuideFull = document.getElementById("rotGuideFull");
183 | rotGuideFull.checked = false;
184 | rotGuideFull.onclick = function () {
185 | commonEC.setRotGuideFull(rotGuideFull.checked);
186 | };
187 | var undoButton = document.getElementById("undo");
188 | var redoButton = document.getElementById("redo");
189 | undoButton.onclick = function () {
190 | commonEC.undo();
191 | };
192 | redoButton.onclick = function () {
193 | commonEC.redo();
194 | };
195 | var focusButton = document.getElementById("focus");
196 | focusButton.onclick = function () {
197 | camera.target.copyFrom(box.getAbsolutePosition());
198 | };
199 | var pRotButton = document.getElementById("pRot");
200 | var eulerButton = document.getElementById("euler");
201 | pRotButton.onclick = function () {
202 | console.log(box.rotation);
203 | console.log(box.rotationQuaternion);
204 | };
205 | var euler = false;
206 | eulerButton.onclick = function () {
207 | euler = !euler;
208 | commonEC.returnEuler(euler);
209 | console.log("enable euler : " + euler);
210 | };
211 | var selectBox1 = document.getElementById("selectBox1");
212 | var selectBox2 = document.getElementById("selectBox2");
213 | var selectBox3 = document.getElementById("selectBox3");
214 | var switchBox = function () {
215 | if (selectBox1.checked) {
216 | commonEC = ec1;
217 | box = box1;
218 | } else if (selectBox2.checked) {
219 | commonEC = ec2;
220 | box = box2;
221 | } else {
222 | commonEC = ec3;
223 | box = box3;
224 | }
225 | switchSpace();
226 | snapTButton.onclick(null);
227 | snapRButton.onclick(null);
228 | snapSButton.onclick(null);
229 | boundTButton.onclick(null);
230 | boundSButton.onclick(null);
231 | rotGuideFull.onclick(null);
232 | };
233 | selectBox1.onclick = switchBox;
234 | selectBox2.onclick = switchBox;
235 | selectBox3.onclick = switchBox;
236 | var local = document.getElementById("local");
237 | var global = document.getElementById("global");
238 | var switchSpace = function () {
239 | commonEC.setLocal(local.checked);
240 | if (commonEC.isScalingEnabled() && !commonEC.isLocal()) {
241 | alert("Please note that you cannot scale in global mode");
242 | }
243 | };
244 | local.onclick = switchSpace;
245 | global.onclick = switchSpace;
246 | };
247 | //# sourceMappingURL=Test-EditControl.js.map
248 |
--------------------------------------------------------------------------------
/tst/pointerlock.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PointerLock Test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/tst/pointerlock.js:
--------------------------------------------------------------------------------
1 | window.onload = function () {
2 | main();
3 | };
4 |
5 | let main = function () {
6 | let canvas = document.getElementById("renderCanvas");
7 | let engine = new BABYLON.Engine(canvas, true);
8 | let scene = createScene(engine);
9 | let camera = addCamera(scene, canvas);
10 | scene.debugLayer.show({ showExplorer: true, embedMode: true });
11 |
12 | addGUI();
13 | addGrid(scene);
14 | let box = addBox(scene);
15 | let editControl = attachEditControl(box, camera, canvas);
16 | setButtons(editControl, canvas);
17 |
18 | engine.runRenderLoop(function () {
19 | scene.render();
20 | });
21 |
22 | window.addEventListener("resize", function () {
23 | engine.resize();
24 | });
25 | };
26 |
27 | let createScene = function (engine) {
28 | let scene = new BABYLON.Scene(engine);
29 | scene.clearColor = new BABYLON.Color3(0.75, 0.75, 0.75);
30 | let light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
31 | light.intensity = 0.5;
32 | return scene;
33 | };
34 |
35 | let addCamera = function (scene, canvas) {
36 | let camera = new BABYLON.FlyCamera("FlyCamera", new BABYLON.Vector3(10, 10, 10), scene);
37 | camera.setTarget(BABYLON.Vector3.Zero());
38 | camera.attachControl(canvas, false);
39 | return camera;
40 | };
41 |
42 | let addGUI = function () {
43 | let advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
44 | var text1 = new BABYLON.GUI.TextBlock();
45 | text1.text = "X";
46 | text1.color = "black";
47 | text1.fontSize = 24;
48 | advancedTexture.addControl(text1);
49 | };
50 |
51 | let addGrid = function (scene) {
52 | let ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 10, scene);
53 | let gridMaterial = new BABYLON.StandardMaterial("Grid Material", scene);
54 | gridMaterial.wireframe = true;
55 | ground.material = gridMaterial;
56 | };
57 |
58 | let addBox = function (scene) {
59 | let mat = new BABYLON.StandardMaterial("mat", scene);
60 | mat.diffuseColor = new BABYLON.Color3(1, 0, 0);
61 |
62 | box = BABYLON.MeshBuilder.CreateBox("", { height: 5, width: 3, depth: 2 });
63 | box.material = mat;
64 |
65 | return box;
66 | };
67 |
68 | //------------------EDIT COTROL -------------------------------------------------
69 | let attachEditControl = function (mesh, camera, canvas) {
70 | //if we are planning on doing rotation in quaternion then make sure the rotationQuaternion is atleast initialized
71 | //else edit control will throw following exception
72 | //"Eulerian is set to false but the mesh's rotationQuaternion is not set."
73 | mesh.rotationQuaternion = BABYLON.Quaternion.Identity();
74 | mesh.position = new BABYLON.Vector3(0, 1, 0);
75 | //create edit control (mesh to attach to,camera, canvas, scale of editcontrol, if doing rotation in euler)
76 | let ec = new EditControl(mesh, camera, canvas, 0.75, false, 0.02);
77 | //show translation controls
78 | ec.enableTranslation();
79 | return ec;
80 | };
81 |
82 | var isLocked = false;
83 | let setButtons = function (editControl, canvas) {
84 | let transButton = document.getElementById("trans");
85 | let rotButton = document.getElementById("rotate");
86 | let scaleButton = document.getElementById("scale");
87 | let plButton = document.getElementById("pl");
88 |
89 | transButton.onclick = function () {
90 | editControl.enableTranslation();
91 | };
92 | rotButton.onclick = function () {
93 | editControl.enableRotation();
94 | };
95 | scaleButton.onclick = function () {
96 | editControl.enableScaling();
97 | };
98 |
99 | plButton.onclick = function () {
100 | if (!isLocked) {
101 | canvas.requestPointerLock = canvas.requestPointerLock || canvas.msRequestPointerLock || canvas.mozRequestPointerLock || canvas.webkitRequestPointerLock || false;
102 | if (canvas.requestPointerLock) {
103 | canvas.requestPointerLock();
104 | }
105 | } else {
106 | document.exitPointerLock = document.exitPointerLock || document.mozExitPointerLock;
107 | document.exitPointerLock();
108 | }
109 | };
110 | };
111 |
--------------------------------------------------------------------------------
/tst/simple.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Simple EditControl Test
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/tst/simple.js:
--------------------------------------------------------------------------------
1 | window.onload = function () {
2 | main();
3 | };
4 |
5 | let main = function () {
6 | let canvas = document.getElementById("renderCanvas");
7 | let engine = new BABYLON.Engine(canvas, true);
8 | let scene = createScene(engine);
9 | let camera = addCamera(scene, canvas);
10 | scene.debugLayer.show({ showExplorer: true, embedMode: true });
11 |
12 | addGrid(scene);
13 | let box = addBox(scene);
14 | let editControl = attachEditControl(box, camera, canvas);
15 | setButtons(editControl);
16 |
17 | engine.runRenderLoop(function () {
18 | scene.render();
19 | });
20 |
21 | window.addEventListener("resize", function () {
22 | engine.resize();
23 | });
24 | };
25 |
26 | let createScene = function (engine) {
27 | let scene = new BABYLON.Scene(engine);
28 | scene.clearColor = new BABYLON.Color3(0.75, 0.75, 0.75);
29 | let light = new BABYLON.HemisphericLight("light1", new BABYLON.Vector3(0, 1, 0), scene);
30 | light.intensity = 0.5;
31 | return scene;
32 | };
33 |
34 | let addCamera = function (scene, canvas) {
35 | let camera = new BABYLON.ArcRotateCamera("ArcRotateCamera", Math.PI / 4, Math.PI / 4, 20, new BABYLON.Vector3(0, 0, 0), scene);
36 | camera.wheelPrecision = 15;
37 | camera.setTarget(BABYLON.Vector3.Zero());
38 | camera.attachControl(canvas, false);
39 | return camera;
40 | };
41 |
42 | let addGrid = function (scene) {
43 | let ground = BABYLON.Mesh.CreateGround("ground1", 20, 20, 10, scene);
44 | let gridMaterial = new BABYLON.StandardMaterial("Grid Material", scene);
45 | gridMaterial.wireframe = true;
46 | ground.material = gridMaterial;
47 | };
48 |
49 | let addBox = function (scene) {
50 | let mat = new BABYLON.StandardMaterial("mat", scene);
51 | mat.diffuseColor = new BABYLON.Color3(1, 0, 0);
52 |
53 | box = BABYLON.MeshBuilder.CreateBox("box", { height: 5, width: 3, depth: 2 });
54 | box.material = mat;
55 |
56 | return box;
57 | };
58 |
59 | //------------------EDIT COTROL -------------------------------------------------
60 | let attachEditControl = function (mesh, camera, canvas) {
61 | //if we are planning on doing rotation in quaternion then make sure the rotationQuaternion is atleast initialized
62 | //else edit control will throw following exception
63 | //"Eulerian is set to false but the mesh's rotationQuaternion is not set."
64 | mesh.rotationQuaternion = BABYLON.Quaternion.Identity();
65 | mesh.position = new BABYLON.Vector3(0, 1, 0);
66 | //create edit control (mesh to attach to,camera, canvas, scale of editcontrol, if doing rotation in euler)
67 | let ec = new EditControl(mesh, camera, canvas, 0.75, false, 0.02);
68 | //show translation controls
69 | ec.enableTranslation();
70 | return ec;
71 | };
72 |
73 | let setButtons = function (editControl) {
74 | let transButton = document.getElementById("trans");
75 | let rotButton = document.getElementById("rotate");
76 | let scaleButton = document.getElementById("scale");
77 |
78 | transButton.onclick = function () {
79 | editControl.enableTranslation();
80 | };
81 | rotButton.onclick = function () {
82 | editControl.enableRotation();
83 | };
84 | scaleButton.onclick = function () {
85 | editControl.enableScaling();
86 | };
87 | };
88 |
--------------------------------------------------------------------------------
/tst/test.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | overflow: hidden;
4 | width: 100%;
5 | height: 100%;
6 | margin: 0;
7 | padding: 0;
8 | }
9 |
10 | #controls {
11 | position: absolute;
12 | left: 10px;
13 | top: 10px;
14 | }
15 |
16 | #renderCanvas {
17 | position: absolute;
18 | top: 0;
19 | right: 0;
20 | width: 100%;
21 | height: 100%;
22 | touch-action: none;
23 | }
24 |
25 | a {
26 | text-decoration: none;
27 | display: block;
28 | width: 100%;
29 | margin: 0;
30 | }
31 |
32 | table {
33 | border-radius: 10px;
34 | }
35 |
36 | table,
37 | th,
38 | td {
39 | border: 1px solid black;
40 | padding: 5px;
41 | padding-left: 15px;
42 | padding-right: 15px;
43 | border-collapse: collapse;
44 | }
45 |
46 | #overlay {
47 | visibility: hidden;
48 | position: absolute;
49 | left: 0px;
50 | top: 0px;
51 | width: 100%;
52 | height: 100%;
53 | text-align: center;
54 | z-index: 1000;
55 | }
56 |
57 | #overlay div {
58 | width: 400px;
59 | margin: 100px auto;
60 | background-color: #fff;
61 | border: 1px solid #000;
62 | padding: 15px;
63 | text-align: center;
64 | }
65 |
--------------------------------------------------------------------------------
/tst/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |