|
@@ -1,19 +1,20 @@
|
|
|
|
|
|
import * as THREE from "../../libs/three.js/build/three.module.js";
|
|
import * as THREE from "../../libs/three.js/build/three.module.js";
|
|
import {Utils} from "../utils.js";
|
|
import {Utils} from "../utils.js";
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+import History from "../custom/utils/History.js"
|
|
|
|
+//问题:如何转换到世界坐标?(缩放方向有bug。)
|
|
|
|
|
|
//add-------------------------------------
|
|
//add-------------------------------------
|
|
-const OpaWhenNotSelect = 0.6
|
|
|
|
-const ScaleRatio = 8
|
|
|
|
|
|
+const OpaWhenNotSelect = 0.4
|
|
|
|
+const ScaleRatio = 5
|
|
const OutlineColor = 0x666666
|
|
const OutlineColor = 0x666666
|
|
//----------------------------------------
|
|
//----------------------------------------
|
|
const hideFocusHandles = true//add
|
|
const hideFocusHandles = true//add
|
|
|
|
|
|
|
|
|
|
-export class TransformationTool {
|
|
|
|
|
|
+export class TransformationTool extends THREE.EventDispatcher{
|
|
constructor(viewer) {
|
|
constructor(viewer) {
|
|
|
|
+ super()
|
|
this.viewer = viewer;
|
|
this.viewer = viewer;
|
|
|
|
|
|
this.scene = new THREE.Scene();
|
|
this.scene = new THREE.Scene();
|
|
@@ -25,17 +26,17 @@ export class TransformationTool {
|
|
|
|
|
|
this.viewer.inputHandler.registerInteractiveScene(this.scene);
|
|
this.viewer.inputHandler.registerInteractiveScene(this.scene);
|
|
this.viewer.inputHandler.addEventListener('selection_changed', (e) => {
|
|
this.viewer.inputHandler.addEventListener('selection_changed', (e) => {
|
|
- for(let selected of this.selection){
|
|
|
|
|
|
+ /* for(let selected of this.selection){ //若不删除,应该会穿过选中的物体选到别的而不是取消选择
|
|
this.viewer.inputHandler.blacklist.delete(selected);
|
|
this.viewer.inputHandler.blacklist.delete(selected);
|
|
- }
|
|
|
|
|
|
+ } */
|
|
|
|
|
|
this.selection = e.selection;
|
|
this.selection = e.selection;
|
|
|
|
|
|
- for(let selected of this.selection){
|
|
|
|
|
|
+ /* for(let selected of this.selection){
|
|
this.viewer.inputHandler.blacklist.add(selected);
|
|
this.viewer.inputHandler.blacklist.add(selected);
|
|
- }
|
|
|
|
|
|
+ } */
|
|
|
|
|
|
- });
|
|
|
|
|
|
+ });
|
|
|
|
|
|
|
|
|
|
this.viewer.addEventListener('global_touchstart',(e)=>{ //add
|
|
this.viewer.addEventListener('global_touchstart',(e)=>{ //add
|
|
@@ -116,13 +117,59 @@ export class TransformationTool {
|
|
}
|
|
}
|
|
this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: 0xffff00}));
|
|
this.frame = new THREE.LineSegments(boxFrameGeometry, new THREE.LineBasicMaterial({color: 0xffff00}));
|
|
this.scene.add(this.frame);
|
|
this.scene.add(this.frame);
|
|
|
|
+ //------------------add-----------------------
|
|
|
|
+
|
|
|
|
+
|
|
viewer.setObjectLayers(this.scene, 'transformationTool' )
|
|
viewer.setObjectLayers(this.scene, 'transformationTool' )
|
|
|
|
|
|
this.scene.traverse(e=>{
|
|
this.scene.traverse(e=>{
|
|
e.pickDontCheckDis = true; //pick时不需要识别是否在点云之上
|
|
e.pickDontCheckDis = true; //pick时不需要识别是否在点云之上
|
|
})
|
|
})
|
|
|
|
|
|
-
|
|
|
|
|
|
+ {
|
|
|
|
+ let exist = (object)=>{//是否没被删除(暂时不考虑换了parent)
|
|
|
|
+ while(object.parent){
|
|
|
|
+ object = object.parent
|
|
|
|
+ }
|
|
|
|
+ if(object instanceof THREE.Scene){
|
|
|
|
+ return true
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ this.history = new History({ //也可以写到全局,但需要加个判断物品是否存在的函数
|
|
|
|
+ applyData: (data)=>{
|
|
|
|
+ if(exist(data.object)){//viewer.scene.volumes.includes(data.box) //或许还要识别是否matrixAuto
|
|
|
|
+ data.matrix.decompose( data.object.position, data.object.quaternion, data.object.scale );
|
|
|
|
+ }else{
|
|
|
|
+ this.history.undo()//找不到就回退下一个。(直接写这?)
|
|
|
|
+ }
|
|
|
|
+ } ,
|
|
|
|
+ getData:(data)=>{
|
|
|
|
+ return data
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ //this.prepareRecord = true
|
|
|
|
+ this.addEventListener('transformed', (e)=>{
|
|
|
|
+ /* if(this.prepareRecord){
|
|
|
|
+ let object = viewer.transformationTool.selection[0]
|
|
|
|
+ this.history.writeIn({object, matrix:e.matrixBefore.clone()})
|
|
|
|
+ this.prepareRecord = false
|
|
|
|
+ } */
|
|
|
|
+ let object = viewer.transformationTool.selection[0]
|
|
|
|
+ this.history.beforeChange({object, matrix:e.matrixBefore.clone()},[object],[Potree.BoxVolume])
|
|
|
|
+ })
|
|
|
|
+ this.addEventListener('stopDrag', (e)=>{
|
|
|
|
+ //this.prepareRecord = true
|
|
|
|
+ let object = viewer.transformationTool.selection[0]
|
|
|
|
+ object && this.history.afterChange({object, matrix:object.matrix.clone()},[object])
|
|
|
|
+ })
|
|
|
|
+ viewer.inputHandler.addEventListener('keydown', (e)=>{
|
|
|
|
+ if(e.keyCode == 90 && e.event.ctrlKey){//Z
|
|
|
|
+ this.history.undo()
|
|
|
|
+ }else if(e.keyCode == 89 && e.event.ctrlKey){//Y
|
|
|
|
+ this.history.redo()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -130,7 +177,7 @@ export class TransformationTool {
|
|
let handels = this[mode + 'Handles']
|
|
let handels = this[mode + 'Handles']
|
|
if(!handels)return
|
|
if(!handels)return
|
|
for(let o in handels){
|
|
for(let o in handels){
|
|
- handels[o].node.visible = !!enable
|
|
|
|
|
|
+ viewer.updateVisible(handels[o].node,'modeForce',!!enable)
|
|
}
|
|
}
|
|
this.modesEnabled[mode] = !!enable
|
|
this.modesEnabled[mode] = !!enable
|
|
}
|
|
}
|
|
@@ -148,6 +195,7 @@ export class TransformationTool {
|
|
|
|
|
|
let material = new THREE.MeshBasicMaterial({
|
|
let material = new THREE.MeshBasicMaterial({
|
|
color: handle.color,
|
|
color: handle.color,
|
|
|
|
+ side:THREE.DoubleSide,//xzw add
|
|
opacity: OpaWhenNotSelect,
|
|
opacity: OpaWhenNotSelect,
|
|
transparent: true
|
|
transparent: true
|
|
});
|
|
});
|
|
@@ -161,10 +209,11 @@ export class TransformationTool {
|
|
let pickMaterial = new THREE.MeshNormalMaterial({
|
|
let pickMaterial = new THREE.MeshNormalMaterial({
|
|
opacity: 0.2,
|
|
opacity: 0.2,
|
|
transparent: true,
|
|
transparent: true,
|
|
|
|
+ side:THREE.DoubleSide,//xzw add for orthoCam, 缩小画面时因球体放大导致到相机背面去了而看不到球体正面
|
|
visible: this.showPickVolumes});
|
|
visible: this.showPickVolumes});
|
|
|
|
|
|
let sphere = new THREE.Mesh(sgSphere, material);
|
|
let sphere = new THREE.Mesh(sgSphere, material);
|
|
- sphere.scale.set(2, 2, 2 );
|
|
|
|
|
|
+ sphere.scale.set(3, 3, 3 );
|
|
sphere.name = `${handleName}.handle`;
|
|
sphere.name = `${handleName}.handle`;
|
|
node.add(sphere);
|
|
node.add(sphere);
|
|
|
|
|
|
@@ -182,7 +231,7 @@ export class TransformationTool {
|
|
|
|
|
|
node.setOpacity = (target) => {
|
|
node.setOpacity = (target) => {
|
|
let opacity = {x: material.opacity};
|
|
let opacity = {x: material.opacity};
|
|
- let t = new TWEEN.Tween(opacity).to({x: target}, 100);
|
|
|
|
|
|
+ let t = new TWEEN.Tween(opacity).to({x: target}, 0); //xzw改 原100毫秒,因为太慢容易选错
|
|
t.onUpdate(() => {
|
|
t.onUpdate(() => {
|
|
sphere.visible = opacity.x > 0;
|
|
sphere.visible = opacity.x > 0;
|
|
pickSphere.visible = opacity.x > 0;
|
|
pickSphere.visible = opacity.x > 0;
|
|
@@ -286,7 +335,7 @@ export class TransformationTool {
|
|
|
|
|
|
node.setOpacity = (target) => {
|
|
node.setOpacity = (target) => {
|
|
let opacity = {x: material.opacity};
|
|
let opacity = {x: material.opacity};
|
|
- let t = new TWEEN.Tween(opacity).to({x: target}, 100);
|
|
|
|
|
|
+ let t = new TWEEN.Tween(opacity).to({x: target}, 0);
|
|
t.onUpdate(() => {
|
|
t.onUpdate(() => {
|
|
pickSphere.visible = opacity.x > 0;
|
|
pickSphere.visible = opacity.x > 0;
|
|
box.visible = opacity.x > 0;
|
|
box.visible = opacity.x > 0;
|
|
@@ -381,7 +430,7 @@ export class TransformationTool {
|
|
|
|
|
|
node.setOpacity = (target) => {
|
|
node.setOpacity = (target) => {
|
|
let opacity = {x: material.opacity};
|
|
let opacity = {x: material.opacity};
|
|
- let t = new TWEEN.Tween(opacity).to({x: target}, 100);
|
|
|
|
|
|
+ let t = new TWEEN.Tween(opacity).to({x: target}, 0);
|
|
t.onUpdate(() => {
|
|
t.onUpdate(() => {
|
|
box.visible = opacity.x > 0;
|
|
box.visible = opacity.x > 0;
|
|
pickVolume.visible = opacity.x > 0;
|
|
pickVolume.visible = opacity.x > 0;
|
|
@@ -449,7 +498,7 @@ export class TransformationTool {
|
|
|
|
|
|
node.setOpacity = (target) => {
|
|
node.setOpacity = (target) => {
|
|
let opacity = {x: material.opacity};
|
|
let opacity = {x: material.opacity};
|
|
- let t = new TWEEN.Tween(opacity).to({x: target}, 100);
|
|
|
|
|
|
+ let t = new TWEEN.Tween(opacity).to({x: target}, 0);
|
|
t.onUpdate(() => {
|
|
t.onUpdate(() => {
|
|
box.visible = opacity.x > 0;
|
|
box.visible = opacity.x > 0;
|
|
pickVolume.visible = opacity.x > 0;
|
|
pickVolume.visible = opacity.x > 0;
|
|
@@ -474,7 +523,7 @@ export class TransformationTool {
|
|
dragRotationHandle(e){
|
|
dragRotationHandle(e){
|
|
let drag = e.drag;
|
|
let drag = e.drag;
|
|
let handle = this.activeHandle;
|
|
let handle = this.activeHandle;
|
|
- let camera = this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
+ let camera = this.viewer.mainViewport.camera//this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
if(!handle){
|
|
if(!handle){
|
|
return
|
|
return
|
|
@@ -505,7 +554,7 @@ export class TransformationTool {
|
|
}else{
|
|
}else{
|
|
handle = drag.handle;
|
|
handle = drag.handle;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ if(!drag.dragPlane)return//xzw add 因有时候没有
|
|
this.dragging = true;
|
|
this.dragging = true;
|
|
|
|
|
|
let pointer = this.viewer.inputHandler.pointer
|
|
let pointer = this.viewer.inputHandler.pointer
|
|
@@ -528,7 +577,7 @@ export class TransformationTool {
|
|
if (Number.isNaN(angle)) {
|
|
if (Number.isNaN(angle)) {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ let matrixBefore = this.selection[0].matrix.clone()
|
|
let normal = new THREE.Vector3(...handle.alignment);
|
|
let normal = new THREE.Vector3(...handle.alignment);
|
|
for (let selection of this.selection) {
|
|
for (let selection of this.selection) {
|
|
selection.rotateOnAxis(normal, angle);
|
|
selection.rotateOnAxis(normal, angle);
|
|
@@ -537,7 +586,7 @@ export class TransformationTool {
|
|
object: selection
|
|
object: selection
|
|
});
|
|
});
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ this.dispatchEvent({type:'transformed', changeType: ['orientation'], matrixBefore })//add
|
|
drag.pivot = I;
|
|
drag.pivot = I;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -545,13 +594,16 @@ export class TransformationTool {
|
|
dropRotationHandle(e){
|
|
dropRotationHandle(e){
|
|
this.dragging = false;
|
|
this.dragging = false;
|
|
this.setActiveHandle(null);
|
|
this.setActiveHandle(null);
|
|
|
|
+ this.dispatchEvent({type:'stopDrag', handle:'rotation'})//add
|
|
}
|
|
}
|
|
|
|
|
|
dragTranslationHandle(e){
|
|
dragTranslationHandle(e){
|
|
let drag = e.drag;
|
|
let drag = e.drag;
|
|
let handle = this.activeHandle;
|
|
let handle = this.activeHandle;
|
|
- let camera = this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
+ let camera = this.viewer.mainViewport.camera//this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
if(!drag.intersectionStart && handle){
|
|
if(!drag.intersectionStart && handle){
|
|
drag.intersectionStart = drag.location;
|
|
drag.intersectionStart = drag.location;
|
|
drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
|
|
drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
|
|
@@ -561,10 +613,16 @@ export class TransformationTool {
|
|
let end = new THREE.Vector3().addVectors(start, dir);
|
|
let end = new THREE.Vector3().addVectors(start, dir);
|
|
let line = new THREE.Line3(start.clone(), end.clone());
|
|
let line = new THREE.Line3(start.clone(), end.clone());
|
|
drag.line = line;
|
|
drag.line = line;
|
|
-
|
|
|
|
- let camOnLine = line.closestPointToPoint(camera.position, false, new THREE.Vector3());
|
|
|
|
- let normal = new THREE.Vector3().subVectors(camera.position, camOnLine);
|
|
|
|
- let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, drag.intersectionStart);
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ let normal
|
|
|
|
+ if(camera.type == 'OrthographicCamera'){//xzw add
|
|
|
|
+ normal = new THREE.Vector3(0,0,-1).applyQuaternion(camera.quaternion)
|
|
|
|
+ }else{
|
|
|
|
+ let camOnLine = line.closestPointToPoint(camera.position, false, new THREE.Vector3());
|
|
|
|
+ normal = new THREE.Vector3().subVectors(camera.position, camOnLine);
|
|
|
|
+ }
|
|
|
|
+ let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, drag.intersectionStart);
|
|
drag.dragPlane = plane;
|
|
drag.dragPlane = plane;
|
|
drag.pivot = drag.intersectionStart;
|
|
drag.pivot = drag.intersectionStart;
|
|
}else{
|
|
}else{
|
|
@@ -573,7 +631,7 @@ export class TransformationTool {
|
|
|
|
|
|
this.dragging = true;
|
|
this.dragging = true;
|
|
|
|
|
|
- {
|
|
|
|
|
|
+ if(drag.dragPlane){//xzw add 因有时候没有
|
|
let pointer = this.viewer.inputHandler.pointer
|
|
let pointer = this.viewer.inputHandler.pointer
|
|
let domElement = this.viewer.renderer.domElement;
|
|
let domElement = this.viewer.renderer.domElement;
|
|
let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
|
|
let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
|
|
@@ -583,7 +641,7 @@ export class TransformationTool {
|
|
let iOnLine = drag.line.closestPointToPoint(I, false, new THREE.Vector3());
|
|
let iOnLine = drag.line.closestPointToPoint(I, false, new THREE.Vector3());
|
|
|
|
|
|
let diff = new THREE.Vector3().subVectors(iOnLine, drag.pivot);
|
|
let diff = new THREE.Vector3().subVectors(iOnLine, drag.pivot);
|
|
-
|
|
|
|
|
|
+ let matrixBefore = this.selection[0].matrix.clone()
|
|
for (let selection of this.selection) {
|
|
for (let selection of this.selection) {
|
|
selection.position.add(diff);
|
|
selection.position.add(diff);
|
|
selection.dispatchEvent({
|
|
selection.dispatchEvent({
|
|
@@ -591,7 +649,7 @@ export class TransformationTool {
|
|
object: selection
|
|
object: selection
|
|
});
|
|
});
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+ this.dispatchEvent({type:'transformed', changeType: ['position'], matrixBefore})//add
|
|
drag.pivot = drag.pivot.add(diff);
|
|
drag.pivot = drag.pivot.add(diff);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -600,31 +658,37 @@ export class TransformationTool {
|
|
dropTranslationHandle(e){
|
|
dropTranslationHandle(e){
|
|
this.dragging = false;
|
|
this.dragging = false;
|
|
this.setActiveHandle(null);
|
|
this.setActiveHandle(null);
|
|
|
|
+ this.dispatchEvent({type:'stopDrag', handle:'translation'})//add
|
|
}
|
|
}
|
|
|
|
|
|
dropScaleHandle(e){
|
|
dropScaleHandle(e){
|
|
this.dragging = false;
|
|
this.dragging = false;
|
|
this.setActiveHandle(null);
|
|
this.setActiveHandle(null);
|
|
|
|
+ this.dispatchEvent({type:'stopDrag', handle:'scale'})//add
|
|
}
|
|
}
|
|
|
|
|
|
dragScaleHandle(e){
|
|
dragScaleHandle(e){
|
|
let drag = e.drag;
|
|
let drag = e.drag;
|
|
let handle = this.activeHandle;
|
|
let handle = this.activeHandle;
|
|
- let camera = this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
+ let camera = this.viewer.mainViewport.camera//this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
if(!drag.intersectionStart){
|
|
if(!drag.intersectionStart){
|
|
drag.intersectionStart = drag.location;
|
|
drag.intersectionStart = drag.location;
|
|
drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
|
|
drag.objectStart = drag.object.getWorldPosition(new THREE.Vector3());
|
|
drag.handle = handle;
|
|
drag.handle = handle;
|
|
-
|
|
|
|
- let start = drag.intersectionStart;
|
|
|
|
- let dir = new THREE.Vector4(...handle.alignment, 0).applyMatrix4(this.scene.matrixWorld);
|
|
|
|
- let end = new THREE.Vector3().addVectors(start, dir);
|
|
|
|
- let line = new THREE.Line3(start.clone(), end.clone());
|
|
|
|
|
|
+ let start = drag.intersectionStart;
|
|
|
|
+ let dir = new THREE.Vector4(...handle.alignment, 0).applyMatrix4(this.scene.matrixWorld);
|
|
|
|
+ let end = new THREE.Vector3().addVectors(start, dir);
|
|
|
|
+ let line = new THREE.Line3(start.clone(), end.clone());
|
|
drag.line = line;
|
|
drag.line = line;
|
|
-
|
|
|
|
- let camOnLine = line.closestPointToPoint(camera.position, false, new THREE.Vector3());
|
|
|
|
- let normal = new THREE.Vector3().subVectors(camera.position, camOnLine);
|
|
|
|
|
|
+
|
|
|
|
+ let normal
|
|
|
|
+ if(camera.type == 'OrthographicCamera'){//xzw add
|
|
|
|
+ normal = new THREE.Vector3(0,0,-1).applyQuaternion(camera.quaternion)
|
|
|
|
+ }else{
|
|
|
|
+ let camOnLine = line.closestPointToPoint(camera.position, false, new THREE.Vector3());
|
|
|
|
+ normal = new THREE.Vector3().subVectors(camera.position, camOnLine);
|
|
|
|
+ }
|
|
let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, drag.intersectionStart);
|
|
let plane = new THREE.Plane().setFromNormalAndCoplanarPoint(normal, drag.intersectionStart);
|
|
drag.dragPlane = plane;
|
|
drag.dragPlane = plane;
|
|
drag.pivot = drag.intersectionStart;
|
|
drag.pivot = drag.intersectionStart;
|
|
@@ -636,7 +700,7 @@ export class TransformationTool {
|
|
|
|
|
|
this.dragging = true;
|
|
this.dragging = true;
|
|
|
|
|
|
- {
|
|
|
|
|
|
+ if(drag.dragPlane){//xzw add 因有时候没有
|
|
let pointer = this.viewer.inputHandler.pointer
|
|
let pointer = this.viewer.inputHandler.pointer
|
|
let domElement = this.viewer.renderer.domElement;
|
|
let domElement = this.viewer.renderer.domElement;
|
|
let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
|
|
let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
|
|
@@ -661,7 +725,7 @@ export class TransformationTool {
|
|
let diffPosition = diff.clone().multiplyScalar(0.5);
|
|
let diffPosition = diff.clone().multiplyScalar(0.5);
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
|
|
+ let matrixBefore = this.selection[0].matrix.clone()
|
|
for (let selection of this.selection) {
|
|
for (let selection of this.selection) {
|
|
//xzw 改:否则不跟手
|
|
//xzw 改:否则不跟手
|
|
let diffScale_ = diffScale.clone().divide(selection.boundingBox.getSize(new THREE.Vector3))
|
|
let diffScale_ = diffScale.clone().divide(selection.boundingBox.getSize(new THREE.Vector3))
|
|
@@ -681,6 +745,8 @@ export class TransformationTool {
|
|
type: "scale_changed",
|
|
type: "scale_changed",
|
|
object: selection
|
|
object: selection
|
|
});
|
|
});
|
|
|
|
+
|
|
|
|
+ this.dispatchEvent({type:'transformed', changeType: ['position','scale'], matrixBefore})//add
|
|
}
|
|
}
|
|
|
|
|
|
drag.pivot.copy(iOnLine);
|
|
drag.pivot.copy(iOnLine);
|
|
@@ -788,83 +854,125 @@ export class TransformationTool {
|
|
|
|
|
|
let selected = this.selection[0];
|
|
let selected = this.selection[0];
|
|
let world = selected.matrixWorld;
|
|
let world = selected.matrixWorld;
|
|
- let camera = this.viewer.scene.getActiveCamera();
|
|
|
|
|
|
+ let camera = this.viewer.mainViewport.camera//this.viewer.scene.getActiveCamera();
|
|
let domElement = this.viewer.renderer.domElement;
|
|
let domElement = this.viewer.renderer.domElement;
|
|
let pointer = this.viewer.inputHandler.pointer;
|
|
let pointer = this.viewer.inputHandler.pointer;
|
|
|
|
|
|
|
|
+
|
|
|
|
+
|
|
let center = selected.boundingBox.getCenter(new THREE.Vector3()).clone().applyMatrix4(selected.matrixWorld);
|
|
let center = selected.boundingBox.getCenter(new THREE.Vector3()).clone().applyMatrix4(selected.matrixWorld);
|
|
|
|
|
|
this.scene.scale.copy(selected.boundingBox.getSize(new THREE.Vector3()).multiply(selected.scale));
|
|
this.scene.scale.copy(selected.boundingBox.getSize(new THREE.Vector3()).multiply(selected.scale));
|
|
this.scene.position.copy(center);
|
|
this.scene.position.copy(center);
|
|
- this.scene.rotation.copy(selected.rotation);
|
|
|
|
|
|
+ this.scene.rotation.copy(selected.rotation);
|
|
|
|
+
|
|
|
|
+ //如果是世界坐标 (缩放方向有bug。)
|
|
|
|
+ /*
|
|
|
|
+ let boundingBox = selected.boundingBox.clone().applyMatrix4(selected.matrixWorld);
|
|
|
|
+ let center = boundingBox.getCenter(new THREE.Vector3())
|
|
|
|
+ this.scene.position.copy(center);
|
|
|
|
+ this.scene.scale.copy(boundingBox.getSize(new THREE.Vector3()));
|
|
|
|
+
|
|
|
|
+ */
|
|
|
|
+
|
|
|
|
|
|
this.scene.updateMatrixWorld();
|
|
this.scene.updateMatrixWorld();
|
|
|
|
|
|
{
|
|
{
|
|
// adjust rotation handles
|
|
// adjust rotation handles
|
|
if(!this.dragging){
|
|
if(!this.dragging){
|
|
- let tWorld = this.scene.matrixWorld;
|
|
|
|
- let tObject = tWorld.clone().invert();
|
|
|
|
- let camObjectPos = camera.getWorldPosition(new THREE.Vector3()).applyMatrix4(tObject);
|
|
|
|
-
|
|
|
|
- let x = this.rotationHandles["rotation.x"].node.rotation;
|
|
|
|
- let y = this.rotationHandles["rotation.y"].node.rotation;
|
|
|
|
- let z = this.rotationHandles["rotation.z"].node.rotation;
|
|
|
|
-
|
|
|
|
- x.order = "ZYX";
|
|
|
|
- y.order = "ZYX";
|
|
|
|
-
|
|
|
|
- let above = camObjectPos.z > 0;
|
|
|
|
- let below = !above;
|
|
|
|
- let PI_HALF = Math.PI / 2;
|
|
|
|
-
|
|
|
|
- if(above){
|
|
|
|
- if(camObjectPos.x > 0 && camObjectPos.y > 0){
|
|
|
|
- x.x = 1 * PI_HALF;
|
|
|
|
- y.y = 3 * PI_HALF;
|
|
|
|
- z.z = 0 * PI_HALF;
|
|
|
|
- }else if(camObjectPos.x < 0 && camObjectPos.y > 0){
|
|
|
|
- x.x = 1 * PI_HALF;
|
|
|
|
- y.y = 2 * PI_HALF;
|
|
|
|
- z.z = 1 * PI_HALF;
|
|
|
|
- }else if(camObjectPos.x < 0 && camObjectPos.y < 0){
|
|
|
|
- x.x = 2 * PI_HALF;
|
|
|
|
- y.y = 2 * PI_HALF;
|
|
|
|
- z.z = 2 * PI_HALF;
|
|
|
|
- }else if(camObjectPos.x > 0 && camObjectPos.y < 0){
|
|
|
|
- x.x = 2 * PI_HALF;
|
|
|
|
- y.y = 3 * PI_HALF;
|
|
|
|
- z.z = 3 * PI_HALF;
|
|
|
|
- }
|
|
|
|
- }else if(below){
|
|
|
|
- if(camObjectPos.x > 0 && camObjectPos.y > 0){
|
|
|
|
- x.x = 0 * PI_HALF;
|
|
|
|
- y.y = 0 * PI_HALF;
|
|
|
|
- z.z = 0 * PI_HALF;
|
|
|
|
- }else if(camObjectPos.x < 0 && camObjectPos.y > 0){
|
|
|
|
- x.x = 0 * PI_HALF;
|
|
|
|
- y.y = 1 * PI_HALF;
|
|
|
|
- z.z = 1 * PI_HALF;
|
|
|
|
- }else if(camObjectPos.x < 0 && camObjectPos.y < 0){
|
|
|
|
- x.x = 3 * PI_HALF;
|
|
|
|
- y.y = 1 * PI_HALF;
|
|
|
|
- z.z = 2 * PI_HALF;
|
|
|
|
- }else if(camObjectPos.x > 0 && camObjectPos.y < 0){
|
|
|
|
- x.x = 3 * PI_HALF;
|
|
|
|
- y.y = 0 * PI_HALF;
|
|
|
|
- z.z = 3 * PI_HALF;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
|
|
+ if(this.modesEnabled.rotation){
|
|
|
|
+ let tWorld = this.scene.matrixWorld;
|
|
|
|
+ let tObject = tWorld.clone().invert();
|
|
|
|
+ let camObjectPos = camera.getWorldPosition(new THREE.Vector3()).applyMatrix4(tObject);
|
|
|
|
+
|
|
|
|
+ let x = this.rotationHandles["rotation.x"].node.rotation;
|
|
|
|
+ let y = this.rotationHandles["rotation.y"].node.rotation;
|
|
|
|
+ let z = this.rotationHandles["rotation.z"].node.rotation;
|
|
|
|
+
|
|
|
|
+ x.order = "ZYX";
|
|
|
|
+ y.order = "ZYX";
|
|
|
|
+
|
|
|
|
+ let above = camObjectPos.z > 0;
|
|
|
|
+ let below = !above;
|
|
|
|
+ let PI_HALF = Math.PI / 2;
|
|
|
|
+
|
|
|
|
+ if(above){
|
|
|
|
+ if(camObjectPos.x > 0 && camObjectPos.y > 0){
|
|
|
|
+ x.x = 1 * PI_HALF;
|
|
|
|
+ y.y = 3 * PI_HALF;
|
|
|
|
+ z.z = 0 * PI_HALF;
|
|
|
|
+ }else if(camObjectPos.x < 0 && camObjectPos.y > 0){
|
|
|
|
+ x.x = 1 * PI_HALF;
|
|
|
|
+ y.y = 2 * PI_HALF;
|
|
|
|
+ z.z = 1 * PI_HALF;
|
|
|
|
+ }else if(camObjectPos.x < 0 && camObjectPos.y < 0){
|
|
|
|
+ x.x = 2 * PI_HALF;
|
|
|
|
+ y.y = 2 * PI_HALF;
|
|
|
|
+ z.z = 2 * PI_HALF;
|
|
|
|
+ }else if(camObjectPos.x > 0 && camObjectPos.y < 0){
|
|
|
|
+ x.x = 2 * PI_HALF;
|
|
|
|
+ y.y = 3 * PI_HALF;
|
|
|
|
+ z.z = 3 * PI_HALF;
|
|
|
|
+ }
|
|
|
|
+ }else if(below){
|
|
|
|
+ if(camObjectPos.x > 0 && camObjectPos.y > 0){
|
|
|
|
+ x.x = 0 * PI_HALF;
|
|
|
|
+ y.y = 0 * PI_HALF;
|
|
|
|
+ z.z = 0 * PI_HALF;
|
|
|
|
+ }else if(camObjectPos.x < 0 && camObjectPos.y > 0){
|
|
|
|
+ x.x = 0 * PI_HALF;
|
|
|
|
+ y.y = 1 * PI_HALF;
|
|
|
|
+ z.z = 1 * PI_HALF;
|
|
|
|
+ }else if(camObjectPos.x < 0 && camObjectPos.y < 0){
|
|
|
|
+ x.x = 3 * PI_HALF;
|
|
|
|
+ y.y = 1 * PI_HALF;
|
|
|
|
+ z.z = 2 * PI_HALF;
|
|
|
|
+ }else if(camObjectPos.x > 0 && camObjectPos.y < 0){
|
|
|
|
+ x.x = 3 * PI_HALF;
|
|
|
|
+ y.y = 0 * PI_HALF;
|
|
|
|
+ z.z = 3 * PI_HALF;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
// adjust scale of components
|
|
// adjust scale of components
|
|
for(let handleName of Object.keys(this.handles)){
|
|
for(let handleName of Object.keys(this.handles)){
|
|
let handle = this.handles[handleName];
|
|
let handle = this.handles[handleName];
|
|
- let node = handle.node;
|
|
|
|
-
|
|
|
|
|
|
+ let node = handle.node;
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ //xzw add:---- -当该轴正对相机时隐藏。(主要针对ortho类型camera。 )
|
|
|
|
+ if(!viewer.getObjVisiByReason(node,'modeForce') )continue;
|
|
|
|
+ if(!handleName.includes('rotation') || camera.type == 'OrthographicCamera'){//旋转的话正常都应该显示
|
|
|
|
+ let alignment = handle.alignment;
|
|
|
|
+ let normal
|
|
|
|
+ let dir = new THREE.Vector3(...alignment).applyQuaternion(this.scene.quaternion)
|
|
|
|
+ if(camera.type == 'OrthographicCamera'){
|
|
|
|
+ normal = new THREE.Vector3(0,0,-1).applyQuaternion(camera.quaternion)
|
|
|
|
+ }else{
|
|
|
|
+ normal = new THREE.Vector3().subVectors(center, camera.position).normalize()
|
|
|
|
+ }
|
|
|
|
+ let ifOnLine
|
|
|
|
+
|
|
|
|
+ if(handleName.includes('rotation')){ //旋转时 旋转轴和视线垂直时隐藏
|
|
|
|
+ ifOnLine = Math.abs(dir.dot(normal)) < 0.01
|
|
|
|
+ }else{
|
|
|
|
+ ifOnLine = Math.abs(dir.dot(normal)) > 0.995
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ viewer.updateVisible(node, 'faceToCamHide', !ifOnLine)
|
|
|
|
+ }else{
|
|
|
|
+ viewer.updateVisible(node, 'faceToCamHide', true)
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if(!node.visible)continue;
|
|
|
|
+
|
|
|
|
+ //------------------------------------------------------------------------
|
|
|
|
+
|
|
let handlePos = node.getWorldPosition(new THREE.Vector3());
|
|
let handlePos = node.getWorldPosition(new THREE.Vector3());
|
|
let distance = handlePos.distanceTo(camera.position);
|
|
let distance = handlePos.distanceTo(camera.position);
|
|
let pr = Utils.projectedRadius(1, camera, distance, domElement.clientWidth, domElement.clientHeight);
|
|
let pr = Utils.projectedRadius(1, camera, distance, domElement.clientWidth, domElement.clientHeight);
|
|
@@ -883,15 +991,20 @@ export class TransformationTool {
|
|
scale.z = Math.abs(scale.z);
|
|
scale.z = Math.abs(scale.z);
|
|
|
|
|
|
node.scale.copy(scale);
|
|
node.scale.copy(scale);
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- {
|
|
|
|
- let ray = Utils.mouseToRay(pointer, camera, domElement.clientWidth, domElement.clientHeight);
|
|
|
|
|
|
+ if(!this.dragging){ //xzw 添加dragging条件
|
|
|
|
+ let ray = Utils.mouseToRay(pointer, camera/* , domElement.clientWidth, domElement.clientHeight */);
|
|
let raycaster = new THREE.Raycaster(ray.origin, ray.direction);
|
|
let raycaster = new THREE.Raycaster(ray.origin, ray.direction);
|
|
raycaster.layers.enableAll()//add
|
|
raycaster.layers.enableAll()//add
|
|
-
|
|
|
|
|
|
+
|
|
|
|
|
|
let pickVolumes = this.pickVolumes.filter(v=>{
|
|
let pickVolumes = this.pickVolumes.filter(v=>{
|
|
let mode = v.handle.split('.')[0];
|
|
let mode = v.handle.split('.')[0];
|
|
@@ -903,22 +1016,14 @@ export class TransformationTool {
|
|
if(intersects.length > 0){
|
|
if(intersects.length > 0){
|
|
let I = intersects[0];
|
|
let I = intersects[0];
|
|
let handleName = I.object.handle;
|
|
let handleName = I.object.handle;
|
|
- console.log(handleName)
|
|
|
|
|
|
+ //console.log(handleName)
|
|
this.setActiveHandle(this.handles[handleName]);
|
|
this.setActiveHandle(this.handles[handleName]);
|
|
}else{
|
|
}else{
|
|
this.setActiveHandle(null);
|
|
this.setActiveHandle(null);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- //
|
|
|
|
- for(let handleName of Object.keys(this.scaleHandles)){
|
|
|
|
- let handle = this.handles[handleName];
|
|
|
|
- let node = handle.node;
|
|
|
|
- let alignment = handle.alignment;
|
|
|
|
-
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
}else{
|
|
}else{
|