babylonjs-editcontrol 3.2.5 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -201
- package/README.md +478 -436
- package/dist/EditControl.d.ts +323 -315
- package/dist/EditControl.js +1 -1
- package/dist/EditControl.js.map +1 -1
- package/dist/EditControl.max.js +2055 -2124
- package/dist/EditControl.max.js.map +1 -1
- package/package.json +37 -37
- package/src/EditControl.ts +84 -84
package/dist/EditControl.max.js
CHANGED
|
@@ -7,2148 +7,2079 @@
|
|
|
7
7
|
var a = typeof exports === 'object' ? factory(require("babylonjs")) : factory(root["BABYLON"]);
|
|
8
8
|
for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
|
|
9
9
|
}
|
|
10
|
-
})(
|
|
11
|
-
return /******/ (
|
|
10
|
+
})(self, (__WEBPACK_EXTERNAL_MODULE_babylonjs__) => {
|
|
11
|
+
return /******/ (() => { // webpackBootstrap
|
|
12
|
+
/******/ "use strict";
|
|
13
|
+
/******/ var __webpack_modules__ = ({
|
|
14
|
+
|
|
15
|
+
/***/ "babylonjs"
|
|
16
|
+
/*!****************************************************************************************************!*\
|
|
17
|
+
!*** external {"commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs","root":"BABYLON"} ***!
|
|
18
|
+
\****************************************************************************************************/
|
|
19
|
+
(module) {
|
|
20
|
+
|
|
21
|
+
module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs__;
|
|
22
|
+
|
|
23
|
+
/***/ }
|
|
24
|
+
|
|
25
|
+
/******/ });
|
|
26
|
+
/************************************************************************/
|
|
12
27
|
/******/ // The module cache
|
|
13
|
-
/******/ var
|
|
14
|
-
/******/
|
|
28
|
+
/******/ var __webpack_module_cache__ = {};
|
|
29
|
+
/******/
|
|
15
30
|
/******/ // The require function
|
|
16
31
|
/******/ function __webpack_require__(moduleId) {
|
|
17
|
-
/******/
|
|
18
32
|
/******/ // Check if module is in cache
|
|
19
|
-
/******/
|
|
20
|
-
/******/
|
|
33
|
+
/******/ var cachedModule = __webpack_module_cache__[moduleId];
|
|
34
|
+
/******/ if (cachedModule !== undefined) {
|
|
35
|
+
/******/ return cachedModule.exports;
|
|
36
|
+
/******/ }
|
|
37
|
+
/******/ // Check if module exists (development only)
|
|
38
|
+
/******/ if (__webpack_modules__[moduleId] === undefined) {
|
|
39
|
+
/******/ var e = new Error("Cannot find module '" + moduleId + "'");
|
|
40
|
+
/******/ e.code = 'MODULE_NOT_FOUND';
|
|
41
|
+
/******/ throw e;
|
|
21
42
|
/******/ }
|
|
22
43
|
/******/ // Create a new module (and put it into the cache)
|
|
23
|
-
/******/ var module =
|
|
24
|
-
/******/
|
|
25
|
-
/******/
|
|
44
|
+
/******/ var module = __webpack_module_cache__[moduleId] = {
|
|
45
|
+
/******/ // no module.id needed
|
|
46
|
+
/******/ // no module.loaded needed
|
|
26
47
|
/******/ exports: {}
|
|
27
48
|
/******/ };
|
|
28
|
-
/******/
|
|
49
|
+
/******/
|
|
29
50
|
/******/ // Execute the module function
|
|
30
|
-
/******/
|
|
31
|
-
/******/
|
|
32
|
-
/******/ // Flag the module as loaded
|
|
33
|
-
/******/ module.l = true;
|
|
34
|
-
/******/
|
|
51
|
+
/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
|
|
52
|
+
/******/
|
|
35
53
|
/******/ // Return the exports of the module
|
|
36
54
|
/******/ return module.exports;
|
|
37
55
|
/******/ }
|
|
38
|
-
/******/
|
|
39
|
-
/******/
|
|
40
|
-
/******/ // expose the modules object (__webpack_modules__)
|
|
41
|
-
/******/ __webpack_require__.m = modules;
|
|
42
|
-
/******/
|
|
43
|
-
/******/ // expose the module cache
|
|
44
|
-
/******/ __webpack_require__.c = installedModules;
|
|
45
|
-
/******/
|
|
46
|
-
/******/ // define getter function for harmony exports
|
|
47
|
-
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
48
|
-
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
49
|
-
/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter });
|
|
50
|
-
/******/ }
|
|
51
|
-
/******/ };
|
|
52
|
-
/******/
|
|
53
|
-
/******/ // define __esModule on exports
|
|
54
|
-
/******/ __webpack_require__.r = function(exports) {
|
|
55
|
-
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
|
|
56
|
-
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
57
|
-
/******/ }
|
|
58
|
-
/******/ Object.defineProperty(exports, '__esModule', { value: true });
|
|
59
|
-
/******/ };
|
|
60
|
-
/******/
|
|
61
|
-
/******/ // create a fake namespace object
|
|
62
|
-
/******/ // mode & 1: value is a module id, require it
|
|
63
|
-
/******/ // mode & 2: merge all properties of value into the ns
|
|
64
|
-
/******/ // mode & 4: return value when already ns object
|
|
65
|
-
/******/ // mode & 8|1: behave like require
|
|
66
|
-
/******/ __webpack_require__.t = function(value, mode) {
|
|
67
|
-
/******/ if(mode & 1) value = __webpack_require__(value);
|
|
68
|
-
/******/ if(mode & 8) return value;
|
|
69
|
-
/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
|
|
70
|
-
/******/ var ns = Object.create(null);
|
|
71
|
-
/******/ __webpack_require__.r(ns);
|
|
72
|
-
/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value });
|
|
73
|
-
/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
|
|
74
|
-
/******/ return ns;
|
|
75
|
-
/******/ };
|
|
76
|
-
/******/
|
|
77
|
-
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
78
|
-
/******/ __webpack_require__.n = function(module) {
|
|
79
|
-
/******/ var getter = module && module.__esModule ?
|
|
80
|
-
/******/ function getDefault() { return module['default']; } :
|
|
81
|
-
/******/ function getModuleExports() { return module; };
|
|
82
|
-
/******/ __webpack_require__.d(getter, 'a', getter);
|
|
83
|
-
/******/ return getter;
|
|
84
|
-
/******/ };
|
|
85
|
-
/******/
|
|
86
|
-
/******/ // Object.prototype.hasOwnProperty.call
|
|
87
|
-
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
|
88
|
-
/******/
|
|
89
|
-
/******/ // __webpack_public_path__
|
|
90
|
-
/******/ __webpack_require__.p = "";
|
|
91
|
-
/******/
|
|
92
|
-
/******/
|
|
93
|
-
/******/ // Load entry module and return exports
|
|
94
|
-
/******/ return __webpack_require__(__webpack_require__.s = "./src/EditControl.ts");
|
|
95
|
-
/******/ })
|
|
56
|
+
/******/
|
|
96
57
|
/************************************************************************/
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
58
|
+
var __webpack_exports__ = {};
|
|
59
|
+
// This entry needs to be wrapped in an IIFE because it needs to be isolated against other modules in the chunk.
|
|
60
|
+
(() => {
|
|
61
|
+
var exports = __webpack_exports__;
|
|
100
62
|
/*!****************************!*\
|
|
101
63
|
!*** ./src/EditControl.ts ***!
|
|
102
64
|
\****************************/
|
|
103
|
-
/*! exports provided: EditControl */
|
|
104
|
-
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
105
|
-
|
|
106
|
-
"use strict";
|
|
107
|
-
__webpack_require__.r(__webpack_exports__);
|
|
108
|
-
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EditControl", function() { return EditControl; });
|
|
109
|
-
/* harmony import */ var babylonjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs */ "babylonjs");
|
|
110
|
-
/* harmony import */ var babylonjs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs__WEBPACK_IMPORTED_MODULE_0__);
|
|
111
|
-
|
|
112
|
-
var ActionType;
|
|
113
|
-
(function (ActionType) {
|
|
114
|
-
ActionType[ActionType["TRANS"] = 0] = "TRANS";
|
|
115
|
-
ActionType[ActionType["ROT"] = 1] = "ROT";
|
|
116
|
-
ActionType[ActionType["SCALE"] = 2] = "SCALE";
|
|
117
|
-
})(ActionType || (ActionType = {}));
|
|
118
|
-
/**
|
|
119
|
-
* Draws a transform widget at the mesh's location (its pivot location).
|
|
120
|
-
* The widget transforms(translates,rotates and scales) the mesh based on user
|
|
121
|
-
* interactions with the widget.
|
|
122
|
-
* The widget shows the mesh position and rotation at any time.
|
|
123
|
-
* The widget follows the mesh constantly.
|
|
124
|
-
* Note: An alternate approach would have been for the mesh to follow the widget.
|
|
125
|
-
* The problem with the alternate approach - syncing the transforms
|
|
126
|
-
* if the mesh was being transformed by entities other than the widget say physics
|
|
127
|
-
* or script for example.
|
|
128
|
-
*
|
|
129
|
-
*/
|
|
130
|
-
var EditControl = /** @class */ (function () {
|
|
131
|
-
function EditControl(mesh, camera, canvas, scale, eulerian, pickWidth) {
|
|
132
|
-
var _this = this;
|
|
133
|
-
this._local = true;
|
|
134
|
-
this._snapT = false;
|
|
135
|
-
this._snapR = false;
|
|
136
|
-
this._transSnap = 1;
|
|
137
|
-
this._rotSnap = Math.PI / 18;
|
|
138
|
-
this._axesLen = 0.4;
|
|
139
|
-
this._axesScale = 1;
|
|
140
|
-
//how close to an axis should we get before we can pick it
|
|
141
|
-
this._pickWidth = 0.02;
|
|
142
|
-
this._redCol = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"](1, 0.2, 0.2);
|
|
143
|
-
this._greenCol = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"](0.2, 1, 0.2);
|
|
144
|
-
this._blueCol = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"](0.2, 0.2, 1);
|
|
145
|
-
this._whiteCol = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"](1, 1, 1);
|
|
146
|
-
this._yellowCol = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"](1, 1, 0.2);
|
|
147
|
-
//axes visibility
|
|
148
|
-
this._visibility = 0.75;
|
|
149
|
-
//lhs-rhs issue. lhs mesh in rhs or rhs mesh in lhs
|
|
150
|
-
this._lhsRhs = false;
|
|
151
|
-
this._ecMatrix = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Matrix"]();
|
|
152
|
-
//edit control to camera vector
|
|
153
|
-
this._ecTOcamera = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
154
|
-
//how far away from camera should the edit control appear to be
|
|
155
|
-
this._distFromCamera = 2;
|
|
156
|
-
//vector from camera to edit control
|
|
157
|
-
this._cameraTOec = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
158
|
-
this._cameraNormal = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
159
|
-
this._prevState = "";
|
|
160
|
-
this._hidden = false;
|
|
161
|
-
this._actionListener = null;
|
|
162
|
-
this._actionStartListener = null;
|
|
163
|
-
this._actionEndListener = null;
|
|
164
|
-
this._pDown = false;
|
|
165
|
-
this._pointerIsOver = false;
|
|
166
|
-
this._editing = false;
|
|
167
|
-
//rotate differently if camera is too close to the rotation plane
|
|
168
|
-
this._rotate2 = false;
|
|
169
|
-
//TODO when translating, the orientation of pALL keeps changing
|
|
170
|
-
//TODo this is not so with rotation or scaling
|
|
171
|
-
//TODO so for translation instead of pALL maybe we should use the camera view plane for picking
|
|
172
|
-
this._transBy = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
173
|
-
this._snapTV = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
174
|
-
this._snapS = false;
|
|
175
|
-
this._snapSV = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
176
|
-
this._scaleSnap = 0.25;
|
|
177
|
-
this._scale = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
178
|
-
this._localX = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
179
|
-
this._localY = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
180
|
-
this._localZ = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
181
|
-
this._eulerian = false;
|
|
182
|
-
this._snapRA = 0;
|
|
183
|
-
this._transEnabled = false;
|
|
184
|
-
this._rotEnabled = false;
|
|
185
|
-
this._scaleEnabled = false;
|
|
186
|
-
this._guideSize = 180;
|
|
187
|
-
this._tSnap = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](this._transSnap, this._transSnap, this._transSnap);
|
|
188
|
-
//few temp vectors & matrix
|
|
189
|
-
this._tv1 = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
190
|
-
this._tv2 = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
191
|
-
this._tv3 = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0);
|
|
192
|
-
this._tm = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Matrix"]();
|
|
193
|
-
this._mesh = mesh;
|
|
194
|
-
this._mainCamera = camera;
|
|
195
|
-
this._canvas = canvas;
|
|
196
|
-
if (scale != null) {
|
|
197
|
-
this._axesScale = scale;
|
|
198
|
-
}
|
|
199
|
-
if (eulerian !== null) {
|
|
200
|
-
this._eulerian = eulerian;
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
this._eulerian = false;
|
|
204
|
-
}
|
|
205
|
-
this._checkQuaternion();
|
|
206
|
-
if (pickWidth != null) {
|
|
207
|
-
this._pickWidth = pickWidth;
|
|
208
|
-
}
|
|
209
|
-
this._scene = mesh.getScene();
|
|
210
|
-
this._actHist = new ActHist(mesh, 10);
|
|
211
|
-
mesh.computeWorldMatrix(true);
|
|
212
|
-
this._boundingDimesion = this._getBoundingDimension(mesh);
|
|
213
|
-
this._setLocalAxes(mesh);
|
|
214
|
-
this._lhsRhs = this._check_LHS_RHS(mesh);
|
|
215
|
-
console.log("lhs rhs issue " + this._lhsRhs);
|
|
216
|
-
//build the edit control axes
|
|
217
|
-
this._ecRoot = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"]("", this._scene);
|
|
218
|
-
this._ecRoot.rotationQuaternion = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity();
|
|
219
|
-
this._ecRoot.visibility = 0;
|
|
220
|
-
this._ecRoot.isPickable = false;
|
|
221
|
-
this._createMaterials(this._scene);
|
|
222
|
-
var guideAxes = this._createCommonAxes();
|
|
223
|
-
guideAxes.parent = this._ecRoot;
|
|
224
|
-
//build the pickplanes
|
|
225
|
-
var pickPlanes = this._createPickPlanes();
|
|
226
|
-
pickPlanes.parent = this._ecRoot;
|
|
227
|
-
this._pointerdown = function (evt) { return _this._onPointerDown(evt); };
|
|
228
|
-
this._pointerup = function (evt) { return _this._onPointerUp(evt); };
|
|
229
|
-
this._pointermove = function (evt) { return _this._onPointerMove(evt); };
|
|
230
|
-
//use canvas rather than scene to handle pointer events
|
|
231
|
-
//scene cannot have mutiple eventlisteners for an event
|
|
232
|
-
//with canvas one will have to do ones own pickinfo generation.
|
|
233
|
-
canvas.addEventListener("pointerdown", this._pointerdown, false);
|
|
234
|
-
canvas.addEventListener("pointerup", this._pointerup, false);
|
|
235
|
-
canvas.addEventListener("pointermove", this._pointermove, false);
|
|
236
|
-
this._renderer = function () { return _this._renderLoopProcess(); };
|
|
237
|
-
this._scene.registerBeforeRender(this._renderer);
|
|
238
|
-
}
|
|
239
|
-
EditControl.prototype.getRoot = function () {
|
|
240
|
-
return this._ecRoot;
|
|
241
|
-
};
|
|
242
|
-
//make sure that if eulerian is set to false then mesh's rotation is in quaternion
|
|
243
|
-
//throw error and exit if not so.
|
|
244
|
-
EditControl.prototype._checkQuaternion = function () {
|
|
245
|
-
if (!this._eulerian) {
|
|
246
|
-
if ((this._mesh.rotationQuaternion == null) || (this._mesh.rotationQuaternion == undefined)) {
|
|
247
|
-
throw "Error: Eulerian is set to false but the mesh's rotationQuaternion is not set.";
|
|
248
|
-
}
|
|
249
|
-
}
|
|
250
|
-
};
|
|
251
|
-
/**
|
|
252
|
-
* checks if a have left hand , right hand issue.
|
|
253
|
-
* In other words if a mesh is a LHS mesh in RHS system or
|
|
254
|
-
* a RHS mesh in LHS system
|
|
255
|
-
* The X axis will be reversed in such cases.
|
|
256
|
-
* thus Cross product of X and Y should be inverse of Z.
|
|
257
|
-
*
|
|
258
|
-
* if no parent then we are ok.
|
|
259
|
-
* If parent and parent has issue then we have issue.
|
|
260
|
-
*
|
|
261
|
-
*/
|
|
262
|
-
EditControl.prototype._check_LHS_RHS = function (mesh) {
|
|
263
|
-
var _issue = false;
|
|
264
|
-
var root = mesh.parent;
|
|
265
|
-
if (root == null)
|
|
266
|
-
return false;
|
|
267
|
-
this._setLocalAxes(root);
|
|
268
|
-
var actualZ = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Cross(this._localX, this._localY);
|
|
269
|
-
//same direction or opposite direction of Z
|
|
270
|
-
if (babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(actualZ, this._localZ) < 0)
|
|
271
|
-
_issue = true;
|
|
272
|
-
else
|
|
273
|
-
_issue = false;
|
|
274
|
-
this._setLocalAxes(mesh);
|
|
275
|
-
return _issue;
|
|
276
|
-
};
|
|
277
|
-
EditControl.prototype._renderLoopProcess = function () {
|
|
278
|
-
//sync the edit control position and rotation with that of mesh
|
|
279
|
-
this._ecRoot.position = this._mesh.getAbsolutePivotPoint();
|
|
280
|
-
this._setECRotation();
|
|
281
|
-
//scale the EditControl so it seems at the same distance from camera/user
|
|
282
|
-
this._setECScale();
|
|
283
|
-
//rotate the free move,rotate,scale pick plane to face the camera/user
|
|
284
|
-
if (this._local) {
|
|
285
|
-
this._ecRoot.getWorldMatrix().invertToRef(this._ecMatrix);
|
|
286
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this._mainCamera.position, this._ecMatrix, this._ecTOcamera);
|
|
287
|
-
//note pALL is child of ecRoot hence lookAt in local space
|
|
288
|
-
this._pALL.lookAt(this._ecTOcamera, 0, 0, 0, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].LOCAL);
|
|
289
|
-
}
|
|
290
|
-
else {
|
|
291
|
-
this._mainCamera.position.subtractToRef(this._ecRoot.position, this._ecTOcamera);
|
|
292
|
-
this._pALL.lookAt(this._mainCamera.position, 0, 0, 0, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
293
|
-
}
|
|
294
|
-
//rotate the rotation and planar guide to face the camera/user
|
|
295
|
-
if (this._rotEnabled) {
|
|
296
|
-
this._rotRotGuides();
|
|
297
|
-
}
|
|
298
|
-
else if (this._transEnabled)
|
|
299
|
-
this._rotPlanarGuides(this._tXZ, this._tZY, this._tYX);
|
|
300
|
-
else if (this._scaleEnabled)
|
|
301
|
-
this._rotPlanarGuides(this._sXZ, this._sZY, this._sYX);
|
|
302
|
-
//check pointer over axes only during pointer moves
|
|
303
|
-
//this.onPointerOver();
|
|
304
|
-
};
|
|
305
|
-
/**
|
|
306
|
-
* sets rotaion of edit control to that of the mesh
|
|
307
|
-
*/
|
|
308
|
-
EditControl.prototype._setECRotation = function () {
|
|
309
|
-
if (this._local) {
|
|
310
|
-
if (this._mesh.parent == null) {
|
|
311
|
-
if (this._eulerian) {
|
|
312
|
-
var rot = this._mesh.rotation;
|
|
313
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRollToRef(rot.y, rot.x, rot.z, this._ecRoot.rotationQuaternion);
|
|
314
|
-
}
|
|
315
|
-
else {
|
|
316
|
-
this._ecRoot.rotationQuaternion.copyFrom(this._mesh.rotationQuaternion);
|
|
317
|
-
}
|
|
318
|
-
}
|
|
319
|
-
else {
|
|
320
|
-
if (this._isScaleUnEqual(this._mesh))
|
|
321
|
-
return;
|
|
322
|
-
this._mesh.getWorldMatrix().getRotationMatrixToRef(this._tm);
|
|
323
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].FromRotationMatrixToRef(this._tm, this._ecRoot.rotationQuaternion);
|
|
324
|
-
//this._ecRoot.rotationQuaternion.normalize();
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
};
|
|
328
|
-
/**
|
|
329
|
-
* checks if any of the mesh's ancestors has non uniform scale
|
|
330
|
-
*/
|
|
331
|
-
EditControl.prototype._isScaleUnEqual = function (mesh) {
|
|
332
|
-
if (mesh.parent == null)
|
|
333
|
-
return false;
|
|
334
|
-
while (mesh.parent != null) {
|
|
335
|
-
if ((mesh.parent.scaling.x != mesh.parent.scaling.y ||
|
|
336
|
-
mesh.parent.scaling.y != mesh.parent.scaling.z)) {
|
|
337
|
-
return true;
|
|
338
|
-
}
|
|
339
|
-
else {
|
|
340
|
-
mesh = mesh.parent;
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
return false;
|
|
344
|
-
};
|
|
345
|
-
EditControl.prototype._setECScale = function () {
|
|
346
|
-
this._ecRoot.position.subtractToRef(this._mainCamera.position, this._cameraTOec);
|
|
347
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatArrayToRef(this._mainCamera.getWorldMatrix().asArray(), 8, this._cameraNormal);
|
|
348
|
-
//get distance of edit control from the camera plane
|
|
349
|
-
//project "camera to edit control" vector onto the camera normal
|
|
350
|
-
var parentOnNormal = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._cameraTOec, this._cameraNormal) / this._cameraNormal.length();
|
|
351
|
-
var s = Math.abs(parentOnNormal / this._distFromCamera);
|
|
352
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatsToRef(s, s, s, this._ecRoot.scaling);
|
|
353
|
-
//Vector3.FromFloatsToRef(s,s,s,this.pALL.scaling);
|
|
354
|
-
};
|
|
355
|
-
//rotate the rotation guides so that they are facing the camera
|
|
356
|
-
EditControl.prototype._rotRotGuides = function () {
|
|
357
|
-
var rotX = Math.atan(this._ecTOcamera.y / this._ecTOcamera.z);
|
|
358
|
-
if (this._ecTOcamera.z >= 0) {
|
|
359
|
-
this._rX.rotation.x = -rotX;
|
|
360
|
-
}
|
|
361
|
-
else {
|
|
362
|
-
this._rX.rotation.x = -rotX - Math.PI;
|
|
363
|
-
}
|
|
364
|
-
var rotY = Math.atan(this._ecTOcamera.x / this._ecTOcamera.z);
|
|
365
|
-
if (this._ecTOcamera.z >= 0) {
|
|
366
|
-
this._rY.rotation.y = rotY;
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
this._rY.rotation.y = rotY + Math.PI;
|
|
370
|
-
}
|
|
371
|
-
var rotZ = Math.atan(this._ecTOcamera.x / this._ecTOcamera.y);
|
|
372
|
-
if (this._ecTOcamera.y >= 0) {
|
|
373
|
-
this._rZ.rotation.z = -rotZ;
|
|
374
|
-
}
|
|
375
|
-
else {
|
|
376
|
-
this._rZ.rotation.z = -rotZ - Math.PI;
|
|
377
|
-
}
|
|
378
|
-
};
|
|
379
|
-
/**
|
|
380
|
-
* rotate the planar guide so that they are facing the camera
|
|
381
|
-
*/
|
|
382
|
-
EditControl.prototype._rotPlanarGuides = function (XZ, ZY, YX) {
|
|
383
|
-
var ec = this._ecTOcamera;
|
|
384
|
-
XZ.rotation.x = 0;
|
|
385
|
-
XZ.rotation.y = 0;
|
|
386
|
-
XZ.rotation.z = 0;
|
|
387
|
-
ZY.rotation.x = 0;
|
|
388
|
-
ZY.rotation.y = 0;
|
|
389
|
-
ZY.rotation.z = 0;
|
|
390
|
-
YX.rotation.x = 0;
|
|
391
|
-
YX.rotation.y = 0;
|
|
392
|
-
YX.rotation.z = 0;
|
|
393
|
-
if (ec.x <= 0 && ec.y >= 0 && ec.z >= 0) {
|
|
394
|
-
XZ.rotation.z = 3.14;
|
|
395
|
-
YX.rotation.y = 3.14;
|
|
396
|
-
}
|
|
397
|
-
else if (ec.x <= 0 && ec.y >= 0 && ec.z <= 0) {
|
|
398
|
-
XZ.rotation.y = 3.14;
|
|
399
|
-
ZY.rotation.y = 3.14;
|
|
400
|
-
YX.rotation.y = 3.14;
|
|
401
|
-
}
|
|
402
|
-
else if (ec.x >= 0 && ec.y >= 0 && ec.z <= 0) {
|
|
403
|
-
XZ.rotation.x = 3.14;
|
|
404
|
-
ZY.rotation.y = 3.14;
|
|
405
|
-
}
|
|
406
|
-
else if (ec.x >= 0 && ec.y <= 0 && ec.z >= 0) {
|
|
407
|
-
ZY.rotation.z = 3.14;
|
|
408
|
-
YX.rotation.x = 3.14;
|
|
409
|
-
}
|
|
410
|
-
else if (ec.x <= 0 && ec.y <= 0 && ec.z >= 0) {
|
|
411
|
-
XZ.rotation.z = 3.14;
|
|
412
|
-
ZY.rotation.z = 3.14;
|
|
413
|
-
YX.rotation.z = 3.14;
|
|
414
|
-
}
|
|
415
|
-
else if (ec.x <= 0 && ec.y <= 0 && ec.z <= 0) {
|
|
416
|
-
XZ.rotation.y = 3.14;
|
|
417
|
-
ZY.rotation.x = 3.14;
|
|
418
|
-
YX.rotation.z = 3.14;
|
|
419
|
-
}
|
|
420
|
-
else if (ec.x >= 0 && ec.y <= 0 && ec.z <= 0) {
|
|
421
|
-
XZ.rotation.x = 3.14;
|
|
422
|
-
ZY.rotation.x = 3.14;
|
|
423
|
-
YX.rotation.x = 3.14;
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
EditControl.prototype.switchTo = function (mesh, eulerian) {
|
|
427
|
-
mesh.computeWorldMatrix(true);
|
|
428
|
-
this._mesh = mesh;
|
|
429
|
-
if (eulerian != null) {
|
|
430
|
-
this._eulerian = eulerian;
|
|
431
|
-
}
|
|
432
|
-
this._checkQuaternion();
|
|
433
|
-
this._setLocalAxes(mesh);
|
|
434
|
-
this._actHist = new ActHist(mesh, 10);
|
|
435
|
-
this._lhsRhs = this._check_LHS_RHS(mesh);
|
|
436
|
-
this.refreshBoundingInfo();
|
|
437
|
-
};
|
|
438
|
-
EditControl.prototype.switchCamera = function (camera) {
|
|
439
|
-
this._mainCamera = camera;
|
|
440
|
-
};
|
|
441
|
-
EditControl.prototype.setUndoCount = function (c) {
|
|
442
|
-
this._actHist.setCapacity(c);
|
|
443
|
-
};
|
|
444
|
-
EditControl.prototype.undo = function () {
|
|
445
|
-
var at = this._actHist.undo();
|
|
446
|
-
this._mesh.computeWorldMatrix(true);
|
|
447
|
-
this._setLocalAxes(this._mesh);
|
|
448
|
-
this._callActionStartListener(at);
|
|
449
|
-
this._callActionListener(at);
|
|
450
|
-
this._callActionEndListener(at);
|
|
451
|
-
};
|
|
452
|
-
EditControl.prototype.redo = function () {
|
|
453
|
-
var at = this._actHist.redo();
|
|
454
|
-
this._mesh.computeWorldMatrix(true);
|
|
455
|
-
this._setLocalAxes(this._mesh);
|
|
456
|
-
this._callActionStartListener(at);
|
|
457
|
-
this._callActionListener(at);
|
|
458
|
-
this._callActionEndListener(at);
|
|
459
|
-
};
|
|
460
|
-
/**
|
|
461
|
-
* detach the edit control from the mesh and dispose off all
|
|
462
|
-
* resources created by the edit control
|
|
463
|
-
*/
|
|
464
|
-
EditControl.prototype.detach = function () {
|
|
465
|
-
this._canvas.removeEventListener("pointerdown", this._pointerdown, false);
|
|
466
|
-
this._canvas.removeEventListener("pointerup", this._pointerup, false);
|
|
467
|
-
this._canvas.removeEventListener("pointermove", this._pointermove, false);
|
|
468
|
-
this._scene.unregisterBeforeRender(this._renderer);
|
|
469
|
-
this.removeAllActionListeners();
|
|
470
|
-
this._disposeAll();
|
|
471
|
-
};
|
|
472
|
-
/**
|
|
473
|
-
* hide the edit control. use show() to unhide the control.
|
|
474
|
-
*/
|
|
475
|
-
EditControl.prototype.hide = function () {
|
|
476
|
-
this._hidden = true;
|
|
477
|
-
if (this._transEnabled) {
|
|
478
|
-
this._prevState = "T";
|
|
479
|
-
this.disableTranslation();
|
|
480
|
-
}
|
|
481
|
-
else if (this._rotEnabled) {
|
|
482
|
-
this._prevState = "R";
|
|
483
|
-
this.disableRotation();
|
|
484
|
-
}
|
|
485
|
-
else if (this._scaleEnabled) {
|
|
486
|
-
this._prevState = "S";
|
|
487
|
-
this.disableScaling();
|
|
488
|
-
}
|
|
489
|
-
this._hideCommonAxes();
|
|
490
|
-
};
|
|
491
|
-
EditControl.prototype._hideCommonAxes = function () {
|
|
492
|
-
this._xaxis.visibility = 0;
|
|
493
|
-
this._yaxis.visibility = 0;
|
|
494
|
-
this._zaxis.visibility = 0;
|
|
495
|
-
};
|
|
496
|
-
EditControl.prototype._showCommonAxes = function () {
|
|
497
|
-
this._xaxis.visibility = this._visibility;
|
|
498
|
-
this._yaxis.visibility = this._visibility;
|
|
499
|
-
this._zaxis.visibility = this._visibility;
|
|
500
|
-
};
|
|
501
|
-
/**
|
|
502
|
-
* unhide the editcontrol hidden using the hide() method
|
|
503
|
-
*/
|
|
504
|
-
EditControl.prototype.show = function () {
|
|
505
|
-
this._hidden = false;
|
|
506
|
-
this._showCommonAxes();
|
|
507
|
-
if (this._prevState == "T")
|
|
508
|
-
this.enableTranslation();
|
|
509
|
-
else if (this._prevState == "R")
|
|
510
|
-
this.enableRotation();
|
|
511
|
-
else if (this._prevState == "S")
|
|
512
|
-
this.enableScaling();
|
|
513
|
-
};
|
|
514
|
-
/**
|
|
515
|
-
* check if the editcontrol was hidden using the hide() methods
|
|
516
|
-
*/
|
|
517
|
-
EditControl.prototype.isHidden = function () {
|
|
518
|
-
return this._hidden;
|
|
519
|
-
};
|
|
520
|
-
EditControl.prototype._disposeAll = function () {
|
|
521
|
-
this._ecRoot.dispose();
|
|
522
|
-
this._disposeMaterials();
|
|
523
|
-
this._actHist = null;
|
|
524
|
-
};
|
|
525
|
-
EditControl.prototype.addActionListener = function (actionListener) {
|
|
526
|
-
this._actionListener = actionListener;
|
|
527
|
-
};
|
|
528
|
-
EditControl.prototype.removeActionListener = function () {
|
|
529
|
-
this._actionListener = null;
|
|
530
|
-
};
|
|
531
|
-
EditControl.prototype.addActionStartListener = function (actionStartListener) {
|
|
532
|
-
this._actionStartListener = actionStartListener;
|
|
533
|
-
};
|
|
534
|
-
EditControl.prototype.removeActionStartListener = function () {
|
|
535
|
-
this._actionStartListener = null;
|
|
536
|
-
};
|
|
537
|
-
EditControl.prototype.addActionEndListener = function (actionEndListener) {
|
|
538
|
-
this._actionEndListener = actionEndListener;
|
|
539
|
-
};
|
|
540
|
-
EditControl.prototype.removeActionEndListener = function () {
|
|
541
|
-
this._actionEndListener = null;
|
|
542
|
-
};
|
|
543
|
-
EditControl.prototype.removeAllActionListeners = function () {
|
|
544
|
-
this._actionListener = null;
|
|
545
|
-
this._actionStartListener = null;
|
|
546
|
-
this._actionEndListener = null;
|
|
547
|
-
};
|
|
548
|
-
EditControl.prototype._onPointerDown = function (evt) {
|
|
549
|
-
var _this = this;
|
|
550
|
-
evt.preventDefault();
|
|
551
|
-
this._pDown = true;
|
|
552
|
-
if (evt.button != 0)
|
|
553
|
-
return;
|
|
554
|
-
var engine = this._scene.getEngine();
|
|
555
|
-
var x = (engine.isPointerLock) ? this._canvas.width * 0.5 : this._scene.pointerX;
|
|
556
|
-
var y = (engine.isPointerLock) ? this._canvas.height * 0.5 : this._scene.pointerY;
|
|
557
|
-
var pickResult = this._scene.pick(x, y, function (mesh) {
|
|
558
|
-
if (_this._transEnabled) {
|
|
559
|
-
if ((mesh == _this._tX) || (mesh == _this._tY) || (mesh == _this._tZ) || (mesh == _this._tXZ) || (mesh == _this._tZY) || (mesh == _this._tYX) || (mesh == _this._tAll))
|
|
560
|
-
return true;
|
|
561
|
-
}
|
|
562
|
-
else if ((_this._rotEnabled)) {
|
|
563
|
-
if ((mesh == _this._rX) || (mesh == _this._rY) || (mesh == _this._rZ) || (mesh == _this._rAll))
|
|
564
|
-
return true;
|
|
565
|
-
}
|
|
566
|
-
else if ((_this._scaleEnabled)) {
|
|
567
|
-
if ((mesh == _this._sX) || (mesh == _this._sY) || (mesh == _this._sZ) || (mesh == _this._sXZ) || (mesh == _this._sZY) || (mesh == _this._sYX) || (mesh == _this._sAll))
|
|
568
|
-
return true;
|
|
569
|
-
}
|
|
570
|
-
return false;
|
|
571
|
-
}, null, this._mainCamera);
|
|
572
|
-
if (pickResult.hit) {
|
|
573
|
-
//this.setAxesVisiblity(0);
|
|
574
|
-
this._axisPicked = pickResult.pickedMesh;
|
|
575
|
-
var childs = this._axisPicked.getChildren();
|
|
576
|
-
if (childs.length > 0) {
|
|
577
|
-
childs[0].visibility = this._visibility;
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
this._axisPicked.visibility = this._visibility;
|
|
581
|
-
}
|
|
582
|
-
var name_1 = this._axisPicked.name;
|
|
583
|
-
if ((name_1 == "X"))
|
|
584
|
-
this._bXaxis.visibility = 1;
|
|
585
|
-
else if ((name_1 == "Y"))
|
|
586
|
-
this._bYaxis.visibility = 1;
|
|
587
|
-
else if ((name_1 == "Z"))
|
|
588
|
-
this._bZaxis.visibility = 1;
|
|
589
|
-
else if ((name_1 == "XZ")) {
|
|
590
|
-
this._bXaxis.visibility = 1;
|
|
591
|
-
this._bZaxis.visibility = 1;
|
|
592
|
-
}
|
|
593
|
-
else if ((name_1 == "ZY")) {
|
|
594
|
-
this._bZaxis.visibility = 1;
|
|
595
|
-
this._bYaxis.visibility = 1;
|
|
596
|
-
}
|
|
597
|
-
else if ((name_1 == "YX")) {
|
|
598
|
-
this._bYaxis.visibility = 1;
|
|
599
|
-
this._bXaxis.visibility = 1;
|
|
600
|
-
}
|
|
601
|
-
else if ((name_1 == "ALL")) {
|
|
602
|
-
this._bXaxis.visibility = 1;
|
|
603
|
-
this._bYaxis.visibility = 1;
|
|
604
|
-
this._bZaxis.visibility = 1;
|
|
605
|
-
}
|
|
606
|
-
this._setEditing(true);
|
|
607
|
-
//lets find out where we are on the pickplane
|
|
608
|
-
this._pickedPlane = this._getPickPlane(this._axisPicked);
|
|
609
|
-
if (this._pickedPlane != null) {
|
|
610
|
-
this._prevPos = this._getPosOnPickPlane();
|
|
611
|
-
}
|
|
612
|
-
else {
|
|
613
|
-
this._prevPos = null;
|
|
614
|
-
}
|
|
615
|
-
window.setTimeout((function (cam, can) { return _this._detachCamera(cam, can); }), 0, this._mainCamera, this._canvas);
|
|
616
|
-
}
|
|
617
|
-
};
|
|
618
|
-
EditControl.prototype._setEditing = function (editing) {
|
|
619
|
-
this._editing = editing;
|
|
620
|
-
if (editing) {
|
|
621
|
-
this._setActionType();
|
|
622
|
-
if (this._actionType == ActionType.ROT) {
|
|
623
|
-
this._snapRA = 0;
|
|
624
|
-
}
|
|
625
|
-
this._callActionStartListener(this._actionType);
|
|
626
|
-
}
|
|
627
|
-
else {
|
|
628
|
-
this._callActionEndListener(this._actionType);
|
|
629
|
-
}
|
|
630
|
-
};
|
|
631
|
-
EditControl.prototype.isEditing = function () {
|
|
632
|
-
return this._editing;
|
|
633
|
-
};
|
|
634
|
-
/**
|
|
635
|
-
* no camera movement during edit
|
|
636
|
-
*/
|
|
637
|
-
EditControl.prototype._detachCamera = function (cam, can) {
|
|
638
|
-
var camera = cam;
|
|
639
|
-
var canvas = can;
|
|
640
|
-
var engine = this._scene.getEngine();
|
|
641
|
-
if (!engine.isPointerLock) {
|
|
642
|
-
camera.detachControl(canvas);
|
|
643
|
-
}
|
|
644
|
-
};
|
|
645
|
-
EditControl.prototype.isPointerOver = function () {
|
|
646
|
-
return this._pointerIsOver;
|
|
647
|
-
};
|
|
648
|
-
EditControl.prototype._onPointerOver = function () {
|
|
649
|
-
var _this = this;
|
|
650
|
-
//if(this.pDown) return;
|
|
651
|
-
var engine = this._scene.getEngine();
|
|
652
|
-
var x = (engine.isPointerLock) ? this._canvas.width * 0.5 : this._scene.pointerX;
|
|
653
|
-
var y = (engine.isPointerLock) ? this._canvas.height * 0.5 : this._scene.pointerY;
|
|
654
|
-
var pickResult = this._scene.pick(x, y, function (mesh) {
|
|
655
|
-
if (_this._transEnabled) {
|
|
656
|
-
if ((mesh == _this._tX) || (mesh == _this._tY) || (mesh == _this._tZ) || (mesh == _this._tXZ) || (mesh == _this._tZY) || (mesh == _this._tYX) || (mesh == _this._tAll))
|
|
657
|
-
return true;
|
|
658
|
-
}
|
|
659
|
-
else if ((_this._rotEnabled)) {
|
|
660
|
-
if ((mesh == _this._rX) || (mesh == _this._rY) || (mesh == _this._rZ) || (mesh == _this._rAll))
|
|
661
|
-
return true;
|
|
662
|
-
}
|
|
663
|
-
else if (_this._scaleEnabled) {
|
|
664
|
-
if ((mesh == _this._sX) || (mesh == _this._sY) || (mesh == _this._sZ) || (mesh == _this._sXZ) || (mesh == _this._sZY) || (mesh == _this._sYX) || (mesh == _this._sAll))
|
|
665
|
-
return true;
|
|
666
|
-
}
|
|
667
|
-
return false;
|
|
668
|
-
}, null, this._mainCamera);
|
|
669
|
-
if (pickResult.hit) {
|
|
670
|
-
//if we are still over the same axis mesh then don't do anything
|
|
671
|
-
if (pickResult.pickedMesh != this._prevOverMesh) {
|
|
672
|
-
this._pointerIsOver = true;
|
|
673
|
-
//if we moved directly from one axis mesh to this then clean up the prev axis mesh
|
|
674
|
-
this._clearPrevOverMesh();
|
|
675
|
-
this._prevOverMesh = pickResult.pickedMesh;
|
|
676
|
-
if (this._rotEnabled) {
|
|
677
|
-
this._savedCol = this._prevOverMesh.getChildren()[0].color;
|
|
678
|
-
this._prevOverMesh.getChildren()[0].color = this._whiteCol;
|
|
679
|
-
}
|
|
680
|
-
else {
|
|
681
|
-
var childs = this._prevOverMesh.getChildren();
|
|
682
|
-
if (childs.length > 0) {
|
|
683
|
-
this._savedMat = childs[0].material;
|
|
684
|
-
childs[0].material = this._whiteMat;
|
|
685
|
-
}
|
|
686
|
-
else {
|
|
687
|
-
this._savedMat = this._prevOverMesh.material;
|
|
688
|
-
this._prevOverMesh.material = this._whiteMat;
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
if (this._prevOverMesh.name == "X") {
|
|
692
|
-
this._xaxis.color = this._whiteCol;
|
|
693
|
-
}
|
|
694
|
-
else if (this._prevOverMesh.name == "Y") {
|
|
695
|
-
this._yaxis.color = this._whiteCol;
|
|
696
|
-
}
|
|
697
|
-
else if (this._prevOverMesh.name == "Z") {
|
|
698
|
-
this._zaxis.color = this._whiteCol;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
else {
|
|
703
|
-
this._pointerIsOver = false;
|
|
704
|
-
if (this._prevOverMesh != null) {
|
|
705
|
-
this._restoreColor(this._prevOverMesh);
|
|
706
|
-
this._prevOverMesh = null;
|
|
707
|
-
}
|
|
708
|
-
}
|
|
709
|
-
};
|
|
710
|
-
//clean up any axis we might have been howering over before
|
|
711
|
-
EditControl.prototype._clearPrevOverMesh = function () {
|
|
712
|
-
if (this._prevOverMesh != null) {
|
|
713
|
-
this._prevOverMesh.visibility = 0;
|
|
714
|
-
this._restoreColor(this._prevOverMesh);
|
|
715
|
-
}
|
|
716
|
-
};
|
|
717
|
-
EditControl.prototype._restoreColor = function (mesh) {
|
|
718
|
-
switch (mesh.name) {
|
|
719
|
-
case "X":
|
|
720
|
-
this._xaxis.color = this._redCol;
|
|
721
|
-
break;
|
|
722
|
-
case "Y":
|
|
723
|
-
this._yaxis.color = this._greenCol;
|
|
724
|
-
break;
|
|
725
|
-
case "Z":
|
|
726
|
-
this._zaxis.color = this._blueCol;
|
|
727
|
-
break;
|
|
728
|
-
}
|
|
729
|
-
if (this._rotEnabled) {
|
|
730
|
-
mesh.getChildren()[0].color = this._savedCol;
|
|
731
|
-
}
|
|
732
|
-
else {
|
|
733
|
-
var childs = mesh.getChildren();
|
|
734
|
-
if (childs.length > 0) {
|
|
735
|
-
childs[0].material = this._savedMat;
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
mesh.material = this._savedMat;
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
};
|
|
742
|
-
EditControl.prototype._onPointerUp = function (evt) {
|
|
743
|
-
this._pDown = false;
|
|
744
|
-
if (this._editing) {
|
|
745
|
-
var engine = this._scene.getEngine();
|
|
746
|
-
if (!engine.isPointerLock) {
|
|
747
|
-
this._mainCamera.attachControl(this._canvas);
|
|
748
|
-
}
|
|
749
|
-
this._setEditing(false);
|
|
750
|
-
//this.setAxesVisiblity(1);
|
|
751
|
-
this._hideBaxis();
|
|
752
|
-
if (this._prevOverMesh != null) {
|
|
753
|
-
this._restoreColor(this._prevOverMesh);
|
|
754
|
-
this._prevOverMesh = null;
|
|
755
|
-
}
|
|
756
|
-
this._actHist.add(this._actionType);
|
|
757
|
-
}
|
|
758
|
-
};
|
|
759
|
-
EditControl.prototype._setActionType = function () {
|
|
760
|
-
if (this._transEnabled) {
|
|
761
|
-
this._actionType = ActionType.TRANS;
|
|
762
|
-
}
|
|
763
|
-
else if ((this._rotEnabled)) {
|
|
764
|
-
this._actionType = ActionType.ROT;
|
|
765
|
-
}
|
|
766
|
-
else if ((this._scaleEnabled)) {
|
|
767
|
-
this._actionType = ActionType.SCALE;
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
EditControl.prototype._callActionListener = function (at) {
|
|
771
|
-
//call actionListener if registered
|
|
772
|
-
if (this._actionListener != null) {
|
|
773
|
-
this._actionListener(at);
|
|
774
|
-
}
|
|
775
|
-
};
|
|
776
|
-
EditControl.prototype._callActionStartListener = function (at) {
|
|
777
|
-
//call actionListener if registered
|
|
778
|
-
if (this._actionStartListener != null) {
|
|
779
|
-
this._actionStartListener(at);
|
|
780
|
-
}
|
|
781
|
-
};
|
|
782
|
-
EditControl.prototype._callActionEndListener = function (at) {
|
|
783
|
-
//call actionListener if registered
|
|
784
|
-
if (this._actionEndListener != null) {
|
|
785
|
-
this._actionEndListener(at);
|
|
786
|
-
}
|
|
787
|
-
};
|
|
788
|
-
EditControl.prototype._onPointerMove = function (evt) {
|
|
789
|
-
if (!this._pDown) {
|
|
790
|
-
this._onPointerOver();
|
|
791
|
-
return;
|
|
792
|
-
}
|
|
793
|
-
if (!this._editing)
|
|
794
|
-
return;
|
|
795
|
-
if (this._prevPos == null)
|
|
796
|
-
return;
|
|
797
|
-
var newPos = this._getPosOnPickPlane();
|
|
798
|
-
if (newPos == null)
|
|
799
|
-
return;
|
|
800
|
-
if (this._rotEnabled) {
|
|
801
|
-
this._doRotation(this._mesh, this._axisPicked, newPos, this._prevPos);
|
|
802
|
-
}
|
|
803
|
-
else {
|
|
804
|
-
var diff = newPos.subtract(this._prevPos);
|
|
805
|
-
if (diff.x == 0 && diff.y == 0 && diff.z == 0)
|
|
806
|
-
return;
|
|
807
|
-
if (this._transEnabled) {
|
|
808
|
-
this._doTranslation(diff);
|
|
809
|
-
}
|
|
810
|
-
else {
|
|
811
|
-
if (this._scaleEnabled && this._local)
|
|
812
|
-
this._doScaling(diff);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
this._prevPos = newPos;
|
|
816
|
-
this._callActionListener(this._actionType);
|
|
817
|
-
};
|
|
818
|
-
EditControl.prototype._getPickPlane = function (axis) {
|
|
819
|
-
var n = axis.name;
|
|
820
|
-
if (this._transEnabled || this._scaleEnabled) {
|
|
821
|
-
if (n == "XZ")
|
|
822
|
-
return this._pXZ;
|
|
823
|
-
else if (n == "ZY")
|
|
824
|
-
return this._pZY;
|
|
825
|
-
else if (n == "YX")
|
|
826
|
-
return this._pYX;
|
|
827
|
-
else if (n == "ALL")
|
|
828
|
-
return this._pALL;
|
|
829
|
-
else {
|
|
830
|
-
//get the position of camera in the edit control frame of reference
|
|
831
|
-
this._ecRoot.getWorldMatrix().invertToRef(this._ecMatrix);
|
|
832
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this._mainCamera.position, this._ecMatrix, this._ecTOcamera);
|
|
833
|
-
var c = this._ecTOcamera;
|
|
834
|
-
if (n === "X") {
|
|
835
|
-
if (Math.abs(c.y) > Math.abs(c.z)) {
|
|
836
|
-
return this._pXZ;
|
|
837
|
-
}
|
|
838
|
-
else
|
|
839
|
-
return this._pYX;
|
|
840
|
-
}
|
|
841
|
-
else if (n === "Z") {
|
|
842
|
-
if (Math.abs(c.y) > Math.abs(c.x)) {
|
|
843
|
-
return this._pXZ;
|
|
844
|
-
}
|
|
845
|
-
else
|
|
846
|
-
return this._pZY;
|
|
847
|
-
}
|
|
848
|
-
else if (n === "Y") {
|
|
849
|
-
if (Math.abs(c.z) > Math.abs(c.x)) {
|
|
850
|
-
return this._pYX;
|
|
851
|
-
}
|
|
852
|
-
else
|
|
853
|
-
return this._pZY;
|
|
854
|
-
}
|
|
855
|
-
}
|
|
856
|
-
}
|
|
857
|
-
else if (this._rotEnabled) {
|
|
858
|
-
this._rotate2 = false;
|
|
859
|
-
//get the position of camera in the edit control frame of reference
|
|
860
|
-
this._ecRoot.getWorldMatrix().invertToRef(this._ecMatrix);
|
|
861
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this._mainCamera.position, this._ecMatrix, this._ecTOcamera);
|
|
862
|
-
var c = this._ecTOcamera;
|
|
863
|
-
//if camera is too close to the rotation plane then use alternate rotation process
|
|
864
|
-
switch (n) {
|
|
865
|
-
case "X":
|
|
866
|
-
if (Math.abs(c.x) < 0.2) {
|
|
867
|
-
this._rotate2 = true;
|
|
868
|
-
return this._pALL;
|
|
869
|
-
}
|
|
870
|
-
else
|
|
871
|
-
return this._pZY;
|
|
872
|
-
case "Y":
|
|
873
|
-
if (Math.abs(c.y) < 0.2) {
|
|
874
|
-
this._rotate2 = true;
|
|
875
|
-
return this._pALL;
|
|
876
|
-
}
|
|
877
|
-
else
|
|
878
|
-
return this._pXZ;
|
|
879
|
-
case "Z":
|
|
880
|
-
if (Math.abs(c.z) < 0.2) {
|
|
881
|
-
this._rotate2 = true;
|
|
882
|
-
return this._pALL;
|
|
883
|
-
}
|
|
884
|
-
else
|
|
885
|
-
return this._pYX;
|
|
886
|
-
default:
|
|
887
|
-
return this._pALL;
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
else
|
|
891
|
-
return null;
|
|
892
|
-
};
|
|
893
|
-
EditControl.prototype._doTranslation = function (diff) {
|
|
894
|
-
if ((this._mesh.parent != null) && this._isScaleUnEqual(this._mesh)) {
|
|
895
|
-
this._setLocalAxes(this._ecRoot);
|
|
896
|
-
}
|
|
897
|
-
else {
|
|
898
|
-
this._setLocalAxes(this._mesh);
|
|
899
|
-
}
|
|
900
|
-
var n = this._axisPicked.name;
|
|
901
|
-
this._transBy.x = 0;
|
|
902
|
-
this._transBy.y = 0;
|
|
903
|
-
this._transBy.z = 0;
|
|
904
|
-
if ((n == "X") || (n == "XZ") || (n == "YX") || (n == "ALL")) {
|
|
905
|
-
if (this._local)
|
|
906
|
-
this._transBy.x = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._localX) / this._localX.length();
|
|
907
|
-
else
|
|
908
|
-
this._transBy.x = diff.x;
|
|
909
|
-
}
|
|
910
|
-
if ((n == "Y") || (n == "ZY") || (n == "YX") || (n == "ALL")) {
|
|
911
|
-
if (this._local)
|
|
912
|
-
this._transBy.y = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._localY) / this._localY.length();
|
|
913
|
-
else
|
|
914
|
-
this._transBy.y = diff.y;
|
|
915
|
-
}
|
|
916
|
-
if ((n == "Z") || (n == "XZ") || (n == "ZY") || (n == "ALL")) {
|
|
917
|
-
if (this._local)
|
|
918
|
-
this._transBy.z = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._localZ) / this._localZ.length();
|
|
919
|
-
else
|
|
920
|
-
this._transBy.z = diff.z;
|
|
921
|
-
}
|
|
922
|
-
this._transWithSnap(this._mesh, this._transBy, this._local);
|
|
923
|
-
// bound the translation
|
|
924
|
-
if (this._transBoundsMin) {
|
|
925
|
-
this._mesh.position.x = Math.max(this._mesh.position.x, this._transBoundsMin.x);
|
|
926
|
-
this._mesh.position.y = Math.max(this._mesh.position.y, this._transBoundsMin.y);
|
|
927
|
-
this._mesh.position.z = Math.max(this._mesh.position.z, this._transBoundsMin.z);
|
|
928
|
-
}
|
|
929
|
-
if (this._transBoundsMax) {
|
|
930
|
-
this._mesh.position.x = Math.min(this._mesh.position.x, this._transBoundsMax.x);
|
|
931
|
-
this._mesh.position.y = Math.min(this._mesh.position.y, this._transBoundsMax.y);
|
|
932
|
-
this._mesh.position.z = Math.min(this._mesh.position.z, this._transBoundsMax.z);
|
|
933
|
-
}
|
|
934
|
-
this._mesh.computeWorldMatrix(true);
|
|
935
|
-
};
|
|
936
|
-
EditControl.prototype._transWithSnap = function (mesh, trans, local) {
|
|
937
|
-
if (this._snapT) {
|
|
938
|
-
var snapit = false;
|
|
939
|
-
this._snapTV.addInPlace(trans);
|
|
940
|
-
if (Math.abs(this._snapTV.x) > this._tSnap.x) {
|
|
941
|
-
if (this._snapTV.x > 0)
|
|
942
|
-
trans.x = this._tSnap.x;
|
|
943
|
-
else
|
|
944
|
-
trans.x = -this._tSnap.x;
|
|
945
|
-
snapit = true;
|
|
946
|
-
}
|
|
947
|
-
if (Math.abs(this._snapTV.y) > this._tSnap.y) {
|
|
948
|
-
if (this._snapTV.y > 0)
|
|
949
|
-
trans.y = this._tSnap.y;
|
|
950
|
-
else
|
|
951
|
-
trans.y = -this._tSnap.y;
|
|
952
|
-
snapit = true;
|
|
953
|
-
}
|
|
954
|
-
if (Math.abs(this._snapTV.z) > this._tSnap.z) {
|
|
955
|
-
if (this._snapTV.z > 0)
|
|
956
|
-
trans.z = this._tSnap.z;
|
|
957
|
-
else
|
|
958
|
-
trans.z = -this._tSnap.z;
|
|
959
|
-
snapit = true;
|
|
960
|
-
}
|
|
961
|
-
if (snapit) {
|
|
962
|
-
if (Math.abs(trans.x) !== this._tSnap.x)
|
|
963
|
-
trans.x = 0;
|
|
964
|
-
if (Math.abs(trans.y) !== this._tSnap.y)
|
|
965
|
-
trans.y = 0;
|
|
966
|
-
if (Math.abs(trans.z) !== this._tSnap.z)
|
|
967
|
-
trans.z = 0;
|
|
968
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatsToRef(0, 0, 0, this._snapTV);
|
|
969
|
-
snapit = false;
|
|
970
|
-
}
|
|
971
|
-
else {
|
|
972
|
-
return;
|
|
973
|
-
}
|
|
974
|
-
}
|
|
975
|
-
if (local) {
|
|
976
|
-
//locallyTranslate moves the mesh wrt the absolute location not pivotlocation :(
|
|
977
|
-
//this.mesh.locallyTranslate(trans);
|
|
978
|
-
//
|
|
979
|
-
this._localX.normalizeToRef(this._tv1);
|
|
980
|
-
this._localY.normalizeToRef(this._tv2);
|
|
981
|
-
this._localZ.normalizeToRef(this._tv3);
|
|
982
|
-
this._mesh.translate(this._tv1, trans.x, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
983
|
-
this._mesh.translate(this._tv2, trans.y, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
984
|
-
this._mesh.translate(this._tv3, trans.z, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
985
|
-
}
|
|
986
|
-
else {
|
|
987
|
-
if (this._mesh.parent == null) {
|
|
988
|
-
this._mesh.position.addInPlace(trans);
|
|
989
|
-
}
|
|
990
|
-
else {
|
|
991
|
-
this._mesh.setAbsolutePosition(trans.addInPlace(this._mesh.absolutePosition));
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
};
|
|
995
|
-
EditControl.prototype._doScaling = function (diff) {
|
|
996
|
-
this._setLocalAxes(this._mesh);
|
|
997
|
-
this._scale.x = 0;
|
|
998
|
-
this._scale.y = 0;
|
|
999
|
-
this._scale.z = 0;
|
|
1000
|
-
var n = this._axisPicked.name;
|
|
1001
|
-
if ((n == "X") || (n == "XZ") || (n == "YX")) {
|
|
1002
|
-
this._scale.x = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._localX) / this._localX.length();
|
|
1003
|
-
if (this._mesh.scaling.x < 0)
|
|
1004
|
-
this._scale.x = -this._scale.x;
|
|
1005
|
-
//if(this.lhsRhs) this.scale.x=-this.scale.x;
|
|
1006
|
-
}
|
|
1007
|
-
if ((n == "Y") || (n == "ZY") || (n == "YX")) {
|
|
1008
|
-
this._scale.y = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._localY) / this._localY.length();
|
|
1009
|
-
if (this._mesh.scaling.y < 0)
|
|
1010
|
-
this._scale.y = -this._scale.y;
|
|
1011
|
-
}
|
|
1012
|
-
if ((n == "Z") || (n == "XZ") || (n == "ZY")) {
|
|
1013
|
-
this._scale.z = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._localZ) / this._localZ.length();
|
|
1014
|
-
if (this._mesh.scaling.z < 0)
|
|
1015
|
-
this._scale.z = -this._scale.z;
|
|
1016
|
-
}
|
|
1017
|
-
//as the mesh becomes large reduce the amount by which we scale.
|
|
1018
|
-
var bbd = this._boundingDimesion;
|
|
1019
|
-
this._scale.x = this._scale.x / bbd.x;
|
|
1020
|
-
this._scale.y = this._scale.y / bbd.y;
|
|
1021
|
-
this._scale.z = this._scale.z / bbd.z;
|
|
1022
|
-
if (n == "ALL") {
|
|
1023
|
-
//project movement along camera up vector
|
|
1024
|
-
//if up then scale up else scale down
|
|
1025
|
-
var s = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._mainCamera.upVector);
|
|
1026
|
-
s = s / Math.max(bbd.x, bbd.y, bbd.z);
|
|
1027
|
-
this._scale.copyFromFloats(s, s, s);
|
|
1028
|
-
}
|
|
1029
|
-
else {
|
|
1030
|
-
var inPlane = false;
|
|
1031
|
-
if (n == "XZ") {
|
|
1032
|
-
inPlane = true;
|
|
1033
|
-
if (Math.abs(this._scale.x) > Math.abs(this._scale.z)) {
|
|
1034
|
-
this._scale.z = this._scale.x;
|
|
1035
|
-
}
|
|
1036
|
-
else
|
|
1037
|
-
this._scale.x = this._scale.z;
|
|
1038
|
-
}
|
|
1039
|
-
else if (n == "ZY") {
|
|
1040
|
-
inPlane = true;
|
|
1041
|
-
if (Math.abs(this._scale.z) > Math.abs(this._scale.y)) {
|
|
1042
|
-
this._scale.y = this._scale.z;
|
|
1043
|
-
}
|
|
1044
|
-
else
|
|
1045
|
-
this._scale.z = this._scale.y;
|
|
1046
|
-
}
|
|
1047
|
-
else if (n == "YX") {
|
|
1048
|
-
inPlane = true;
|
|
1049
|
-
if (Math.abs(this._scale.y) > Math.abs(this._scale.x)) {
|
|
1050
|
-
this._scale.x = this._scale.y;
|
|
1051
|
-
}
|
|
1052
|
-
else
|
|
1053
|
-
this._scale.y = this._scale.x;
|
|
1054
|
-
}
|
|
1055
|
-
if (inPlane) {
|
|
1056
|
-
//check if the mouse/pointer was moved towards camera or away from camera
|
|
1057
|
-
//if towards then scale up else scale down
|
|
1058
|
-
this._ecRoot.position.subtractToRef(this._mainCamera.position, this._cameraTOec);
|
|
1059
|
-
var s = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(diff, this._cameraTOec);
|
|
1060
|
-
this._scale.x = Math.abs(this._scale.x);
|
|
1061
|
-
this._scale.y = Math.abs(this._scale.y);
|
|
1062
|
-
this._scale.z = Math.abs(this._scale.z);
|
|
1063
|
-
if (s > 0) {
|
|
1064
|
-
if (this._mesh.scaling.x > 0)
|
|
1065
|
-
this._scale.x = -this._scale.x;
|
|
1066
|
-
//if(this.lhsRhs) this.scale.y=Math.abs(this.scale.y);
|
|
1067
|
-
if (this._mesh.scaling.y > 0)
|
|
1068
|
-
this._scale.y = -this._scale.y;
|
|
1069
|
-
if (this._mesh.scaling.z > 0)
|
|
1070
|
-
this._scale.z = -this._scale.z;
|
|
1071
|
-
}
|
|
1072
|
-
else {
|
|
1073
|
-
//this.scale.x=Math.abs(this.scale.x);
|
|
1074
|
-
//if(this.lhsRhs) this.scale.y=-Math.abs(this.scale.y);
|
|
1075
|
-
//else this.scale.y=Math.abs(this.scale.y);
|
|
1076
|
-
if (this._mesh.scaling.x < 0)
|
|
1077
|
-
this._scale.x = -this._scale.x;
|
|
1078
|
-
if (this._mesh.scaling.y < 0)
|
|
1079
|
-
this._scale.y = -this._scale.y;
|
|
1080
|
-
if (this._mesh.scaling.z < 0)
|
|
1081
|
-
this._scale.z = -this._scale.z;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
this._scaleWithSnap(this._mesh, this._scale);
|
|
1086
|
-
// bound the scale
|
|
1087
|
-
if (this._scaleBoundsMin) {
|
|
1088
|
-
this._mesh.scaling.x = Math.max(this._mesh.scaling.x, this._scaleBoundsMin.x);
|
|
1089
|
-
this._mesh.scaling.y = Math.max(this._mesh.scaling.y, this._scaleBoundsMin.y);
|
|
1090
|
-
this._mesh.scaling.z = Math.max(this._mesh.scaling.z, this._scaleBoundsMin.z);
|
|
1091
|
-
}
|
|
1092
|
-
if (this._scaleBoundsMax) {
|
|
1093
|
-
this._mesh.scaling.x = Math.min(this._mesh.scaling.x, this._scaleBoundsMax.x);
|
|
1094
|
-
this._mesh.scaling.y = Math.min(this._mesh.scaling.y, this._scaleBoundsMax.y);
|
|
1095
|
-
this._mesh.scaling.z = Math.min(this._mesh.scaling.z, this._scaleBoundsMax.z);
|
|
1096
|
-
}
|
|
1097
|
-
};
|
|
1098
|
-
EditControl.prototype._scaleWithSnap = function (mesh, p) {
|
|
1099
|
-
if (this._snapS) {
|
|
1100
|
-
var snapit = false;
|
|
1101
|
-
this._snapSV.addInPlace(p);
|
|
1102
|
-
if (Math.abs(this._snapSV.x) > this._scaleSnap) {
|
|
1103
|
-
if (p.x > 0)
|
|
1104
|
-
p.x = this._scaleSnap;
|
|
1105
|
-
else
|
|
1106
|
-
p.x = -this._scaleSnap;
|
|
1107
|
-
snapit = true;
|
|
1108
|
-
}
|
|
1109
|
-
if (Math.abs(this._snapSV.y) > this._scaleSnap) {
|
|
1110
|
-
if (p.y > 0)
|
|
1111
|
-
p.y = this._scaleSnap;
|
|
1112
|
-
else
|
|
1113
|
-
p.y = -this._scaleSnap;
|
|
1114
|
-
snapit = true;
|
|
1115
|
-
}
|
|
1116
|
-
if (Math.abs(this._snapSV.z) > this._scaleSnap) {
|
|
1117
|
-
if (p.z > 0)
|
|
1118
|
-
p.z = this._scaleSnap;
|
|
1119
|
-
else
|
|
1120
|
-
p.z = -this._scaleSnap;
|
|
1121
|
-
snapit = true;
|
|
1122
|
-
}
|
|
1123
|
-
if (!snapit)
|
|
1124
|
-
return;
|
|
1125
|
-
if ((Math.abs(p.x) !== this._scaleSnap) && (p.x !== 0))
|
|
1126
|
-
p.x = 0;
|
|
1127
|
-
if ((Math.abs(p.y) !== this._scaleSnap) && (p.y !== 0))
|
|
1128
|
-
p.y = 0;
|
|
1129
|
-
if ((Math.abs(p.z) !== this._scaleSnap) && (p.z !== 0))
|
|
1130
|
-
p.z = 0;
|
|
1131
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatsToRef(0, 0, 0, this._snapSV);
|
|
1132
|
-
snapit = false;
|
|
1133
|
-
}
|
|
1134
|
-
mesh.scaling.addInPlace(p);
|
|
1135
|
-
};
|
|
1136
|
-
/*
|
|
1137
|
-
* This would be called after rotation or scaling as the local axes direction or length might have changed
|
|
1138
|
-
* We need to set the local axis as these are used in all three modes to figure out
|
|
1139
|
-
* direction of mouse move wrt the axes
|
|
1140
|
-
* TODO should use world pivotmatrix instead of worldmatrix - incase pivot axes were rotated?
|
|
1141
|
-
*/
|
|
1142
|
-
EditControl.prototype._setLocalAxes = function (mesh) {
|
|
1143
|
-
var meshMatrix = mesh.getWorldMatrix();
|
|
1144
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatArrayToRef(meshMatrix.m, 0, this._localX);
|
|
1145
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatArrayToRef(meshMatrix.m, 4, this._localY);
|
|
1146
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].FromFloatArrayToRef(meshMatrix.m, 8, this._localZ);
|
|
1147
|
-
};
|
|
1148
|
-
EditControl.prototype._getBoundingDimension = function (mesh) {
|
|
1149
|
-
if (mesh instanceof babylonjs__WEBPACK_IMPORTED_MODULE_0__["AbstractMesh"]) {
|
|
1150
|
-
{ }
|
|
1151
|
-
var bb = mesh.getBoundingInfo().boundingBox;
|
|
1152
|
-
var bd = bb.maximum.subtract(bb.minimum);
|
|
1153
|
-
if (bd.x == 0)
|
|
1154
|
-
bd.x = 1;
|
|
1155
|
-
if (bd.y == 0)
|
|
1156
|
-
bd.y = 1;
|
|
1157
|
-
if (bd.z == 0)
|
|
1158
|
-
bd.z = 1;
|
|
1159
|
-
return bd;
|
|
1160
|
-
}
|
|
1161
|
-
else
|
|
1162
|
-
return new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](1, 1, 1);
|
|
1163
|
-
};
|
|
1164
|
-
/*
|
|
1165
|
-
*
|
|
1166
|
-
* For the sake of speed the editcontrol calculates bounding info only once.
|
|
1167
|
-
* This is in the constructor.
|
|
1168
|
-
* Now The boundingbox dimension can change if the mesh is baked.
|
|
1169
|
-
* If the editcontrol is attached to the mesh when the mesh was baked then
|
|
1170
|
-
* the scaling speed will be incorrect.
|
|
1171
|
-
* Thus client application should call refreshBoundingInfo if it bakes the mesh.
|
|
1172
|
-
*
|
|
1173
|
-
*/
|
|
1174
|
-
EditControl.prototype.refreshBoundingInfo = function () {
|
|
1175
|
-
this._boundingDimesion = this._getBoundingDimension(this._mesh);
|
|
1176
|
-
};
|
|
1177
|
-
EditControl.prototype._doRotation = function (mesh, axis, newPos, prevPos) {
|
|
1178
|
-
//for now no rotation if parents have non uniform scale
|
|
1179
|
-
if (this._local && (this._mesh.parent != null) && this._isScaleUnEqual(mesh)) {
|
|
1180
|
-
this._setLocalAxes(this._ecRoot);
|
|
1181
|
-
}
|
|
1182
|
-
else {
|
|
1183
|
-
this._setLocalAxes(mesh);
|
|
1184
|
-
}
|
|
1185
|
-
var angle = 0;
|
|
1186
|
-
//rotation axis
|
|
1187
|
-
var rAxis;
|
|
1188
|
-
if (axis == this._rX)
|
|
1189
|
-
rAxis = this._local ? this._localX : babylonjs__WEBPACK_IMPORTED_MODULE_0__["Axis"].X;
|
|
1190
|
-
else if (axis == this._rY)
|
|
1191
|
-
rAxis = this._local ? this._localY : babylonjs__WEBPACK_IMPORTED_MODULE_0__["Axis"].Y;
|
|
1192
|
-
else if (axis == this._rZ)
|
|
1193
|
-
rAxis = this._local ? this._localZ : babylonjs__WEBPACK_IMPORTED_MODULE_0__["Axis"].Z;
|
|
1194
|
-
this._ecRoot.position.subtractToRef(this._mainCamera.position, this._cameraTOec);
|
|
1195
|
-
/**
|
|
1196
|
-
* A)first find the angle and the direction (clockwise or anticlockwise) by which the user was trying to rotate
|
|
1197
|
-
* from the user(camera) perspective
|
|
1198
|
-
*/
|
|
1199
|
-
if (this._rotate2) {
|
|
1200
|
-
angle = this._getAngle2(prevPos, newPos, this._mainCamera.position, this._cameraTOec, rAxis);
|
|
1201
|
-
//TODO check why we need to handle righ hand this way
|
|
1202
|
-
if (this._scene.useRightHandedSystem)
|
|
1203
|
-
angle = -angle;
|
|
1204
|
-
}
|
|
1205
|
-
else {
|
|
1206
|
-
angle = this._getAngle(prevPos, newPos, mesh.getAbsolutePivotPoint(), this._cameraTOec);
|
|
1207
|
-
}
|
|
1208
|
-
if (this._lhsRhs) {
|
|
1209
|
-
angle = -angle;
|
|
1210
|
-
}
|
|
1211
|
-
/**
|
|
1212
|
-
* B)then rotate based on users(camera) postion and orientation in the local/world space
|
|
1213
|
-
*
|
|
1214
|
-
*/
|
|
1215
|
-
if (this._snapR) {
|
|
1216
|
-
this._snapRA += angle;
|
|
1217
|
-
angle = 0;
|
|
1218
|
-
if (Math.abs(this._snapRA) >= this._rotSnap) {
|
|
1219
|
-
if (this._snapRA > 0)
|
|
1220
|
-
angle = this._rotSnap;
|
|
1221
|
-
else
|
|
1222
|
-
angle = -this._rotSnap;
|
|
1223
|
-
this._snapRA = 0;
|
|
1224
|
-
}
|
|
1225
|
-
}
|
|
1226
|
-
if (angle !== 0) {
|
|
1227
|
-
this._cameraTOec.normalize();
|
|
1228
|
-
if (axis == this._rAll) {
|
|
1229
|
-
mesh.rotate(this._cameraTOec, -angle, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
1230
|
-
}
|
|
1231
|
-
else {
|
|
1232
|
-
if (babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(rAxis, this._cameraTOec) >= 0)
|
|
1233
|
-
angle = -angle;
|
|
1234
|
-
mesh.rotate(rAxis, angle, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
1235
|
-
}
|
|
1236
|
-
if (this._eulerian) {
|
|
1237
|
-
mesh.rotation = mesh.rotationQuaternion.toEulerAngles();
|
|
1238
|
-
mesh.rotationQuaternion = null;
|
|
1239
|
-
}
|
|
1240
|
-
if (this._local) {
|
|
1241
|
-
if (this._lhsRhs) {
|
|
1242
|
-
angle = -angle;
|
|
1243
|
-
}
|
|
1244
|
-
if ((this._mesh.parent != null) && this._isScaleUnEqual(mesh)) {
|
|
1245
|
-
if (axis == this._rAll) {
|
|
1246
|
-
this._ecRoot.rotate(this._cameraTOec, -angle, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
1247
|
-
}
|
|
1248
|
-
else {
|
|
1249
|
-
this._ecRoot.rotate(rAxis, angle, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Space"].WORLD);
|
|
1250
|
-
}
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
|
-
}
|
|
1254
|
-
};
|
|
1255
|
-
EditControl.prototype._getPosOnPickPlane = function () {
|
|
1256
|
-
var _this = this;
|
|
1257
|
-
var engine = this._scene.getEngine();
|
|
1258
|
-
var x = (engine.isPointerLock) ? this._canvas.width * 0.5 : this._scene.pointerX;
|
|
1259
|
-
var y = (engine.isPointerLock) ? this._canvas.height * 0.5 : this._scene.pointerY;
|
|
1260
|
-
var pickinfo = this._scene.pick(x, y, function (mesh) {
|
|
1261
|
-
return mesh == _this._pickedPlane;
|
|
1262
|
-
}, null, this._mainCamera);
|
|
1263
|
-
if (pickinfo.hit) {
|
|
1264
|
-
return pickinfo.pickedPoint;
|
|
1265
|
-
}
|
|
1266
|
-
else {
|
|
1267
|
-
return null;
|
|
1268
|
-
}
|
|
1269
|
-
};
|
|
1270
|
-
EditControl.prototype._hideBaxis = function () {
|
|
1271
|
-
this._bXaxis.visibility = 0;
|
|
1272
|
-
this._bYaxis.visibility = 0;
|
|
1273
|
-
this._bZaxis.visibility = 0;
|
|
1274
|
-
};
|
|
1275
|
-
// private _setAxesVisiblity(v: number) {
|
|
1276
|
-
// if (this._transEnabled) {
|
|
1277
|
-
// this._tEndX.visibility = v;
|
|
1278
|
-
// this._tEndY.visibility = v;
|
|
1279
|
-
// this._tEndZ.visibility = v;
|
|
1280
|
-
// this._tEndXZ.visibility = v;
|
|
1281
|
-
// this._tEndZY.visibility = v;
|
|
1282
|
-
// this._tEndYX.visibility = v;
|
|
1283
|
-
// this._tEndAll.visibility = v;
|
|
1284
|
-
// }
|
|
1285
|
-
// if (this._rotEnabled) {
|
|
1286
|
-
// this._rEndX.visibility = v;
|
|
1287
|
-
// this._rEndY.visibility = v;
|
|
1288
|
-
// this._rEndZ.visibility = v;
|
|
1289
|
-
// this._rEndAll.visibility = v;
|
|
1290
|
-
// }
|
|
1291
|
-
// if (this._scaleEnabled) {
|
|
1292
|
-
// this._sEndX.visibility = v;
|
|
1293
|
-
// this._sEndY.visibility = v;
|
|
1294
|
-
// this._sEndZ.visibility = v;
|
|
1295
|
-
// this._sEndXZ.visibility = v;
|
|
1296
|
-
// this._sEndZY.visibility = v;
|
|
1297
|
-
// this._sEndYX.visibility = v;
|
|
1298
|
-
// this._sEndAll.visibility = v;
|
|
1299
|
-
// }
|
|
1300
|
-
// }
|
|
1301
|
-
EditControl.prototype.getRotationQuaternion = function () {
|
|
1302
|
-
return this._ecRoot.rotationQuaternion;
|
|
1303
|
-
};
|
|
1304
|
-
EditControl.prototype.getPosition = function () {
|
|
1305
|
-
return this._ecRoot.position;
|
|
1306
|
-
};
|
|
1307
|
-
EditControl.prototype.isTranslationEnabled = function () {
|
|
1308
|
-
return this._transEnabled;
|
|
1309
|
-
};
|
|
1310
|
-
EditControl.prototype.enableTranslation = function () {
|
|
1311
|
-
if (this._hidden)
|
|
1312
|
-
return;
|
|
1313
|
-
if (this._tX == null) {
|
|
1314
|
-
this._createTransAxes();
|
|
1315
|
-
this._tCtl.parent = this._ecRoot;
|
|
1316
|
-
}
|
|
1317
|
-
this._clearPrevOverMesh();
|
|
1318
|
-
if (!this._transEnabled) {
|
|
1319
|
-
this._setVisibility(this._all_tEnd, this._visibility);
|
|
1320
|
-
this._transEnabled = true;
|
|
1321
|
-
this.disableRotation();
|
|
1322
|
-
this.disableScaling();
|
|
1323
|
-
}
|
|
1324
|
-
};
|
|
1325
|
-
EditControl.prototype.disableTranslation = function () {
|
|
1326
|
-
if (this._transEnabled) {
|
|
1327
|
-
this._setVisibility(this._all_tEnd, 0);
|
|
1328
|
-
this._transEnabled = false;
|
|
1329
|
-
}
|
|
1330
|
-
};
|
|
1331
|
-
EditControl.prototype.isRotationEnabled = function () {
|
|
1332
|
-
return this._rotEnabled;
|
|
1333
|
-
};
|
|
1334
|
-
EditControl.prototype.returnEuler = function (euler) {
|
|
1335
|
-
this._eulerian = euler;
|
|
1336
|
-
};
|
|
1337
|
-
EditControl.prototype.enableRotation = function () {
|
|
1338
|
-
if (this._hidden)
|
|
1339
|
-
return;
|
|
1340
|
-
if (this._rCtl == null) {
|
|
1341
|
-
this._createRotAxes();
|
|
1342
|
-
this._rCtl.parent = this._ecRoot;
|
|
1343
|
-
}
|
|
1344
|
-
this._clearPrevOverMesh();
|
|
1345
|
-
if (!this._rotEnabled) {
|
|
1346
|
-
this._setVisibility(this._all_rEnd, this._visibility);
|
|
1347
|
-
this._rotEnabled = true;
|
|
1348
|
-
this.disableTranslation();
|
|
1349
|
-
this.disableScaling();
|
|
1350
|
-
}
|
|
1351
|
-
};
|
|
1352
|
-
EditControl.prototype.disableRotation = function () {
|
|
1353
|
-
if (this._rotEnabled) {
|
|
1354
|
-
this._setVisibility(this._all_rEnd, 0);
|
|
1355
|
-
this._rotEnabled = false;
|
|
1356
|
-
}
|
|
1357
|
-
};
|
|
1358
|
-
EditControl.prototype.isScalingEnabled = function () {
|
|
1359
|
-
return this._scaleEnabled;
|
|
1360
|
-
};
|
|
1361
|
-
EditControl.prototype.enableScaling = function () {
|
|
1362
|
-
if (this._hidden)
|
|
1363
|
-
return;
|
|
1364
|
-
if (this._sX == null) {
|
|
1365
|
-
this._createScaleAxes();
|
|
1366
|
-
this._sCtl.parent = this._ecRoot;
|
|
1367
|
-
}
|
|
1368
|
-
this._clearPrevOverMesh();
|
|
1369
|
-
if (!this._scaleEnabled) {
|
|
1370
|
-
this._setVisibility(this._all_sEnd, this._visibility);
|
|
1371
|
-
this._scaleEnabled = true;
|
|
1372
|
-
this.disableTranslation();
|
|
1373
|
-
this.disableRotation();
|
|
1374
|
-
}
|
|
1375
|
-
};
|
|
1376
|
-
EditControl.prototype.disableScaling = function () {
|
|
1377
|
-
if (this._scaleEnabled) {
|
|
1378
|
-
this._setVisibility(this._all_sEnd, 0);
|
|
1379
|
-
this._scaleEnabled = false;
|
|
1380
|
-
}
|
|
1381
|
-
};
|
|
1382
|
-
EditControl.prototype.setScaleBounds = function (min, max) {
|
|
1383
|
-
this._scaleBoundsMin = min ? min : null;
|
|
1384
|
-
this._scaleBoundsMax = max ? max : null;
|
|
1385
|
-
if (this._scaleBoundsMin != null) {
|
|
1386
|
-
if (this._scaleBoundsMin.x == 0)
|
|
1387
|
-
this._scaleBoundsMin.x = 0.00000001;
|
|
1388
|
-
if (this._scaleBoundsMin.y == 0)
|
|
1389
|
-
this._scaleBoundsMin.y = 0.00000001;
|
|
1390
|
-
if (this._scaleBoundsMin.z == 0)
|
|
1391
|
-
this._scaleBoundsMin.z = 0.00000001;
|
|
1392
|
-
}
|
|
1393
|
-
};
|
|
1394
|
-
EditControl.prototype.removeScaleBounds = function () {
|
|
1395
|
-
this._scaleBoundsMin = null;
|
|
1396
|
-
this._scaleBoundsMax = null;
|
|
1397
|
-
};
|
|
1398
|
-
EditControl.prototype.setTransBounds = function (min, max) {
|
|
1399
|
-
this._transBoundsMin = min ? min : null;
|
|
1400
|
-
this._transBoundsMax = max ? max : null;
|
|
1401
|
-
};
|
|
1402
|
-
EditControl.prototype.removeTransBounds = function () {
|
|
1403
|
-
this._transBoundsMin = null;
|
|
1404
|
-
this._transBoundsMax = null;
|
|
1405
|
-
};
|
|
1406
|
-
EditControl.prototype.setRotBounds = function (min, max) {
|
|
1407
|
-
this._rotBoundsMin = min ? min : null;
|
|
1408
|
-
this._rotBoundsMax = max ? max : null;
|
|
1409
|
-
};
|
|
1410
|
-
EditControl.prototype.removeRotBounds = function () {
|
|
1411
|
-
this._rotBoundsMin = null;
|
|
1412
|
-
this._rotBoundsMax = null;
|
|
1413
|
-
};
|
|
1414
|
-
/*
|
|
1415
|
-
* create big and small axeses which will be shown in translate, rotate and scale mode.
|
|
1416
|
-
*
|
|
1417
|
-
*/
|
|
1418
|
-
EditControl.prototype._createCommonAxes = function () {
|
|
1419
|
-
var guideAxes = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"]("", this._scene);
|
|
1420
|
-
//the big axes, shown when an axis is selected
|
|
1421
|
-
this._bXaxis = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-100, 0, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](100, 0, 0)], this._scene);
|
|
1422
|
-
this._bYaxis = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, -100, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 100, 0)], this._scene);
|
|
1423
|
-
this._bZaxis = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, -100), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 100)], this._scene);
|
|
1424
|
-
//lines are now pickable too
|
|
1425
|
-
this._bXaxis.isPickable = false;
|
|
1426
|
-
this._bYaxis.isPickable = false;
|
|
1427
|
-
this._bZaxis.isPickable = false;
|
|
1428
|
-
this._bXaxis.parent = guideAxes;
|
|
1429
|
-
this._bYaxis.parent = guideAxes;
|
|
1430
|
-
this._bZaxis.parent = guideAxes;
|
|
1431
|
-
this._bXaxis.color = this._redCol;
|
|
1432
|
-
this._bYaxis.color = this._greenCol;
|
|
1433
|
-
this._bZaxis.color = this._blueCol;
|
|
1434
|
-
this._hideBaxis();
|
|
1435
|
-
//the small axis
|
|
1436
|
-
var al = this._axesLen * this._axesScale * 0.75;
|
|
1437
|
-
this._xaxis = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](al, 0, 0)], this._scene);
|
|
1438
|
-
this._yaxis = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, al, 0)], this._scene);
|
|
1439
|
-
this._zaxis = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, al)], this._scene);
|
|
1440
|
-
//lines are now pickable too
|
|
1441
|
-
this._xaxis.isPickable = false;
|
|
1442
|
-
this._yaxis.isPickable = false;
|
|
1443
|
-
this._zaxis.isPickable = false;
|
|
1444
|
-
this._xaxis.parent = guideAxes;
|
|
1445
|
-
this._yaxis.parent = guideAxes;
|
|
1446
|
-
this._zaxis.parent = guideAxes;
|
|
1447
|
-
this._xaxis.color = this._redCol;
|
|
1448
|
-
this._yaxis.color = this._greenCol;
|
|
1449
|
-
this._zaxis.color = this._blueCol;
|
|
1450
|
-
this._xaxis.renderingGroupId = 1;
|
|
1451
|
-
this._yaxis.renderingGroupId = 1;
|
|
1452
|
-
this._zaxis.renderingGroupId = 1;
|
|
1453
|
-
return guideAxes;
|
|
1454
|
-
};
|
|
1455
|
-
EditControl.prototype._createPickPlanes = function () {
|
|
1456
|
-
this._pALL = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreatePlane("", 5, this._scene);
|
|
1457
|
-
this._pXZ = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreatePlane("", 5, this._scene);
|
|
1458
|
-
this._pZY = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreatePlane("", 5, this._scene);
|
|
1459
|
-
this._pYX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreatePlane("", 5, this._scene);
|
|
1460
|
-
this._pALL.isPickable = false;
|
|
1461
|
-
this._pXZ.isPickable = false;
|
|
1462
|
-
this._pZY.isPickable = false;
|
|
1463
|
-
this._pYX.isPickable = false;
|
|
1464
|
-
this._pALL.visibility = 0;
|
|
1465
|
-
this._pXZ.visibility = 0;
|
|
1466
|
-
this._pZY.visibility = 0;
|
|
1467
|
-
this._pYX.visibility = 0;
|
|
1468
|
-
this._pALL.renderingGroupId = 1;
|
|
1469
|
-
this._pXZ.renderingGroupId = 1;
|
|
1470
|
-
this._pZY.renderingGroupId = 1;
|
|
1471
|
-
this._pYX.renderingGroupId = 1;
|
|
1472
|
-
this._pALL.lookAt(this._mainCamera.position);
|
|
1473
|
-
this._pXZ.rotate(babylonjs__WEBPACK_IMPORTED_MODULE_0__["Axis"].X, 1.57);
|
|
1474
|
-
this._pZY.rotate(babylonjs__WEBPACK_IMPORTED_MODULE_0__["Axis"].Y, 1.57);
|
|
1475
|
-
var pickPlanes = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"]("", this._scene);
|
|
1476
|
-
this._pALL.parent = pickPlanes;
|
|
1477
|
-
this._pXZ.parent = pickPlanes;
|
|
1478
|
-
this._pZY.parent = pickPlanes;
|
|
1479
|
-
this._pYX.parent = pickPlanes;
|
|
1480
|
-
return pickPlanes;
|
|
1481
|
-
};
|
|
1482
|
-
EditControl.prototype._createTransAxes = function () {
|
|
1483
|
-
var r = this._pickWidth * 2 * this._axesScale;
|
|
1484
|
-
var l = this._axesLen * this._axesScale;
|
|
1485
|
-
this._tCtl = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"]("", this._scene);
|
|
1486
|
-
/*pickable invisible boxes around axes lines*/
|
|
1487
|
-
this._createPickableTrans(r, l, this._tCtl, this._scene);
|
|
1488
|
-
//non pickable but visible cones at end of axes lines
|
|
1489
|
-
this._createNonPickableTrans(r, l, this._scene);
|
|
1490
|
-
};
|
|
1491
|
-
EditControl.prototype._createPickableTrans = function (r, l, tCtl, scene) {
|
|
1492
|
-
var tX = this._extrudeBox(r / 2, l);
|
|
1493
|
-
tX.name = "X";
|
|
1494
|
-
var tY = tX.clone("Y");
|
|
1495
|
-
var tZ = tX.clone("Z");
|
|
1496
|
-
var tXZ = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("XZ", { size: r * 2 }, scene);
|
|
1497
|
-
var tZY = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("ZY", { size: r * 2 }, scene);
|
|
1498
|
-
var tYX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("YX", { size: r * 2 }, scene);
|
|
1499
|
-
tXZ.rotation.x = 1.57;
|
|
1500
|
-
tZY.rotation.y = -1.57;
|
|
1501
|
-
tXZ.position.x = 2 * r;
|
|
1502
|
-
tXZ.position.z = 2 * r;
|
|
1503
|
-
tZY.position.z = 2 * r;
|
|
1504
|
-
tZY.position.y = 2 * r;
|
|
1505
|
-
tYX.position.y = 2 * r;
|
|
1506
|
-
tYX.position.x = 2 * r;
|
|
1507
|
-
tXZ.bakeCurrentTransformIntoVertices();
|
|
1508
|
-
tZY.bakeCurrentTransformIntoVertices();
|
|
1509
|
-
tYX.bakeCurrentTransformIntoVertices();
|
|
1510
|
-
var tAll = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateBox("ALL", r * 2, scene);
|
|
1511
|
-
tX.parent = tCtl;
|
|
1512
|
-
tY.parent = tCtl;
|
|
1513
|
-
tZ.parent = tCtl;
|
|
1514
|
-
tXZ.parent = tCtl;
|
|
1515
|
-
tZY.parent = tCtl;
|
|
1516
|
-
tYX.parent = tCtl;
|
|
1517
|
-
tAll.parent = tCtl;
|
|
1518
|
-
tX.rotation.y = 1.57;
|
|
1519
|
-
tY.rotation.x -= 1.57;
|
|
1520
|
-
this._tX = tX;
|
|
1521
|
-
this._tY = tY;
|
|
1522
|
-
this._tZ = tZ;
|
|
1523
|
-
this._tXZ = tXZ;
|
|
1524
|
-
this._tZY = tZY;
|
|
1525
|
-
this._tYX = tYX;
|
|
1526
|
-
this._tAll = tAll;
|
|
1527
|
-
this._all_t = [tX, tY, tZ, tXZ, tZY, tYX, tAll];
|
|
1528
|
-
this._setVisibility(this._all_t, 0);
|
|
1529
|
-
//do not want clients picking this
|
|
1530
|
-
//we will pick using mesh filter in scene.pick function
|
|
1531
|
-
this._setPickableFalse(this._all_t);
|
|
1532
|
-
};
|
|
1533
|
-
EditControl.prototype._createNonPickableTrans = function (r, l, scene) {
|
|
1534
|
-
//cone length
|
|
1535
|
-
var cl = l / 5;
|
|
1536
|
-
//cone base radius
|
|
1537
|
-
//let cr: number = r;
|
|
1538
|
-
var tEndX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateCylinder("", cl, 0, r, 6, 1, scene);
|
|
1539
|
-
var tEndY = tEndX.clone("");
|
|
1540
|
-
var tEndZ = tEndX.clone("");
|
|
1541
|
-
var s = r * 2;
|
|
1542
|
-
var tEndXZ = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("XZ", { size: s }, scene);
|
|
1543
|
-
var tEndZY = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("ZY", { size: s }, scene);
|
|
1544
|
-
var tEndYX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("YX", { size: s }, scene);
|
|
1545
|
-
var tEndAll = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateBox("ALL", r, scene);
|
|
1546
|
-
tEndX.rotation.x = 1.57;
|
|
1547
|
-
tEndY.rotation.x = 1.57;
|
|
1548
|
-
tEndZ.rotation.x = 1.57;
|
|
1549
|
-
tEndXZ.rotation.x = 1.57;
|
|
1550
|
-
tEndZY.rotation.y = 1.57;
|
|
1551
|
-
//tEndYX.rotation.x = 0;
|
|
1552
|
-
tEndXZ.position.x = s;
|
|
1553
|
-
tEndXZ.position.z = s;
|
|
1554
|
-
tEndZY.position.z = s;
|
|
1555
|
-
tEndZY.position.y = s;
|
|
1556
|
-
tEndYX.position.y = s;
|
|
1557
|
-
tEndYX.position.x = s;
|
|
1558
|
-
tEndX.parent = this._tX;
|
|
1559
|
-
tEndY.parent = this._tY;
|
|
1560
|
-
tEndZ.parent = this._tZ;
|
|
1561
|
-
tEndXZ.parent = this._tXZ;
|
|
1562
|
-
tEndZY.parent = this._tZY;
|
|
1563
|
-
tEndYX.parent = this._tYX;
|
|
1564
|
-
tEndAll.parent = this._tAll;
|
|
1565
|
-
tEndX.position.z = l - cl / 2;
|
|
1566
|
-
tEndY.position.z = l - cl / 2;
|
|
1567
|
-
tEndZ.position.z = l - cl / 2;
|
|
1568
|
-
tEndX.material = this._redMat;
|
|
1569
|
-
tEndY.material = this._greenMat;
|
|
1570
|
-
tEndZ.material = this._blueMat;
|
|
1571
|
-
tEndXZ.material = this._greenMat;
|
|
1572
|
-
tEndZY.material = this._redMat;
|
|
1573
|
-
tEndYX.material = this._blueMat;
|
|
1574
|
-
tEndAll.material = this._yellowMat;
|
|
1575
|
-
this._tEndX = tEndX;
|
|
1576
|
-
this._tEndY = tEndY;
|
|
1577
|
-
this._tEndZ = tEndZ;
|
|
1578
|
-
this._tEndXZ = tEndXZ;
|
|
1579
|
-
this._tEndZY = tEndZY;
|
|
1580
|
-
this._tEndYX = tEndYX;
|
|
1581
|
-
this._tEndAll = tEndAll;
|
|
1582
|
-
this._all_tEnd = [tEndX, tEndY, tEndZ, tEndXZ, tEndZY, tEndYX, tEndAll];
|
|
1583
|
-
this._setPickableFalse(this._all_tEnd);
|
|
1584
|
-
this._setRenderingGroup(this._all_tEnd);
|
|
1585
|
-
};
|
|
1586
|
-
EditControl.prototype.setRotGuideFull = function (y) {
|
|
1587
|
-
if (y)
|
|
1588
|
-
this._guideSize = 360;
|
|
1589
|
-
else
|
|
1590
|
-
this._guideSize = 180;
|
|
1591
|
-
if (this._rCtl != null) {
|
|
1592
|
-
this._rCtl.dispose();
|
|
1593
|
-
this._rAll.dispose();
|
|
1594
|
-
this._rCtl = null;
|
|
1595
|
-
this.enableRotation();
|
|
1596
|
-
}
|
|
1597
|
-
};
|
|
1598
|
-
EditControl.prototype._createRotAxes = function () {
|
|
1599
|
-
var d = this._axesLen * this._axesScale * 2;
|
|
1600
|
-
this._rCtl = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"]("", this._scene);
|
|
1601
|
-
//pickable invisible torus around the rotation circles
|
|
1602
|
-
this._createPickableRot(d, this._rCtl);
|
|
1603
|
-
/*non pickable but visible circles */
|
|
1604
|
-
this._createNonPickableRot(d);
|
|
1605
|
-
};
|
|
1606
|
-
EditControl.prototype._createPickableRot = function (d, rCtl) {
|
|
1607
|
-
var rX = this._createTube(d / 2, this._guideSize);
|
|
1608
|
-
var rY = this._createTube(d / 2, this._guideSize);
|
|
1609
|
-
var rZ = this._createTube(d / 2, this._guideSize);
|
|
1610
|
-
var rAll = this._createTube(d / 1.75, 360);
|
|
1611
|
-
rX.name = "X";
|
|
1612
|
-
rY.name = "Y";
|
|
1613
|
-
rZ.name = "Z";
|
|
1614
|
-
rAll.name = "ALL";
|
|
1615
|
-
rX.rotation.z = 1.57;
|
|
1616
|
-
rZ.rotation.x = -1.57;
|
|
1617
|
-
rX.bakeCurrentTransformIntoVertices();
|
|
1618
|
-
rZ.bakeCurrentTransformIntoVertices();
|
|
1619
|
-
rAll.rotation.x = 1.57;
|
|
1620
|
-
rX.parent = rCtl;
|
|
1621
|
-
rY.parent = rCtl;
|
|
1622
|
-
rZ.parent = rCtl;
|
|
1623
|
-
rAll.parent = this._pALL;
|
|
1624
|
-
this._rX = rX;
|
|
1625
|
-
this._rY = rY;
|
|
1626
|
-
this._rZ = rZ;
|
|
1627
|
-
this._rAll = rAll;
|
|
1628
|
-
this._all_r = [rX, rY, rZ, rAll];
|
|
1629
|
-
this._setVisibility(this._all_r, 0);
|
|
1630
|
-
//do not want clients picking this
|
|
1631
|
-
//we will pick using mesh filter in scene.pick function
|
|
1632
|
-
this._setPickableFalse(this._all_r);
|
|
1633
|
-
};
|
|
1634
|
-
EditControl.prototype._createNonPickableRot = function (d) {
|
|
1635
|
-
var rEndX = this._createCircle(d / 2, this._guideSize, false);
|
|
1636
|
-
var rEndY = rEndX.clone("");
|
|
1637
|
-
var rEndZ = rEndX.clone("");
|
|
1638
|
-
var rEndAll = this._createCircle(d / 1.75, 360, false);
|
|
1639
|
-
var rEndAll2 = this._createCircle(d / 2, 360, false);
|
|
1640
|
-
rEndX.parent = this._rX;
|
|
1641
|
-
rEndY.parent = this._rY;
|
|
1642
|
-
rEndZ.parent = this._rZ;
|
|
1643
|
-
rEndX.rotation.z = 1.57;
|
|
1644
|
-
rEndZ.rotation.x = -1.57;
|
|
1645
|
-
rEndAll.parent = this._rAll;
|
|
1646
|
-
rEndAll2.parent = this._rAll;
|
|
1647
|
-
rEndX.color = this._redCol;
|
|
1648
|
-
rEndY.color = this._greenCol;
|
|
1649
|
-
rEndZ.color = this._blueCol;
|
|
1650
|
-
rEndAll.color = this._yellowCol;
|
|
1651
|
-
rEndAll2.color = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"].Gray();
|
|
1652
|
-
this._rEndX = rEndX;
|
|
1653
|
-
this._rEndY = rEndY;
|
|
1654
|
-
this._rEndZ = rEndZ;
|
|
1655
|
-
this._rEndAll = rEndAll;
|
|
1656
|
-
this._rEndAll2 = rEndAll2;
|
|
1657
|
-
this._all_rEnd = [rEndX, rEndY, rEndZ, rEndAll, rEndAll2];
|
|
1658
|
-
this._setPickableFalse(this._all_rEnd);
|
|
1659
|
-
this._setRenderingGroup(this._all_rEnd);
|
|
1660
|
-
};
|
|
1661
|
-
EditControl.prototype._setVisibility = function (meshes, v) {
|
|
1662
|
-
meshes.map(function (m) { return m.visibility = v; });
|
|
1663
|
-
};
|
|
1664
|
-
EditControl.prototype._setPickableFalse = function (meshes) {
|
|
1665
|
-
meshes.map(function (m) { m.isPickable = false; });
|
|
1666
|
-
};
|
|
1667
|
-
EditControl.prototype._setRenderingGroup = function (meshes) {
|
|
1668
|
-
meshes.map(function (m) { return m.renderingGroupId = 2; });
|
|
1669
|
-
};
|
|
1670
|
-
EditControl.prototype._extrudeBox = function (w, l) {
|
|
1671
|
-
var shape = [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](w, w, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-w, w, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](-w, -w, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](w, -w, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](w, w, 0)];
|
|
1672
|
-
var path = [new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, 0), new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](0, 0, l)];
|
|
1673
|
-
var box = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].ExtrudeShape("", shape, path, 1, 0, 2, this._scene);
|
|
1674
|
-
return box;
|
|
1675
|
-
};
|
|
1676
|
-
EditControl.prototype._createCircle = function (r, t, double) {
|
|
1677
|
-
if (t === null)
|
|
1678
|
-
t = 360;
|
|
1679
|
-
var points = [];
|
|
1680
|
-
var x;
|
|
1681
|
-
var z;
|
|
1682
|
-
var a = 3.14 / 180;
|
|
1683
|
-
var p = 0;
|
|
1684
|
-
for (var i = 0; i <= t; i = i + 5) {
|
|
1685
|
-
x = r * Math.cos(i * a);
|
|
1686
|
-
if (i == 90)
|
|
1687
|
-
z = r;
|
|
1688
|
-
else if (i == 270)
|
|
1689
|
-
z = -r;
|
|
1690
|
-
else
|
|
1691
|
-
z = r * Math.sin(i * a);
|
|
1692
|
-
points[p] = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](x, 0, z);
|
|
1693
|
-
p++;
|
|
1694
|
-
}
|
|
1695
|
-
if (double) {
|
|
1696
|
-
r = r - 0.04;
|
|
1697
|
-
for (var i = 0; i <= t; i = i + 5) {
|
|
1698
|
-
x = r * Math.cos(i * a);
|
|
1699
|
-
if (i == 90)
|
|
1700
|
-
z = r;
|
|
1701
|
-
else if (i == 270)
|
|
1702
|
-
z = -r;
|
|
1703
|
-
else
|
|
1704
|
-
z = r * Math.sin(i * a);
|
|
1705
|
-
points[p] = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](x, 0, z);
|
|
1706
|
-
p++;
|
|
1707
|
-
}
|
|
1708
|
-
}
|
|
1709
|
-
var circle = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateLines("", points, this._scene);
|
|
1710
|
-
return circle;
|
|
1711
|
-
};
|
|
1712
|
-
EditControl.prototype._createTube = function (r, t) {
|
|
1713
|
-
if (t === null)
|
|
1714
|
-
t = 360;
|
|
1715
|
-
var points = [];
|
|
1716
|
-
var x;
|
|
1717
|
-
var z;
|
|
1718
|
-
var a = 3.14 / 180;
|
|
1719
|
-
var p = 0;
|
|
1720
|
-
for (var i = 0; i <= t; i = i + 30) {
|
|
1721
|
-
x = r * Math.cos(i * a);
|
|
1722
|
-
if (i == 90)
|
|
1723
|
-
z = r;
|
|
1724
|
-
else if (i == 270)
|
|
1725
|
-
z = -r;
|
|
1726
|
-
else
|
|
1727
|
-
z = r * Math.sin(i * a);
|
|
1728
|
-
points[p] = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"](x, 0, z);
|
|
1729
|
-
p++;
|
|
1730
|
-
}
|
|
1731
|
-
var tube = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateTube("", points, this._pickWidth * this._axesScale * 2, 3, null, babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].NO_CAP, this._scene);
|
|
1732
|
-
return tube;
|
|
1733
|
-
};
|
|
1734
|
-
EditControl.prototype._createScaleAxes = function () {
|
|
1735
|
-
var r = this._pickWidth * 2 * this._axesScale;
|
|
1736
|
-
var l = this._axesLen * this._axesScale;
|
|
1737
|
-
this._sCtl = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"]("", this._scene);
|
|
1738
|
-
/* pickable , invisible part */
|
|
1739
|
-
this._createPickableScale(r, l, this._sCtl);
|
|
1740
|
-
/* non pickable visible boxes at end of axes */
|
|
1741
|
-
this._createNonPickableScale(r, l);
|
|
1742
|
-
};
|
|
1743
|
-
EditControl.prototype._createPickableScale = function (r, l, sCtl) {
|
|
1744
|
-
var sX = this._extrudeBox(r / 2, l);
|
|
1745
|
-
sX.name = "X";
|
|
1746
|
-
var sY = sX.clone("Y");
|
|
1747
|
-
var sZ = sX.clone("Z");
|
|
1748
|
-
var sXZ = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("XZ", { size: r * 2 }, this._scene);
|
|
1749
|
-
var sZY = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("ZY", { size: r * 2 }, this._scene);
|
|
1750
|
-
var sYX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("YX", { size: r * 2 }, this._scene);
|
|
1751
|
-
sXZ.rotation.x = 1.57;
|
|
1752
|
-
sZY.rotation.y = -1.57;
|
|
1753
|
-
sXZ.position.x = 2 * r;
|
|
1754
|
-
sXZ.position.z = 2 * r;
|
|
1755
|
-
sZY.position.z = 2 * r;
|
|
1756
|
-
sZY.position.y = 2 * r;
|
|
1757
|
-
sYX.position.y = 2 * r;
|
|
1758
|
-
sYX.position.x = 2 * r;
|
|
1759
|
-
sXZ.bakeCurrentTransformIntoVertices();
|
|
1760
|
-
sZY.bakeCurrentTransformIntoVertices();
|
|
1761
|
-
sYX.bakeCurrentTransformIntoVertices();
|
|
1762
|
-
var sAll = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateBox("ALL", 2 * r, this._scene);
|
|
1763
|
-
sX.parent = sCtl;
|
|
1764
|
-
sY.parent = sCtl;
|
|
1765
|
-
sZ.parent = sCtl;
|
|
1766
|
-
sAll.parent = sCtl;
|
|
1767
|
-
sXZ.parent = sCtl;
|
|
1768
|
-
sZY.parent = sCtl;
|
|
1769
|
-
sYX.parent = sCtl;
|
|
1770
|
-
sX.rotation.y = 1.57;
|
|
1771
|
-
sY.rotation.x -= 1.57;
|
|
1772
|
-
this._sX = sX;
|
|
1773
|
-
this._sY = sY;
|
|
1774
|
-
this._sZ = sZ;
|
|
1775
|
-
this._sXZ = sXZ;
|
|
1776
|
-
this._sZY = sZY;
|
|
1777
|
-
this._sYX = sYX;
|
|
1778
|
-
this._sAll = sAll;
|
|
1779
|
-
this._all_s = [sX, sY, sZ, sXZ, sZY, sYX, sAll];
|
|
1780
|
-
this._setVisibility(this._all_s, 0);
|
|
1781
|
-
//do not want clients picking this
|
|
1782
|
-
//we will pick using mesh filter in scene.pick function
|
|
1783
|
-
this._setPickableFalse(this._all_s);
|
|
1784
|
-
};
|
|
1785
|
-
EditControl.prototype._createNonPickableScale = function (r, l) {
|
|
1786
|
-
var sEndX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateBox("", r, this._scene);
|
|
1787
|
-
var sEndY = sEndX.clone("");
|
|
1788
|
-
var sEndZ = sEndX.clone("");
|
|
1789
|
-
var s = r * 2;
|
|
1790
|
-
var sEndXZ = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("XZ", { size: s }, this._scene);
|
|
1791
|
-
var sEndZY = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("ZY", { size: s }, this._scene);
|
|
1792
|
-
var sEndYX = babylonjs__WEBPACK_IMPORTED_MODULE_0__["MeshBuilder"].CreatePlane("YX", { size: s }, this._scene);
|
|
1793
|
-
var sEndAll = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Mesh"].CreateBox("ALL", r, this._scene);
|
|
1794
|
-
sEndXZ.rotation.x = 1.57;
|
|
1795
|
-
sEndZY.rotation.y = -1.57;
|
|
1796
|
-
sEndXZ.position.x = s;
|
|
1797
|
-
sEndXZ.position.z = s;
|
|
1798
|
-
sEndZY.position.z = s;
|
|
1799
|
-
sEndZY.position.y = s;
|
|
1800
|
-
sEndYX.position.y = s;
|
|
1801
|
-
sEndYX.position.x = s;
|
|
1802
|
-
sEndX.parent = this._sX;
|
|
1803
|
-
sEndY.parent = this._sY;
|
|
1804
|
-
sEndZ.parent = this._sZ;
|
|
1805
|
-
sEndXZ.parent = this._sXZ;
|
|
1806
|
-
sEndZY.parent = this._sZY;
|
|
1807
|
-
sEndYX.parent = this._sYX;
|
|
1808
|
-
sEndAll.parent = this._sAll;
|
|
1809
|
-
sEndX.position.z = l - r / 2;
|
|
1810
|
-
sEndY.position.z = l - r / 2;
|
|
1811
|
-
sEndZ.position.z = l - r / 2;
|
|
1812
|
-
sEndX.material = this._redMat;
|
|
1813
|
-
sEndY.material = this._greenMat;
|
|
1814
|
-
sEndZ.material = this._blueMat;
|
|
1815
|
-
sEndXZ.material = this._greenMat;
|
|
1816
|
-
sEndZY.material = this._redMat;
|
|
1817
|
-
sEndYX.material = this._blueMat;
|
|
1818
|
-
sEndAll.material = this._yellowMat;
|
|
1819
|
-
this._sEndX = sEndX;
|
|
1820
|
-
this._sEndY = sEndY;
|
|
1821
|
-
this._sEndZ = sEndZ;
|
|
1822
|
-
this._sEndXZ = sEndXZ;
|
|
1823
|
-
this._sEndZY = sEndZY;
|
|
1824
|
-
this._sEndYX = sEndYX;
|
|
1825
|
-
this._sEndAll = sEndAll;
|
|
1826
|
-
this._all_sEnd = [sEndX, sEndY, sEndZ, sEndXZ, sEndZY, sEndYX, sEndAll];
|
|
1827
|
-
this._setPickableFalse(this._all_sEnd);
|
|
1828
|
-
this._setRenderingGroup(this._all_sEnd);
|
|
1829
|
-
};
|
|
1830
|
-
/**
|
|
1831
|
-
* checks if a have left hand , right hand issue.
|
|
1832
|
-
* In other words if a mesh is a LHS mesh in RHS system or
|
|
1833
|
-
* a RHS mesh in LHS system
|
|
1834
|
-
* The X axis will be reversed in such cases.
|
|
1835
|
-
* thus Cross product of X and Y should be inverse of Z.
|
|
1836
|
-
*
|
|
1837
|
-
*/
|
|
1838
|
-
// private _check_LHS_RHS(mesh: Mesh) {
|
|
1839
|
-
// let actualZ = Vector3.Cross(this._localX, this._localY);
|
|
1840
|
-
// //same direction or opposite direction of Z
|
|
1841
|
-
// if (Vector3.Dot(actualZ, this._localZ) < 0) return true;
|
|
1842
|
-
// else return false;
|
|
1843
|
-
// }
|
|
1844
|
-
/**
|
|
1845
|
-
* set how transparent the axes are
|
|
1846
|
-
* 0 to 1
|
|
1847
|
-
* 0 - completely transparent
|
|
1848
|
-
* 1 - completely non transparent
|
|
1849
|
-
* default is 0.75
|
|
1850
|
-
*/
|
|
1851
|
-
EditControl.prototype.setVisibility = function (v) {
|
|
1852
|
-
this._visibility = v;
|
|
1853
|
-
};
|
|
1854
|
-
EditControl.prototype.setLocal = function (l) {
|
|
1855
|
-
if (this._local == l)
|
|
1856
|
-
return;
|
|
1857
|
-
this._local = l;
|
|
1858
|
-
if (!l) {
|
|
1859
|
-
this._ecRoot.rotationQuaternion = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity();
|
|
1860
|
-
}
|
|
1861
|
-
};
|
|
1862
|
-
EditControl.prototype.isLocal = function () {
|
|
1863
|
-
return this._local;
|
|
1864
|
-
};
|
|
1865
|
-
EditControl.prototype.setTransSnap = function (s) {
|
|
1866
|
-
this._snapT = s;
|
|
1867
|
-
};
|
|
1868
|
-
EditControl.prototype.isTransSnap = function () {
|
|
1869
|
-
return this._snapT;
|
|
1870
|
-
};
|
|
1871
|
-
EditControl.prototype.setRotSnap = function (s) {
|
|
1872
|
-
this._snapR = s;
|
|
1873
|
-
};
|
|
1874
|
-
EditControl.prototype.isRotSnap = function () {
|
|
1875
|
-
return this._snapR;
|
|
1876
|
-
};
|
|
1877
|
-
EditControl.prototype.setScaleSnap = function (s) {
|
|
1878
|
-
this._snapS = s;
|
|
1879
|
-
};
|
|
1880
|
-
EditControl.prototype.isScaleSnap = function () {
|
|
1881
|
-
return this._snapS;
|
|
1882
|
-
};
|
|
1883
|
-
EditControl.prototype.setTransSnapValue = function (t) {
|
|
1884
|
-
this._tSnap.copyFromFloats(t, t, t);
|
|
1885
|
-
this._transSnap = t;
|
|
1886
|
-
};
|
|
1887
|
-
EditControl.prototype.getTransSnapValue = function () {
|
|
1888
|
-
return this._transSnap;
|
|
1889
|
-
};
|
|
1890
|
-
EditControl.prototype.setRotSnapValue = function (r) {
|
|
1891
|
-
this._rotSnap = r;
|
|
1892
|
-
};
|
|
1893
|
-
EditControl.prototype.getRotSnapValue = function () {
|
|
1894
|
-
return this._rotSnap;
|
|
1895
|
-
};
|
|
1896
|
-
EditControl.prototype.setScaleSnapValue = function (r) {
|
|
1897
|
-
this._scaleSnap = r;
|
|
1898
|
-
};
|
|
1899
|
-
EditControl.prototype.getScaleSnapValue = function () {
|
|
1900
|
-
return this._scaleSnap;
|
|
1901
|
-
};
|
|
1902
|
-
EditControl.prototype._getAngle2 = function (p1, p2, cameraPos, c2ec, mN) {
|
|
1903
|
-
/**
|
|
1904
|
-
* A) find out if the camera is above , below, left, right of the rotation plane
|
|
1905
|
-
*/
|
|
1906
|
-
//project "camera to ec" vector onto mesh normal to get distance to rotation plane
|
|
1907
|
-
var d = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(c2ec, mN);
|
|
1908
|
-
//scale mesh normal by above ammount to get vector to rotation plane
|
|
1909
|
-
mN.scaleToRef(d, this._tv1);
|
|
1910
|
-
//get the point of intersection of vector from camera perpendicular to rotation plane
|
|
1911
|
-
cameraPos.addToRef(this._tv1, this._tv2);
|
|
1912
|
-
var i = this._tv2; //save some typing
|
|
1913
|
-
//find the co-ordinate of this point in the cameras frame of reference
|
|
1914
|
-
this._mainCamera.getWorldMatrix().invertToRef(this._tm);
|
|
1915
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(this._tv2, this._tm, this._tv2);
|
|
1916
|
-
//find in which quadarant the point (and thus the rotation plane) is in the camera xy plane
|
|
1917
|
-
var q = 0; //(1=x y,2=-x y,3=-x -y,4=x -y)
|
|
1918
|
-
if (i.x >= 0 && i.y >= 0)
|
|
1919
|
-
q = 1;
|
|
1920
|
-
else if (i.x <= 0 && i.y >= 0)
|
|
1921
|
-
q = 2;
|
|
1922
|
-
else if (i.x <= 0 && i.y <= 0)
|
|
1923
|
-
q = 3;
|
|
1924
|
-
else if (i.x >= 0 && i.y <= 0)
|
|
1925
|
-
q = 4;
|
|
1926
|
-
/**
|
|
1927
|
-
* B) find out if the user moved pointer up,down, right, left
|
|
1928
|
-
*/
|
|
1929
|
-
//find movement vector in camera frame of reference
|
|
1930
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(p1, this._tm, this._tv1);
|
|
1931
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].TransformCoordinatesToRef(p2, this._tm, this._tv2);
|
|
1932
|
-
this._tv2.subtractInPlace(this._tv1);
|
|
1933
|
-
var mv = this._tv2; //save some typing
|
|
1934
|
-
//for now lets set the angle magnitutde same as amount by which the mouse moved
|
|
1935
|
-
var angle = mv.length();
|
|
1936
|
-
var m = ""; //(u ,d ,r,l)
|
|
1937
|
-
if (mv.x >= 0 && mv.y >= 0) {
|
|
1938
|
-
if (mv.x >= mv.y)
|
|
1939
|
-
m = "r";
|
|
1940
|
-
else
|
|
1941
|
-
m = "u";
|
|
1942
|
-
}
|
|
1943
|
-
else if (mv.x <= 0 && mv.y >= 0) {
|
|
1944
|
-
if (-mv.x >= mv.y)
|
|
1945
|
-
m = "l";
|
|
1946
|
-
else
|
|
1947
|
-
m = "u";
|
|
1948
|
-
}
|
|
1949
|
-
else if (mv.x <= 0 && mv.y <= 0) {
|
|
1950
|
-
if (-mv.x >= -mv.y)
|
|
1951
|
-
m = "l";
|
|
1952
|
-
else
|
|
1953
|
-
m = "d";
|
|
1954
|
-
}
|
|
1955
|
-
else if (mv.x >= 0 && mv.y <= 0) {
|
|
1956
|
-
if (mv.x >= -mv.y)
|
|
1957
|
-
m = "r";
|
|
1958
|
-
else
|
|
1959
|
-
m = "d";
|
|
1960
|
-
}
|
|
1961
|
-
/**
|
|
1962
|
-
* C) decide if the user was trying to rotate clockwise (+1) or anti-clockwise(-1)
|
|
1963
|
-
*/
|
|
1964
|
-
var r = 0;
|
|
1965
|
-
//if mouse moved down /up and rotation plane is on right or left side of user
|
|
1966
|
-
if (m == "d") {
|
|
1967
|
-
if (q == 1 || q == 4)
|
|
1968
|
-
r = 1;
|
|
1969
|
-
else
|
|
1970
|
-
r = -1;
|
|
1971
|
-
}
|
|
1972
|
-
else if (m == "u") {
|
|
1973
|
-
if (q == 1 || q == 4)
|
|
1974
|
-
r = -1;
|
|
1975
|
-
else
|
|
1976
|
-
r = 1;
|
|
1977
|
-
//if mouse moved right/left and rotation plane is above or below user
|
|
1978
|
-
}
|
|
1979
|
-
else if (m == "r") {
|
|
1980
|
-
if (q == 2 || q == 1)
|
|
1981
|
-
r = 1;
|
|
1982
|
-
else
|
|
1983
|
-
r = -1;
|
|
1984
|
-
}
|
|
1985
|
-
else if (m == "l") {
|
|
1986
|
-
if (q == 2 || q == 1)
|
|
1987
|
-
r = -1;
|
|
1988
|
-
else
|
|
1989
|
-
r = 1;
|
|
1990
|
-
}
|
|
1991
|
-
return r * angle;
|
|
1992
|
-
};
|
|
1993
|
-
/**
|
|
1994
|
-
* finds the angle subtended from points p1 to p2 around the point p
|
|
1995
|
-
* checks if the user was trying to rotate clockwise (+ve in LHS) or anticlockwise (-ve in LHS)
|
|
1996
|
-
* to figure this check the orientation of the user(camera)to ec vector with the rotation normal vector
|
|
1997
|
-
*/
|
|
1998
|
-
EditControl.prototype._getAngle = function (p1, p2, p, c2ec) {
|
|
1999
|
-
p1.subtractToRef(p, this._tv1);
|
|
2000
|
-
p2.subtractToRef(p, this._tv2);
|
|
2001
|
-
babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].CrossToRef(this._tv1, this._tv2, this._tv3);
|
|
2002
|
-
var angle = Math.asin(this._tv3.length() / (this._tv1.length() * this._tv2.length()));
|
|
2003
|
-
//camera looking down from front of plane or looking up from behind plane
|
|
2004
|
-
if ((babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Dot(this._tv3, c2ec) > 0)) {
|
|
2005
|
-
angle = -1 * angle;
|
|
2006
|
-
}
|
|
2007
|
-
return angle;
|
|
2008
|
-
};
|
|
2009
|
-
EditControl._getStandardMaterial = function (col, scene) {
|
|
2010
|
-
var mat = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["StandardMaterial"]("", scene);
|
|
2011
|
-
mat.emissiveColor = col;
|
|
2012
|
-
mat.diffuseColor = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"].Black();
|
|
2013
|
-
mat.specularColor = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Color3"].Black();
|
|
2014
|
-
mat.backFaceCulling = false;
|
|
2015
|
-
return mat;
|
|
2016
|
-
};
|
|
2017
|
-
EditControl.prototype._createMaterials = function (scene) {
|
|
2018
|
-
this._redMat = EditControl._getStandardMaterial(this._redCol, scene);
|
|
2019
|
-
this._greenMat = EditControl._getStandardMaterial(this._greenCol, scene);
|
|
2020
|
-
this._blueMat = EditControl._getStandardMaterial(this._blueCol, scene);
|
|
2021
|
-
this._whiteMat = EditControl._getStandardMaterial(this._whiteCol, scene);
|
|
2022
|
-
this._yellowMat = EditControl._getStandardMaterial(this._yellowCol, scene);
|
|
2023
|
-
};
|
|
2024
|
-
EditControl.prototype._disposeMaterials = function () {
|
|
2025
|
-
this._redMat.dispose();
|
|
2026
|
-
this._greenMat.dispose();
|
|
2027
|
-
this._blueMat.dispose();
|
|
2028
|
-
this._whiteMat.dispose();
|
|
2029
|
-
this._yellowMat.dispose();
|
|
2030
|
-
};
|
|
2031
|
-
return EditControl;
|
|
2032
|
-
}());
|
|
2033
|
-
|
|
2034
|
-
var ActHist = /** @class */ (function () {
|
|
2035
|
-
function ActHist(mesh, capacity) {
|
|
2036
|
-
this.lastMax = 10;
|
|
2037
|
-
this.acts = new Array();
|
|
2038
|
-
this.last = -1;
|
|
2039
|
-
this.current = -1;
|
|
2040
|
-
this.mesh = mesh;
|
|
2041
|
-
this.lastMax = capacity - 1;
|
|
2042
|
-
this.add();
|
|
2043
|
-
}
|
|
2044
|
-
ActHist.prototype.setCapacity = function (c) {
|
|
2045
|
-
if ((c == 0)) {
|
|
2046
|
-
console.error("capacity should be more than zero");
|
|
2047
|
-
return;
|
|
2048
|
-
}
|
|
2049
|
-
this.lastMax = c - 1;
|
|
2050
|
-
this.last = -1;
|
|
2051
|
-
this.current = -1;
|
|
2052
|
-
this.acts = new Array();
|
|
2053
|
-
this.add();
|
|
2054
|
-
};
|
|
2055
|
-
ActHist.prototype.add = function (at) {
|
|
2056
|
-
if (at === undefined)
|
|
2057
|
-
at = null;
|
|
2058
|
-
var act = new Act(this.mesh, at);
|
|
2059
|
-
if ((this.current < this.last)) {
|
|
2060
|
-
this.acts.splice(this.current + 1);
|
|
2061
|
-
this.last = this.current;
|
|
2062
|
-
}
|
|
2063
|
-
if ((this.last == this.lastMax)) {
|
|
2064
|
-
this.acts.shift();
|
|
2065
|
-
this.acts.push(act);
|
|
2066
|
-
}
|
|
2067
|
-
else {
|
|
2068
|
-
this.acts.push(act);
|
|
2069
|
-
this.last++;
|
|
2070
|
-
this.current++;
|
|
2071
|
-
}
|
|
2072
|
-
};
|
|
2073
|
-
ActHist.prototype.undo = function () {
|
|
2074
|
-
if ((this.current > 0)) {
|
|
2075
|
-
var at = this.acts[this.current].getActionType();
|
|
2076
|
-
this.current--;
|
|
2077
|
-
this.acts[this.current].perform(this.mesh);
|
|
2078
|
-
return at;
|
|
2079
|
-
}
|
|
2080
|
-
};
|
|
2081
|
-
ActHist.prototype.redo = function () {
|
|
2082
|
-
if ((this.current < this.last)) {
|
|
2083
|
-
this.current++;
|
|
2084
|
-
this.acts[this.current].perform(this.mesh);
|
|
2085
|
-
return this.acts[this.current].getActionType();
|
|
2086
|
-
}
|
|
2087
|
-
};
|
|
2088
|
-
return ActHist;
|
|
2089
|
-
}());
|
|
2090
|
-
var Act = /** @class */ (function () {
|
|
2091
|
-
function Act(mesh, at) {
|
|
2092
|
-
this._p = mesh.position.clone();
|
|
2093
|
-
//if (mesh.rotationQuaternion == null) {
|
|
2094
|
-
if (mesh.rotationQuaternion == null) {
|
|
2095
|
-
this._rQ = null;
|
|
2096
|
-
this._rE = mesh.rotation.clone();
|
|
2097
|
-
}
|
|
2098
|
-
else {
|
|
2099
|
-
this._rQ = mesh.rotationQuaternion.clone();
|
|
2100
|
-
this._rE = null;
|
|
2101
|
-
}
|
|
2102
|
-
this._s = mesh.scaling.clone();
|
|
2103
|
-
this._at = at;
|
|
2104
|
-
}
|
|
2105
|
-
Act.prototype.getActionType = function () {
|
|
2106
|
-
return this._at;
|
|
2107
|
-
};
|
|
2108
|
-
Act.prototype.perform = function (mesh) {
|
|
2109
|
-
mesh.position.copyFrom(this._p);
|
|
2110
|
-
//check if we are doing euler or quaternion now
|
|
2111
|
-
//also check what were we doing when the rotation value
|
|
2112
|
-
//was captured and set value accordingly
|
|
2113
|
-
if (mesh.rotationQuaternion == null) {
|
|
2114
|
-
if (this._rE != null) {
|
|
2115
|
-
//mesh.rotation = this.rE.clone();
|
|
2116
|
-
mesh.rotation.copyFrom(this._rE);
|
|
2117
|
-
}
|
|
2118
|
-
else {
|
|
2119
|
-
//mesh.rotation = this.r.toEulerAngles();
|
|
2120
|
-
mesh.rotation.copyFrom(this._rQ.toEulerAngles());
|
|
2121
|
-
}
|
|
2122
|
-
}
|
|
2123
|
-
else {
|
|
2124
|
-
if (this._rQ != null) {
|
|
2125
|
-
mesh.rotationQuaternion.copyFrom(this._rQ);
|
|
2126
|
-
}
|
|
2127
|
-
else {
|
|
2128
|
-
//TODO use BABYLON.Quaternion.RotationYawPitchRoll(rot.y, rot.x, rot.z) instead of toQuaternion.
|
|
2129
|
-
//mesh.rotationQuaternion.copyFrom(this.rE.toQuaternion());
|
|
2130
|
-
mesh.rotationQuaternion.copyFrom(babylonjs__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(this._rE.y, this._rE.x, this._rE.z));
|
|
2131
|
-
}
|
|
2132
|
-
}
|
|
2133
|
-
mesh.scaling.copyFrom(this._s);
|
|
2134
|
-
};
|
|
2135
|
-
return Act;
|
|
2136
|
-
}());
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
/***/ }),
|
|
2140
65
|
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
66
|
+
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
67
|
+
exports.EditControl = void 0;
|
|
68
|
+
const babylonjs_1 = __webpack_require__(/*! babylonjs */ "babylonjs");
|
|
69
|
+
var ActionType;
|
|
70
|
+
(function (ActionType) {
|
|
71
|
+
ActionType[ActionType["TRANS"] = 0] = "TRANS";
|
|
72
|
+
ActionType[ActionType["ROT"] = 1] = "ROT";
|
|
73
|
+
ActionType[ActionType["SCALE"] = 2] = "SCALE";
|
|
74
|
+
})(ActionType || (ActionType = {}));
|
|
75
|
+
/**
|
|
76
|
+
* Draws a transform widget at the mesh's location (its pivot location).
|
|
77
|
+
* The widget transforms(translates,rotates and scales) the mesh based on user
|
|
78
|
+
* interactions with the widget.
|
|
79
|
+
* The widget shows the mesh position and rotation at any time.
|
|
80
|
+
* The widget follows the mesh constantly.
|
|
81
|
+
* Note: An alternate approach would have been for the mesh to follow the widget.
|
|
82
|
+
* The problem with the alternate approach - syncing the transforms
|
|
83
|
+
* if the mesh was being transformed by entities other than the widget say physics
|
|
84
|
+
* or script for example.
|
|
85
|
+
*
|
|
86
|
+
*/
|
|
87
|
+
class EditControl {
|
|
88
|
+
_isEulerian(mesh) {
|
|
89
|
+
return ((mesh.rotationQuaternion == null) || (mesh.rotationQuaternion == undefined));
|
|
90
|
+
}
|
|
91
|
+
constructor(mesh, camera, canvas, scale, pickWidth) {
|
|
92
|
+
this._local = true;
|
|
93
|
+
this._snapT = false;
|
|
94
|
+
this._snapR = false;
|
|
95
|
+
this._transSnap = 1;
|
|
96
|
+
this._rotSnap = Math.PI / 18;
|
|
97
|
+
this._axesLen = 0.4;
|
|
98
|
+
this._axesScale = 1;
|
|
99
|
+
//how close to an axis should we get before we can pick it
|
|
100
|
+
this._pickWidth = 0.02;
|
|
101
|
+
this._redCol = new babylonjs_1.Color3(1, 0.34, 0.26);
|
|
102
|
+
this._greenCol = new babylonjs_1.Color3(0.0, 0.8, 0.16);
|
|
103
|
+
this._blueCol = new babylonjs_1.Color3(0.21, 0.5, 1);
|
|
104
|
+
this._whiteCol = new babylonjs_1.Color3(0.7, 0.7, 0.7);
|
|
105
|
+
this._yellowCol = new babylonjs_1.Color3(1, 1, 0);
|
|
106
|
+
//axes visibility
|
|
107
|
+
this._visibility = 0.75;
|
|
108
|
+
//lhs-rhs issue. lhs mesh in rhs or rhs mesh in lhs
|
|
109
|
+
this._lhsRhs = false;
|
|
110
|
+
this._ecMatrix = new babylonjs_1.Matrix();
|
|
111
|
+
//edit control to camera vector
|
|
112
|
+
this._ecTOcamera = new babylonjs_1.Vector3(0, 0, 0);
|
|
113
|
+
//how far away from camera should the edit control appear to be
|
|
114
|
+
this._distFromCamera = 2;
|
|
115
|
+
//vector from camera to edit control
|
|
116
|
+
this._cameraTOec = new babylonjs_1.Vector3(0, 0, 0);
|
|
117
|
+
this._cameraNormal = new babylonjs_1.Vector3(0, 0, 0);
|
|
118
|
+
this._prevState = "";
|
|
119
|
+
this._hidden = false;
|
|
120
|
+
this._actionListener = null;
|
|
121
|
+
this._actionStartListener = null;
|
|
122
|
+
this._actionEndListener = null;
|
|
123
|
+
this._pDown = false;
|
|
124
|
+
this._pointerIsOver = false;
|
|
125
|
+
this._editing = false;
|
|
126
|
+
//rotate differently if camera is too close to the rotation plane
|
|
127
|
+
this._rotate2 = false;
|
|
128
|
+
//TODO when translating, the orientation of pALL keeps changing
|
|
129
|
+
//TODo this is not so with rotation or scaling
|
|
130
|
+
//TODO so for translation instead of pALL maybe we should use the camera view plane for picking
|
|
131
|
+
this._transBy = new babylonjs_1.Vector3(0, 0, 0);
|
|
132
|
+
this._snapTV = new babylonjs_1.Vector3(0, 0, 0);
|
|
133
|
+
this._snapS = false;
|
|
134
|
+
this._snapSV = new babylonjs_1.Vector3(0, 0, 0);
|
|
135
|
+
this._scaleSnap = 0.25;
|
|
136
|
+
this._scale = new babylonjs_1.Vector3(0, 0, 0);
|
|
137
|
+
this._localX = new babylonjs_1.Vector3(0, 0, 0);
|
|
138
|
+
this._localY = new babylonjs_1.Vector3(0, 0, 0);
|
|
139
|
+
this._localZ = new babylonjs_1.Vector3(0, 0, 0);
|
|
140
|
+
// private _eulerian: boolean = false;
|
|
141
|
+
this._snapRA = 0;
|
|
142
|
+
this._transEnabled = false;
|
|
143
|
+
this._rotEnabled = false;
|
|
144
|
+
this._scaleEnabled = false;
|
|
145
|
+
this._guideSize = 180;
|
|
146
|
+
this._tSnap = new babylonjs_1.Vector3(this._transSnap, this._transSnap, this._transSnap);
|
|
147
|
+
//few temp vectors & matrix
|
|
148
|
+
this._tv1 = new babylonjs_1.Vector3(0, 0, 0);
|
|
149
|
+
this._tv2 = new babylonjs_1.Vector3(0, 0, 0);
|
|
150
|
+
this._tv3 = new babylonjs_1.Vector3(0, 0, 0);
|
|
151
|
+
this._tm = new babylonjs_1.Matrix();
|
|
152
|
+
this._mesh = mesh;
|
|
153
|
+
this._mainCamera = camera;
|
|
154
|
+
this._canvas = canvas;
|
|
155
|
+
if (scale != null) {
|
|
156
|
+
this._axesScale = scale;
|
|
157
|
+
}
|
|
158
|
+
if (pickWidth != null) {
|
|
159
|
+
this._pickWidth = pickWidth;
|
|
160
|
+
}
|
|
161
|
+
this._utilLayer = babylonjs_1.UtilityLayerRenderer.DefaultUtilityLayer;
|
|
162
|
+
this._utilLayer.onlyCheckPointerDownEvents = false;
|
|
163
|
+
this._scene = this._utilLayer.utilityLayerScene;
|
|
164
|
+
this._actHist = new ActHist(mesh, 10);
|
|
165
|
+
mesh.computeWorldMatrix(true);
|
|
166
|
+
this._boundingDimesion = this._getBoundingDimension(mesh);
|
|
167
|
+
this._setLocalAxes(mesh);
|
|
168
|
+
this._lhsRhs = this._check_LHS_RHS(mesh);
|
|
169
|
+
if (this._lhsRhs)
|
|
170
|
+
console.warn("we have lhs rhs issue " + this._lhsRhs);
|
|
171
|
+
//build the edit control axes
|
|
172
|
+
this._ecRoot = new babylonjs_1.Mesh("", this._scene);
|
|
173
|
+
this._ecRoot.rotationQuaternion = babylonjs_1.Quaternion.Identity();
|
|
174
|
+
this._ecRoot.visibility = 0;
|
|
175
|
+
this._ecRoot.isPickable = false;
|
|
176
|
+
this._createMaterials(this._scene);
|
|
177
|
+
let guideAxes = this._createCommonAxes();
|
|
178
|
+
guideAxes.parent = this._ecRoot;
|
|
179
|
+
//build the pickplanes
|
|
180
|
+
let pickPlanes = this._createPickPlanes();
|
|
181
|
+
pickPlanes.parent = this._ecRoot;
|
|
182
|
+
this._pointerdown = (evt) => { return this._onPointerDown(evt); };
|
|
183
|
+
this._pointerup = (evt) => { return this._onPointerUp(evt); };
|
|
184
|
+
this._pointermove = (evt) => { return this._onPointerMove(evt); };
|
|
185
|
+
//use canvas rather than scene to handle pointer events
|
|
186
|
+
//scene cannot have mutiple eventlisteners for an event
|
|
187
|
+
//with canvas one will have to do ones own pickinfo generation.
|
|
188
|
+
canvas.addEventListener("pointerdown", this._pointerdown, false);
|
|
189
|
+
canvas.addEventListener("pointerup", this._pointerup, false);
|
|
190
|
+
canvas.addEventListener("pointermove", this._pointermove, false);
|
|
191
|
+
this._renderer = () => { return this._renderLoopProcess(); };
|
|
192
|
+
this._scene.registerBeforeRender(this._renderer);
|
|
193
|
+
}
|
|
194
|
+
getRoot() {
|
|
195
|
+
return this._ecRoot;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* checks if a have left hand , right hand issue.
|
|
199
|
+
* In other words if a mesh is a LHS mesh in RHS system or
|
|
200
|
+
* a RHS mesh in LHS system
|
|
201
|
+
* The X axis will be reversed in such cases.
|
|
202
|
+
* thus Cross product of X and Y should be inverse of Z.
|
|
203
|
+
*
|
|
204
|
+
* if no parent then we are ok.
|
|
205
|
+
* If parent and parent has issue then we have issue.
|
|
206
|
+
*
|
|
207
|
+
*/
|
|
208
|
+
_check_LHS_RHS(mesh) {
|
|
209
|
+
let _issue = false;
|
|
210
|
+
let root = mesh.parent;
|
|
211
|
+
if (root == null)
|
|
212
|
+
return false;
|
|
213
|
+
this._setLocalAxes(root);
|
|
214
|
+
let actualZ = babylonjs_1.Vector3.Cross(this._localX, this._localY);
|
|
215
|
+
//same direction or opposite direction of Z
|
|
216
|
+
if (babylonjs_1.Vector3.Dot(actualZ, this._localZ) < 0)
|
|
217
|
+
_issue = true;
|
|
218
|
+
else
|
|
219
|
+
_issue = false;
|
|
220
|
+
this._setLocalAxes(mesh);
|
|
221
|
+
return _issue;
|
|
222
|
+
}
|
|
223
|
+
_renderLoopProcess() {
|
|
224
|
+
//sync the edit control position and rotation with that of mesh
|
|
225
|
+
this._ecRoot.position = this._mesh.getAbsolutePivotPoint();
|
|
226
|
+
this._setECRotation();
|
|
227
|
+
//scale the EditControl so it seems at the same distance from camera/user
|
|
228
|
+
this._setECScale();
|
|
229
|
+
//rotate the free move,rotate,scale pick plane to face the camera/user
|
|
230
|
+
if (this._local) {
|
|
231
|
+
this._ecRoot.getWorldMatrix().invertToRef(this._ecMatrix);
|
|
232
|
+
babylonjs_1.Vector3.TransformCoordinatesToRef(this._mainCamera.position, this._ecMatrix, this._ecTOcamera);
|
|
233
|
+
//note pALL is child of ecRoot hence lookAt in local space
|
|
234
|
+
this._pALL.lookAt(this._ecTOcamera, 0, 0, 0, babylonjs_1.Space.LOCAL);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
this._mainCamera.position.subtractToRef(this._ecRoot.position, this._ecTOcamera);
|
|
238
|
+
this._pALL.lookAt(this._mainCamera.position, 0, 0, 0, babylonjs_1.Space.WORLD);
|
|
239
|
+
}
|
|
240
|
+
//rotate the rotation and planar guide to face the camera/user
|
|
241
|
+
if (this._rotEnabled) {
|
|
242
|
+
this._rotRotGuides();
|
|
243
|
+
}
|
|
244
|
+
else if (this._transEnabled)
|
|
245
|
+
this._rotPlanarGuides(this._tXZ, this._tZY, this._tYX);
|
|
246
|
+
else if (this._scaleEnabled)
|
|
247
|
+
this._rotPlanarGuides(this._sXZ, this._sZY, this._sYX);
|
|
248
|
+
//check pointer over axes only during pointer moves
|
|
249
|
+
//this.onPointerOver();
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* sets rotaion of edit control to that of the mesh
|
|
253
|
+
*/
|
|
254
|
+
_setECRotation() {
|
|
255
|
+
if (this._local) {
|
|
256
|
+
if (this._mesh.parent == null) {
|
|
257
|
+
if (this._isEulerian(this._mesh)) {
|
|
258
|
+
let rot = this._mesh.rotation;
|
|
259
|
+
babylonjs_1.Quaternion.RotationYawPitchRollToRef(rot.y, rot.x, rot.z, this._ecRoot.rotationQuaternion);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
this._ecRoot.rotationQuaternion.copyFrom(this._mesh.rotationQuaternion);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
if (this._isScaleUnEqual(this._mesh))
|
|
267
|
+
return;
|
|
268
|
+
this._mesh.getWorldMatrix().getRotationMatrixToRef(this._tm);
|
|
269
|
+
babylonjs_1.Quaternion.FromRotationMatrixToRef(this._tm, this._ecRoot.rotationQuaternion);
|
|
270
|
+
//this._ecRoot.rotationQuaternion.normalize();
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
/**
|
|
275
|
+
* checks if any of the mesh's ancestors has non uniform scale
|
|
276
|
+
*/
|
|
277
|
+
_isScaleUnEqual(mesh) {
|
|
278
|
+
if (mesh.parent == null)
|
|
279
|
+
return false;
|
|
280
|
+
while (mesh.parent != null) {
|
|
281
|
+
if ((mesh.parent.scaling.x != mesh.parent.scaling.y ||
|
|
282
|
+
mesh.parent.scaling.y != mesh.parent.scaling.z)) {
|
|
283
|
+
return true;
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
mesh = mesh.parent;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return false;
|
|
290
|
+
}
|
|
291
|
+
_setECScale() {
|
|
292
|
+
this._ecRoot.position.subtractToRef(this._mainCamera.position, this._cameraTOec);
|
|
293
|
+
babylonjs_1.Vector3.FromArrayToRef(this._mainCamera.getWorldMatrix().asArray(), 8, this._cameraNormal);
|
|
294
|
+
//get distance of edit control from the camera plane
|
|
295
|
+
//project "camera to edit control" vector onto the camera normal
|
|
296
|
+
let parentOnNormal = babylonjs_1.Vector3.Dot(this._cameraTOec, this._cameraNormal) / this._cameraNormal.length();
|
|
297
|
+
let s = Math.abs(parentOnNormal / this._distFromCamera);
|
|
298
|
+
babylonjs_1.Vector3.FromFloatsToRef(s, s, s, this._ecRoot.scaling);
|
|
299
|
+
//Vector3.FromFloatsToRef(s,s,s,this.pALL.scaling);
|
|
300
|
+
}
|
|
301
|
+
//rotate the rotation guides so that they are facing the camera
|
|
302
|
+
_rotRotGuides() {
|
|
303
|
+
let rotX = Math.atan(this._ecTOcamera.y / this._ecTOcamera.z);
|
|
304
|
+
if (this._ecTOcamera.z >= 0) {
|
|
305
|
+
this._rX.rotation.x = -rotX;
|
|
306
|
+
}
|
|
307
|
+
else {
|
|
308
|
+
this._rX.rotation.x = -rotX - Math.PI;
|
|
309
|
+
}
|
|
310
|
+
let rotY = Math.atan(this._ecTOcamera.x / this._ecTOcamera.z);
|
|
311
|
+
if (this._ecTOcamera.z >= 0) {
|
|
312
|
+
this._rY.rotation.y = rotY;
|
|
313
|
+
}
|
|
314
|
+
else {
|
|
315
|
+
this._rY.rotation.y = rotY + Math.PI;
|
|
316
|
+
}
|
|
317
|
+
let rotZ = Math.atan(this._ecTOcamera.x / this._ecTOcamera.y);
|
|
318
|
+
if (this._ecTOcamera.y >= 0) {
|
|
319
|
+
this._rZ.rotation.z = -rotZ;
|
|
320
|
+
}
|
|
321
|
+
else {
|
|
322
|
+
this._rZ.rotation.z = -rotZ - Math.PI;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* rotate the planar guide so that they are facing the camera
|
|
327
|
+
*/
|
|
328
|
+
_rotPlanarGuides(XZ, ZY, YX) {
|
|
329
|
+
let ec = this._ecTOcamera;
|
|
330
|
+
XZ.rotation.x = 0;
|
|
331
|
+
XZ.rotation.y = 0;
|
|
332
|
+
XZ.rotation.z = 0;
|
|
333
|
+
ZY.rotation.x = 0;
|
|
334
|
+
ZY.rotation.y = 0;
|
|
335
|
+
ZY.rotation.z = 0;
|
|
336
|
+
YX.rotation.x = 0;
|
|
337
|
+
YX.rotation.y = 0;
|
|
338
|
+
YX.rotation.z = 0;
|
|
339
|
+
if (ec.x <= 0 && ec.y >= 0 && ec.z >= 0) {
|
|
340
|
+
XZ.rotation.z = 3.14;
|
|
341
|
+
YX.rotation.y = 3.14;
|
|
342
|
+
}
|
|
343
|
+
else if (ec.x <= 0 && ec.y >= 0 && ec.z <= 0) {
|
|
344
|
+
XZ.rotation.y = 3.14;
|
|
345
|
+
ZY.rotation.y = 3.14;
|
|
346
|
+
YX.rotation.y = 3.14;
|
|
347
|
+
}
|
|
348
|
+
else if (ec.x >= 0 && ec.y >= 0 && ec.z <= 0) {
|
|
349
|
+
XZ.rotation.x = 3.14;
|
|
350
|
+
ZY.rotation.y = 3.14;
|
|
351
|
+
}
|
|
352
|
+
else if (ec.x >= 0 && ec.y <= 0 && ec.z >= 0) {
|
|
353
|
+
ZY.rotation.z = 3.14;
|
|
354
|
+
YX.rotation.x = 3.14;
|
|
355
|
+
}
|
|
356
|
+
else if (ec.x <= 0 && ec.y <= 0 && ec.z >= 0) {
|
|
357
|
+
XZ.rotation.z = 3.14;
|
|
358
|
+
ZY.rotation.z = 3.14;
|
|
359
|
+
YX.rotation.z = 3.14;
|
|
360
|
+
}
|
|
361
|
+
else if (ec.x <= 0 && ec.y <= 0 && ec.z <= 0) {
|
|
362
|
+
XZ.rotation.y = 3.14;
|
|
363
|
+
ZY.rotation.x = 3.14;
|
|
364
|
+
YX.rotation.z = 3.14;
|
|
365
|
+
}
|
|
366
|
+
else if (ec.x >= 0 && ec.y <= 0 && ec.z <= 0) {
|
|
367
|
+
XZ.rotation.x = 3.14;
|
|
368
|
+
ZY.rotation.x = 3.14;
|
|
369
|
+
YX.rotation.x = 3.14;
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
switchTo(mesh) {
|
|
373
|
+
mesh.computeWorldMatrix(true);
|
|
374
|
+
this._mesh = mesh;
|
|
375
|
+
this._setLocalAxes(mesh);
|
|
376
|
+
this._actHist = new ActHist(mesh, 10);
|
|
377
|
+
this._lhsRhs = this._check_LHS_RHS(mesh);
|
|
378
|
+
this.refreshBoundingInfo();
|
|
379
|
+
}
|
|
380
|
+
switchCamera(camera) {
|
|
381
|
+
this._mainCamera = camera;
|
|
382
|
+
}
|
|
383
|
+
setUndoCount(c) {
|
|
384
|
+
this._actHist.setCapacity(c);
|
|
385
|
+
}
|
|
386
|
+
undo() {
|
|
387
|
+
let at = this._actHist.undo();
|
|
388
|
+
this._mesh.computeWorldMatrix(true);
|
|
389
|
+
this._setLocalAxes(this._mesh);
|
|
390
|
+
this._callActionStartListener(at);
|
|
391
|
+
this._callActionListener(at);
|
|
392
|
+
this._callActionEndListener(at);
|
|
393
|
+
}
|
|
394
|
+
redo() {
|
|
395
|
+
let at = this._actHist.redo();
|
|
396
|
+
this._mesh.computeWorldMatrix(true);
|
|
397
|
+
this._setLocalAxes(this._mesh);
|
|
398
|
+
this._callActionStartListener(at);
|
|
399
|
+
this._callActionListener(at);
|
|
400
|
+
this._callActionEndListener(at);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* detach the edit control from the mesh and dispose off all
|
|
404
|
+
* resources created by the edit control
|
|
405
|
+
*/
|
|
406
|
+
detach() {
|
|
407
|
+
this._canvas.removeEventListener("pointerdown", this._pointerdown, false);
|
|
408
|
+
this._canvas.removeEventListener("pointerup", this._pointerup, false);
|
|
409
|
+
this._canvas.removeEventListener("pointermove", this._pointermove, false);
|
|
410
|
+
this._scene.unregisterBeforeRender(this._renderer);
|
|
411
|
+
this.removeAllActionListeners();
|
|
412
|
+
this._disposeAll();
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* hide the edit control. use show() to unhide the control.
|
|
416
|
+
*/
|
|
417
|
+
hide() {
|
|
418
|
+
this._hidden = true;
|
|
419
|
+
if (this._transEnabled) {
|
|
420
|
+
this._prevState = "T";
|
|
421
|
+
this.disableTranslation();
|
|
422
|
+
}
|
|
423
|
+
else if (this._rotEnabled) {
|
|
424
|
+
this._prevState = "R";
|
|
425
|
+
this.disableRotation();
|
|
426
|
+
}
|
|
427
|
+
else if (this._scaleEnabled) {
|
|
428
|
+
this._prevState = "S";
|
|
429
|
+
this.disableScaling();
|
|
430
|
+
}
|
|
431
|
+
this._hideCommonAxes();
|
|
432
|
+
}
|
|
433
|
+
_hideCommonAxes() {
|
|
434
|
+
this._xaxis.visibility = 0;
|
|
435
|
+
this._yaxis.visibility = 0;
|
|
436
|
+
this._zaxis.visibility = 0;
|
|
437
|
+
}
|
|
438
|
+
_showCommonAxes() {
|
|
439
|
+
this._xaxis.visibility = this._visibility;
|
|
440
|
+
this._yaxis.visibility = this._visibility;
|
|
441
|
+
this._zaxis.visibility = this._visibility;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* unhide the editcontrol hidden using the hide() method
|
|
445
|
+
*/
|
|
446
|
+
show() {
|
|
447
|
+
this._hidden = false;
|
|
448
|
+
this._showCommonAxes();
|
|
449
|
+
if (this._prevState == "T")
|
|
450
|
+
this.enableTranslation();
|
|
451
|
+
else if (this._prevState == "R")
|
|
452
|
+
this.enableRotation();
|
|
453
|
+
else if (this._prevState == "S")
|
|
454
|
+
this.enableScaling();
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* check if the editcontrol was hidden using the hide() methods
|
|
458
|
+
*/
|
|
459
|
+
isHidden() {
|
|
460
|
+
return this._hidden;
|
|
461
|
+
}
|
|
462
|
+
_disposeAll() {
|
|
463
|
+
this._ecRoot.dispose();
|
|
464
|
+
this._disposeMaterials();
|
|
465
|
+
this._actHist = null;
|
|
466
|
+
}
|
|
467
|
+
addActionListener(actionListener) {
|
|
468
|
+
this._actionListener = actionListener;
|
|
469
|
+
}
|
|
470
|
+
removeActionListener() {
|
|
471
|
+
this._actionListener = null;
|
|
472
|
+
}
|
|
473
|
+
addActionStartListener(actionStartListener) {
|
|
474
|
+
this._actionStartListener = actionStartListener;
|
|
475
|
+
}
|
|
476
|
+
removeActionStartListener() {
|
|
477
|
+
this._actionStartListener = null;
|
|
478
|
+
}
|
|
479
|
+
addActionEndListener(actionEndListener) {
|
|
480
|
+
this._actionEndListener = actionEndListener;
|
|
481
|
+
}
|
|
482
|
+
removeActionEndListener() {
|
|
483
|
+
this._actionEndListener = null;
|
|
484
|
+
}
|
|
485
|
+
removeAllActionListeners() {
|
|
486
|
+
this._actionListener = null;
|
|
487
|
+
this._actionStartListener = null;
|
|
488
|
+
this._actionEndListener = null;
|
|
489
|
+
}
|
|
490
|
+
_onPointerDown(evt) {
|
|
491
|
+
evt.preventDefault();
|
|
492
|
+
this._pDown = true;
|
|
493
|
+
if (evt.button != 0)
|
|
494
|
+
return;
|
|
495
|
+
let engine = this._scene.getEngine();
|
|
496
|
+
let x = (engine.isPointerLock) ? this._canvas.width * 0.5 : this._scene.pointerX;
|
|
497
|
+
let y = (engine.isPointerLock) ? this._canvas.height * 0.5 : this._scene.pointerY;
|
|
498
|
+
let pickResult = this._scene.pick(x, y, (mesh) => {
|
|
499
|
+
if (this._transEnabled) {
|
|
500
|
+
if ((mesh == this._tX) || (mesh == this._tY) || (mesh == this._tZ) || (mesh == this._tXZ) || (mesh == this._tZY) || (mesh == this._tYX) || (mesh == this._tAll))
|
|
501
|
+
return true;
|
|
502
|
+
}
|
|
503
|
+
else if ((this._rotEnabled)) {
|
|
504
|
+
if ((mesh == this._rX) || (mesh == this._rY) || (mesh == this._rZ) || (mesh == this._rAll))
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
else if ((this._scaleEnabled)) {
|
|
508
|
+
if ((mesh == this._sX) || (mesh == this._sY) || (mesh == this._sZ) || (mesh == this._sXZ) || (mesh == this._sZY) || (mesh == this._sYX) || (mesh == this._sAll))
|
|
509
|
+
return true;
|
|
510
|
+
}
|
|
511
|
+
return false;
|
|
512
|
+
}, false, this._mainCamera);
|
|
513
|
+
if (pickResult.hit) {
|
|
514
|
+
//this.setAxesVisiblity(0);
|
|
515
|
+
this._axisPicked = pickResult.pickedMesh;
|
|
516
|
+
let childs = this._axisPicked.getChildren();
|
|
517
|
+
if (childs.length > 0) {
|
|
518
|
+
childs[0].visibility = this._visibility;
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
this._axisPicked.visibility = this._visibility;
|
|
522
|
+
}
|
|
523
|
+
let name = this._axisPicked.name;
|
|
524
|
+
if ((name == "X"))
|
|
525
|
+
this._bXaxis.visibility = 1;
|
|
526
|
+
else if ((name == "Y"))
|
|
527
|
+
this._bYaxis.visibility = 1;
|
|
528
|
+
else if ((name == "Z"))
|
|
529
|
+
this._bZaxis.visibility = 1;
|
|
530
|
+
else if ((name == "XZ")) {
|
|
531
|
+
this._bXaxis.visibility = 1;
|
|
532
|
+
this._bZaxis.visibility = 1;
|
|
533
|
+
}
|
|
534
|
+
else if ((name == "ZY")) {
|
|
535
|
+
this._bZaxis.visibility = 1;
|
|
536
|
+
this._bYaxis.visibility = 1;
|
|
537
|
+
}
|
|
538
|
+
else if ((name == "YX")) {
|
|
539
|
+
this._bYaxis.visibility = 1;
|
|
540
|
+
this._bXaxis.visibility = 1;
|
|
541
|
+
}
|
|
542
|
+
else if ((name == "ALL")) {
|
|
543
|
+
this._bXaxis.visibility = 1;
|
|
544
|
+
this._bYaxis.visibility = 1;
|
|
545
|
+
this._bZaxis.visibility = 1;
|
|
546
|
+
}
|
|
547
|
+
this._setEditing(true);
|
|
548
|
+
//lets find out where we are on the pickplane
|
|
549
|
+
this._pickedPlane = this._getPickPlane(this._axisPicked);
|
|
550
|
+
if (this._pickedPlane != null) {
|
|
551
|
+
this._prevPos = this._getPosOnPickPlane();
|
|
552
|
+
}
|
|
553
|
+
else {
|
|
554
|
+
this._prevPos = null;
|
|
555
|
+
}
|
|
556
|
+
window.setTimeout(((cam, can) => { return this._detachCamera(cam, can); }), 0, this._mainCamera, this._canvas);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
_setEditing(editing) {
|
|
560
|
+
this._editing = editing;
|
|
561
|
+
if (editing) {
|
|
562
|
+
this._setActionType();
|
|
563
|
+
if (this._actionType == ActionType.ROT) {
|
|
564
|
+
this._snapRA = 0;
|
|
565
|
+
}
|
|
566
|
+
this._callActionStartListener(this._actionType);
|
|
567
|
+
}
|
|
568
|
+
else {
|
|
569
|
+
this._callActionEndListener(this._actionType);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
isEditing() {
|
|
573
|
+
return this._editing;
|
|
574
|
+
}
|
|
575
|
+
/**
|
|
576
|
+
* no camera movement during edit
|
|
577
|
+
*/
|
|
578
|
+
_detachCamera(cam, can) {
|
|
579
|
+
let camera = cam;
|
|
580
|
+
let canvas = can;
|
|
581
|
+
let engine = this._scene.getEngine();
|
|
582
|
+
if (!engine.isPointerLock) {
|
|
583
|
+
camera.detachControl(canvas);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
isPointerOver() {
|
|
587
|
+
return this._pointerIsOver;
|
|
588
|
+
}
|
|
589
|
+
_onPointerOver() {
|
|
590
|
+
//if(this.pDown) return;
|
|
591
|
+
let engine = this._scene.getEngine();
|
|
592
|
+
let x = (engine.isPointerLock) ? this._canvas.width * 0.5 : this._scene.pointerX;
|
|
593
|
+
let y = (engine.isPointerLock) ? this._canvas.height * 0.5 : this._scene.pointerY;
|
|
594
|
+
let pickResult = this._scene.pick(x, y, (mesh) => {
|
|
595
|
+
if (this._transEnabled) {
|
|
596
|
+
if ((mesh == this._tX) || (mesh == this._tY) || (mesh == this._tZ) || (mesh == this._tXZ) || (mesh == this._tZY) || (mesh == this._tYX) || (mesh == this._tAll))
|
|
597
|
+
return true;
|
|
598
|
+
}
|
|
599
|
+
else if ((this._rotEnabled)) {
|
|
600
|
+
if ((mesh == this._rX) || (mesh == this._rY) || (mesh == this._rZ) || (mesh == this._rAll))
|
|
601
|
+
return true;
|
|
602
|
+
}
|
|
603
|
+
else if (this._scaleEnabled) {
|
|
604
|
+
if ((mesh == this._sX) || (mesh == this._sY) || (mesh == this._sZ) || (mesh == this._sXZ) || (mesh == this._sZY) || (mesh == this._sYX) || (mesh == this._sAll))
|
|
605
|
+
return true;
|
|
606
|
+
}
|
|
607
|
+
return false;
|
|
608
|
+
}, false, this._mainCamera);
|
|
609
|
+
if (pickResult.hit) {
|
|
610
|
+
//if we are still over the same axis mesh then don't do anything
|
|
611
|
+
if (pickResult.pickedMesh != this._prevOverMesh) {
|
|
612
|
+
this._pointerIsOver = true;
|
|
613
|
+
//if we moved directly from one axis mesh to this then clean up the prev axis mesh
|
|
614
|
+
this._clearPrevOverMesh();
|
|
615
|
+
this._prevOverMesh = pickResult.pickedMesh;
|
|
616
|
+
if (this._rotEnabled) {
|
|
617
|
+
this._savedCol = this._prevOverMesh.getChildren()[0].color;
|
|
618
|
+
this._prevOverMesh.getChildren()[0].color = this._yellowCol;
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
let childs = this._prevOverMesh.getChildren();
|
|
622
|
+
if (childs.length > 0) {
|
|
623
|
+
this._savedMat = childs[0].material;
|
|
624
|
+
childs[0].material = this._whiteMat;
|
|
625
|
+
}
|
|
626
|
+
else {
|
|
627
|
+
this._savedMat = this._prevOverMesh.material;
|
|
628
|
+
this._prevOverMesh.material = this._whiteMat;
|
|
629
|
+
}
|
|
630
|
+
}
|
|
631
|
+
if (this._prevOverMesh.name == "X") {
|
|
632
|
+
this._xaxis.color = this._yellowCol;
|
|
633
|
+
}
|
|
634
|
+
else if (this._prevOverMesh.name == "Y") {
|
|
635
|
+
this._yaxis.color = this._yellowCol;
|
|
636
|
+
}
|
|
637
|
+
else if (this._prevOverMesh.name == "Z") {
|
|
638
|
+
this._zaxis.color = this._yellowCol;
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
this._pointerIsOver = false;
|
|
644
|
+
if (this._prevOverMesh != null) {
|
|
645
|
+
this._restoreColor(this._prevOverMesh);
|
|
646
|
+
this._prevOverMesh = null;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
//clean up any axis we might have been howering over before
|
|
651
|
+
_clearPrevOverMesh() {
|
|
652
|
+
if (this._prevOverMesh != null) {
|
|
653
|
+
this._prevOverMesh.visibility = 0;
|
|
654
|
+
this._restoreColor(this._prevOverMesh);
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
_restoreColor(mesh) {
|
|
658
|
+
switch (mesh.name) {
|
|
659
|
+
case "X":
|
|
660
|
+
this._xaxis.color = this._redCol;
|
|
661
|
+
break;
|
|
662
|
+
case "Y":
|
|
663
|
+
this._yaxis.color = this._greenCol;
|
|
664
|
+
break;
|
|
665
|
+
case "Z":
|
|
666
|
+
this._zaxis.color = this._blueCol;
|
|
667
|
+
break;
|
|
668
|
+
}
|
|
669
|
+
if (this._rotEnabled) {
|
|
670
|
+
mesh.getChildren()[0].color = this._savedCol;
|
|
671
|
+
}
|
|
672
|
+
else {
|
|
673
|
+
let childs = mesh.getChildren();
|
|
674
|
+
if (childs.length > 0) {
|
|
675
|
+
childs[0].material = this._savedMat;
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
mesh.material = this._savedMat;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
_onPointerUp(evt) {
|
|
683
|
+
this._pDown = false;
|
|
684
|
+
if (this._editing) {
|
|
685
|
+
let engine = this._scene.getEngine();
|
|
686
|
+
if (!engine.isPointerLock) {
|
|
687
|
+
this._mainCamera.attachControl(true);
|
|
688
|
+
}
|
|
689
|
+
this._setEditing(false);
|
|
690
|
+
//this.setAxesVisiblity(1);
|
|
691
|
+
this._hideBaxis();
|
|
692
|
+
if (this._prevOverMesh != null) {
|
|
693
|
+
this._restoreColor(this._prevOverMesh);
|
|
694
|
+
this._prevOverMesh = null;
|
|
695
|
+
}
|
|
696
|
+
this._actHist.add(this._actionType);
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
_setActionType() {
|
|
700
|
+
if (this._transEnabled) {
|
|
701
|
+
this._actionType = ActionType.TRANS;
|
|
702
|
+
}
|
|
703
|
+
else if ((this._rotEnabled)) {
|
|
704
|
+
this._actionType = ActionType.ROT;
|
|
705
|
+
}
|
|
706
|
+
else if ((this._scaleEnabled)) {
|
|
707
|
+
this._actionType = ActionType.SCALE;
|
|
708
|
+
}
|
|
709
|
+
}
|
|
710
|
+
_callActionListener(at) {
|
|
711
|
+
//call actionListener if registered
|
|
712
|
+
if (this._actionListener != null) {
|
|
713
|
+
this._actionListener(at);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
_callActionStartListener(at) {
|
|
717
|
+
//call actionListener if registered
|
|
718
|
+
if (this._actionStartListener != null) {
|
|
719
|
+
this._actionStartListener(at);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
_callActionEndListener(at) {
|
|
723
|
+
//call actionListener if registered
|
|
724
|
+
if (this._actionEndListener != null) {
|
|
725
|
+
this._actionEndListener(at);
|
|
726
|
+
}
|
|
727
|
+
}
|
|
728
|
+
_onPointerMove(evt) {
|
|
729
|
+
if (!this._pDown) {
|
|
730
|
+
this._onPointerOver();
|
|
731
|
+
return;
|
|
732
|
+
}
|
|
733
|
+
if (!this._editing)
|
|
734
|
+
return;
|
|
735
|
+
if (this._prevPos == null)
|
|
736
|
+
return;
|
|
737
|
+
let newPos = this._getPosOnPickPlane();
|
|
738
|
+
if (newPos == null)
|
|
739
|
+
return;
|
|
740
|
+
if (this._rotEnabled) {
|
|
741
|
+
this._doRotation(this._mesh, this._axisPicked, newPos, this._prevPos);
|
|
742
|
+
}
|
|
743
|
+
else {
|
|
744
|
+
let diff = newPos.subtract(this._prevPos);
|
|
745
|
+
if (diff.x == 0 && diff.y == 0 && diff.z == 0)
|
|
746
|
+
return;
|
|
747
|
+
if (this._transEnabled) {
|
|
748
|
+
this._doTranslation(diff);
|
|
749
|
+
}
|
|
750
|
+
else {
|
|
751
|
+
if (this._scaleEnabled && this._local)
|
|
752
|
+
this._doScaling(diff);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
this._prevPos = newPos;
|
|
756
|
+
this._callActionListener(this._actionType);
|
|
757
|
+
}
|
|
758
|
+
_getPickPlane(axis) {
|
|
759
|
+
let n = axis.name;
|
|
760
|
+
if (this._transEnabled || this._scaleEnabled) {
|
|
761
|
+
if (n == "XZ")
|
|
762
|
+
return this._pXZ;
|
|
763
|
+
else if (n == "ZY")
|
|
764
|
+
return this._pZY;
|
|
765
|
+
else if (n == "YX")
|
|
766
|
+
return this._pYX;
|
|
767
|
+
else if (n == "ALL")
|
|
768
|
+
return this._pALL;
|
|
769
|
+
else {
|
|
770
|
+
//get the position of camera in the edit control frame of reference
|
|
771
|
+
this._ecRoot.getWorldMatrix().invertToRef(this._ecMatrix);
|
|
772
|
+
babylonjs_1.Vector3.TransformCoordinatesToRef(this._mainCamera.position, this._ecMatrix, this._ecTOcamera);
|
|
773
|
+
let c = this._ecTOcamera;
|
|
774
|
+
if (n === "X") {
|
|
775
|
+
if (Math.abs(c.y) > Math.abs(c.z)) {
|
|
776
|
+
return this._pXZ;
|
|
777
|
+
}
|
|
778
|
+
else
|
|
779
|
+
return this._pYX;
|
|
780
|
+
}
|
|
781
|
+
else if (n === "Z") {
|
|
782
|
+
if (Math.abs(c.y) > Math.abs(c.x)) {
|
|
783
|
+
return this._pXZ;
|
|
784
|
+
}
|
|
785
|
+
else
|
|
786
|
+
return this._pZY;
|
|
787
|
+
}
|
|
788
|
+
else if (n === "Y") {
|
|
789
|
+
if (Math.abs(c.z) > Math.abs(c.x)) {
|
|
790
|
+
return this._pYX;
|
|
791
|
+
}
|
|
792
|
+
else
|
|
793
|
+
return this._pZY;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
else if (this._rotEnabled) {
|
|
798
|
+
this._rotate2 = false;
|
|
799
|
+
//get the position of camera in the edit control frame of reference
|
|
800
|
+
this._ecRoot.getWorldMatrix().invertToRef(this._ecMatrix);
|
|
801
|
+
babylonjs_1.Vector3.TransformCoordinatesToRef(this._mainCamera.position, this._ecMatrix, this._ecTOcamera);
|
|
802
|
+
let c = this._ecTOcamera;
|
|
803
|
+
//if camera is too close to the rotation plane then use alternate rotation process
|
|
804
|
+
switch (n) {
|
|
805
|
+
case "X":
|
|
806
|
+
if (Math.abs(c.x) < 0.2) {
|
|
807
|
+
this._rotate2 = true;
|
|
808
|
+
return this._pALL;
|
|
809
|
+
}
|
|
810
|
+
else
|
|
811
|
+
return this._pZY;
|
|
812
|
+
case "Y":
|
|
813
|
+
if (Math.abs(c.y) < 0.2) {
|
|
814
|
+
this._rotate2 = true;
|
|
815
|
+
return this._pALL;
|
|
816
|
+
}
|
|
817
|
+
else
|
|
818
|
+
return this._pXZ;
|
|
819
|
+
case "Z":
|
|
820
|
+
if (Math.abs(c.z) < 0.2) {
|
|
821
|
+
this._rotate2 = true;
|
|
822
|
+
return this._pALL;
|
|
823
|
+
}
|
|
824
|
+
else
|
|
825
|
+
return this._pYX;
|
|
826
|
+
default:
|
|
827
|
+
return this._pALL;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
else
|
|
831
|
+
return null;
|
|
832
|
+
}
|
|
833
|
+
_doTranslation(diff) {
|
|
834
|
+
if ((this._mesh.parent != null) && this._isScaleUnEqual(this._mesh)) {
|
|
835
|
+
this._setLocalAxes(this._ecRoot);
|
|
836
|
+
}
|
|
837
|
+
else {
|
|
838
|
+
this._setLocalAxes(this._mesh);
|
|
839
|
+
}
|
|
840
|
+
let n = this._axisPicked.name;
|
|
841
|
+
this._transBy.x = 0;
|
|
842
|
+
this._transBy.y = 0;
|
|
843
|
+
this._transBy.z = 0;
|
|
844
|
+
if ((n == "X") || (n == "XZ") || (n == "YX") || (n == "ALL")) {
|
|
845
|
+
if (this._local)
|
|
846
|
+
this._transBy.x = babylonjs_1.Vector3.Dot(diff, this._localX) / this._localX.length();
|
|
847
|
+
else
|
|
848
|
+
this._transBy.x = diff.x;
|
|
849
|
+
}
|
|
850
|
+
if ((n == "Y") || (n == "ZY") || (n == "YX") || (n == "ALL")) {
|
|
851
|
+
if (this._local)
|
|
852
|
+
this._transBy.y = babylonjs_1.Vector3.Dot(diff, this._localY) / this._localY.length();
|
|
853
|
+
else
|
|
854
|
+
this._transBy.y = diff.y;
|
|
855
|
+
}
|
|
856
|
+
if ((n == "Z") || (n == "XZ") || (n == "ZY") || (n == "ALL")) {
|
|
857
|
+
if (this._local)
|
|
858
|
+
this._transBy.z = babylonjs_1.Vector3.Dot(diff, this._localZ) / this._localZ.length();
|
|
859
|
+
else
|
|
860
|
+
this._transBy.z = diff.z;
|
|
861
|
+
}
|
|
862
|
+
this._transWithSnap(this._mesh, this._transBy, this._local);
|
|
863
|
+
// bound the translation
|
|
864
|
+
if (this._transBoundsMin) {
|
|
865
|
+
this._mesh.position.x = Math.max(this._mesh.position.x, this._transBoundsMin.x);
|
|
866
|
+
this._mesh.position.y = Math.max(this._mesh.position.y, this._transBoundsMin.y);
|
|
867
|
+
this._mesh.position.z = Math.max(this._mesh.position.z, this._transBoundsMin.z);
|
|
868
|
+
}
|
|
869
|
+
if (this._transBoundsMax) {
|
|
870
|
+
this._mesh.position.x = Math.min(this._mesh.position.x, this._transBoundsMax.x);
|
|
871
|
+
this._mesh.position.y = Math.min(this._mesh.position.y, this._transBoundsMax.y);
|
|
872
|
+
this._mesh.position.z = Math.min(this._mesh.position.z, this._transBoundsMax.z);
|
|
873
|
+
}
|
|
874
|
+
this._mesh.computeWorldMatrix(true);
|
|
875
|
+
}
|
|
876
|
+
_transWithSnap(mesh, trans, local) {
|
|
877
|
+
if (this._snapT) {
|
|
878
|
+
let snapit = false;
|
|
879
|
+
this._snapTV.addInPlace(trans);
|
|
880
|
+
if (Math.abs(this._snapTV.x) > this._tSnap.x) {
|
|
881
|
+
if (this._snapTV.x > 0)
|
|
882
|
+
trans.x = this._tSnap.x;
|
|
883
|
+
else
|
|
884
|
+
trans.x = -this._tSnap.x;
|
|
885
|
+
snapit = true;
|
|
886
|
+
}
|
|
887
|
+
if (Math.abs(this._snapTV.y) > this._tSnap.y) {
|
|
888
|
+
if (this._snapTV.y > 0)
|
|
889
|
+
trans.y = this._tSnap.y;
|
|
890
|
+
else
|
|
891
|
+
trans.y = -this._tSnap.y;
|
|
892
|
+
snapit = true;
|
|
893
|
+
}
|
|
894
|
+
if (Math.abs(this._snapTV.z) > this._tSnap.z) {
|
|
895
|
+
if (this._snapTV.z > 0)
|
|
896
|
+
trans.z = this._tSnap.z;
|
|
897
|
+
else
|
|
898
|
+
trans.z = -this._tSnap.z;
|
|
899
|
+
snapit = true;
|
|
900
|
+
}
|
|
901
|
+
if (snapit) {
|
|
902
|
+
if (Math.abs(trans.x) !== this._tSnap.x)
|
|
903
|
+
trans.x = 0;
|
|
904
|
+
if (Math.abs(trans.y) !== this._tSnap.y)
|
|
905
|
+
trans.y = 0;
|
|
906
|
+
if (Math.abs(trans.z) !== this._tSnap.z)
|
|
907
|
+
trans.z = 0;
|
|
908
|
+
babylonjs_1.Vector3.FromFloatsToRef(0, 0, 0, this._snapTV);
|
|
909
|
+
snapit = false;
|
|
910
|
+
}
|
|
911
|
+
else {
|
|
912
|
+
return;
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
if (local) {
|
|
916
|
+
//locallyTranslate moves the mesh wrt the absolute location not pivotlocation :(
|
|
917
|
+
//this.mesh.locallyTranslate(trans);
|
|
918
|
+
//
|
|
919
|
+
this._localX.normalizeToRef(this._tv1);
|
|
920
|
+
this._localY.normalizeToRef(this._tv2);
|
|
921
|
+
this._localZ.normalizeToRef(this._tv3);
|
|
922
|
+
this._mesh.translate(this._tv1, trans.x, babylonjs_1.Space.WORLD);
|
|
923
|
+
this._mesh.translate(this._tv2, trans.y, babylonjs_1.Space.WORLD);
|
|
924
|
+
this._mesh.translate(this._tv3, trans.z, babylonjs_1.Space.WORLD);
|
|
925
|
+
}
|
|
926
|
+
else {
|
|
927
|
+
if (this._mesh.parent == null) {
|
|
928
|
+
this._mesh.position.addInPlace(trans);
|
|
929
|
+
}
|
|
930
|
+
else {
|
|
931
|
+
this._mesh.setAbsolutePosition(trans.addInPlace(this._mesh.absolutePosition));
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
_doScaling(diff) {
|
|
936
|
+
this._setLocalAxes(this._mesh);
|
|
937
|
+
this._scale.x = 0;
|
|
938
|
+
this._scale.y = 0;
|
|
939
|
+
this._scale.z = 0;
|
|
940
|
+
let n = this._axisPicked.name;
|
|
941
|
+
if ((n == "X") || (n == "XZ") || (n == "YX")) {
|
|
942
|
+
this._scale.x = babylonjs_1.Vector3.Dot(diff, this._localX) / this._localX.length();
|
|
943
|
+
if (this._mesh.scaling.x < 0)
|
|
944
|
+
this._scale.x = -this._scale.x;
|
|
945
|
+
//if(this.lhsRhs) this.scale.x=-this.scale.x;
|
|
946
|
+
}
|
|
947
|
+
if ((n == "Y") || (n == "ZY") || (n == "YX")) {
|
|
948
|
+
this._scale.y = babylonjs_1.Vector3.Dot(diff, this._localY) / this._localY.length();
|
|
949
|
+
if (this._mesh.scaling.y < 0)
|
|
950
|
+
this._scale.y = -this._scale.y;
|
|
951
|
+
}
|
|
952
|
+
if ((n == "Z") || (n == "XZ") || (n == "ZY")) {
|
|
953
|
+
this._scale.z = babylonjs_1.Vector3.Dot(diff, this._localZ) / this._localZ.length();
|
|
954
|
+
if (this._mesh.scaling.z < 0)
|
|
955
|
+
this._scale.z = -this._scale.z;
|
|
956
|
+
}
|
|
957
|
+
//as the mesh becomes large reduce the amount by which we scale.
|
|
958
|
+
let bbd = this._boundingDimesion;
|
|
959
|
+
this._scale.x = this._scale.x / bbd.x;
|
|
960
|
+
this._scale.y = this._scale.y / bbd.y;
|
|
961
|
+
this._scale.z = this._scale.z / bbd.z;
|
|
962
|
+
if (n == "ALL") {
|
|
963
|
+
//project movement along camera up vector
|
|
964
|
+
//if up then scale up else scale down
|
|
965
|
+
let s = babylonjs_1.Vector3.Dot(diff, this._mainCamera.upVector);
|
|
966
|
+
s = s / Math.max(bbd.x, bbd.y, bbd.z);
|
|
967
|
+
this._scale.copyFromFloats(s, s, s);
|
|
968
|
+
}
|
|
969
|
+
else {
|
|
970
|
+
let inPlane = false;
|
|
971
|
+
if (n == "XZ") {
|
|
972
|
+
inPlane = true;
|
|
973
|
+
if (Math.abs(this._scale.x) > Math.abs(this._scale.z)) {
|
|
974
|
+
this._scale.z = this._scale.x;
|
|
975
|
+
}
|
|
976
|
+
else
|
|
977
|
+
this._scale.x = this._scale.z;
|
|
978
|
+
}
|
|
979
|
+
else if (n == "ZY") {
|
|
980
|
+
inPlane = true;
|
|
981
|
+
if (Math.abs(this._scale.z) > Math.abs(this._scale.y)) {
|
|
982
|
+
this._scale.y = this._scale.z;
|
|
983
|
+
}
|
|
984
|
+
else
|
|
985
|
+
this._scale.z = this._scale.y;
|
|
986
|
+
}
|
|
987
|
+
else if (n == "YX") {
|
|
988
|
+
inPlane = true;
|
|
989
|
+
if (Math.abs(this._scale.y) > Math.abs(this._scale.x)) {
|
|
990
|
+
this._scale.x = this._scale.y;
|
|
991
|
+
}
|
|
992
|
+
else
|
|
993
|
+
this._scale.y = this._scale.x;
|
|
994
|
+
}
|
|
995
|
+
if (inPlane) {
|
|
996
|
+
//check if the mouse/pointer was moved towards camera or away from camera
|
|
997
|
+
//if towards then scale up else scale down
|
|
998
|
+
this._ecRoot.position.subtractToRef(this._mainCamera.position, this._cameraTOec);
|
|
999
|
+
let s = babylonjs_1.Vector3.Dot(diff, this._cameraTOec);
|
|
1000
|
+
this._scale.x = Math.abs(this._scale.x);
|
|
1001
|
+
this._scale.y = Math.abs(this._scale.y);
|
|
1002
|
+
this._scale.z = Math.abs(this._scale.z);
|
|
1003
|
+
if (s > 0) {
|
|
1004
|
+
if (this._mesh.scaling.x > 0)
|
|
1005
|
+
this._scale.x = -this._scale.x;
|
|
1006
|
+
//if(this.lhsRhs) this.scale.y=Math.abs(this.scale.y);
|
|
1007
|
+
if (this._mesh.scaling.y > 0)
|
|
1008
|
+
this._scale.y = -this._scale.y;
|
|
1009
|
+
if (this._mesh.scaling.z > 0)
|
|
1010
|
+
this._scale.z = -this._scale.z;
|
|
1011
|
+
}
|
|
1012
|
+
else {
|
|
1013
|
+
//this.scale.x=Math.abs(this.scale.x);
|
|
1014
|
+
//if(this.lhsRhs) this.scale.y=-Math.abs(this.scale.y);
|
|
1015
|
+
//else this.scale.y=Math.abs(this.scale.y);
|
|
1016
|
+
if (this._mesh.scaling.x < 0)
|
|
1017
|
+
this._scale.x = -this._scale.x;
|
|
1018
|
+
if (this._mesh.scaling.y < 0)
|
|
1019
|
+
this._scale.y = -this._scale.y;
|
|
1020
|
+
if (this._mesh.scaling.z < 0)
|
|
1021
|
+
this._scale.z = -this._scale.z;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
this._scaleWithSnap(this._mesh, this._scale);
|
|
1026
|
+
// bound the scale
|
|
1027
|
+
if (this._scaleBoundsMin) {
|
|
1028
|
+
this._mesh.scaling.x = Math.max(this._mesh.scaling.x, this._scaleBoundsMin.x);
|
|
1029
|
+
this._mesh.scaling.y = Math.max(this._mesh.scaling.y, this._scaleBoundsMin.y);
|
|
1030
|
+
this._mesh.scaling.z = Math.max(this._mesh.scaling.z, this._scaleBoundsMin.z);
|
|
1031
|
+
}
|
|
1032
|
+
if (this._scaleBoundsMax) {
|
|
1033
|
+
this._mesh.scaling.x = Math.min(this._mesh.scaling.x, this._scaleBoundsMax.x);
|
|
1034
|
+
this._mesh.scaling.y = Math.min(this._mesh.scaling.y, this._scaleBoundsMax.y);
|
|
1035
|
+
this._mesh.scaling.z = Math.min(this._mesh.scaling.z, this._scaleBoundsMax.z);
|
|
1036
|
+
}
|
|
1037
|
+
}
|
|
1038
|
+
_scaleWithSnap(mesh, p) {
|
|
1039
|
+
if (this._snapS) {
|
|
1040
|
+
let snapit = false;
|
|
1041
|
+
this._snapSV.addInPlace(p);
|
|
1042
|
+
if (Math.abs(this._snapSV.x) > this._scaleSnap) {
|
|
1043
|
+
if (p.x > 0)
|
|
1044
|
+
p.x = this._scaleSnap;
|
|
1045
|
+
else
|
|
1046
|
+
p.x = -this._scaleSnap;
|
|
1047
|
+
snapit = true;
|
|
1048
|
+
}
|
|
1049
|
+
if (Math.abs(this._snapSV.y) > this._scaleSnap) {
|
|
1050
|
+
if (p.y > 0)
|
|
1051
|
+
p.y = this._scaleSnap;
|
|
1052
|
+
else
|
|
1053
|
+
p.y = -this._scaleSnap;
|
|
1054
|
+
snapit = true;
|
|
1055
|
+
}
|
|
1056
|
+
if (Math.abs(this._snapSV.z) > this._scaleSnap) {
|
|
1057
|
+
if (p.z > 0)
|
|
1058
|
+
p.z = this._scaleSnap;
|
|
1059
|
+
else
|
|
1060
|
+
p.z = -this._scaleSnap;
|
|
1061
|
+
snapit = true;
|
|
1062
|
+
}
|
|
1063
|
+
if (!snapit)
|
|
1064
|
+
return;
|
|
1065
|
+
if ((Math.abs(p.x) !== this._scaleSnap) && (p.x !== 0))
|
|
1066
|
+
p.x = 0;
|
|
1067
|
+
if ((Math.abs(p.y) !== this._scaleSnap) && (p.y !== 0))
|
|
1068
|
+
p.y = 0;
|
|
1069
|
+
if ((Math.abs(p.z) !== this._scaleSnap) && (p.z !== 0))
|
|
1070
|
+
p.z = 0;
|
|
1071
|
+
babylonjs_1.Vector3.FromFloatsToRef(0, 0, 0, this._snapSV);
|
|
1072
|
+
snapit = false;
|
|
1073
|
+
}
|
|
1074
|
+
mesh.scaling.addInPlace(p);
|
|
1075
|
+
}
|
|
1076
|
+
/*
|
|
1077
|
+
* This would be called after rotation or scaling as the local axes direction or length might have changed
|
|
1078
|
+
* We need to set the local axis as these are used in all three modes to figure out
|
|
1079
|
+
* direction of mouse move wrt the axes
|
|
1080
|
+
* TODO should use world pivotmatrix instead of worldmatrix - incase pivot axes were rotated?
|
|
1081
|
+
*/
|
|
1082
|
+
_setLocalAxes(mesh) {
|
|
1083
|
+
let meshMatrix = mesh.getWorldMatrix();
|
|
1084
|
+
babylonjs_1.Vector3.FromArrayToRef(meshMatrix.m, 0, this._localX);
|
|
1085
|
+
babylonjs_1.Vector3.FromArrayToRef(meshMatrix.m, 4, this._localY);
|
|
1086
|
+
babylonjs_1.Vector3.FromArrayToRef(meshMatrix.m, 8, this._localZ);
|
|
1087
|
+
}
|
|
1088
|
+
_getBoundingDimension(mesh) {
|
|
1089
|
+
if (mesh instanceof babylonjs_1.AbstractMesh) {
|
|
1090
|
+
{ }
|
|
1091
|
+
let bb = mesh.getBoundingInfo().boundingBox;
|
|
1092
|
+
let bd = bb.maximum.subtract(bb.minimum);
|
|
1093
|
+
if (bd.x == 0)
|
|
1094
|
+
bd.x = 1;
|
|
1095
|
+
if (bd.y == 0)
|
|
1096
|
+
bd.y = 1;
|
|
1097
|
+
if (bd.z == 0)
|
|
1098
|
+
bd.z = 1;
|
|
1099
|
+
return bd;
|
|
1100
|
+
}
|
|
1101
|
+
else
|
|
1102
|
+
return new babylonjs_1.Vector3(1, 1, 1);
|
|
1103
|
+
}
|
|
1104
|
+
/*
|
|
1105
|
+
*
|
|
1106
|
+
* For the sake of speed the editcontrol calculates bounding info only once.
|
|
1107
|
+
* This is in the constructor.
|
|
1108
|
+
* Now The boundingbox dimension can change if the mesh is baked.
|
|
1109
|
+
* If the editcontrol is attached to the mesh when the mesh was baked then
|
|
1110
|
+
* the scaling speed will be incorrect.
|
|
1111
|
+
* Thus client application should call refreshBoundingInfo if it bakes the mesh.
|
|
1112
|
+
*
|
|
1113
|
+
*/
|
|
1114
|
+
refreshBoundingInfo() {
|
|
1115
|
+
this._boundingDimesion = this._getBoundingDimension(this._mesh);
|
|
1116
|
+
}
|
|
1117
|
+
_doRotation(mesh, axis, newPos, prevPos) {
|
|
1118
|
+
//for now no rotation if parents have non uniform scale
|
|
1119
|
+
if (this._local && (this._mesh.parent != null) && this._isScaleUnEqual(mesh)) {
|
|
1120
|
+
this._setLocalAxes(this._ecRoot);
|
|
1121
|
+
}
|
|
1122
|
+
else {
|
|
1123
|
+
this._setLocalAxes(mesh);
|
|
1124
|
+
}
|
|
1125
|
+
let angle = 0;
|
|
1126
|
+
//rotation axis
|
|
1127
|
+
let rAxis;
|
|
1128
|
+
if (axis == this._rX)
|
|
1129
|
+
rAxis = this._local ? this._localX : babylonjs_1.Axis.X;
|
|
1130
|
+
else if (axis == this._rY)
|
|
1131
|
+
rAxis = this._local ? this._localY : babylonjs_1.Axis.Y;
|
|
1132
|
+
else if (axis == this._rZ)
|
|
1133
|
+
rAxis = this._local ? this._localZ : babylonjs_1.Axis.Z;
|
|
1134
|
+
this._ecRoot.position.subtractToRef(this._mainCamera.position, this._cameraTOec);
|
|
1135
|
+
/**
|
|
1136
|
+
* A)first find the angle and the direction (clockwise or anticlockwise) by which the user was trying to rotate
|
|
1137
|
+
* from the user(camera) perspective
|
|
1138
|
+
*/
|
|
1139
|
+
if (this._rotate2) {
|
|
1140
|
+
angle = this._getAngle2(prevPos, newPos, this._mainCamera.position, this._cameraTOec, rAxis);
|
|
1141
|
+
//TODO check why we need to handle righ hand this way
|
|
1142
|
+
if (this._scene.useRightHandedSystem)
|
|
1143
|
+
angle = -angle;
|
|
1144
|
+
}
|
|
1145
|
+
else {
|
|
1146
|
+
angle = this._getAngle(prevPos, newPos, mesh.getAbsolutePivotPoint(), this._cameraTOec);
|
|
1147
|
+
}
|
|
1148
|
+
if (this._lhsRhs) {
|
|
1149
|
+
angle = -angle;
|
|
1150
|
+
}
|
|
1151
|
+
/**
|
|
1152
|
+
* B)then rotate based on users(camera) postion and orientation in the local/world space
|
|
1153
|
+
*
|
|
1154
|
+
*/
|
|
1155
|
+
if (this._snapR) {
|
|
1156
|
+
this._snapRA += angle;
|
|
1157
|
+
angle = 0;
|
|
1158
|
+
if (Math.abs(this._snapRA) >= this._rotSnap) {
|
|
1159
|
+
if (this._snapRA > 0)
|
|
1160
|
+
angle = this._rotSnap;
|
|
1161
|
+
else
|
|
1162
|
+
angle = -this._rotSnap;
|
|
1163
|
+
this._snapRA = 0;
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
if (angle !== 0) {
|
|
1167
|
+
this._cameraTOec.normalize();
|
|
1168
|
+
if (axis == this._rAll) {
|
|
1169
|
+
mesh.rotate(this._cameraTOec, -angle, babylonjs_1.Space.WORLD);
|
|
1170
|
+
}
|
|
1171
|
+
else {
|
|
1172
|
+
if (babylonjs_1.Vector3.Dot(rAxis, this._cameraTOec) >= 0)
|
|
1173
|
+
angle = -angle;
|
|
1174
|
+
mesh.rotate(rAxis, angle, babylonjs_1.Space.WORLD);
|
|
1175
|
+
}
|
|
1176
|
+
if (this._local) {
|
|
1177
|
+
if (this._lhsRhs) {
|
|
1178
|
+
angle = -angle;
|
|
1179
|
+
}
|
|
1180
|
+
if ((this._mesh.parent != null) && this._isScaleUnEqual(mesh)) {
|
|
1181
|
+
if (axis == this._rAll) {
|
|
1182
|
+
this._ecRoot.rotate(this._cameraTOec, -angle, babylonjs_1.Space.WORLD);
|
|
1183
|
+
}
|
|
1184
|
+
else {
|
|
1185
|
+
this._ecRoot.rotate(rAxis, angle, babylonjs_1.Space.WORLD);
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
_getPosOnPickPlane() {
|
|
1192
|
+
let engine = this._scene.getEngine();
|
|
1193
|
+
let x = (engine.isPointerLock) ? this._canvas.width * 0.5 : this._scene.pointerX;
|
|
1194
|
+
let y = (engine.isPointerLock) ? this._canvas.height * 0.5 : this._scene.pointerY;
|
|
1195
|
+
let pickinfo = this._scene.pick(x, y, (mesh) => {
|
|
1196
|
+
return mesh == this._pickedPlane;
|
|
1197
|
+
}, null, this._mainCamera);
|
|
1198
|
+
if (pickinfo.hit) {
|
|
1199
|
+
return pickinfo.pickedPoint;
|
|
1200
|
+
}
|
|
1201
|
+
else {
|
|
1202
|
+
return null;
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
_hideBaxis() {
|
|
1206
|
+
this._bXaxis.visibility = 0;
|
|
1207
|
+
this._bYaxis.visibility = 0;
|
|
1208
|
+
this._bZaxis.visibility = 0;
|
|
1209
|
+
}
|
|
1210
|
+
// private _setAxesVisiblity(v: number) {
|
|
1211
|
+
// if (this._transEnabled) {
|
|
1212
|
+
// this._tEndX.visibility = v;
|
|
1213
|
+
// this._tEndY.visibility = v;
|
|
1214
|
+
// this._tEndZ.visibility = v;
|
|
1215
|
+
// this._tEndXZ.visibility = v;
|
|
1216
|
+
// this._tEndZY.visibility = v;
|
|
1217
|
+
// this._tEndYX.visibility = v;
|
|
1218
|
+
// this._tEndAll.visibility = v;
|
|
1219
|
+
// }
|
|
1220
|
+
// if (this._rotEnabled) {
|
|
1221
|
+
// this._rEndX.visibility = v;
|
|
1222
|
+
// this._rEndY.visibility = v;
|
|
1223
|
+
// this._rEndZ.visibility = v;
|
|
1224
|
+
// this._rEndAll.visibility = v;
|
|
1225
|
+
// }
|
|
1226
|
+
// if (this._scaleEnabled) {
|
|
1227
|
+
// this._sEndX.visibility = v;
|
|
1228
|
+
// this._sEndY.visibility = v;
|
|
1229
|
+
// this._sEndZ.visibility = v;
|
|
1230
|
+
// this._sEndXZ.visibility = v;
|
|
1231
|
+
// this._sEndZY.visibility = v;
|
|
1232
|
+
// this._sEndYX.visibility = v;
|
|
1233
|
+
// this._sEndAll.visibility = v;
|
|
1234
|
+
// }
|
|
1235
|
+
// }
|
|
1236
|
+
getRotationQuaternion() {
|
|
1237
|
+
return this._ecRoot.rotationQuaternion;
|
|
1238
|
+
}
|
|
1239
|
+
getPosition() {
|
|
1240
|
+
return this._ecRoot.position;
|
|
1241
|
+
}
|
|
1242
|
+
isTranslationEnabled() {
|
|
1243
|
+
return this._transEnabled;
|
|
1244
|
+
}
|
|
1245
|
+
enableTranslation() {
|
|
1246
|
+
if (this._hidden)
|
|
1247
|
+
return;
|
|
1248
|
+
if (this._tX == null) {
|
|
1249
|
+
this._createTransAxes();
|
|
1250
|
+
this._tCtl.parent = this._ecRoot;
|
|
1251
|
+
}
|
|
1252
|
+
this._clearPrevOverMesh();
|
|
1253
|
+
if (!this._transEnabled) {
|
|
1254
|
+
this._setVisibility(this._all_tEnd, this._visibility);
|
|
1255
|
+
this._transEnabled = true;
|
|
1256
|
+
this.disableRotation();
|
|
1257
|
+
this.disableScaling();
|
|
1258
|
+
}
|
|
1259
|
+
}
|
|
1260
|
+
disableTranslation() {
|
|
1261
|
+
if (this._transEnabled) {
|
|
1262
|
+
this._setVisibility(this._all_tEnd, 0);
|
|
1263
|
+
this._transEnabled = false;
|
|
1264
|
+
}
|
|
1265
|
+
}
|
|
1266
|
+
isRotationEnabled() {
|
|
1267
|
+
return this._rotEnabled;
|
|
1268
|
+
}
|
|
1269
|
+
enableRotation() {
|
|
1270
|
+
if (this._hidden)
|
|
1271
|
+
return;
|
|
1272
|
+
if (this._rCtl == null) {
|
|
1273
|
+
this._createRotAxes();
|
|
1274
|
+
this._rCtl.parent = this._ecRoot;
|
|
1275
|
+
}
|
|
1276
|
+
this._clearPrevOverMesh();
|
|
1277
|
+
if (!this._rotEnabled) {
|
|
1278
|
+
this._setVisibility(this._all_rEnd, this._visibility);
|
|
1279
|
+
this._rotEnabled = true;
|
|
1280
|
+
this.disableTranslation();
|
|
1281
|
+
this.disableScaling();
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
disableRotation() {
|
|
1285
|
+
if (this._rotEnabled) {
|
|
1286
|
+
this._setVisibility(this._all_rEnd, 0);
|
|
1287
|
+
this._rotEnabled = false;
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
isScalingEnabled() {
|
|
1291
|
+
return this._scaleEnabled;
|
|
1292
|
+
}
|
|
1293
|
+
enableScaling() {
|
|
1294
|
+
if (this._hidden)
|
|
1295
|
+
return;
|
|
1296
|
+
if (this._sX == null) {
|
|
1297
|
+
this._createScaleAxes();
|
|
1298
|
+
this._sCtl.parent = this._ecRoot;
|
|
1299
|
+
}
|
|
1300
|
+
this._clearPrevOverMesh();
|
|
1301
|
+
if (!this._scaleEnabled) {
|
|
1302
|
+
this._setVisibility(this._all_sEnd, this._visibility);
|
|
1303
|
+
this._scaleEnabled = true;
|
|
1304
|
+
this.disableTranslation();
|
|
1305
|
+
this.disableRotation();
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
disableScaling() {
|
|
1309
|
+
if (this._scaleEnabled) {
|
|
1310
|
+
this._setVisibility(this._all_sEnd, 0);
|
|
1311
|
+
this._scaleEnabled = false;
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
setScaleBounds(min, max) {
|
|
1315
|
+
this._scaleBoundsMin = min ? min : null;
|
|
1316
|
+
this._scaleBoundsMax = max ? max : null;
|
|
1317
|
+
if (this._scaleBoundsMin != null) {
|
|
1318
|
+
if (this._scaleBoundsMin.x == 0)
|
|
1319
|
+
this._scaleBoundsMin.x = 0.00000001;
|
|
1320
|
+
if (this._scaleBoundsMin.y == 0)
|
|
1321
|
+
this._scaleBoundsMin.y = 0.00000001;
|
|
1322
|
+
if (this._scaleBoundsMin.z == 0)
|
|
1323
|
+
this._scaleBoundsMin.z = 0.00000001;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
removeScaleBounds() {
|
|
1327
|
+
this._scaleBoundsMin = null;
|
|
1328
|
+
this._scaleBoundsMax = null;
|
|
1329
|
+
}
|
|
1330
|
+
setTransBounds(min, max) {
|
|
1331
|
+
this._transBoundsMin = min ? min : null;
|
|
1332
|
+
this._transBoundsMax = max ? max : null;
|
|
1333
|
+
}
|
|
1334
|
+
removeTransBounds() {
|
|
1335
|
+
this._transBoundsMin = null;
|
|
1336
|
+
this._transBoundsMax = null;
|
|
1337
|
+
}
|
|
1338
|
+
setRotBounds(min, max) {
|
|
1339
|
+
this._rotBoundsMin = min ? min : null;
|
|
1340
|
+
this._rotBoundsMax = max ? max : null;
|
|
1341
|
+
}
|
|
1342
|
+
removeRotBounds() {
|
|
1343
|
+
this._rotBoundsMin = null;
|
|
1344
|
+
this._rotBoundsMax = null;
|
|
1345
|
+
}
|
|
1346
|
+
/*
|
|
1347
|
+
* create big and small axeses which will be shown in translate, rotate and scale mode.
|
|
1348
|
+
*
|
|
1349
|
+
*/
|
|
1350
|
+
_createCommonAxes() {
|
|
1351
|
+
let guideAxes = new babylonjs_1.Mesh("", this._scene);
|
|
1352
|
+
//the big axes, shown when an axis is selected
|
|
1353
|
+
this._bXaxis = babylonjs_1.MeshBuilder.CreateLines("", { points: [new babylonjs_1.Vector3(-100, 0, 0), new babylonjs_1.Vector3(100, 0, 0)] }, this._scene);
|
|
1354
|
+
this._bYaxis = babylonjs_1.MeshBuilder.CreateLines("", { points: [new babylonjs_1.Vector3(0, -100, 0), new babylonjs_1.Vector3(0, 100, 0)] }, this._scene);
|
|
1355
|
+
this._bZaxis = babylonjs_1.MeshBuilder.CreateLines("", { points: [new babylonjs_1.Vector3(0, 0, -100), new babylonjs_1.Vector3(0, 0, 100)] }, this._scene);
|
|
1356
|
+
//lines are now pickable too
|
|
1357
|
+
this._bXaxis.isPickable = false;
|
|
1358
|
+
this._bYaxis.isPickable = false;
|
|
1359
|
+
this._bZaxis.isPickable = false;
|
|
1360
|
+
this._bXaxis.parent = guideAxes;
|
|
1361
|
+
this._bYaxis.parent = guideAxes;
|
|
1362
|
+
this._bZaxis.parent = guideAxes;
|
|
1363
|
+
this._bXaxis.color = this._redCol;
|
|
1364
|
+
this._bYaxis.color = this._greenCol;
|
|
1365
|
+
this._bZaxis.color = this._blueCol;
|
|
1366
|
+
this._hideBaxis();
|
|
1367
|
+
//the small axis
|
|
1368
|
+
let al = this._axesLen * this._axesScale * 0.75;
|
|
1369
|
+
this._xaxis = babylonjs_1.MeshBuilder.CreateLines("", { points: [new babylonjs_1.Vector3(0, 0, 0), new babylonjs_1.Vector3(al, 0, 0)] }, this._scene);
|
|
1370
|
+
this._yaxis = babylonjs_1.MeshBuilder.CreateLines("", { points: [new babylonjs_1.Vector3(0, 0, 0), new babylonjs_1.Vector3(0, al, 0)] }, this._scene);
|
|
1371
|
+
this._zaxis = babylonjs_1.MeshBuilder.CreateLines("", { points: [new babylonjs_1.Vector3(0, 0, 0), new babylonjs_1.Vector3(0, 0, al)] }, this._scene);
|
|
1372
|
+
//lines are now pickable too
|
|
1373
|
+
this._xaxis.isPickable = false;
|
|
1374
|
+
this._yaxis.isPickable = false;
|
|
1375
|
+
this._zaxis.isPickable = false;
|
|
1376
|
+
this._xaxis.parent = guideAxes;
|
|
1377
|
+
this._yaxis.parent = guideAxes;
|
|
1378
|
+
this._zaxis.parent = guideAxes;
|
|
1379
|
+
this._xaxis.color = this._redCol;
|
|
1380
|
+
this._yaxis.color = this._greenCol;
|
|
1381
|
+
this._zaxis.color = this._blueCol;
|
|
1382
|
+
this._xaxis.renderingGroupId = 1;
|
|
1383
|
+
this._yaxis.renderingGroupId = 1;
|
|
1384
|
+
this._zaxis.renderingGroupId = 1;
|
|
1385
|
+
return guideAxes;
|
|
1386
|
+
}
|
|
1387
|
+
_createPickPlanes() {
|
|
1388
|
+
this._pALL = babylonjs_1.MeshBuilder.CreatePlane("", { size: 5 }, this._scene);
|
|
1389
|
+
this._pXZ = babylonjs_1.MeshBuilder.CreatePlane("", { size: 5 }, this._scene);
|
|
1390
|
+
this._pZY = babylonjs_1.MeshBuilder.CreatePlane("", { size: 5 }, this._scene);
|
|
1391
|
+
this._pYX = babylonjs_1.MeshBuilder.CreatePlane("", { size: 5 }, this._scene);
|
|
1392
|
+
this._pALL.isPickable = false;
|
|
1393
|
+
this._pXZ.isPickable = false;
|
|
1394
|
+
this._pZY.isPickable = false;
|
|
1395
|
+
this._pYX.isPickable = false;
|
|
1396
|
+
this._pALL.visibility = 0;
|
|
1397
|
+
this._pXZ.visibility = 0;
|
|
1398
|
+
this._pZY.visibility = 0;
|
|
1399
|
+
this._pYX.visibility = 0;
|
|
1400
|
+
this._pALL.renderingGroupId = 1;
|
|
1401
|
+
this._pXZ.renderingGroupId = 1;
|
|
1402
|
+
this._pZY.renderingGroupId = 1;
|
|
1403
|
+
this._pYX.renderingGroupId = 1;
|
|
1404
|
+
this._pALL.lookAt(this._mainCamera.position);
|
|
1405
|
+
this._pXZ.rotate(babylonjs_1.Axis.X, 1.57);
|
|
1406
|
+
this._pZY.rotate(babylonjs_1.Axis.Y, 1.57);
|
|
1407
|
+
let pickPlanes = new babylonjs_1.Mesh("", this._scene);
|
|
1408
|
+
this._pALL.parent = pickPlanes;
|
|
1409
|
+
this._pXZ.parent = pickPlanes;
|
|
1410
|
+
this._pZY.parent = pickPlanes;
|
|
1411
|
+
this._pYX.parent = pickPlanes;
|
|
1412
|
+
return pickPlanes;
|
|
1413
|
+
}
|
|
1414
|
+
_createTransAxes() {
|
|
1415
|
+
let r = this._pickWidth * 2 * this._axesScale;
|
|
1416
|
+
let l = this._axesLen * this._axesScale;
|
|
1417
|
+
this._tCtl = new babylonjs_1.Mesh("", this._scene);
|
|
1418
|
+
// pickable invisible boxes around axes lines
|
|
1419
|
+
this._createPickableTrans(r, l, this._tCtl, this._scene);
|
|
1420
|
+
//non pickable but visible cones at end of axes lines
|
|
1421
|
+
this._createNonPickableTrans(r, l, this._scene);
|
|
1422
|
+
}
|
|
1423
|
+
/**
|
|
1424
|
+
* pickable but invisible
|
|
1425
|
+
* a) 3 boxes around each of the 3 small axes lines
|
|
1426
|
+
* b) 3 small planes near origin for movement along a plane
|
|
1427
|
+
* @param r
|
|
1428
|
+
* @param l
|
|
1429
|
+
* @param tCtl
|
|
1430
|
+
* @param scene
|
|
1431
|
+
*/
|
|
1432
|
+
_createPickableTrans(r, l, tCtl, scene) {
|
|
1433
|
+
let tX = this._extrudeBox(r / 2, l);
|
|
1434
|
+
tX.name = "X";
|
|
1435
|
+
let tY = tX.clone("Y");
|
|
1436
|
+
let tZ = tX.clone("Z");
|
|
1437
|
+
let s = r * 2;
|
|
1438
|
+
let tXZ = babylonjs_1.MeshBuilder.CreatePlane("XZ", { size: s }, scene);
|
|
1439
|
+
let tZY = babylonjs_1.MeshBuilder.CreatePlane("ZY", { size: s }, scene);
|
|
1440
|
+
let tYX = babylonjs_1.MeshBuilder.CreatePlane("YX", { size: s }, scene);
|
|
1441
|
+
tXZ.rotation.x = 1.57;
|
|
1442
|
+
tZY.rotation.y = -1.57;
|
|
1443
|
+
tXZ.position.x = 2 * r;
|
|
1444
|
+
tXZ.position.z = 2 * r;
|
|
1445
|
+
tZY.position.z = 2 * r;
|
|
1446
|
+
tZY.position.y = 2 * r;
|
|
1447
|
+
tYX.position.y = 2 * r;
|
|
1448
|
+
tYX.position.x = 2 * r;
|
|
1449
|
+
tXZ.bakeCurrentTransformIntoVertices();
|
|
1450
|
+
tZY.bakeCurrentTransformIntoVertices();
|
|
1451
|
+
tYX.bakeCurrentTransformIntoVertices();
|
|
1452
|
+
let tAll = babylonjs_1.MeshBuilder.CreateBox("ALL", { size: r * 2 }, scene);
|
|
1453
|
+
tX.parent = tCtl;
|
|
1454
|
+
tY.parent = tCtl;
|
|
1455
|
+
tZ.parent = tCtl;
|
|
1456
|
+
tXZ.parent = tCtl;
|
|
1457
|
+
tZY.parent = tCtl;
|
|
1458
|
+
tYX.parent = tCtl;
|
|
1459
|
+
tAll.parent = tCtl;
|
|
1460
|
+
tX.rotation.y = 1.57;
|
|
1461
|
+
tY.rotation.x -= 1.57;
|
|
1462
|
+
this._tX = tX;
|
|
1463
|
+
this._tY = tY;
|
|
1464
|
+
this._tZ = tZ;
|
|
1465
|
+
this._tXZ = tXZ;
|
|
1466
|
+
this._tZY = tZY;
|
|
1467
|
+
this._tYX = tYX;
|
|
1468
|
+
this._tAll = tAll;
|
|
1469
|
+
this._all_t = [tX, tY, tZ, tXZ, tZY, tYX, tAll];
|
|
1470
|
+
this._setVisibility(this._all_t, 0);
|
|
1471
|
+
//do not want clients picking this
|
|
1472
|
+
//we will pick using mesh filter in scene.pick function
|
|
1473
|
+
this._setPickableFalse(this._all_t);
|
|
1474
|
+
}
|
|
1475
|
+
//non pickable but visible
|
|
1476
|
+
// a) 3 cones at end of the 3 small axes lines
|
|
1477
|
+
// b) 3 small planes near origin for movement along a plane
|
|
1478
|
+
_createNonPickableTrans(r, l, scene) {
|
|
1479
|
+
//cone length
|
|
1480
|
+
let cl = l / 5;
|
|
1481
|
+
//cone base radius
|
|
1482
|
+
//let cr: number = r;
|
|
1483
|
+
let tEndX = babylonjs_1.MeshBuilder.CreateCylinder("", { height: cl, diameterTop: 0, diameterBottom: r, tessellation: 6, subdivisions: 1 }, scene);
|
|
1484
|
+
let tEndY = tEndX.clone("");
|
|
1485
|
+
let tEndZ = tEndX.clone("");
|
|
1486
|
+
let s = r * 2;
|
|
1487
|
+
let tEndXZ = babylonjs_1.MeshBuilder.CreatePlane("XZ", { size: s }, scene);
|
|
1488
|
+
let tEndZY = babylonjs_1.MeshBuilder.CreatePlane("ZY", { size: s }, scene);
|
|
1489
|
+
let tEndYX = babylonjs_1.MeshBuilder.CreatePlane("YX", { size: s }, scene);
|
|
1490
|
+
let tEndAll = babylonjs_1.MeshBuilder.CreateBox("ALL", { size: r }, scene);
|
|
1491
|
+
tEndX.rotation.x = 1.57;
|
|
1492
|
+
tEndY.rotation.x = 1.57;
|
|
1493
|
+
tEndZ.rotation.x = 1.57;
|
|
1494
|
+
tEndXZ.rotation.x = 1.57;
|
|
1495
|
+
tEndZY.rotation.y = 1.57;
|
|
1496
|
+
//tEndYX.rotation.x = 0;
|
|
1497
|
+
tEndXZ.position.x = s;
|
|
1498
|
+
tEndXZ.position.z = s;
|
|
1499
|
+
tEndZY.position.z = s;
|
|
1500
|
+
tEndZY.position.y = s;
|
|
1501
|
+
tEndYX.position.y = s;
|
|
1502
|
+
tEndYX.position.x = s;
|
|
1503
|
+
tEndX.parent = this._tX;
|
|
1504
|
+
tEndY.parent = this._tY;
|
|
1505
|
+
tEndZ.parent = this._tZ;
|
|
1506
|
+
tEndXZ.parent = this._tXZ;
|
|
1507
|
+
tEndZY.parent = this._tZY;
|
|
1508
|
+
tEndYX.parent = this._tYX;
|
|
1509
|
+
tEndAll.parent = this._tAll;
|
|
1510
|
+
tEndX.position.z = l - cl / 2;
|
|
1511
|
+
tEndY.position.z = l - cl / 2;
|
|
1512
|
+
tEndZ.position.z = l - cl / 2;
|
|
1513
|
+
tEndX.material = this._redMat;
|
|
1514
|
+
tEndY.material = this._greenMat;
|
|
1515
|
+
tEndZ.material = this._blueMat;
|
|
1516
|
+
tEndXZ.material = this._greenMat;
|
|
1517
|
+
tEndZY.material = this._redMat;
|
|
1518
|
+
tEndYX.material = this._blueMat;
|
|
1519
|
+
tEndAll.material = this._yellowMat;
|
|
1520
|
+
this._tEndX = tEndX;
|
|
1521
|
+
this._tEndY = tEndY;
|
|
1522
|
+
this._tEndZ = tEndZ;
|
|
1523
|
+
this._tEndXZ = tEndXZ;
|
|
1524
|
+
this._tEndZY = tEndZY;
|
|
1525
|
+
this._tEndYX = tEndYX;
|
|
1526
|
+
this._tEndAll = tEndAll;
|
|
1527
|
+
this._all_tEnd = [tEndX, tEndY, tEndZ, tEndXZ, tEndZY, tEndYX, tEndAll];
|
|
1528
|
+
this._setPickableFalse(this._all_tEnd);
|
|
1529
|
+
this._setRenderingGroup(this._all_tEnd);
|
|
1530
|
+
}
|
|
1531
|
+
setRotGuideFull(y) {
|
|
1532
|
+
if (y)
|
|
1533
|
+
this._guideSize = 360;
|
|
1534
|
+
else
|
|
1535
|
+
this._guideSize = 180;
|
|
1536
|
+
if (this._rCtl != null) {
|
|
1537
|
+
this._rCtl.dispose();
|
|
1538
|
+
this._rAll.dispose();
|
|
1539
|
+
this._rCtl = null;
|
|
1540
|
+
this.enableRotation();
|
|
1541
|
+
}
|
|
1542
|
+
}
|
|
1543
|
+
_createRotAxes() {
|
|
1544
|
+
let d = this._axesLen * this._axesScale * 2;
|
|
1545
|
+
this._rCtl = new babylonjs_1.Mesh("", this._scene);
|
|
1546
|
+
//pickable invisible torus around the rotation circles
|
|
1547
|
+
this._createPickableRot(d, this._rCtl);
|
|
1548
|
+
/*non pickable but visible circles */
|
|
1549
|
+
this._createNonPickableRot(d);
|
|
1550
|
+
}
|
|
1551
|
+
_createPickableRot(d, rCtl) {
|
|
1552
|
+
let rX = this._createTube(d / 2, this._guideSize);
|
|
1553
|
+
let rY = this._createTube(d / 2, this._guideSize);
|
|
1554
|
+
let rZ = this._createTube(d / 2, this._guideSize);
|
|
1555
|
+
let rAll = this._createTube(d / 1.75, 360);
|
|
1556
|
+
rX.name = "X";
|
|
1557
|
+
rY.name = "Y";
|
|
1558
|
+
rZ.name = "Z";
|
|
1559
|
+
rAll.name = "ALL";
|
|
1560
|
+
rX.rotation.z = 1.57;
|
|
1561
|
+
rZ.rotation.x = -1.57;
|
|
1562
|
+
rX.bakeCurrentTransformIntoVertices();
|
|
1563
|
+
rZ.bakeCurrentTransformIntoVertices();
|
|
1564
|
+
rAll.rotation.x = 1.57;
|
|
1565
|
+
rX.parent = rCtl;
|
|
1566
|
+
rY.parent = rCtl;
|
|
1567
|
+
rZ.parent = rCtl;
|
|
1568
|
+
rAll.parent = this._pALL;
|
|
1569
|
+
this._rX = rX;
|
|
1570
|
+
this._rY = rY;
|
|
1571
|
+
this._rZ = rZ;
|
|
1572
|
+
this._rAll = rAll;
|
|
1573
|
+
this._all_r = [rX, rY, rZ, rAll];
|
|
1574
|
+
this._setVisibility(this._all_r, 0);
|
|
1575
|
+
//do not want clients picking this
|
|
1576
|
+
//we will pick using mesh filter in scene.pick function
|
|
1577
|
+
this._setPickableFalse(this._all_r);
|
|
1578
|
+
}
|
|
1579
|
+
_createNonPickableRot(d) {
|
|
1580
|
+
let rEndX = this._createCircle(d / 2, this._guideSize, false);
|
|
1581
|
+
let rEndY = rEndX.clone("");
|
|
1582
|
+
let rEndZ = rEndX.clone("");
|
|
1583
|
+
let rEndAll = this._createCircle(d / 1.75, 360, false);
|
|
1584
|
+
let rEndAll2 = this._createCircle(d / 2, 360, false);
|
|
1585
|
+
rEndX.parent = this._rX;
|
|
1586
|
+
rEndY.parent = this._rY;
|
|
1587
|
+
rEndZ.parent = this._rZ;
|
|
1588
|
+
rEndX.rotation.z = 1.57;
|
|
1589
|
+
rEndZ.rotation.x = -1.57;
|
|
1590
|
+
rEndAll.parent = this._rAll;
|
|
1591
|
+
rEndAll2.parent = this._rAll;
|
|
1592
|
+
rEndX.color = this._redCol;
|
|
1593
|
+
rEndY.color = this._greenCol;
|
|
1594
|
+
rEndZ.color = this._blueCol;
|
|
1595
|
+
rEndAll.color = this._whiteCol;
|
|
1596
|
+
rEndAll2.color = babylonjs_1.Color3.Gray();
|
|
1597
|
+
this._rEndX = rEndX;
|
|
1598
|
+
this._rEndY = rEndY;
|
|
1599
|
+
this._rEndZ = rEndZ;
|
|
1600
|
+
this._rEndAll = rEndAll;
|
|
1601
|
+
this._rEndAll2 = rEndAll2;
|
|
1602
|
+
this._all_rEnd = [rEndX, rEndY, rEndZ, rEndAll, rEndAll2];
|
|
1603
|
+
this._setPickableFalse(this._all_rEnd);
|
|
1604
|
+
this._setRenderingGroup(this._all_rEnd);
|
|
1605
|
+
}
|
|
1606
|
+
_setVisibility(meshes, v) {
|
|
1607
|
+
meshes.map((m) => m.visibility = v);
|
|
1608
|
+
}
|
|
1609
|
+
_setPickableFalse(meshes) {
|
|
1610
|
+
meshes.map((m) => { m.isPickable = false; });
|
|
1611
|
+
}
|
|
1612
|
+
_setRenderingGroup(meshes) {
|
|
1613
|
+
meshes.map((m) => m.renderingGroupId = 2);
|
|
1614
|
+
}
|
|
1615
|
+
_extrudeBox(w, l) {
|
|
1616
|
+
let shape = [new babylonjs_1.Vector3(w, w, 0), new babylonjs_1.Vector3(-w, w, 0), new babylonjs_1.Vector3(-w, -w, 0), new babylonjs_1.Vector3(w, -w, 0), new babylonjs_1.Vector3(w, w, 0)];
|
|
1617
|
+
let path = [new babylonjs_1.Vector3(0, 0, 0), new babylonjs_1.Vector3(0, 0, l)];
|
|
1618
|
+
let box = babylonjs_1.MeshBuilder.ExtrudeShape("", { shape: shape, path: path, scale: 1, rotation: 0, cap: 2 }, this._scene);
|
|
1619
|
+
return box;
|
|
1620
|
+
}
|
|
1621
|
+
_createCircle(r, t, double) {
|
|
1622
|
+
if (t === null)
|
|
1623
|
+
t = 360;
|
|
1624
|
+
let points = [];
|
|
1625
|
+
let x;
|
|
1626
|
+
let z;
|
|
1627
|
+
let a = 3.14 / 180;
|
|
1628
|
+
let p = 0;
|
|
1629
|
+
for (let i = 0; i <= t; i = i + 5) {
|
|
1630
|
+
x = r * Math.cos(i * a);
|
|
1631
|
+
if (i == 90)
|
|
1632
|
+
z = r;
|
|
1633
|
+
else if (i == 270)
|
|
1634
|
+
z = -r;
|
|
1635
|
+
else
|
|
1636
|
+
z = r * Math.sin(i * a);
|
|
1637
|
+
points[p] = new babylonjs_1.Vector3(x, 0, z);
|
|
1638
|
+
p++;
|
|
1639
|
+
}
|
|
1640
|
+
if (double) {
|
|
1641
|
+
r = r - 0.04;
|
|
1642
|
+
for (let i = 0; i <= t; i = i + 5) {
|
|
1643
|
+
x = r * Math.cos(i * a);
|
|
1644
|
+
if (i == 90)
|
|
1645
|
+
z = r;
|
|
1646
|
+
else if (i == 270)
|
|
1647
|
+
z = -r;
|
|
1648
|
+
else
|
|
1649
|
+
z = r * Math.sin(i * a);
|
|
1650
|
+
points[p] = new babylonjs_1.Vector3(x, 0, z);
|
|
1651
|
+
p++;
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
let circle = babylonjs_1.MeshBuilder.CreateLines("", { points: points }, this._scene);
|
|
1655
|
+
return circle;
|
|
1656
|
+
}
|
|
1657
|
+
_createTube(r, t) {
|
|
1658
|
+
if (t === null)
|
|
1659
|
+
t = 360;
|
|
1660
|
+
let points = [];
|
|
1661
|
+
let x;
|
|
1662
|
+
let z;
|
|
1663
|
+
let a = 3.14 / 180;
|
|
1664
|
+
let p = 0;
|
|
1665
|
+
for (let i = 0; i <= t; i = i + 30) {
|
|
1666
|
+
x = r * Math.cos(i * a);
|
|
1667
|
+
if (i == 90)
|
|
1668
|
+
z = r;
|
|
1669
|
+
else if (i == 270)
|
|
1670
|
+
z = -r;
|
|
1671
|
+
else
|
|
1672
|
+
z = r * Math.sin(i * a);
|
|
1673
|
+
points[p] = new babylonjs_1.Vector3(x, 0, z);
|
|
1674
|
+
p++;
|
|
1675
|
+
}
|
|
1676
|
+
let tube = babylonjs_1.MeshBuilder.CreateTube("", { path: points, radius: this._pickWidth * this._axesScale * 2, tessellation: 3, cap: babylonjs_1.Mesh.NO_CAP }, this._scene);
|
|
1677
|
+
return tube;
|
|
1678
|
+
}
|
|
1679
|
+
_createScaleAxes() {
|
|
1680
|
+
let r = this._pickWidth * 2 * this._axesScale;
|
|
1681
|
+
let l = this._axesLen * this._axesScale;
|
|
1682
|
+
this._sCtl = new babylonjs_1.Mesh("", this._scene);
|
|
1683
|
+
/* pickable , invisible part */
|
|
1684
|
+
this._createPickableScale(r, l, this._sCtl);
|
|
1685
|
+
/* non pickable visible boxes at end of axes */
|
|
1686
|
+
this._createNonPickableScale(r, l);
|
|
1687
|
+
}
|
|
1688
|
+
_createPickableScale(r, l, sCtl) {
|
|
1689
|
+
let sX = this._extrudeBox(r / 2, l);
|
|
1690
|
+
sX.name = "X";
|
|
1691
|
+
let sY = sX.clone("Y");
|
|
1692
|
+
let sZ = sX.clone("Z");
|
|
1693
|
+
let sXZ = babylonjs_1.MeshBuilder.CreatePlane("XZ", { size: r * 2 }, this._scene);
|
|
1694
|
+
let sZY = babylonjs_1.MeshBuilder.CreatePlane("ZY", { size: r * 2 }, this._scene);
|
|
1695
|
+
let sYX = babylonjs_1.MeshBuilder.CreatePlane("YX", { size: r * 2 }, this._scene);
|
|
1696
|
+
sXZ.rotation.x = 1.57;
|
|
1697
|
+
sZY.rotation.y = -1.57;
|
|
1698
|
+
sXZ.position.x = 2 * r;
|
|
1699
|
+
sXZ.position.z = 2 * r;
|
|
1700
|
+
sZY.position.z = 2 * r;
|
|
1701
|
+
sZY.position.y = 2 * r;
|
|
1702
|
+
sYX.position.y = 2 * r;
|
|
1703
|
+
sYX.position.x = 2 * r;
|
|
1704
|
+
sXZ.bakeCurrentTransformIntoVertices();
|
|
1705
|
+
sZY.bakeCurrentTransformIntoVertices();
|
|
1706
|
+
sYX.bakeCurrentTransformIntoVertices();
|
|
1707
|
+
let sAll = babylonjs_1.MeshBuilder.CreateBox("ALL", { size: 2 * r }, this._scene);
|
|
1708
|
+
sX.parent = sCtl;
|
|
1709
|
+
sY.parent = sCtl;
|
|
1710
|
+
sZ.parent = sCtl;
|
|
1711
|
+
sAll.parent = sCtl;
|
|
1712
|
+
sXZ.parent = sCtl;
|
|
1713
|
+
sZY.parent = sCtl;
|
|
1714
|
+
sYX.parent = sCtl;
|
|
1715
|
+
sX.rotation.y = 1.57;
|
|
1716
|
+
sY.rotation.x -= 1.57;
|
|
1717
|
+
this._sX = sX;
|
|
1718
|
+
this._sY = sY;
|
|
1719
|
+
this._sZ = sZ;
|
|
1720
|
+
this._sXZ = sXZ;
|
|
1721
|
+
this._sZY = sZY;
|
|
1722
|
+
this._sYX = sYX;
|
|
1723
|
+
this._sAll = sAll;
|
|
1724
|
+
this._all_s = [sX, sY, sZ, sXZ, sZY, sYX, sAll];
|
|
1725
|
+
this._setVisibility(this._all_s, 0);
|
|
1726
|
+
//do not want clients picking this
|
|
1727
|
+
//we will pick using mesh filter in scene.pick function
|
|
1728
|
+
this._setPickableFalse(this._all_s);
|
|
1729
|
+
}
|
|
1730
|
+
_createNonPickableScale(r, l) {
|
|
1731
|
+
let sEndX = babylonjs_1.MeshBuilder.CreateBox("", { size: r }, this._scene);
|
|
1732
|
+
let sEndY = sEndX.clone("");
|
|
1733
|
+
let sEndZ = sEndX.clone("");
|
|
1734
|
+
let s = r * 2;
|
|
1735
|
+
let sEndXZ = babylonjs_1.MeshBuilder.CreatePlane("XZ", { size: s }, this._scene);
|
|
1736
|
+
let sEndZY = babylonjs_1.MeshBuilder.CreatePlane("ZY", { size: s }, this._scene);
|
|
1737
|
+
let sEndYX = babylonjs_1.MeshBuilder.CreatePlane("YX", { size: s }, this._scene);
|
|
1738
|
+
let sEndAll = babylonjs_1.MeshBuilder.CreateBox("ALL", { size: r }, this._scene);
|
|
1739
|
+
sEndXZ.rotation.x = 1.57;
|
|
1740
|
+
sEndZY.rotation.y = -1.57;
|
|
1741
|
+
sEndXZ.position.x = s;
|
|
1742
|
+
sEndXZ.position.z = s;
|
|
1743
|
+
sEndZY.position.z = s;
|
|
1744
|
+
sEndZY.position.y = s;
|
|
1745
|
+
sEndYX.position.y = s;
|
|
1746
|
+
sEndYX.position.x = s;
|
|
1747
|
+
sEndX.parent = this._sX;
|
|
1748
|
+
sEndY.parent = this._sY;
|
|
1749
|
+
sEndZ.parent = this._sZ;
|
|
1750
|
+
sEndXZ.parent = this._sXZ;
|
|
1751
|
+
sEndZY.parent = this._sZY;
|
|
1752
|
+
sEndYX.parent = this._sYX;
|
|
1753
|
+
sEndAll.parent = this._sAll;
|
|
1754
|
+
sEndX.position.z = l - r / 2;
|
|
1755
|
+
sEndY.position.z = l - r / 2;
|
|
1756
|
+
sEndZ.position.z = l - r / 2;
|
|
1757
|
+
sEndX.material = this._redMat;
|
|
1758
|
+
sEndY.material = this._greenMat;
|
|
1759
|
+
sEndZ.material = this._blueMat;
|
|
1760
|
+
sEndXZ.material = this._greenMat;
|
|
1761
|
+
sEndZY.material = this._redMat;
|
|
1762
|
+
sEndYX.material = this._blueMat;
|
|
1763
|
+
sEndAll.material = this._yellowMat;
|
|
1764
|
+
this._sEndX = sEndX;
|
|
1765
|
+
this._sEndY = sEndY;
|
|
1766
|
+
this._sEndZ = sEndZ;
|
|
1767
|
+
this._sEndXZ = sEndXZ;
|
|
1768
|
+
this._sEndZY = sEndZY;
|
|
1769
|
+
this._sEndYX = sEndYX;
|
|
1770
|
+
this._sEndAll = sEndAll;
|
|
1771
|
+
this._all_sEnd = [sEndX, sEndY, sEndZ, sEndXZ, sEndZY, sEndYX, sEndAll];
|
|
1772
|
+
this._setPickableFalse(this._all_sEnd);
|
|
1773
|
+
this._setRenderingGroup(this._all_sEnd);
|
|
1774
|
+
}
|
|
1775
|
+
/**
|
|
1776
|
+
* checks if a have left hand , right hand issue.
|
|
1777
|
+
* In other words if a mesh is a LHS mesh in RHS system or
|
|
1778
|
+
* a RHS mesh in LHS system
|
|
1779
|
+
* The X axis will be reversed in such cases.
|
|
1780
|
+
* thus Cross product of X and Y should be inverse of Z.
|
|
1781
|
+
*
|
|
1782
|
+
*/
|
|
1783
|
+
// private _check_LHS_RHS(mesh: Mesh) {
|
|
1784
|
+
// let actualZ = Vector3.Cross(this._localX, this._localY);
|
|
1785
|
+
// //same direction or opposite direction of Z
|
|
1786
|
+
// if (Vector3.Dot(actualZ, this._localZ) < 0) return true;
|
|
1787
|
+
// else return false;
|
|
1788
|
+
// }
|
|
1789
|
+
/**
|
|
1790
|
+
* set how transparent the axes are
|
|
1791
|
+
* 0 to 1
|
|
1792
|
+
* 0 - completely transparent
|
|
1793
|
+
* 1 - completely non transparent
|
|
1794
|
+
* default is 0.75
|
|
1795
|
+
*/
|
|
1796
|
+
setVisibility(v) {
|
|
1797
|
+
this._visibility = v;
|
|
1798
|
+
}
|
|
1799
|
+
setLocal(l) {
|
|
1800
|
+
if (this._local == l)
|
|
1801
|
+
return;
|
|
1802
|
+
this._local = l;
|
|
1803
|
+
if (!l) {
|
|
1804
|
+
this._ecRoot.rotationQuaternion = babylonjs_1.Quaternion.Identity();
|
|
1805
|
+
}
|
|
1806
|
+
}
|
|
1807
|
+
isLocal() {
|
|
1808
|
+
return this._local;
|
|
1809
|
+
}
|
|
1810
|
+
setTransSnap(s) {
|
|
1811
|
+
this._snapT = s;
|
|
1812
|
+
}
|
|
1813
|
+
isTransSnap() {
|
|
1814
|
+
return this._snapT;
|
|
1815
|
+
}
|
|
1816
|
+
setRotSnap(s) {
|
|
1817
|
+
this._snapR = s;
|
|
1818
|
+
}
|
|
1819
|
+
isRotSnap() {
|
|
1820
|
+
return this._snapR;
|
|
1821
|
+
}
|
|
1822
|
+
setScaleSnap(s) {
|
|
1823
|
+
this._snapS = s;
|
|
1824
|
+
}
|
|
1825
|
+
isScaleSnap() {
|
|
1826
|
+
return this._snapS;
|
|
1827
|
+
}
|
|
1828
|
+
setTransSnapValue(t) {
|
|
1829
|
+
this._tSnap.copyFromFloats(t, t, t);
|
|
1830
|
+
this._transSnap = t;
|
|
1831
|
+
}
|
|
1832
|
+
getTransSnapValue() {
|
|
1833
|
+
return this._transSnap;
|
|
1834
|
+
}
|
|
1835
|
+
setRotSnapValue(r) {
|
|
1836
|
+
this._rotSnap = r;
|
|
1837
|
+
}
|
|
1838
|
+
getRotSnapValue() {
|
|
1839
|
+
return this._rotSnap;
|
|
1840
|
+
}
|
|
1841
|
+
setScaleSnapValue(r) {
|
|
1842
|
+
this._scaleSnap = r;
|
|
1843
|
+
}
|
|
1844
|
+
getScaleSnapValue() {
|
|
1845
|
+
return this._scaleSnap;
|
|
1846
|
+
}
|
|
1847
|
+
_getAngle2(p1, p2, cameraPos, c2ec, mN) {
|
|
1848
|
+
/**
|
|
1849
|
+
* A) find out if the camera is above , below, left, right of the rotation plane
|
|
1850
|
+
*/
|
|
1851
|
+
//project "camera to ec" vector onto mesh normal to get distance to rotation plane
|
|
1852
|
+
let d = babylonjs_1.Vector3.Dot(c2ec, mN);
|
|
1853
|
+
//scale mesh normal by above ammount to get vector to rotation plane
|
|
1854
|
+
mN.scaleToRef(d, this._tv1);
|
|
1855
|
+
//get the point of intersection of vector from camera perpendicular to rotation plane
|
|
1856
|
+
cameraPos.addToRef(this._tv1, this._tv2);
|
|
1857
|
+
let i = this._tv2; //save some typing
|
|
1858
|
+
//find the co-ordinate of this point in the cameras frame of reference
|
|
1859
|
+
this._mainCamera.getWorldMatrix().invertToRef(this._tm);
|
|
1860
|
+
babylonjs_1.Vector3.TransformCoordinatesToRef(this._tv2, this._tm, this._tv2);
|
|
1861
|
+
//find in which quadarant the point (and thus the rotation plane) is in the camera xy plane
|
|
1862
|
+
let q = 0; //(1=x y,2=-x y,3=-x -y,4=x -y)
|
|
1863
|
+
if (i.x >= 0 && i.y >= 0)
|
|
1864
|
+
q = 1;
|
|
1865
|
+
else if (i.x <= 0 && i.y >= 0)
|
|
1866
|
+
q = 2;
|
|
1867
|
+
else if (i.x <= 0 && i.y <= 0)
|
|
1868
|
+
q = 3;
|
|
1869
|
+
else if (i.x >= 0 && i.y <= 0)
|
|
1870
|
+
q = 4;
|
|
1871
|
+
/**
|
|
1872
|
+
* B) find out if the user moved pointer up,down, right, left
|
|
1873
|
+
*/
|
|
1874
|
+
//find movement vector in camera frame of reference
|
|
1875
|
+
babylonjs_1.Vector3.TransformCoordinatesToRef(p1, this._tm, this._tv1);
|
|
1876
|
+
babylonjs_1.Vector3.TransformCoordinatesToRef(p2, this._tm, this._tv2);
|
|
1877
|
+
this._tv2.subtractInPlace(this._tv1);
|
|
1878
|
+
let mv = this._tv2; //save some typing
|
|
1879
|
+
//for now lets set the angle magnitutde same as amount by which the mouse moved
|
|
1880
|
+
let angle = mv.length();
|
|
1881
|
+
let m = ""; //(u ,d ,r,l)
|
|
1882
|
+
if (mv.x >= 0 && mv.y >= 0) {
|
|
1883
|
+
if (mv.x >= mv.y)
|
|
1884
|
+
m = "r";
|
|
1885
|
+
else
|
|
1886
|
+
m = "u";
|
|
1887
|
+
}
|
|
1888
|
+
else if (mv.x <= 0 && mv.y >= 0) {
|
|
1889
|
+
if (-mv.x >= mv.y)
|
|
1890
|
+
m = "l";
|
|
1891
|
+
else
|
|
1892
|
+
m = "u";
|
|
1893
|
+
}
|
|
1894
|
+
else if (mv.x <= 0 && mv.y <= 0) {
|
|
1895
|
+
if (-mv.x >= -mv.y)
|
|
1896
|
+
m = "l";
|
|
1897
|
+
else
|
|
1898
|
+
m = "d";
|
|
1899
|
+
}
|
|
1900
|
+
else if (mv.x >= 0 && mv.y <= 0) {
|
|
1901
|
+
if (mv.x >= -mv.y)
|
|
1902
|
+
m = "r";
|
|
1903
|
+
else
|
|
1904
|
+
m = "d";
|
|
1905
|
+
}
|
|
1906
|
+
/**
|
|
1907
|
+
* C) decide if the user was trying to rotate clockwise (+1) or anti-clockwise(-1)
|
|
1908
|
+
*/
|
|
1909
|
+
let r = 0;
|
|
1910
|
+
//if mouse moved down /up and rotation plane is on right or left side of user
|
|
1911
|
+
if (m == "d") {
|
|
1912
|
+
if (q == 1 || q == 4)
|
|
1913
|
+
r = 1;
|
|
1914
|
+
else
|
|
1915
|
+
r = -1;
|
|
1916
|
+
}
|
|
1917
|
+
else if (m == "u") {
|
|
1918
|
+
if (q == 1 || q == 4)
|
|
1919
|
+
r = -1;
|
|
1920
|
+
else
|
|
1921
|
+
r = 1;
|
|
1922
|
+
//if mouse moved right/left and rotation plane is above or below user
|
|
1923
|
+
}
|
|
1924
|
+
else if (m == "r") {
|
|
1925
|
+
if (q == 2 || q == 1)
|
|
1926
|
+
r = 1;
|
|
1927
|
+
else
|
|
1928
|
+
r = -1;
|
|
1929
|
+
}
|
|
1930
|
+
else if (m == "l") {
|
|
1931
|
+
if (q == 2 || q == 1)
|
|
1932
|
+
r = -1;
|
|
1933
|
+
else
|
|
1934
|
+
r = 1;
|
|
1935
|
+
}
|
|
1936
|
+
return r * angle;
|
|
1937
|
+
}
|
|
1938
|
+
/**
|
|
1939
|
+
* finds the angle subtended from points p1 to p2 around the point p
|
|
1940
|
+
* checks if the user was trying to rotate clockwise (+ve in LHS) or anticlockwise (-ve in LHS)
|
|
1941
|
+
* to figure this check the orientation of the user(camera)to ec vector with the rotation normal vector
|
|
1942
|
+
*/
|
|
1943
|
+
_getAngle(p1, p2, p, c2ec) {
|
|
1944
|
+
p1.subtractToRef(p, this._tv1);
|
|
1945
|
+
p2.subtractToRef(p, this._tv2);
|
|
1946
|
+
babylonjs_1.Vector3.CrossToRef(this._tv1, this._tv2, this._tv3);
|
|
1947
|
+
let angle = Math.asin(this._tv3.length() / (this._tv1.length() * this._tv2.length()));
|
|
1948
|
+
//camera looking down from front of plane or looking up from behind plane
|
|
1949
|
+
if ((babylonjs_1.Vector3.Dot(this._tv3, c2ec) > 0)) {
|
|
1950
|
+
angle = -1 * angle;
|
|
1951
|
+
}
|
|
1952
|
+
return angle;
|
|
1953
|
+
}
|
|
1954
|
+
static _getStandardMaterial(col, scene) {
|
|
1955
|
+
let mat = new babylonjs_1.StandardMaterial("", scene);
|
|
1956
|
+
mat.emissiveColor = col;
|
|
1957
|
+
mat.diffuseColor = babylonjs_1.Color3.Black();
|
|
1958
|
+
mat.specularColor = babylonjs_1.Color3.Black();
|
|
1959
|
+
mat.backFaceCulling = false;
|
|
1960
|
+
return mat;
|
|
1961
|
+
}
|
|
1962
|
+
_createMaterials(scene) {
|
|
1963
|
+
this._redMat = EditControl._getStandardMaterial(this._redCol, scene);
|
|
1964
|
+
this._greenMat = EditControl._getStandardMaterial(this._greenCol, scene);
|
|
1965
|
+
this._blueMat = EditControl._getStandardMaterial(this._blueCol, scene);
|
|
1966
|
+
this._whiteMat = EditControl._getStandardMaterial(this._yellowCol, scene);
|
|
1967
|
+
this._yellowMat = EditControl._getStandardMaterial(this._whiteCol, scene);
|
|
1968
|
+
}
|
|
1969
|
+
_disposeMaterials() {
|
|
1970
|
+
this._redMat.dispose();
|
|
1971
|
+
this._greenMat.dispose();
|
|
1972
|
+
this._blueMat.dispose();
|
|
1973
|
+
this._whiteMat.dispose();
|
|
1974
|
+
this._yellowMat.dispose();
|
|
1975
|
+
}
|
|
1976
|
+
}
|
|
1977
|
+
exports.EditControl = EditControl;
|
|
1978
|
+
class ActHist {
|
|
1979
|
+
constructor(mesh, capacity) {
|
|
1980
|
+
this.lastMax = 10;
|
|
1981
|
+
this.acts = new Array();
|
|
1982
|
+
this.last = -1;
|
|
1983
|
+
this.current = -1;
|
|
1984
|
+
this.mesh = mesh;
|
|
1985
|
+
this.lastMax = capacity - 1;
|
|
1986
|
+
this.add();
|
|
1987
|
+
}
|
|
1988
|
+
setCapacity(c) {
|
|
1989
|
+
if ((c == 0)) {
|
|
1990
|
+
console.error("capacity should be more than zero");
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
this.lastMax = c - 1;
|
|
1994
|
+
this.last = -1;
|
|
1995
|
+
this.current = -1;
|
|
1996
|
+
this.acts = new Array();
|
|
1997
|
+
this.add();
|
|
1998
|
+
}
|
|
1999
|
+
add(at) {
|
|
2000
|
+
if (at === undefined)
|
|
2001
|
+
at = null;
|
|
2002
|
+
let act = new Act(this.mesh, at);
|
|
2003
|
+
if ((this.current < this.last)) {
|
|
2004
|
+
this.acts.splice(this.current + 1);
|
|
2005
|
+
this.last = this.current;
|
|
2006
|
+
}
|
|
2007
|
+
if ((this.last == this.lastMax)) {
|
|
2008
|
+
this.acts.shift();
|
|
2009
|
+
this.acts.push(act);
|
|
2010
|
+
}
|
|
2011
|
+
else {
|
|
2012
|
+
this.acts.push(act);
|
|
2013
|
+
this.last++;
|
|
2014
|
+
this.current++;
|
|
2015
|
+
}
|
|
2016
|
+
}
|
|
2017
|
+
undo() {
|
|
2018
|
+
if ((this.current > 0)) {
|
|
2019
|
+
let at = this.acts[this.current].getActionType();
|
|
2020
|
+
this.current--;
|
|
2021
|
+
this.acts[this.current].perform(this.mesh);
|
|
2022
|
+
return at;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
redo() {
|
|
2026
|
+
if ((this.current < this.last)) {
|
|
2027
|
+
this.current++;
|
|
2028
|
+
this.acts[this.current].perform(this.mesh);
|
|
2029
|
+
return this.acts[this.current].getActionType();
|
|
2030
|
+
}
|
|
2031
|
+
}
|
|
2032
|
+
}
|
|
2033
|
+
class Act {
|
|
2034
|
+
constructor(mesh, at) {
|
|
2035
|
+
this._p = mesh.position.clone();
|
|
2036
|
+
if (mesh.rotationQuaternion == null) {
|
|
2037
|
+
this._rQ = null;
|
|
2038
|
+
this._rE = mesh.rotation.clone();
|
|
2039
|
+
}
|
|
2040
|
+
else {
|
|
2041
|
+
this._rQ = mesh.rotationQuaternion.clone();
|
|
2042
|
+
this._rE = null;
|
|
2043
|
+
}
|
|
2044
|
+
this._s = mesh.scaling.clone();
|
|
2045
|
+
this._at = at;
|
|
2046
|
+
}
|
|
2047
|
+
getActionType() {
|
|
2048
|
+
return this._at;
|
|
2049
|
+
}
|
|
2050
|
+
perform(mesh) {
|
|
2051
|
+
mesh.position.copyFrom(this._p);
|
|
2052
|
+
//check if we are doing euler or quaternion now
|
|
2053
|
+
//also check what were we doing when the rotation value
|
|
2054
|
+
//was captured and set value accordingly
|
|
2055
|
+
if (mesh.rotationQuaternion == null) {
|
|
2056
|
+
if (this._rE != null) {
|
|
2057
|
+
//mesh.rotation = this.rE.clone();
|
|
2058
|
+
mesh.rotation.copyFrom(this._rE);
|
|
2059
|
+
}
|
|
2060
|
+
else {
|
|
2061
|
+
//mesh.rotation = this.r.toEulerAngles();
|
|
2062
|
+
mesh.rotation.copyFrom(this._rQ.toEulerAngles());
|
|
2063
|
+
}
|
|
2064
|
+
}
|
|
2065
|
+
else {
|
|
2066
|
+
if (this._rQ != null) {
|
|
2067
|
+
mesh.rotationQuaternion.copyFrom(this._rQ);
|
|
2068
|
+
}
|
|
2069
|
+
else {
|
|
2070
|
+
//TODO use BABYLON.Quaternion.RotationYawPitchRoll(rot.y, rot.x, rot.z) instead of toQuaternion.
|
|
2071
|
+
//mesh.rotationQuaternion.copyFrom(this.rE.toQuaternion());
|
|
2072
|
+
mesh.rotationQuaternion.copyFrom(babylonjs_1.Quaternion.RotationYawPitchRoll(this._rE.y, this._rE.x, this._rE.z));
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
mesh.scaling.copyFrom(this._s);
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2149
2078
|
|
|
2150
|
-
|
|
2079
|
+
})();
|
|
2151
2080
|
|
|
2152
|
-
/******/
|
|
2081
|
+
/******/ return __webpack_exports__;
|
|
2082
|
+
/******/ })()
|
|
2083
|
+
;
|
|
2153
2084
|
});
|
|
2154
2085
|
//# sourceMappingURL=EditControl.max.js.map
|