├── .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 | 28 | 29 | 30 | 34 | 35 | 36 | 40 | 41 | 42 | 43 | 44 | 45 | 78 | 79 | 80 | 84 | 85 |
26 | box1 is parent of box2 and box2 is parent of box3 27 |
31 | select 32 | box1 box2 box3 33 |
37 | 38 | 39 |
local global
46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 74 | 75 | 76 |
snap translationsnap rotationsnap scale
bound translationbound rotationbound scale
full rotation guides
70 | 71 |
72 | 73 |
77 |
81 | 82 | 83 |
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 |

Test Suite

9 | 10 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /tst/w3.css: -------------------------------------------------------------------------------- 1 | /* W3.CSS 4.13 June 2019 by Jan Egil and Borge Refsnes */ 2 | html{box-sizing:border-box}*,*:before,*:after{box-sizing:inherit} 3 | /* Extract from normalize.css by Nicolas Gallagher and Jonathan Neal git.io/normalize */ 4 | html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} 5 | article,aside,details,figcaption,figure,footer,header,main,menu,nav,section{display:block}summary{display:list-item} 6 | audio,canvas,progress,video{display:inline-block}progress{vertical-align:baseline} 7 | audio:not([controls]){display:none;height:0}[hidden],template{display:none} 8 | a{background-color:transparent}a:active,a:hover{outline-width:0} 9 | abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted} 10 | b,strong{font-weight:bolder}dfn{font-style:italic}mark{background:#ff0;color:#000} 11 | small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline} 12 | sub{bottom:-0.25em}sup{top:-0.5em}figure{margin:1em 40px}img{border-style:none} 13 | code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}hr{box-sizing:content-box;height:0;overflow:visible} 14 | button,input,select,textarea,optgroup{font:inherit;margin:0}optgroup{font-weight:bold} 15 | button,input{overflow:visible}button,select{text-transform:none} 16 | button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button} 17 | button::-moz-focus-inner,[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner{border-style:none;padding:0} 18 | button:-moz-focusring,[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring{outline:1px dotted ButtonText} 19 | fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:.35em .625em .75em} 20 | legend{color:inherit;display:table;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto} 21 | [type=checkbox],[type=radio]{padding:0} 22 | [type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto} 23 | [type=search]{-webkit-appearance:textfield;outline-offset:-2px} 24 | [type=search]::-webkit-search-decoration{-webkit-appearance:none} 25 | ::-webkit-file-upload-button{-webkit-appearance:button;font:inherit} 26 | /* End extract */ 27 | html,body{font-family:Verdana,sans-serif;font-size:15px;line-height:1.5}html{overflow-x:hidden} 28 | h1{font-size:36px}h2{font-size:30px}h3{font-size:24px}h4{font-size:20px}h5{font-size:18px}h6{font-size:16px}.w3-serif{font-family:serif} 29 | h1,h2,h3,h4,h5,h6{font-family:"Segoe UI",Arial,sans-serif;font-weight:400;margin:10px 0}.w3-wide{letter-spacing:4px} 30 | hr{border:0;border-top:1px solid #eee;margin:20px 0} 31 | .w3-image{max-width:100%;height:auto}img{vertical-align:middle}a{color:inherit} 32 | .w3-table,.w3-table-all{border-collapse:collapse;border-spacing:0;width:100%;display:table}.w3-table-all{border:1px solid #ccc} 33 | .w3-bordered tr,.w3-table-all tr{border-bottom:1px solid #ddd}.w3-striped tbody tr:nth-child(even){background-color:#f1f1f1} 34 | .w3-table-all tr:nth-child(odd){background-color:#fff}.w3-table-all tr:nth-child(even){background-color:#f1f1f1} 35 | .w3-hoverable tbody tr:hover,.w3-ul.w3-hoverable li:hover{background-color:#ccc}.w3-centered tr th,.w3-centered tr td{text-align:center} 36 | .w3-table td,.w3-table th,.w3-table-all td,.w3-table-all th{padding:8px 8px;display:table-cell;text-align:left;vertical-align:top} 37 | .w3-table th:first-child,.w3-table td:first-child,.w3-table-all th:first-child,.w3-table-all td:first-child{padding-left:16px} 38 | .w3-btn,.w3-button{border:none;display:inline-block;padding:8px 16px;vertical-align:middle;overflow:hidden;text-decoration:none;color:inherit;background-color:inherit;text-align:center;cursor:pointer;white-space:nowrap} 39 | .w3-btn:hover{box-shadow:0 8px 16px 0 rgba(0,0,0,0.2),0 6px 20px 0 rgba(0,0,0,0.19)} 40 | .w3-btn,.w3-button{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none} 41 | .w3-disabled,.w3-btn:disabled,.w3-button:disabled{cursor:not-allowed;opacity:0.3}.w3-disabled *,:disabled *{pointer-events:none} 42 | .w3-btn.w3-disabled:hover,.w3-btn:disabled:hover{box-shadow:none} 43 | .w3-badge,.w3-tag{background-color:#000;color:#fff;display:inline-block;padding-left:8px;padding-right:8px;text-align:center}.w3-badge{border-radius:50%} 44 | .w3-ul{list-style-type:none;padding:0;margin:0}.w3-ul li{padding:8px 16px;border-bottom:1px solid #ddd}.w3-ul li:last-child{border-bottom:none} 45 | .w3-tooltip,.w3-display-container{position:relative}.w3-tooltip .w3-text{display:none}.w3-tooltip:hover .w3-text{display:inline-block} 46 | .w3-ripple:active{opacity:0.5}.w3-ripple{transition:opacity 0s} 47 | .w3-input{padding:8px;display:block;border:none;border-bottom:1px solid #ccc;width:100%} 48 | .w3-select{padding:9px 0;width:100%;border:none;border-bottom:1px solid #ccc} 49 | .w3-dropdown-click,.w3-dropdown-hover{position:relative;display:inline-block;cursor:pointer} 50 | .w3-dropdown-hover:hover .w3-dropdown-content{display:block} 51 | .w3-dropdown-hover:first-child,.w3-dropdown-click:hover{background-color:#ccc;color:#000} 52 | .w3-dropdown-hover:hover > .w3-button:first-child,.w3-dropdown-click:hover > .w3-button:first-child{background-color:#ccc;color:#000} 53 | .w3-dropdown-content{cursor:auto;color:#000;background-color:#fff;display:none;position:absolute;min-width:160px;margin:0;padding:0;z-index:1} 54 | .w3-check,.w3-radio{width:24px;height:24px;position:relative;top:6px} 55 | .w3-sidebar{height:100%;width:200px;background-color:#fff;position:fixed!important;z-index:1;overflow:auto} 56 | .w3-bar-block .w3-dropdown-hover,.w3-bar-block .w3-dropdown-click{width:100%} 57 | .w3-bar-block .w3-dropdown-hover .w3-dropdown-content,.w3-bar-block .w3-dropdown-click .w3-dropdown-content{min-width:100%} 58 | .w3-bar-block .w3-dropdown-hover .w3-button,.w3-bar-block .w3-dropdown-click .w3-button{width:100%;text-align:left;padding:8px 16px} 59 | .w3-main,#main{transition:margin-left .4s} 60 | .w3-modal{z-index:3;display:none;padding-top:100px;position:fixed;left:0;top:0;width:100%;height:100%;overflow:auto;background-color:rgb(0,0,0);background-color:rgba(0,0,0,0.4)} 61 | .w3-modal-content{margin:auto;background-color:#fff;position:relative;padding:0;outline:0;width:600px} 62 | .w3-bar{width:100%;overflow:hidden}.w3-center .w3-bar{display:inline-block;width:auto} 63 | .w3-bar .w3-bar-item{padding:8px 16px;float:left;width:auto;border:none;display:block;outline:0} 64 | .w3-bar .w3-dropdown-hover,.w3-bar .w3-dropdown-click{position:static;float:left} 65 | .w3-bar .w3-button{white-space:normal} 66 | .w3-bar-block .w3-bar-item{width:100%;display:block;padding:8px 16px;text-align:left;border:none;white-space:normal;float:none;outline:0} 67 | .w3-bar-block.w3-center .w3-bar-item{text-align:center}.w3-block{display:block;width:100%} 68 | .w3-responsive{display:block;overflow-x:auto} 69 | .w3-container:after,.w3-container:before,.w3-panel:after,.w3-panel:before,.w3-row:after,.w3-row:before,.w3-row-padding:after,.w3-row-padding:before, 70 | .w3-cell-row:before,.w3-cell-row:after,.w3-clear:after,.w3-clear:before,.w3-bar:before,.w3-bar:after{content:"";display:table;clear:both} 71 | .w3-col,.w3-half,.w3-third,.w3-twothird,.w3-threequarter,.w3-quarter{float:left;width:100%} 72 | .w3-col.s1{width:8.33333%}.w3-col.s2{width:16.66666%}.w3-col.s3{width:24.99999%}.w3-col.s4{width:33.33333%} 73 | .w3-col.s5{width:41.66666%}.w3-col.s6{width:49.99999%}.w3-col.s7{width:58.33333%}.w3-col.s8{width:66.66666%} 74 | .w3-col.s9{width:74.99999%}.w3-col.s10{width:83.33333%}.w3-col.s11{width:91.66666%}.w3-col.s12{width:99.99999%} 75 | @media (min-width:601px){.w3-col.m1{width:8.33333%}.w3-col.m2{width:16.66666%}.w3-col.m3,.w3-quarter{width:24.99999%}.w3-col.m4,.w3-third{width:33.33333%} 76 | .w3-col.m5{width:41.66666%}.w3-col.m6,.w3-half{width:49.99999%}.w3-col.m7{width:58.33333%}.w3-col.m8,.w3-twothird{width:66.66666%} 77 | .w3-col.m9,.w3-threequarter{width:74.99999%}.w3-col.m10{width:83.33333%}.w3-col.m11{width:91.66666%}.w3-col.m12{width:99.99999%}} 78 | @media (min-width:993px){.w3-col.l1{width:8.33333%}.w3-col.l2{width:16.66666%}.w3-col.l3{width:24.99999%}.w3-col.l4{width:33.33333%} 79 | .w3-col.l5{width:41.66666%}.w3-col.l6{width:49.99999%}.w3-col.l7{width:58.33333%}.w3-col.l8{width:66.66666%} 80 | .w3-col.l9{width:74.99999%}.w3-col.l10{width:83.33333%}.w3-col.l11{width:91.66666%}.w3-col.l12{width:99.99999%}} 81 | .w3-rest{overflow:hidden}.w3-stretch{margin-left:-16px;margin-right:-16px} 82 | .w3-content,.w3-auto{margin-left:auto;margin-right:auto}.w3-content{max-width:980px}.w3-auto{max-width:1140px} 83 | .w3-cell-row{display:table;width:100%}.w3-cell{display:table-cell} 84 | .w3-cell-top{vertical-align:top}.w3-cell-middle{vertical-align:middle}.w3-cell-bottom{vertical-align:bottom} 85 | .w3-hide{display:none!important}.w3-show-block,.w3-show{display:block!important}.w3-show-inline-block{display:inline-block!important} 86 | @media (max-width:1205px){.w3-auto{max-width:95%}} 87 | @media (max-width:600px){.w3-modal-content{margin:0 10px;width:auto!important}.w3-modal{padding-top:30px} 88 | .w3-dropdown-hover.w3-mobile .w3-dropdown-content,.w3-dropdown-click.w3-mobile .w3-dropdown-content{position:relative} 89 | .w3-hide-small{display:none!important}.w3-mobile{display:block;width:100%!important}.w3-bar-item.w3-mobile,.w3-dropdown-hover.w3-mobile,.w3-dropdown-click.w3-mobile{text-align:center} 90 | .w3-dropdown-hover.w3-mobile,.w3-dropdown-hover.w3-mobile .w3-btn,.w3-dropdown-hover.w3-mobile .w3-button,.w3-dropdown-click.w3-mobile,.w3-dropdown-click.w3-mobile .w3-btn,.w3-dropdown-click.w3-mobile .w3-button{width:100%}} 91 | @media (max-width:768px){.w3-modal-content{width:500px}.w3-modal{padding-top:50px}} 92 | @media (min-width:993px){.w3-modal-content{width:900px}.w3-hide-large{display:none!important}.w3-sidebar.w3-collapse{display:block!important}} 93 | @media (max-width:992px) and (min-width:601px){.w3-hide-medium{display:none!important}} 94 | @media (max-width:992px){.w3-sidebar.w3-collapse{display:none}.w3-main{margin-left:0!important;margin-right:0!important}.w3-auto{max-width:100%}} 95 | .w3-top,.w3-bottom{position:fixed;width:100%;z-index:1}.w3-top{top:0}.w3-bottom{bottom:0} 96 | .w3-overlay{position:fixed;display:none;width:100%;height:100%;top:0;left:0;right:0;bottom:0;background-color:rgba(0,0,0,0.5);z-index:2} 97 | .w3-display-topleft{position:absolute;left:0;top:0}.w3-display-topright{position:absolute;right:0;top:0} 98 | .w3-display-bottomleft{position:absolute;left:0;bottom:0}.w3-display-bottomright{position:absolute;right:0;bottom:0} 99 | .w3-display-middle{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%)} 100 | .w3-display-left{position:absolute;top:50%;left:0%;transform:translate(0%,-50%);-ms-transform:translate(-0%,-50%)} 101 | .w3-display-right{position:absolute;top:50%;right:0%;transform:translate(0%,-50%);-ms-transform:translate(0%,-50%)} 102 | .w3-display-topmiddle{position:absolute;left:50%;top:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)} 103 | .w3-display-bottommiddle{position:absolute;left:50%;bottom:0;transform:translate(-50%,0%);-ms-transform:translate(-50%,0%)} 104 | .w3-display-container:hover .w3-display-hover{display:block}.w3-display-container:hover span.w3-display-hover{display:inline-block}.w3-display-hover{display:none} 105 | .w3-display-position{position:absolute} 106 | .w3-circle{border-radius:50%} 107 | .w3-round-small{border-radius:2px}.w3-round,.w3-round-medium{border-radius:4px}.w3-round-large{border-radius:8px}.w3-round-xlarge{border-radius:16px}.w3-round-xxlarge{border-radius:32px} 108 | .w3-row-padding,.w3-row-padding>.w3-half,.w3-row-padding>.w3-third,.w3-row-padding>.w3-twothird,.w3-row-padding>.w3-threequarter,.w3-row-padding>.w3-quarter,.w3-row-padding>.w3-col{padding:0 8px} 109 | .w3-container,.w3-panel{padding:0.01em 16px}.w3-panel{margin-top:16px;margin-bottom:16px} 110 | .w3-code,.w3-codespan{font-family:Consolas,"courier new";font-size:16px} 111 | .w3-code{width:auto;background-color:#fff;padding:8px 12px;border-left:4px solid #4CAF50;word-wrap:break-word} 112 | .w3-codespan{color:crimson;background-color:#f1f1f1;padding-left:4px;padding-right:4px;font-size:110%} 113 | .w3-card,.w3-card-2{box-shadow:0 2px 5px 0 rgba(0,0,0,0.16),0 2px 10px 0 rgba(0,0,0,0.12)} 114 | .w3-card-4,.w3-hover-shadow:hover{box-shadow:0 4px 10px 0 rgba(0,0,0,0.2),0 4px 20px 0 rgba(0,0,0,0.19)} 115 | .w3-spin{animation:w3-spin 2s infinite linear}@keyframes w3-spin{0%{transform:rotate(0deg)}100%{transform:rotate(359deg)}} 116 | .w3-animate-fading{animation:fading 10s infinite}@keyframes fading{0%{opacity:0}50%{opacity:1}100%{opacity:0}} 117 | .w3-animate-opacity{animation:opac 0.8s}@keyframes opac{from{opacity:0} to{opacity:1}} 118 | .w3-animate-top{position:relative;animation:animatetop 0.4s}@keyframes animatetop{from{top:-300px;opacity:0} to{top:0;opacity:1}} 119 | .w3-animate-left{position:relative;animation:animateleft 0.4s}@keyframes animateleft{from{left:-300px;opacity:0} to{left:0;opacity:1}} 120 | .w3-animate-right{position:relative;animation:animateright 0.4s}@keyframes animateright{from{right:-300px;opacity:0} to{right:0;opacity:1}} 121 | .w3-animate-bottom{position:relative;animation:animatebottom 0.4s}@keyframes animatebottom{from{bottom:-300px;opacity:0} to{bottom:0;opacity:1}} 122 | .w3-animate-zoom {animation:animatezoom 0.6s}@keyframes animatezoom{from{transform:scale(0)} to{transform:scale(1)}} 123 | .w3-animate-input{transition:width 0.4s ease-in-out}.w3-animate-input:focus{width:100%!important} 124 | .w3-opacity,.w3-hover-opacity:hover{opacity:0.60}.w3-opacity-off,.w3-hover-opacity-off:hover{opacity:1} 125 | .w3-opacity-max{opacity:0.25}.w3-opacity-min{opacity:0.75} 126 | .w3-greyscale-max,.w3-grayscale-max,.w3-hover-greyscale:hover,.w3-hover-grayscale:hover{filter:grayscale(100%)} 127 | .w3-greyscale,.w3-grayscale{filter:grayscale(75%)}.w3-greyscale-min,.w3-grayscale-min{filter:grayscale(50%)} 128 | .w3-sepia{filter:sepia(75%)}.w3-sepia-max,.w3-hover-sepia:hover{filter:sepia(100%)}.w3-sepia-min{filter:sepia(50%)} 129 | .w3-tiny{font-size:10px!important}.w3-small{font-size:12px!important}.w3-medium{font-size:15px!important}.w3-large{font-size:18px!important} 130 | .w3-xlarge{font-size:24px!important}.w3-xxlarge{font-size:36px!important}.w3-xxxlarge{font-size:48px!important}.w3-jumbo{font-size:64px!important} 131 | .w3-left-align{text-align:left!important}.w3-right-align{text-align:right!important}.w3-justify{text-align:justify!important}.w3-center{text-align:center!important} 132 | .w3-border-0{border:0!important}.w3-border{border:1px solid #ccc!important} 133 | .w3-border-top{border-top:1px solid #ccc!important}.w3-border-bottom{border-bottom:1px solid #ccc!important} 134 | .w3-border-left{border-left:1px solid #ccc!important}.w3-border-right{border-right:1px solid #ccc!important} 135 | .w3-topbar{border-top:6px solid #ccc!important}.w3-bottombar{border-bottom:6px solid #ccc!important} 136 | .w3-leftbar{border-left:6px solid #ccc!important}.w3-rightbar{border-right:6px solid #ccc!important} 137 | .w3-section,.w3-code{margin-top:16px!important;margin-bottom:16px!important} 138 | .w3-margin{margin:16px!important}.w3-margin-top{margin-top:16px!important}.w3-margin-bottom{margin-bottom:16px!important} 139 | .w3-margin-left{margin-left:16px!important}.w3-margin-right{margin-right:16px!important} 140 | .w3-padding-small{padding:4px 8px!important}.w3-padding{padding:8px 16px!important}.w3-padding-large{padding:12px 24px!important} 141 | .w3-padding-16{padding-top:16px!important;padding-bottom:16px!important}.w3-padding-24{padding-top:24px!important;padding-bottom:24px!important} 142 | .w3-padding-32{padding-top:32px!important;padding-bottom:32px!important}.w3-padding-48{padding-top:48px!important;padding-bottom:48px!important} 143 | .w3-padding-64{padding-top:64px!important;padding-bottom:64px!important} 144 | .w3-left{float:left!important}.w3-right{float:right!important} 145 | .w3-button:hover{color:#000!important;background-color:#ccc!important} 146 | .w3-transparent,.w3-hover-none:hover{background-color:transparent!important} 147 | .w3-hover-none:hover{box-shadow:none!important} 148 | /* Colors */ 149 | .w3-amber,.w3-hover-amber:hover{color:#000!important;background-color:#ffc107!important} 150 | .w3-aqua,.w3-hover-aqua:hover{color:#000!important;background-color:#00ffff!important} 151 | .w3-blue,.w3-hover-blue:hover{color:#fff!important;background-color:#2196F3!important} 152 | .w3-light-blue,.w3-hover-light-blue:hover{color:#000!important;background-color:#87CEEB!important} 153 | .w3-brown,.w3-hover-brown:hover{color:#fff!important;background-color:#795548!important} 154 | .w3-cyan,.w3-hover-cyan:hover{color:#000!important;background-color:#00bcd4!important} 155 | .w3-blue-grey,.w3-hover-blue-grey:hover,.w3-blue-gray,.w3-hover-blue-gray:hover{color:#fff!important;background-color:#607d8b!important} 156 | .w3-green,.w3-hover-green:hover{color:#fff!important;background-color:#4CAF50!important} 157 | .w3-light-green,.w3-hover-light-green:hover{color:#000!important;background-color:#8bc34a!important} 158 | .w3-indigo,.w3-hover-indigo:hover{color:#fff!important;background-color:#3f51b5!important} 159 | .w3-khaki,.w3-hover-khaki:hover{color:#000!important;background-color:#f0e68c!important} 160 | .w3-lime,.w3-hover-lime:hover{color:#000!important;background-color:#cddc39!important} 161 | .w3-orange,.w3-hover-orange:hover{color:#000!important;background-color:#ff9800!important} 162 | .w3-deep-orange,.w3-hover-deep-orange:hover{color:#fff!important;background-color:#ff5722!important} 163 | .w3-pink,.w3-hover-pink:hover{color:#fff!important;background-color:#e91e63!important} 164 | .w3-purple,.w3-hover-purple:hover{color:#fff!important;background-color:#9c27b0!important} 165 | .w3-deep-purple,.w3-hover-deep-purple:hover{color:#fff!important;background-color:#673ab7!important} 166 | .w3-red,.w3-hover-red:hover{color:#fff!important;background-color:#f44336!important} 167 | .w3-sand,.w3-hover-sand:hover{color:#000!important;background-color:#fdf5e6!important} 168 | .w3-teal,.w3-hover-teal:hover{color:#fff!important;background-color:#009688!important} 169 | .w3-yellow,.w3-hover-yellow:hover{color:#000!important;background-color:#ffeb3b!important} 170 | .w3-white,.w3-hover-white:hover{color:#000!important;background-color:#fff!important} 171 | .w3-black,.w3-hover-black:hover{color:#fff!important;background-color:#000!important} 172 | .w3-grey,.w3-hover-grey:hover,.w3-gray,.w3-hover-gray:hover{color:#000!important;background-color:#9e9e9e!important} 173 | .w3-light-grey,.w3-hover-light-grey:hover,.w3-light-gray,.w3-hover-light-gray:hover{color:#000!important;background-color:#f1f1f1!important} 174 | .w3-dark-grey,.w3-hover-dark-grey:hover,.w3-dark-gray,.w3-hover-dark-gray:hover{color:#fff!important;background-color:#616161!important} 175 | .w3-pale-red,.w3-hover-pale-red:hover{color:#000!important;background-color:#ffdddd!important} 176 | .w3-pale-green,.w3-hover-pale-green:hover{color:#000!important;background-color:#ddffdd!important} 177 | .w3-pale-yellow,.w3-hover-pale-yellow:hover{color:#000!important;background-color:#ffffcc!important} 178 | .w3-pale-blue,.w3-hover-pale-blue:hover{color:#000!important;background-color:#ddffff!important} 179 | .w3-text-amber,.w3-hover-text-amber:hover{color:#ffc107!important} 180 | .w3-text-aqua,.w3-hover-text-aqua:hover{color:#00ffff!important} 181 | .w3-text-blue,.w3-hover-text-blue:hover{color:#2196F3!important} 182 | .w3-text-light-blue,.w3-hover-text-light-blue:hover{color:#87CEEB!important} 183 | .w3-text-brown,.w3-hover-text-brown:hover{color:#795548!important} 184 | .w3-text-cyan,.w3-hover-text-cyan:hover{color:#00bcd4!important} 185 | .w3-text-blue-grey,.w3-hover-text-blue-grey:hover,.w3-text-blue-gray,.w3-hover-text-blue-gray:hover{color:#607d8b!important} 186 | .w3-text-green,.w3-hover-text-green:hover{color:#4CAF50!important} 187 | .w3-text-light-green,.w3-hover-text-light-green:hover{color:#8bc34a!important} 188 | .w3-text-indigo,.w3-hover-text-indigo:hover{color:#3f51b5!important} 189 | .w3-text-khaki,.w3-hover-text-khaki:hover{color:#b4aa50!important} 190 | .w3-text-lime,.w3-hover-text-lime:hover{color:#cddc39!important} 191 | .w3-text-orange,.w3-hover-text-orange:hover{color:#ff9800!important} 192 | .w3-text-deep-orange,.w3-hover-text-deep-orange:hover{color:#ff5722!important} 193 | .w3-text-pink,.w3-hover-text-pink:hover{color:#e91e63!important} 194 | .w3-text-purple,.w3-hover-text-purple:hover{color:#9c27b0!important} 195 | .w3-text-deep-purple,.w3-hover-text-deep-purple:hover{color:#673ab7!important} 196 | .w3-text-red,.w3-hover-text-red:hover{color:#f44336!important} 197 | .w3-text-sand,.w3-hover-text-sand:hover{color:#fdf5e6!important} 198 | .w3-text-teal,.w3-hover-text-teal:hover{color:#009688!important} 199 | .w3-text-yellow,.w3-hover-text-yellow:hover{color:#d2be0e!important} 200 | .w3-text-white,.w3-hover-text-white:hover{color:#fff!important} 201 | .w3-text-black,.w3-hover-text-black:hover{color:#000!important} 202 | .w3-text-grey,.w3-hover-text-grey:hover,.w3-text-gray,.w3-hover-text-gray:hover{color:#757575!important} 203 | .w3-text-light-grey,.w3-hover-text-light-grey:hover,.w3-text-light-gray,.w3-hover-text-light-gray:hover{color:#f1f1f1!important} 204 | .w3-text-dark-grey,.w3-hover-text-dark-grey:hover,.w3-text-dark-gray,.w3-hover-text-dark-gray:hover{color:#3a3a3a!important} 205 | .w3-border-amber,.w3-hover-border-amber:hover{border-color:#ffc107!important} 206 | .w3-border-aqua,.w3-hover-border-aqua:hover{border-color:#00ffff!important} 207 | .w3-border-blue,.w3-hover-border-blue:hover{border-color:#2196F3!important} 208 | .w3-border-light-blue,.w3-hover-border-light-blue:hover{border-color:#87CEEB!important} 209 | .w3-border-brown,.w3-hover-border-brown:hover{border-color:#795548!important} 210 | .w3-border-cyan,.w3-hover-border-cyan:hover{border-color:#00bcd4!important} 211 | .w3-border-blue-grey,.w3-hover-border-blue-grey:hover,.w3-border-blue-gray,.w3-hover-border-blue-gray:hover{border-color:#607d8b!important} 212 | .w3-border-green,.w3-hover-border-green:hover{border-color:#4CAF50!important} 213 | .w3-border-light-green,.w3-hover-border-light-green:hover{border-color:#8bc34a!important} 214 | .w3-border-indigo,.w3-hover-border-indigo:hover{border-color:#3f51b5!important} 215 | .w3-border-khaki,.w3-hover-border-khaki:hover{border-color:#f0e68c!important} 216 | .w3-border-lime,.w3-hover-border-lime:hover{border-color:#cddc39!important} 217 | .w3-border-orange,.w3-hover-border-orange:hover{border-color:#ff9800!important} 218 | .w3-border-deep-orange,.w3-hover-border-deep-orange:hover{border-color:#ff5722!important} 219 | .w3-border-pink,.w3-hover-border-pink:hover{border-color:#e91e63!important} 220 | .w3-border-purple,.w3-hover-border-purple:hover{border-color:#9c27b0!important} 221 | .w3-border-deep-purple,.w3-hover-border-deep-purple:hover{border-color:#673ab7!important} 222 | .w3-border-red,.w3-hover-border-red:hover{border-color:#f44336!important} 223 | .w3-border-sand,.w3-hover-border-sand:hover{border-color:#fdf5e6!important} 224 | .w3-border-teal,.w3-hover-border-teal:hover{border-color:#009688!important} 225 | .w3-border-yellow,.w3-hover-border-yellow:hover{border-color:#ffeb3b!important} 226 | .w3-border-white,.w3-hover-border-white:hover{border-color:#fff!important} 227 | .w3-border-black,.w3-hover-border-black:hover{border-color:#000!important} 228 | .w3-border-grey,.w3-hover-border-grey:hover,.w3-border-gray,.w3-hover-border-gray:hover{border-color:#9e9e9e!important} 229 | .w3-border-light-grey,.w3-hover-border-light-grey:hover,.w3-border-light-gray,.w3-hover-border-light-gray:hover{border-color:#f1f1f1!important} 230 | .w3-border-dark-grey,.w3-hover-border-dark-grey:hover,.w3-border-dark-gray,.w3-hover-border-dark-gray:hover{border-color:#616161!important} 231 | .w3-border-pale-red,.w3-hover-border-pale-red:hover{border-color:#ffe7e7!important}.w3-border-pale-green,.w3-hover-border-pale-green:hover{border-color:#e7ffe7!important} 232 | .w3-border-pale-yellow,.w3-hover-border-pale-yellow:hover{border-color:#ffffcc!important}.w3-border-pale-blue,.w3-hover-border-pale-blue:hover{border-color:#e7ffff!important} -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | var path = require("path"); 2 | const TerserPlugin = require("terser-webpack-plugin"); 3 | var webpack = require("webpack"); 4 | 5 | module.exports = (env, argv) => { 6 | return { 7 | mode: "development", 8 | entry: { 9 | EditControl: "./src/EditControl.ts", 10 | }, 11 | devtool: "source-map", 12 | devServer: { 13 | devMiddleware: { 14 | publicPath: "/dist/", 15 | }, 16 | static: { 17 | directory: "./", 18 | serveIndex: true, 19 | }, 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.tsx?$/, 25 | use: "ts-loader", 26 | exclude: /node_modules/, 27 | }, 28 | ], 29 | }, 30 | resolve: { 31 | extensions: [".tsx", ".ts", ".js"], 32 | }, 33 | output: { 34 | path: path.resolve(__dirname, "dist"), 35 | filename: argv.mode === "production" ? "[name].js" : "[name].max.js", 36 | libraryTarget: "umd", 37 | }, 38 | externals: { 39 | babylonjs: { 40 | commonjs: "babylonjs", 41 | commonjs2: "babylonjs", 42 | amd: "babylonjs", 43 | root: "BABYLON", 44 | }, 45 | }, 46 | optimization: { 47 | minimize: true, 48 | minimizer: [ 49 | new TerserPlugin({ 50 | parallel: true, 51 | terserOptions: { 52 | nameCache: null, 53 | sourceMap: true, // Must be set to true if using source-maps in production 54 | // https://github.com/webpack-contrib/terser-webpack-plugin#terseroptions 55 | ecma: undefined, 56 | mangle: { 57 | // mangle options 58 | properties: { 59 | // mangle property options 60 | //mangle all variables starting with underscore "_" 61 | regex: /^_/, 62 | }, 63 | }, 64 | }, 65 | }), 66 | ], 67 | }, 68 | }; 69 | }; 70 | --------------------------------------------------------------------------------