|
@@ -24709,7 +24709,7 @@ var BABYLON;
|
|
});
|
|
});
|
|
Object.defineProperty(Scene.prototype, "debugLayer", {
|
|
Object.defineProperty(Scene.prototype, "debugLayer", {
|
|
/**
|
|
/**
|
|
- * Gets the debug layer associated with the scene
|
|
|
|
|
|
+ * Gets the debug layer (aka Inspector) associated with the scene
|
|
* @see http://doc.babylonjs.com/features/playground_debuglayer
|
|
* @see http://doc.babylonjs.com/features/playground_debuglayer
|
|
*/
|
|
*/
|
|
get: function () {
|
|
get: function () {
|
|
@@ -28610,10 +28610,14 @@ var BABYLON;
|
|
if (!BABYLON.PickingInfo) {
|
|
if (!BABYLON.PickingInfo) {
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
- return this._internalPick(function (world) {
|
|
|
|
|
|
+ var result = this._internalPick(function (world) {
|
|
_this.createPickingRayToRef(x, y, world, _this._tempPickingRay, camera || null);
|
|
_this.createPickingRayToRef(x, y, world, _this._tempPickingRay, camera || null);
|
|
return _this._tempPickingRay;
|
|
return _this._tempPickingRay;
|
|
}, predicate, fastCheck);
|
|
}, predicate, fastCheck);
|
|
|
|
+ if (result) {
|
|
|
|
+ result.ray = this.createPickingRay(x, y, BABYLON.Matrix.Identity(), camera || null);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
};
|
|
};
|
|
/** Launch a ray to try to pick a sprite in the scene
|
|
/** Launch a ray to try to pick a sprite in the scene
|
|
* @param x position on screen
|
|
* @param x position on screen
|
|
@@ -86920,9 +86924,51 @@ var BABYLON;
|
|
* If the utility layer should automatically be rendered on top of existing scene
|
|
* If the utility layer should automatically be rendered on top of existing scene
|
|
*/
|
|
*/
|
|
this.shouldRender = true;
|
|
this.shouldRender = true;
|
|
|
|
+ /**
|
|
|
|
+ * If set to true, only pointer down onPointerObservable events will be blocked when picking is occluded by original scene
|
|
|
|
+ */
|
|
|
|
+ this.onlyCheckPointerDownEvents = true;
|
|
// Create scene which will be rendered in the foreground and remove it from being referenced by engine to avoid interfering with existing app
|
|
// Create scene which will be rendered in the foreground and remove it from being referenced by engine to avoid interfering with existing app
|
|
this.utilityLayerScene = new BABYLON.Scene(originalScene.getEngine());
|
|
this.utilityLayerScene = new BABYLON.Scene(originalScene.getEngine());
|
|
originalScene.getEngine().scenes.pop();
|
|
originalScene.getEngine().scenes.pop();
|
|
|
|
+ // Detach controls on utility scene, events will be fired by logic below to handle picking priority
|
|
|
|
+ this.utilityLayerScene.detachControl();
|
|
|
|
+ this._originalPointerObserver = originalScene.onPrePointerObservable.add(function (prePointerInfo, eventState) {
|
|
|
|
+ var utilityScenePick = prePointerInfo.ray ? _this.utilityLayerScene.pickWithRay(prePointerInfo.ray) : _this.utilityLayerScene.pick(originalScene.pointerX, originalScene.pointerY);
|
|
|
|
+ if (!prePointerInfo.ray && utilityScenePick) {
|
|
|
|
+ prePointerInfo.ray = utilityScenePick.ray;
|
|
|
|
+ }
|
|
|
|
+ // always fire the prepointer oversvable
|
|
|
|
+ _this.utilityLayerScene.onPrePointerObservable.notifyObservers(prePointerInfo);
|
|
|
|
+ // allow every non pointer down event to flow to the utility layer
|
|
|
|
+ if (_this.onlyCheckPointerDownEvents && prePointerInfo.type != BABYLON.PointerEventTypes.POINTERDOWN) {
|
|
|
|
+ if (!prePointerInfo.skipOnPointerObservable) {
|
|
|
|
+ _this.utilityLayerScene.onPointerObservable.notifyObservers(new BABYLON.PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick));
|
|
|
|
+ }
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (_this.utilityLayerScene.autoClearDepthAndStencil) {
|
|
|
|
+ // If this layer is an overlay, check if this layer was hit and if so, skip pointer events for the main scene
|
|
|
|
+ if (utilityScenePick && utilityScenePick.hit) {
|
|
|
|
+ if (!prePointerInfo.skipOnPointerObservable) {
|
|
|
|
+ _this.utilityLayerScene.onPointerObservable.notifyObservers(new BABYLON.PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick));
|
|
|
|
+ }
|
|
|
|
+ prePointerInfo.skipOnPointerObservable = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ var originalScenePick = prePointerInfo.ray ? originalScene.pickWithRay(prePointerInfo.ray) : originalScene.pick(originalScene.pointerX, originalScene.pointerY);
|
|
|
|
+ // If the layer can be occluded by the original scene, only fire pointer events to the first layer that hit they ray
|
|
|
|
+ if (originalScenePick && utilityScenePick) {
|
|
|
|
+ if (utilityScenePick.distance < originalScenePick.distance) {
|
|
|
|
+ if (!prePointerInfo.skipOnPointerObservable) {
|
|
|
|
+ _this.utilityLayerScene.onPointerObservable.notifyObservers(new BABYLON.PointerInfo(prePointerInfo.type, prePointerInfo.event, utilityScenePick));
|
|
|
|
+ }
|
|
|
|
+ prePointerInfo.skipOnPointerObservable = true;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
// Render directly on top of existing scene without clearing
|
|
// Render directly on top of existing scene without clearing
|
|
this.utilityLayerScene.autoClear = false;
|
|
this.utilityLayerScene.autoClear = false;
|
|
this._afterRenderObserver = this.originalScene.onAfterRenderObservable.add(function () {
|
|
this._afterRenderObserver = this.originalScene.onAfterRenderObservable.add(function () {
|
|
@@ -86952,6 +86998,9 @@ var BABYLON;
|
|
if (this._sceneDisposeObserver) {
|
|
if (this._sceneDisposeObserver) {
|
|
this.originalScene.onDisposeObservable.remove(this._sceneDisposeObserver);
|
|
this.originalScene.onDisposeObservable.remove(this._sceneDisposeObserver);
|
|
}
|
|
}
|
|
|
|
+ if (this._originalPointerObserver) {
|
|
|
|
+ this.originalScene.onPrePointerObservable.remove(this._originalPointerObserver);
|
|
|
|
+ }
|
|
this.utilityLayerScene.dispose();
|
|
this.utilityLayerScene.dispose();
|
|
};
|
|
};
|
|
UtilityLayerRenderer.prototype._updateCamera = function () {
|
|
UtilityLayerRenderer.prototype._updateCamera = function () {
|
|
@@ -86967,6 +87016,190 @@ var BABYLON;
|
|
var BABYLON;
|
|
var BABYLON;
|
|
(function (BABYLON) {
|
|
(function (BABYLON) {
|
|
/**
|
|
/**
|
|
|
|
+ * A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events
|
|
|
|
+ */
|
|
|
|
+ var PointerDragBehavior = /** @class */ (function () {
|
|
|
|
+ /**
|
|
|
|
+ * Creates a pointer drag behavior that can be attached to a mesh
|
|
|
|
+ * @param options The drag axis or normal of the plane that will be dragged across.
|
|
|
|
+ */
|
|
|
|
+ function PointerDragBehavior(options) {
|
|
|
|
+ this.options = options;
|
|
|
|
+ this._draggingID = -1;
|
|
|
|
+ /**
|
|
|
|
+ * Fires each time the attached mesh is dragged with the pointer
|
|
|
|
+ */
|
|
|
|
+ this.onDragObservable = new BABYLON.Observable();
|
|
|
|
+ /**
|
|
|
|
+ * Fires each time a drag begins (eg. mouse down on mesh)
|
|
|
|
+ */
|
|
|
|
+ this.onDragStartObservable = new BABYLON.Observable();
|
|
|
|
+ /**
|
|
|
|
+ * Fires each time a drag ends (eg. mouse release after drag)
|
|
|
|
+ */
|
|
|
|
+ this.onDragEndObservable = new BABYLON.Observable();
|
|
|
|
+ /**
|
|
|
|
+ * If the attached mesh should be moved when dragged
|
|
|
|
+ */
|
|
|
|
+ this.moveAttached = true;
|
|
|
|
+ /**
|
|
|
|
+ * Mesh with the position where the drag plane should be placed
|
|
|
|
+ */
|
|
|
|
+ this._dragPlaneParent = null;
|
|
|
|
+ /**
|
|
|
|
+ * If the drag behavior will react to drag events
|
|
|
|
+ */
|
|
|
|
+ this.enabled = true;
|
|
|
|
+ var optionCount = 0;
|
|
|
|
+ if (options.dragAxis) {
|
|
|
|
+ optionCount++;
|
|
|
|
+ }
|
|
|
|
+ if (options.dragPlaneNormal) {
|
|
|
|
+ optionCount++;
|
|
|
|
+ }
|
|
|
|
+ if (optionCount > 1) {
|
|
|
|
+ throw "Multiple drag modes specified in dragBehavior options. Only one expected";
|
|
|
|
+ }
|
|
|
|
+ if (optionCount < 1) {
|
|
|
|
+ throw "At least one drag mode option must be specified";
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ Object.defineProperty(PointerDragBehavior.prototype, "name", {
|
|
|
|
+ /**
|
|
|
|
+ * The name of the behavior
|
|
|
|
+ */
|
|
|
|
+ get: function () {
|
|
|
|
+ return "PointerDrag";
|
|
|
|
+ },
|
|
|
|
+ enumerable: true,
|
|
|
|
+ configurable: true
|
|
|
|
+ });
|
|
|
|
+ /**
|
|
|
|
+ * Initializes the behavior
|
|
|
|
+ */
|
|
|
|
+ PointerDragBehavior.prototype.init = function () { };
|
|
|
|
+ /**
|
|
|
|
+ * Attaches the drag behavior the passed in mesh
|
|
|
|
+ * @param ownerNode The mesh that will be dragged around once attached
|
|
|
|
+ */
|
|
|
|
+ PointerDragBehavior.prototype.attach = function (ownerNode) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ this._scene = ownerNode.getScene();
|
|
|
|
+ this._attachedNode = ownerNode;
|
|
|
|
+ // Initialize drag plane to not interfere with existing scene
|
|
|
|
+ if (!PointerDragBehavior._planeScene) {
|
|
|
|
+ PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
|
|
|
|
+ this._scene.getEngine().scenes.pop();
|
|
|
|
+ }
|
|
|
|
+ this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", 1000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
|
|
|
|
+ // State of the drag
|
|
|
|
+ var dragging = false;
|
|
|
|
+ var lastPosition = new BABYLON.Vector3(0, 0, 0);
|
|
|
|
+ var delta = new BABYLON.Vector3(0, 0, 0);
|
|
|
|
+ var pickPredicate = function (m) {
|
|
|
|
+ return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
|
|
|
|
+ };
|
|
|
|
+ this._pointerObserver = this._scene.onPointerObservable.add(function (pointerInfo, eventState) {
|
|
|
|
+ if (!_this.enabled) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
|
|
|
|
+ if (!dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh && pointerInfo.pickInfo.ray && pickPredicate(pointerInfo.pickInfo.pickedMesh)) {
|
|
|
|
+ _this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
|
|
|
|
+ var pickedPoint = _this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
|
|
|
|
+ if (pickedPoint) {
|
|
|
|
+ dragging = true;
|
|
|
|
+ _this._draggingID = pointerInfo.event.pointerId;
|
|
|
|
+ lastPosition.copyFrom(pickedPoint);
|
|
|
|
+ _this.onDragStartObservable.notifyObservers({ dragPlanePoint: pickedPoint });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERUP) {
|
|
|
|
+ if (_this._draggingID == pointerInfo.event.pointerId) {
|
|
|
|
+ dragging = false;
|
|
|
|
+ _this._draggingID = -1;
|
|
|
|
+ _this.onDragEndObservable.notifyObservers({ dragPlanePoint: lastPosition });
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERMOVE) {
|
|
|
|
+ if (_this._draggingID == pointerInfo.event.pointerId && dragging && pointerInfo.pickInfo && pointerInfo.pickInfo.ray) {
|
|
|
|
+ var pickedPoint = _this._pickWithRayOnDragPlane(pointerInfo.pickInfo.ray);
|
|
|
|
+ _this._updateDragPlanePosition(pointerInfo.pickInfo.ray);
|
|
|
|
+ if (pickedPoint) {
|
|
|
|
+ // depending on the drag mode option drag accordingly
|
|
|
|
+ if (_this.options.dragAxis) {
|
|
|
|
+ //get the closest point on the dragaxis from the selected mesh to the picked point location
|
|
|
|
+ // https://www.opengl.org/discussion_boards/showthread.php/159717-Closest-point-on-a-Vector-to-a-point
|
|
|
|
+ _this.options.dragAxis.scaleToRef(BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), _this.options.dragAxis), delta);
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ pickedPoint.subtractToRef(lastPosition, delta);
|
|
|
|
+ }
|
|
|
|
+ if (_this.moveAttached) {
|
|
|
|
+ _this._attachedNode.position.addInPlace(delta);
|
|
|
|
+ }
|
|
|
|
+ _this.onDragObservable.notifyObservers({ delta: delta, dragPlanePoint: pickedPoint });
|
|
|
|
+ lastPosition.copyFrom(pickedPoint);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ };
|
|
|
|
+ PointerDragBehavior.prototype._pickWithRayOnDragPlane = function (ray) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ if (!ray) {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ var pickResult = PointerDragBehavior._planeScene.pickWithRay(ray, function (m) { return m == _this._dragPlane; });
|
|
|
|
+ if (pickResult && pickResult.hit && pickResult.pickedMesh && pickResult.pickedPoint) {
|
|
|
|
+ return pickResult.pickedPoint;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
|
|
|
|
+ PointerDragBehavior.prototype._updateDragPlanePosition = function (ray) {
|
|
|
|
+ var pointA = this._dragPlaneParent ? this._dragPlaneParent.position : this._attachedNode.position; // center
|
|
|
|
+ if (this.options.dragAxis) {
|
|
|
|
+ var camPos = ray.origin;
|
|
|
|
+ // Calculate plane normal in direction of camera but perpendicular to drag axis
|
|
|
|
+ var pointB = pointA.add(this.options.dragAxis); // towards drag axis
|
|
|
|
+ var pointC = pointA.add(camPos.subtract(pointA).normalize()); // towards camera
|
|
|
|
+ // Get perpendicular line from direction to camera and drag axis
|
|
|
|
+ var lineA = pointB.subtract(pointA);
|
|
|
|
+ var lineB = pointC.subtract(pointA);
|
|
|
|
+ var perpLine = BABYLON.Vector3.Cross(lineA, lineB);
|
|
|
|
+ // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
|
|
|
|
+ var norm = BABYLON.Vector3.Cross(lineA, perpLine).normalize();
|
|
|
|
+ this._dragPlane.position.copyFrom(pointA);
|
|
|
|
+ this._dragPlane.lookAt(pointA.add(norm));
|
|
|
|
+ }
|
|
|
|
+ else if (this.options.dragPlaneNormal) {
|
|
|
|
+ this._dragPlane.position.copyFrom(pointA);
|
|
|
|
+ this._dragPlane.lookAt(pointA.add(this.options.dragPlaneNormal));
|
|
|
|
+ }
|
|
|
|
+ this._dragPlane.computeWorldMatrix(true);
|
|
|
|
+ };
|
|
|
|
+ /**
|
|
|
|
+ * Detaches the behavior from the mesh
|
|
|
|
+ */
|
|
|
|
+ PointerDragBehavior.prototype.detach = function () {
|
|
|
|
+ if (this._pointerObserver) {
|
|
|
|
+ this._scene.onPointerObservable.remove(this._pointerObserver);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ return PointerDragBehavior;
|
|
|
|
+ }());
|
|
|
|
+ BABYLON.PointerDragBehavior = PointerDragBehavior;
|
|
|
|
+})(BABYLON || (BABYLON = {}));
|
|
|
|
+
|
|
|
|
+//# sourceMappingURL=babylon.pointerDragBehavior.js.map
|
|
|
|
+
|
|
|
|
+var BABYLON;
|
|
|
|
+(function (BABYLON) {
|
|
|
|
+ /**
|
|
* Renders gizmos on top of an existing scene which provide controls for position, rotation, etc.
|
|
* Renders gizmos on top of an existing scene which provide controls for position, rotation, etc.
|
|
*/
|
|
*/
|
|
var Gizmo = /** @class */ (function () {
|
|
var Gizmo = /** @class */ (function () {
|
|
@@ -87056,7 +87289,7 @@ var BABYLON;
|
|
arrowTail.position.z += 0.2;
|
|
arrowTail.position.z += 0.2;
|
|
_this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
|
|
_this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
|
|
// Add drag behavior to handle events when the gizmo is dragged
|
|
// Add drag behavior to handle events when the gizmo is dragged
|
|
- _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis, pointerObservableScene: gizmoLayer.originalScene });
|
|
|
|
|
|
+ _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
|
|
_this._dragBehavior.moveAttached = false;
|
|
_this._dragBehavior.moveAttached = false;
|
|
_this._rootMesh.addBehavior(_this._dragBehavior);
|
|
_this._rootMesh.addBehavior(_this._dragBehavior);
|
|
_this._dragBehavior.onDragObservable.add(function (event) {
|
|
_this._dragBehavior.onDragObservable.add(function (event) {
|
|
@@ -87121,7 +87354,7 @@ var BABYLON;
|
|
arrowTail.position.z += 0.2;
|
|
arrowTail.position.z += 0.2;
|
|
_this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
|
|
_this._rootMesh.lookAt(_this._rootMesh.position.subtract(dragAxis));
|
|
// Add drag behavior to handle events when the gizmo is dragged
|
|
// Add drag behavior to handle events when the gizmo is dragged
|
|
- _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis, pointerObservableScene: gizmoLayer.originalScene });
|
|
|
|
|
|
+ _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragAxis: dragAxis });
|
|
_this._dragBehavior.moveAttached = false;
|
|
_this._dragBehavior.moveAttached = false;
|
|
_this._rootMesh.addBehavior(_this._dragBehavior);
|
|
_this._rootMesh.addBehavior(_this._dragBehavior);
|
|
_this._dragBehavior.onDragObservable.add(function (event) {
|
|
_this._dragBehavior.onDragObservable.add(function (event) {
|
|
@@ -87180,7 +87413,7 @@ var BABYLON;
|
|
rotationMesh.rotation.x = Math.PI / 2;
|
|
rotationMesh.rotation.x = Math.PI / 2;
|
|
_this._rootMesh.lookAt(_this._rootMesh.position.subtract(planeNormal));
|
|
_this._rootMesh.lookAt(_this._rootMesh.position.subtract(planeNormal));
|
|
// Add drag behavior to handle events when the gizmo is dragged
|
|
// Add drag behavior to handle events when the gizmo is dragged
|
|
- _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragPlaneNormal: planeNormal, pointerObservableScene: gizmoLayer.originalScene });
|
|
|
|
|
|
+ _this._dragBehavior = new BABYLON.PointerDragBehavior({ dragPlaneNormal: planeNormal });
|
|
_this._dragBehavior.moveAttached = false;
|
|
_this._dragBehavior.moveAttached = false;
|
|
_this._rootMesh.addBehavior(_this._dragBehavior);
|
|
_this._rootMesh.addBehavior(_this._dragBehavior);
|
|
var lastDragPosition = null;
|
|
var lastDragPosition = null;
|
|
@@ -87389,6 +87622,91 @@ var BABYLON;
|
|
var BABYLON;
|
|
var BABYLON;
|
|
(function (BABYLON) {
|
|
(function (BABYLON) {
|
|
/**
|
|
/**
|
|
|
|
+ * Helps setup gizmo's in the scene to rotate/scale/position meshes
|
|
|
|
+ */
|
|
|
|
+ var GizmoManager = /** @class */ (function () {
|
|
|
|
+ /**
|
|
|
|
+ * Instatiates a gizmo manager
|
|
|
|
+ * @param scene the scene to overlay the gizmos on top of
|
|
|
|
+ * @param options If only a single gizmo should exist at one time
|
|
|
|
+ */
|
|
|
|
+ function GizmoManager(scene, options) {
|
|
|
|
+ var _this = this;
|
|
|
|
+ this.scene = scene;
|
|
|
|
+ // Set of gizmos that are currently in the scene for each mesh
|
|
|
|
+ this._gizmoSet = {};
|
|
|
|
+ this._pointerObserver = null;
|
|
|
|
+ this._gizmoLayer = new BABYLON.UtilityLayerRenderer(scene);
|
|
|
|
+ // Options parsing
|
|
|
|
+ if (!options) {
|
|
|
|
+ options = {};
|
|
|
|
+ }
|
|
|
|
+ if (options.singleGizmo === undefined) {
|
|
|
|
+ options.singleGizmo = true;
|
|
|
|
+ }
|
|
|
|
+ // Instatiate/dispose gizmos based on pointer actions
|
|
|
|
+ this._pointerObserver = scene.onPointerObservable.add(function (pointerInfo, state) {
|
|
|
|
+ if (pointerInfo.type == BABYLON.PointerEventTypes.POINTERDOWN) {
|
|
|
|
+ if (pointerInfo.pickInfo && pointerInfo.pickInfo.pickedMesh) {
|
|
|
|
+ if (!_this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId]) {
|
|
|
|
+ if (options.singleGizmo) {
|
|
|
|
+ _this._clearGizmos();
|
|
|
|
+ }
|
|
|
|
+ // Enable gizmo when mesh is selected
|
|
|
|
+ _this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId] = { positionGizmo: new BABYLON.PositionGizmo(_this._gizmoLayer), rotationGizmo: new BABYLON.RotationGizmo(_this._gizmoLayer) };
|
|
|
|
+ _this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId].positionGizmo.attachedMesh = pointerInfo.pickInfo.pickedMesh;
|
|
|
|
+ _this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId].rotationGizmo.attachedMesh = pointerInfo.pickInfo.pickedMesh;
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ if (!options.singleGizmo) {
|
|
|
|
+ // Disable gizmo when clicked again
|
|
|
|
+ _this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId].positionGizmo.dispose();
|
|
|
|
+ _this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId].rotationGizmo.dispose();
|
|
|
|
+ delete _this._gizmoSet[pointerInfo.pickInfo.pickedMesh.uniqueId];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ if (options.singleGizmo) {
|
|
|
|
+ // Disable gizmo when clicked away
|
|
|
|
+ if (pointerInfo.pickInfo && pointerInfo.pickInfo.ray) {
|
|
|
|
+ var gizmoPick = _this._gizmoLayer.utilityLayerScene.pickWithRay(pointerInfo.pickInfo.ray);
|
|
|
|
+ if (gizmoPick && !gizmoPick.hit) {
|
|
|
|
+ _this._clearGizmos();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * Disposes of the gizmo manager
|
|
|
|
+ */
|
|
|
|
+ GizmoManager.prototype.dispose = function () {
|
|
|
|
+ this.scene.onPointerObservable.remove(this._pointerObserver);
|
|
|
|
+ this._clearGizmos();
|
|
|
|
+ this._gizmoLayer.dispose();
|
|
|
|
+ };
|
|
|
|
+ GizmoManager.prototype._clearGizmos = function () {
|
|
|
|
+ for (var key in this._gizmoSet) {
|
|
|
|
+ if (this._gizmoSet.hasOwnProperty(key)) {
|
|
|
|
+ this._gizmoSet[key].positionGizmo.dispose();
|
|
|
|
+ this._gizmoSet[key].rotationGizmo.dispose();
|
|
|
|
+ delete this._gizmoSet[key];
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ };
|
|
|
|
+ return GizmoManager;
|
|
|
|
+ }());
|
|
|
|
+ BABYLON.GizmoManager = GizmoManager;
|
|
|
|
+})(BABYLON || (BABYLON = {}));
|
|
|
|
+
|
|
|
|
+//# sourceMappingURL=babylon.gizmoManager.js.map
|
|
|
|
+
|
|
|
|
+var BABYLON;
|
|
|
|
+(function (BABYLON) {
|
|
|
|
+ /**
|
|
* Defines a target to use with MorphTargetManager
|
|
* Defines a target to use with MorphTargetManager
|
|
* @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
|
|
* @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
|
|
*/
|
|
*/
|
|
@@ -94734,6 +95052,13 @@ var BABYLON;
|
|
AbstractAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
|
|
AbstractAssetTask.prototype.runTask = function (scene, onSuccess, onError) {
|
|
throw new Error("runTask is not implemented");
|
|
throw new Error("runTask is not implemented");
|
|
};
|
|
};
|
|
|
|
+ /**
|
|
|
|
+ * Reset will set the task state back to INIT, so the next load call of the assets manager will execute this task again.
|
|
|
|
+ * This can be used with failed tasks that have the reason for failure fixed.
|
|
|
|
+ */
|
|
|
|
+ AbstractAssetTask.prototype.reset = function () {
|
|
|
|
+ this._taskState = AssetTaskState.INIT;
|
|
|
|
+ };
|
|
AbstractAssetTask.prototype.onErrorCallback = function (onError, message, exception) {
|
|
AbstractAssetTask.prototype.onErrorCallback = function (onError, message, exception) {
|
|
this._taskState = AssetTaskState.ERROR;
|
|
this._taskState = AssetTaskState.ERROR;
|
|
this._errorObject = {
|
|
this._errorObject = {
|
|
@@ -95299,6 +95624,16 @@ var BABYLON;
|
|
this._tasks.push(task);
|
|
this._tasks.push(task);
|
|
return task;
|
|
return task;
|
|
};
|
|
};
|
|
|
|
+ /**
|
|
|
|
+ * Remove a task from the assets manager.
|
|
|
|
+ * @param task the task to remove
|
|
|
|
+ */
|
|
|
|
+ AssetsManager.prototype.removeTask = function (task) {
|
|
|
|
+ var index = this._tasks.indexOf(task);
|
|
|
|
+ if (index > -1) {
|
|
|
|
+ this._tasks.splice(index, 1);
|
|
|
|
+ }
|
|
|
|
+ };
|
|
AssetsManager.prototype._decreaseWaitingTasksCount = function (task) {
|
|
AssetsManager.prototype._decreaseWaitingTasksCount = function (task) {
|
|
this._waitingTasksCount--;
|
|
this._waitingTasksCount--;
|
|
try {
|
|
try {
|
|
@@ -95394,7 +95729,9 @@ var BABYLON;
|
|
}
|
|
}
|
|
for (var index = 0; index < this._tasks.length; index++) {
|
|
for (var index = 0; index < this._tasks.length; index++) {
|
|
var task = this._tasks[index];
|
|
var task = this._tasks[index];
|
|
- this._runTask(task);
|
|
|
|
|
|
+ if (task.taskState === AssetTaskState.INIT) {
|
|
|
|
+ this._runTask(task);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return this;
|
|
return this;
|
|
};
|
|
};
|
|
@@ -96898,204 +97235,6 @@ var BABYLON;
|
|
|
|
|
|
//# sourceMappingURL=babylon.autoRotationBehavior.js.map
|
|
//# sourceMappingURL=babylon.autoRotationBehavior.js.map
|
|
|
|
|
|
-var BABYLON;
|
|
|
|
-(function (BABYLON) {
|
|
|
|
- /**
|
|
|
|
- * A behavior that when attached to a mesh will allow the mesh to be dragged around the screen based on pointer events
|
|
|
|
- */
|
|
|
|
- var PointerDragBehavior = /** @class */ (function () {
|
|
|
|
- /**
|
|
|
|
- * Creates a pointer drag behavior that can be attached to a mesh
|
|
|
|
- * @param options The drag axis or normal of the plane that will be dragged across. pointerObservableScene can be used to listen to drag events from another scene(eg. if the attached mesh is in an overlay scene).
|
|
|
|
- */
|
|
|
|
- function PointerDragBehavior(options) {
|
|
|
|
- this.options = options;
|
|
|
|
- this._draggingID = -1;
|
|
|
|
- /**
|
|
|
|
- * Fires each time the attached mesh is dragged with the pointer
|
|
|
|
- */
|
|
|
|
- this.onDragObservable = new BABYLON.Observable();
|
|
|
|
- /**
|
|
|
|
- * Fires each time a drag begins (eg. mouse down on mesh)
|
|
|
|
- */
|
|
|
|
- this.onDragStartObservable = new BABYLON.Observable();
|
|
|
|
- /**
|
|
|
|
- * Fires each time a drag ends (eg. mouse release after drag)
|
|
|
|
- */
|
|
|
|
- this.onDragEndObservable = new BABYLON.Observable();
|
|
|
|
- /**
|
|
|
|
- * If the attached mesh should be moved when dragged
|
|
|
|
- */
|
|
|
|
- this.moveAttached = true;
|
|
|
|
- /**
|
|
|
|
- * Mesh with the position where the drag plane should be placed
|
|
|
|
- */
|
|
|
|
- this._dragPlaneParent = null;
|
|
|
|
- /**
|
|
|
|
- * If the drag behavior will react to drag events
|
|
|
|
- */
|
|
|
|
- this.enabled = true;
|
|
|
|
- var optionCount = 0;
|
|
|
|
- if (options.dragAxis) {
|
|
|
|
- optionCount++;
|
|
|
|
- }
|
|
|
|
- if (options.dragPlaneNormal) {
|
|
|
|
- optionCount++;
|
|
|
|
- }
|
|
|
|
- if (optionCount > 1) {
|
|
|
|
- throw "Multiple drag modes specified in dragBehavior options. Only one expected";
|
|
|
|
- }
|
|
|
|
- if (optionCount < 1) {
|
|
|
|
- throw "At least one drag mode option must be specified";
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- Object.defineProperty(PointerDragBehavior.prototype, "name", {
|
|
|
|
- /**
|
|
|
|
- * The name of the behavior
|
|
|
|
- */
|
|
|
|
- get: function () {
|
|
|
|
- return "PointerDrag";
|
|
|
|
- },
|
|
|
|
- enumerable: true,
|
|
|
|
- configurable: true
|
|
|
|
- });
|
|
|
|
- /**
|
|
|
|
- * Initializes the behavior
|
|
|
|
- */
|
|
|
|
- PointerDragBehavior.prototype.init = function () { };
|
|
|
|
- /**
|
|
|
|
- * Attaches the drag behavior the passed in mesh
|
|
|
|
- * @param ownerNode The mesh that will be dragged around once attached
|
|
|
|
- */
|
|
|
|
- PointerDragBehavior.prototype.attach = function (ownerNode) {
|
|
|
|
- var _this = this;
|
|
|
|
- this._scene = ownerNode.getScene();
|
|
|
|
- if (!this.options.pointerObservableScene) {
|
|
|
|
- this.options.pointerObservableScene = this._scene;
|
|
|
|
- }
|
|
|
|
- this._attachedNode = ownerNode;
|
|
|
|
- // Initialize drag plane to not interfere with existing scene
|
|
|
|
- if (!PointerDragBehavior._planeScene) {
|
|
|
|
- PointerDragBehavior._planeScene = new BABYLON.Scene(this._scene.getEngine());
|
|
|
|
- this._scene.getEngine().scenes.pop();
|
|
|
|
- }
|
|
|
|
- this._dragPlane = BABYLON.Mesh.CreatePlane("pointerDragPlane", 1000, PointerDragBehavior._planeScene, false, BABYLON.Mesh.DOUBLESIDE);
|
|
|
|
- // State of the drag
|
|
|
|
- var dragging = false;
|
|
|
|
- var lastPosition = new BABYLON.Vector3(0, 0, 0);
|
|
|
|
- var delta = new BABYLON.Vector3(0, 0, 0);
|
|
|
|
- var pickPredicate = function (m) {
|
|
|
|
- return _this._attachedNode == m || m.isDescendantOf(_this._attachedNode);
|
|
|
|
- };
|
|
|
|
- this._pointerObserver = this.options.pointerObservableScene.onPrePointerObservable.add(function (pointerInfoPre, eventState) {
|
|
|
|
- if (!_this.enabled) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- // Check if attached mesh is picked
|
|
|
|
- var pickInfo = pointerInfoPre.ray ? _this._scene.pickWithRay(pointerInfoPre.ray, pickPredicate) : _this._scene.pick(_this._scene.pointerX, _this._scene.pointerY, pickPredicate);
|
|
|
|
- if (pickInfo) {
|
|
|
|
- pickInfo.ray = pointerInfoPre.ray;
|
|
|
|
- if (!pickInfo.ray) {
|
|
|
|
- pickInfo.ray = _this.options.pointerObservableScene.createPickingRay(_this._scene.pointerX, _this._scene.pointerY, BABYLON.Matrix.Identity(), _this._scene.activeCamera);
|
|
|
|
- }
|
|
|
|
- if (pickInfo.hit && pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {
|
|
|
|
- pointerInfoPre.skipOnPointerObservable = true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- if (pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERDOWN) {
|
|
|
|
- if (!dragging && pickInfo && pickInfo.hit && pickInfo.pickedMesh && pickInfo.ray) {
|
|
|
|
- _this._updateDragPlanePosition(pickInfo.ray);
|
|
|
|
- var pickedPoint = _this._pickWithRayOnDragPlane(pickInfo.ray);
|
|
|
|
- if (pickedPoint) {
|
|
|
|
- dragging = true;
|
|
|
|
- _this._draggingID = pointerInfoPre.event.pointerId;
|
|
|
|
- lastPosition.copyFrom(pickedPoint);
|
|
|
|
- _this.onDragStartObservable.notifyObservers({ dragPlanePoint: pickedPoint });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if (pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERUP) {
|
|
|
|
- if (_this._draggingID == pointerInfoPre.event.pointerId) {
|
|
|
|
- dragging = false;
|
|
|
|
- _this._draggingID = -1;
|
|
|
|
- _this.onDragEndObservable.notifyObservers({ dragPlanePoint: lastPosition });
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if (pointerInfoPre.type == BABYLON.PointerEventTypes.POINTERMOVE) {
|
|
|
|
- if (_this._draggingID == pointerInfoPre.event.pointerId && dragging && pickInfo && pickInfo.ray) {
|
|
|
|
- var pickedPoint = _this._pickWithRayOnDragPlane(pickInfo.ray);
|
|
|
|
- _this._updateDragPlanePosition(pickInfo.ray);
|
|
|
|
- if (pickedPoint) {
|
|
|
|
- // depending on the drag mode option drag accordingly
|
|
|
|
- if (_this.options.dragAxis) {
|
|
|
|
- //get the closest point on the dragaxis from the selected mesh to the picked point location
|
|
|
|
- // https://www.opengl.org/discussion_boards/showthread.php/159717-Closest-point-on-a-Vector-to-a-point
|
|
|
|
- _this.options.dragAxis.scaleToRef(BABYLON.Vector3.Dot(pickedPoint.subtract(lastPosition), _this.options.dragAxis), delta);
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- pickedPoint.subtractToRef(lastPosition, delta);
|
|
|
|
- }
|
|
|
|
- if (_this.moveAttached) {
|
|
|
|
- _this._attachedNode.position.addInPlace(delta);
|
|
|
|
- }
|
|
|
|
- _this.onDragObservable.notifyObservers({ delta: delta, dragPlanePoint: pickedPoint });
|
|
|
|
- lastPosition.copyFrom(pickedPoint);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- };
|
|
|
|
- PointerDragBehavior.prototype._pickWithRayOnDragPlane = function (ray) {
|
|
|
|
- var _this = this;
|
|
|
|
- if (!ray) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- var pickResult = PointerDragBehavior._planeScene.pickWithRay(ray, function (m) { return m == _this._dragPlane; });
|
|
|
|
- if (pickResult && pickResult.hit && pickResult.pickedMesh && pickResult.pickedPoint) {
|
|
|
|
- return pickResult.pickedPoint;
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- // Position the drag plane based on the attached mesh position, for single axis rotate the plane along the axis to face the camera
|
|
|
|
- PointerDragBehavior.prototype._updateDragPlanePosition = function (ray) {
|
|
|
|
- var pointA = this._dragPlaneParent ? this._dragPlaneParent.position : this._attachedNode.position; // center
|
|
|
|
- if (this.options.dragAxis) {
|
|
|
|
- var camPos = ray.origin;
|
|
|
|
- // Calculate plane normal in direction of camera but perpendicular to drag axis
|
|
|
|
- var pointB = pointA.add(this.options.dragAxis); // towards drag axis
|
|
|
|
- var pointC = pointA.add(camPos.subtract(pointA).normalize()); // towards camera
|
|
|
|
- // Get perpendicular line from direction to camera and drag axis
|
|
|
|
- var lineA = pointB.subtract(pointA);
|
|
|
|
- var lineB = pointC.subtract(pointA);
|
|
|
|
- var perpLine = BABYLON.Vector3.Cross(lineA, lineB);
|
|
|
|
- // Get perpendicular line from previous result and drag axis to adjust lineB to be perpendiculat to camera
|
|
|
|
- var norm = BABYLON.Vector3.Cross(lineA, perpLine).normalize();
|
|
|
|
- this._dragPlane.position.copyFrom(pointA);
|
|
|
|
- this._dragPlane.lookAt(pointA.add(norm));
|
|
|
|
- }
|
|
|
|
- else if (this.options.dragPlaneNormal) {
|
|
|
|
- this._dragPlane.position.copyFrom(pointA);
|
|
|
|
- this._dragPlane.lookAt(pointA.add(this.options.dragPlaneNormal));
|
|
|
|
- }
|
|
|
|
- this._dragPlane.computeWorldMatrix(true);
|
|
|
|
- };
|
|
|
|
- /**
|
|
|
|
- * Detaches the behavior from the mesh
|
|
|
|
- */
|
|
|
|
- PointerDragBehavior.prototype.detach = function () {
|
|
|
|
- if (this._pointerObserver) {
|
|
|
|
- this._scene.onPrePointerObservable.remove(this._pointerObserver);
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
- return PointerDragBehavior;
|
|
|
|
- }());
|
|
|
|
- BABYLON.PointerDragBehavior = PointerDragBehavior;
|
|
|
|
-})(BABYLON || (BABYLON = {}));
|
|
|
|
-
|
|
|
|
-//# sourceMappingURL=babylon.pointerDragBehavior.js.map
|
|
|
|
-
|
|
|
|
|
|
|
|
var BABYLON;
|
|
var BABYLON;
|
|
(function (BABYLON) {
|
|
(function (BABYLON) {
|