xzw 4 months ago
parent
commit
c8227aff6a
3 changed files with 393 additions and 12 deletions
  1. 390 9
      public/lib/potree/potree.js
  2. 1 1
      public/lib/potree/potree.js.map
  3. 2 2
      src/sdk/cover/index.js

+ 390 - 9
public/lib/potree/potree.js

@@ -20372,7 +20372,7 @@
 	      r: 255,
 	      g: 255,
 	      b: 255,
-	      a: 1.0
+	      a: 0.7
 	    };
 	    this.textColor = options.textColor ? Common$1.CloneObject(options.textColor) : {
 	      r: 0,
@@ -75511,7 +75511,8 @@
 	      applyData: data => {
 	        if (data.object.parent /* && data.object == this.selected */) {
 	          data = Potree.Common.CloneObject(data); //避免使用后更改数据又被使用 
-	          data.matrix.decompose(data.object.position, data.object.quaternion, data.object.scale);
+	          var matrix = data.object.parent ? data.object.parent.matrixWorld.clone().invert().multiply(data.matrixWorld) : data.matrixWorld;
+	          matrix.decompose(data.object.position, data.object.quaternion, data.object.scale);
 	          data.object.boundCenter.copy(data.boundCenter);
 	          data.object.dispatchEvent('changeByHistory');
 	          data.object.dispatchEvent('transformChanged');
@@ -75522,7 +75523,7 @@
 	      getData: object => {
 	        return {
 	          object,
-	          matrix: object.matrixWorld.clone(),
+	          matrixWorld: object.matrixWorld.clone(),
 	          boundCenter: object.boundCenter.clone()
 	        };
 	      }
@@ -75967,16 +75968,32 @@
 	    this.bus.dispatchEvent('changeSelect');
 	  },
 	  updateBoxHelper(model) {
+	    /* let size = new THREE.Vector3
+	    model.boundingBox.getSize(size)
+	    size.multiply(model.scale)
+	    this.boxHelper.scale.copy(size) 
+	    
+	    let center = new THREE.Vector3 
+	    model.boundingBox.getCenter(center) 
+	    center.applyMatrix4(model.matrixWorld)
+	    //center.add(model.position)     
+	    this.boxHelper.position.copy(center)
+	     
+	    this.boxHelper.quaternion.copy(model.quaternion)   */
+
 	    var size = new Vector3();
 	    model.boundingBox.getSize(size);
-	    size.multiply(model.scale);
+	    size.multiply(model.getWorldScale(new Vector3()));
 	    this.boxHelper.scale.copy(size);
 	    var center = new Vector3();
 	    model.boundingBox.getCenter(center);
 	    center.applyMatrix4(model.matrixWorld);
-	    //center.add(model.position)     
 	    this.boxHelper.position.copy(center);
-	    this.boxHelper.quaternion.copy(model.quaternion);
+	    model.getWorldQuaternion(this.boxHelper.quaternion);
+
+	    /* this.boxHelper.scale.copy(model.getWorldScale(new THREE.Vector3)) 
+	    this.boxHelper.quaternion.copy(model.getWorldQuaternion(new THREE.Quaternion))
+	    this.boxHelper.position.copy(model.getWorldPosition(new THREE.Vector3)) */
 	    viewer.dispatchEvent('content_changed');
 	  },
 	  showModelOutline(model, state) {
@@ -86692,6 +86709,328 @@
 
 	 */
 
+	var _q = new Quaternion();
+	var _targetPos = new Vector3();
+	var _targetVec = new Vector3();
+	var _effectorPos = new Vector3();
+	var _effectorVec = new Vector3();
+	var _linkPos = new Vector3();
+	var _invLinkQ = new Quaternion();
+	var _linkScale = new Vector3();
+	var _axis$2 = new Vector3();
+	var _vector$e = new Vector3();
+	var _matrix$2 = new Matrix4();
+
+	/**
+	 * CCD Algorithm
+	 *  - https://web.archive.org/web/20221206080850/https://sites.google.com/site/auraliusproject/ccd-algorithm
+	 *
+	 * // ik parameter example
+	 * //
+	 * // target, effector, index in links are bone index in skeleton.bones.
+	 * // the bones relation should be
+	 * // <-- parent                                  child -->
+	 * // links[ n ], links[ n - 1 ], ..., links[ 0 ], effector
+	 * iks = [ {
+	 *	target: 1,
+	 *	effector: 2,
+	 *	links: [ { index: 5, limitation: new Vector3( 1, 0, 0 ) }, { index: 4, enabled: false }, { index : 3 } ],
+	 *	iteration: 10,
+	 *	minAngle: 0.0,
+	 *	maxAngle: 1.0,
+	 * } ];
+	 */
+
+	class CCDIKSolver {
+	  /**
+	   * @param {THREE.SkinnedMesh} mesh
+	   * @param {Array<Object>} iks
+	   */
+	  constructor(mesh) {
+	    var iks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
+	    this.mesh = mesh;
+	    this.iks = iks;
+	    this._valid();
+	  }
+
+	  /**
+	   * Update all IK bones.
+	   *
+	   * @return {CCDIKSolver}
+	   */
+	  update() {
+	    var iks = this.iks;
+	    for (var i = 0, il = iks.length; i < il; i++) {
+	      this.updateOne(iks[i]);
+	    }
+	    return this;
+	  }
+
+	  /**
+	   * Update one IK bone
+	   *
+	   * @param {Object} ik parameter
+	   * @return {CCDIKSolver}
+	   */
+	  updateOne(ik) {
+	    var bones = this.mesh.skeleton.bones;
+
+	    // for reference overhead reduction in loop
+	    var math = Math;
+	    var effector = bones[ik.effector];
+	    var target = bones[ik.target];
+
+	    // don't use getWorldPosition() here for the performance
+	    // because it calls updateMatrixWorld( true ) inside.
+	    _targetPos.setFromMatrixPosition(target.matrixWorld);
+	    var links = ik.links;
+	    var iteration = ik.iteration !== undefined ? ik.iteration : 1;
+	    for (var i = 0; i < iteration; i++) {
+	      var rotated = false;
+	      for (var j = 0, jl = links.length; j < jl; j++) {
+	        var link = bones[links[j].index];
+
+	        // skip this link and following links
+	        if (links[j].enabled === false) break;
+	        var limitation = links[j].limitation;
+	        var rotationMin = links[j].rotationMin;
+	        var rotationMax = links[j].rotationMax;
+
+	        // don't use getWorldPosition/Quaternion() here for the performance
+	        // because they call updateMatrixWorld( true ) inside.
+	        link.matrixWorld.decompose(_linkPos, _invLinkQ, _linkScale);
+	        _invLinkQ.invert();
+	        _effectorPos.setFromMatrixPosition(effector.matrixWorld);
+
+	        // work in link world
+	        _effectorVec.subVectors(_effectorPos, _linkPos);
+	        _effectorVec.applyQuaternion(_invLinkQ);
+	        _effectorVec.normalize();
+	        _targetVec.subVectors(_targetPos, _linkPos);
+	        _targetVec.applyQuaternion(_invLinkQ);
+	        _targetVec.normalize();
+	        var angle = _targetVec.dot(_effectorVec);
+	        if (angle > 1.0) {
+	          angle = 1.0;
+	        } else if (angle < -1.0) {
+	          angle = -1.0;
+	        }
+	        angle = math.acos(angle);
+
+	        // skip if changing angle is too small to prevent vibration of bone
+	        if (angle < 1e-5) continue;
+	        if (ik.minAngle !== undefined && angle < ik.minAngle) {
+	          angle = ik.minAngle;
+	        }
+	        if (ik.maxAngle !== undefined && angle > ik.maxAngle) {
+	          angle = ik.maxAngle;
+	        }
+	        _axis$2.crossVectors(_effectorVec, _targetVec);
+	        _axis$2.normalize();
+	        _q.setFromAxisAngle(_axis$2, angle);
+	        link.quaternion.multiply(_q);
+
+	        // TODO: re-consider the limitation specification
+	        if (limitation !== undefined) {
+	          var c = link.quaternion.w;
+	          if (c > 1.0) c = 1.0;
+	          var c2 = math.sqrt(1 - c * c);
+	          link.quaternion.set(limitation.x * c2, limitation.y * c2, limitation.z * c2, c);
+	        }
+	        if (rotationMin !== undefined) {
+	          link.rotation.setFromVector3(_vector$e.setFromEuler(link.rotation).max(rotationMin));
+	        }
+	        if (rotationMax !== undefined) {
+	          link.rotation.setFromVector3(_vector$e.setFromEuler(link.rotation).min(rotationMax));
+	        }
+	        link.updateMatrixWorld(true);
+	        rotated = true;
+	      }
+	      if (!rotated) break;
+	    }
+	    return this;
+	  }
+
+	  /**
+	   * Creates Helper
+	   *
+	   * @param {number} sphereSize
+	   * @return {CCDIKHelper}
+	   */
+	  createHelper(sphereSize) {
+	    return new CCDIKHelper(this.mesh, this.iks, sphereSize);
+	  }
+
+	  // private methods
+
+	  _valid() {
+	    var iks = this.iks;
+	    var bones = this.mesh.skeleton.bones;
+	    for (var i = 0, il = iks.length; i < il; i++) {
+	      var ik = iks[i];
+	      var effector = bones[ik.effector];
+	      var links = ik.links;
+	      var link0 = void 0,
+	        link1 = void 0;
+	      link0 = effector;
+	      for (var j = 0, jl = links.length; j < jl; j++) {
+	        link1 = bones[links[j].index];
+	        if (link0.parent !== link1) {
+	          console.warn('THREE.CCDIKSolver: bone ' + link0.name + ' is not the child of bone ' + link1.name);
+	        }
+	        link0 = link1;
+	      }
+	    }
+	  }
+	}
+	function getPosition(bone, matrixWorldInv) {
+	  return _vector$e.setFromMatrixPosition(bone.matrixWorld).applyMatrix4(matrixWorldInv);
+	}
+	function setPositionOfBoneToAttributeArray(array, index, bone, matrixWorldInv) {
+	  var v = getPosition(bone, matrixWorldInv);
+	  array[index * 3 + 0] = v.x;
+	  array[index * 3 + 1] = v.y;
+	  array[index * 3 + 2] = v.z;
+	}
+
+	/**
+	 * Visualize IK bones
+	 */
+	class CCDIKHelper extends Object3D {
+	  /**
+	   * @param {SkinnedMesh} mesh
+	  	 * @param {Array<Object>} [iks=[]]
+	  	 * @param {number} [sphereSize=0.25]
+	   */
+	  constructor(mesh) {
+	    var iks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
+	    var sphereSize = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0.25;
+	    super();
+	    this.root = mesh;
+	    this.iks = iks;
+	    this.matrix.copy(mesh.matrixWorld);
+	    this.matrixAutoUpdate = false;
+	    this.sphereGeometry = new SphereGeometry(sphereSize, 16, 8);
+	    this.targetSphereMaterial = new MeshBasicMaterial({
+	      color: new Color(0xff8888),
+	      depthTest: false,
+	      depthWrite: false,
+	      transparent: true
+	    });
+	    this.effectorSphereMaterial = new MeshBasicMaterial({
+	      color: new Color(0x88ff88),
+	      depthTest: false,
+	      depthWrite: false,
+	      transparent: true
+	    });
+	    this.linkSphereMaterial = new MeshBasicMaterial({
+	      color: new Color(0x8888ff),
+	      depthTest: false,
+	      depthWrite: false,
+	      transparent: true
+	    });
+	    this.lineMaterial = new LineBasicMaterial({
+	      color: new Color(0xff0000),
+	      depthTest: false,
+	      depthWrite: false,
+	      transparent: true
+	    });
+	    this._init();
+	  }
+
+	  /**
+	   * Updates IK bones visualization.
+	   *
+	   * @param {Boolean} force
+	   */
+	  updateMatrixWorld(force) {
+	    var mesh = this.root;
+	    if (this.visible) {
+	      var offset = 0;
+	      var iks = this.iks;
+	      var bones = mesh.skeleton.bones;
+	      _matrix$2.copy(mesh.matrixWorld).invert();
+	      for (var i = 0, il = iks.length; i < il; i++) {
+	        var ik = iks[i];
+	        var targetBone = bones[ik.target];
+	        var effectorBone = bones[ik.effector];
+	        var targetMesh = this.children[offset++];
+	        var effectorMesh = this.children[offset++];
+	        targetMesh.position.copy(getPosition(targetBone, _matrix$2));
+	        effectorMesh.position.copy(getPosition(effectorBone, _matrix$2));
+	        for (var j = 0, jl = ik.links.length; j < jl; j++) {
+	          var link = ik.links[j];
+	          var linkBone = bones[link.index];
+	          var linkMesh = this.children[offset++];
+	          linkMesh.position.copy(getPosition(linkBone, _matrix$2));
+	        }
+	        var line = this.children[offset++];
+	        var array = line.geometry.attributes.position.array;
+	        setPositionOfBoneToAttributeArray(array, 0, targetBone, _matrix$2);
+	        setPositionOfBoneToAttributeArray(array, 1, effectorBone, _matrix$2);
+	        for (var _j = 0, _jl = ik.links.length; _j < _jl; _j++) {
+	          var _link = ik.links[_j];
+	          var _linkBone = bones[_link.index];
+	          setPositionOfBoneToAttributeArray(array, _j + 2, _linkBone, _matrix$2);
+	        }
+	        line.geometry.attributes.position.needsUpdate = true;
+	      }
+	    }
+	    this.matrix.copy(mesh.matrixWorld);
+	    super.updateMatrixWorld(force);
+	  }
+
+	  /**
+	   * Frees the GPU-related resources allocated by this instance. Call this method whenever this instance is no longer used in your app.
+	   */
+	  dispose() {
+	    this.sphereGeometry.dispose();
+	    this.targetSphereMaterial.dispose();
+	    this.effectorSphereMaterial.dispose();
+	    this.linkSphereMaterial.dispose();
+	    this.lineMaterial.dispose();
+	    var children = this.children;
+	    for (var i = 0; i < children.length; i++) {
+	      var child = children[i];
+	      if (child.isLine) child.geometry.dispose();
+	    }
+	  }
+
+	  // private method
+
+	  _init() {
+	    var scope = this;
+	    var iks = this.iks;
+	    function createLineGeometry(ik) {
+	      var geometry = new BufferGeometry();
+	      var vertices = new Float32Array((2 + ik.links.length) * 3);
+	      geometry.setAttribute('position', new BufferAttribute(vertices, 3));
+	      return geometry;
+	    }
+	    function createTargetMesh() {
+	      return new Mesh(scope.sphereGeometry, scope.targetSphereMaterial);
+	    }
+	    function createEffectorMesh() {
+	      return new Mesh(scope.sphereGeometry, scope.effectorSphereMaterial);
+	    }
+	    function createLinkMesh() {
+	      return new Mesh(scope.sphereGeometry, scope.linkSphereMaterial);
+	    }
+	    function createLine(ik) {
+	      return new Line(createLineGeometry(ik), scope.lineMaterial);
+	    }
+	    for (var i = 0, il = iks.length; i < il; i++) {
+	      var ik = iks[i];
+	      this.add(createTargetMesh());
+	      this.add(createEffectorMesh());
+	      for (var j = 0, jl = ik.links.length; j < jl; j++) {
+	        this.add(createLinkMesh());
+	      }
+	      this.add(createLine(ik));
+	    }
+	  }
+	}
+
 	var loaders = {};
 	var mapArea;
 	var shelterHistory = [];
@@ -91243,6 +91582,8 @@
 	    {
 	      var hasAnimation;
 	      window.pauseAni || this.objs.children.forEach(model => {
+	        //model.traverse(object=>object.isSkinnedMesh && object.computeBoundingSphere())
+
 	        if (model.mixer && model.mixer._nActiveActions) {
 	          hasAnimation = true;
 	          model.mixer.update(deltaTime);
@@ -91250,6 +91591,7 @@
 	      }); //以后有空的话用frust判断是否在画面内,不在的话即使有动画也不要 update 和 render, 如果paused的话是不是也可以不update
 	      hasAnimation && this.dispatchEvent('content_changed');
 	    }
+	    if (this.IKSolver) this.IKSolver.update();
 
 	    // let vrActive = viewer.renderer.xr.isPresenting;
 	    // if(vrActive){
@@ -91696,8 +92038,8 @@
 	    console.log('加载完毕:', fileInfo_.name, Common$1.getNameFromURL(fileInfo_.url), '耗时(ms)', fileInfo_.loadCostTime /* 模型数据量:' + weight + 'M' */);
 	    if (fileInfo_.fileType == '3dTiles') {
 	      var isGroup = !object.runtime;
-	      var children = object.runtime ? [object] : object.children;
-	      children.forEach(object => {
+	      var _children = object.runtime ? [object] : object.children;
+	      _children.forEach(object => {
 	        var boundingBox_ = new Box3();
 	        var tileset = object.runtime.getTileset();
 
@@ -91910,7 +92252,21 @@
 	          var skeleton = new SkeletonHelper(model);
 	          viewer.scene.scene.add(skeleton);
 	          model.skeletonHelper = skeleton; //注意:不能覆盖model.skeleton,因其另有 */
-	          Potree.Utils.updateVisible(skeleton, 'hide', false); //skeleton.material.opacity = 0.1
+	          if (Potree.settings.isOfficial) {
+	            Potree.Utils.updateVisible(skeleton, 'hide', false);
+	          } else {
+	            skeleton.material.opacity = 0.1;
+	            skeleton.bones.forEach((bone, i) => {
+	              var label = new Potree.TextSprite({
+	                text: "".concat(i, " : ").concat(bone.name),
+	                sizeInfo: {
+	                  width2d: 16000
+	                }
+	              });
+	              label.sprite.material.depthTest = false;
+	              bone.add(label);
+	            });
+	          }
 	          var mixer = new AnimationMixer(model);
 	          model.actions = [];
 	          gltf.animations.forEach(ani => {
@@ -92149,6 +92505,31 @@
 	    });
 	    this.paused = !state;
 	  }
+	  setAniIK(model, object) {
+	    //不知道为什么一加上胳膊一直动啊??
+	    var handIndex = 9;
+	    //model.skeletonHelper.bones[handIndex].attach( object ); //bone可以绑定一个球
+	    var mesh = children[0].children[1]; //vanguard_Mesh
+	    var iks = [{
+	      target: 10,
+	      //大拇指
+	      effector: 9,
+	      // 必须是第一个link的child  手腕
+	      links: [{
+	        index: 8 // 肘关节
+	        /* rotationMin: new THREE.Vector3( 1.2, - 1.8, - .4 ),
+	        rotationMax: new THREE.Vector3( 1.7, - 1.1, .3 ) */
+	      }, {
+	        index: 7 // 肩关节 
+	        /* rotationMin: new THREE.Vector3( 0.1, - 0.7, - 1.8 ),
+	        rotationMax: new THREE.Vector3( 1.1, 0, - 1.4 ) */
+	      }]
+	    }];
+	    var IKSolver = new CCDIKSolver(mesh, iks);
+	    var ccdikhelper = new CCDIKHelper(mesh, iks, 1.5);
+	    viewer.scene.scene.add(ccdikhelper);
+	    viewer.IKSolver = IKSolver;
+	  }
 	  addFire() {
 	    if (Potree.settings.number == 't-CwfhfqJ') {
 	      var position = Potree.Utils.datasetPosTransform({

File diff suppressed because it is too large
+ 1 - 1
public/lib/potree/potree.js.map


+ 2 - 2
src/sdk/cover/index.js

@@ -1511,12 +1511,12 @@ export const enter = ({ dom, mapDom, isLocal, lonlat, scenes, laserRoot, laserOS
                                 setMat(data){//设置帧
                                     //console.log('设置帧',data.scale)
                                     Object.assign(key,getData(data)) 
-                                    update()
+                                    //update() //更新的话会使transformControls打滑,因camFollowObject跟随该物体
                                 }
                             } 
                         },
                         getSupportActions(){
-                            return model.actions.map(e=>e._clip.name)
+                            return  model.actions?.map(e=>e._clip.name)
                         },
                         addAction(frame){// 添加模型动作
                             console.log('addAction',frame)