在three.js所一组补间旋转,但其重置为原来的起始位置上按下鼠标

问题描述 投票:1回答:1

我想在补间一three.js所组的旋转,我可以让它转动,但每当你尝试再次旋转组从原来的起始位置复原。我相信它的一个简单的办法,但我无法找到它。任何帮助,将不胜感激。

这里是我的小提琴链接:https://jsfiddle.net/jacob_truax/bw3pmLk1/59/

下面是我为补间实现的代码。

  let isMouseDown = false
  let startX = 0
  let startY = 0

  document.addEventListener("mousedown", function () {
    isMouseDown = true
    startX = event.pageX
    startY = event.pageY
    document.body.style.cursor = 'grabbing';
  })

  document.addEventListener("mouseup", function () {
    isMouseDown = false
    document.body.style.cursor = 'grab';
  })

  document.addEventListener("mousemove", function (event) {
    if (isMouseDown) {
      document.body.style.cursor = 'grabbing'
    }

    aimX = ((window.innerWidth / 2) - event.pageX) * 0.35
    aimY = ((window.innerHeight / 2) - event.pageY) * 0.5


    if(isMouseDown) {
      aimX = aimX + (event.pageX - startX)
      aimY = aimY + (event.pageY - startY)
      group.rotation.set(0, ((aimX + (event.pageX - startX)) + (aimY 
+ (event.pageY - startY))) / 900, 0)
    }
  })
javascript three.js tween
1个回答
1
投票

当鼠标被拖动,则该组已经转动,并且.rotation被设定为一定的值。 THREE.Euler.set()将cancelate当前旋转,并设置一个完全新的一个。这导致旋转复位到其原来的方向。 新的旋转已被应用到现有的旋转。一种常见的方法是计算新的旋转的旋转矩阵。然后,应用新的旋转,以当前矩阵。其结果是,其具有要被设置到组的旋转。

rotation = new_rotation * current_rotation

在three.js所的.rotationTHREE.Euler对象 - 见Euler anglesMatrix4.makeRotationFromEuler可以形式欧拉角转换为4×4的旋转矩阵。 与Matrix4.multiplyMatrices,2点矩阵可以被级联。 而Euler.setFromRotationMatrix可以转换一个4x4的旋转矩阵欧拉角

从获得该组的当前旋转矩阵:

let currentRotation = new THREE.Matrix4();
currentRotation.makeRotationFromEuler(group.rotation);

安装程序与由欧拉新旋转分量的旋转矩阵角:

let newEuler = new THREE.Euler(0, (event.pageX - startX) / 900, 0);
let newRotation = new THREE.Matrix4();
newRotation.makeRotationFromEuler(newEuler);

应用新的旋转,以当前的旋转:

let finalRotation = new THREE.Matrix4();
finalRotation.multiplyMatrices(newRotation, currentRotation);

设置最终和关联旋转到组

group.rotation.setFromRotationMatrix(finalRotation); 

由于旋转被施加到该组,并且startXstartY被设置为当前鼠标位置:

startX = event.pageX;
startY = event.pageY;

最后的“鼠标移动”事件:

document.addEventListener("mousemove", function (event) {
    if (isMouseDown) {
        document.body.style.cursor = 'grabbing'
    }

    if(isMouseDown) {

        let currentRotation = new THREE.Matrix4();
        currentRotation.makeRotationFromEuler(group.rotation);

        let newEuler = new THREE.Euler(0, (event.pageX - startX) / 900, 0);
        let newRotation = new THREE.Matrix4();
        newRotation.makeRotationFromEuler(newEuler);

        let finalRotation = new THREE.Matrix4();
        finalRotation.multiplyMatrices(newRotation, currentRotation);

        group.rotation.setFromRotationMatrix(finalRotation); 

        startX = event.pageX;
        startY = event.pageY;
    }
})

我申请的建议,你的原代码。见例如:

doThree = function () {
  console.clear();

  const renderer = new THREE.WebGLRenderer({
    anitalias: true
  })
  renderer.setSize(window.innerWidth, window.innerHeight)
  renderer.setPixelRatio(window.devicePixelRatio)
  renderer.setClearColor(0x000000, 1)
  const section = document.getElementById('container');
  section.appendChild(renderer.domElement)

  // Scene -------------------------------------------------------
  const scene = new THREE.Scene()
  scene.fog = new THREE.FogExp2(0x000000, 0.00034)

  // Light -------------------------------------------------------
  const light = new THREE.AmbientLight(0xcccccc)
  scene.add(light)

  //const light2 = new THREE.PointLight(0xcccccc, .75, 0)
  const light2 = new THREE.DirectionalLight(0xffffff, 0.5)
  light2.position.set(-1000, 0, -3000)
  scene.add(light2)

  const light3 = new THREE.DirectionalLight(0xffffff, 0.5)
  light3.position.set(1000, 0, -3000)
  scene.add(light3)


  // Camera ------------------------------------------------------
  const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 10000)

  camera.position.z = -2500


  // Texture Loader ----------------------------------------------
  const loader = new THREE.TextureLoader()


  // Shapes ------------------------------------------------------
  var mirrorCube, mirrorCubeCamera; // for mirror material
  var mirrorSphere, mirrorSphereCamera; // for mirror material

  function init () {
  var cubeGeom = new THREE.PlaneGeometry(10000, 12000, 120);
  	mirrorCubeCamera = new THREE.CubeCamera( 0.1, 10000, 1080 );
    mirrorCubeCamera.position.set(0, 1500, 05)

  	scene.add( mirrorCubeCamera );
  	var mirrorCubeMaterial = new THREE.MeshBasicMaterial( { envMap: mirrorCubeCamera.renderTarget.texture } );
  	mirrorCube = new THREE.Mesh( cubeGeom, mirrorCubeMaterial );
  	mirrorCube.position.set(0, -550, -1000)
    mirrorCube.rotation.x = -90 * Math.PI / 180;
  	scene.add(mirrorCube);

    }

  init()

  const createFNUP = function (color, x, y, z) {
    const geometry = new THREE.PlaneGeometry( 943, 512, 120)

    const material = new THREE.MeshPhongMaterial({
      color: color,
      specular: 0x111111,
      shininess: 0,
      side: THREE.DoubleSide,
      transparent: true,
    })


    const mesh = new THREE.Mesh(geometry, material)

    mesh.position.set(x,y,z)

    scene.add(mesh)
    return mesh
  }

  const addFloor = function (color) {
    const geometry = new THREE.PlaneGeometry(10000, 10000, 120)
    const material = new THREE.MeshPhongMaterial({
      color: color,
      side: THREE.DoubleSide
    })
    const mesh = new THREE.Mesh(geometry, material)

    scene.add(mesh)

    return mesh
  }


  // Adding Shapes -----------------------------------------------
  const fnup = createFNUP(0xffffff, 1100, 50, 0)

  const old = createFNUP(0xff0000, -1100, 50, 0)

  const cam = createFNUP(0x00ff00, 0, -100, 1000)
 
  const alex = createFNUP(0x0000ff, -0, 200, -1000)

  const roof = addFloor(0x232323)
  roof.position.z = 2000


  const group = new THREE.Group()
  group.add(fnup, old, cam, alex)
  scene.add(group)


  // Holding Camera Position for tweening ------------------------
  let currentX = 0
  let currentY = 0
  let aimX = 0
  let aimY = 0
  let aimX2 = 0
  let aimY2 = 0

  // Holding data about the shapes
  const shapes = []

  // Animate -----------------------------------------------------
let oldRotate = true
let camRotate = true
let groupRotate = true
let fnupPosition = true
let projectHov = true

  function animate() {
    const diffX = aimX - currentX
    const diffY = aimY - currentY
    const diffX2 = aimX2 - currentX
    const diffY2 = aimY2 - currentY

    currentX = currentX + diffX * 0.1
    currentY = currentY + diffY * 0.1

    camera.position.x = currentX
    camera.position.y = currentY

    group.rotateY(0.003)
  
    camera.lookAt(scene.position)

    mirrorCubeCamera.lookAt(scene.position)

    mirrorCube.visible = false;
  	mirrorCubeCamera.update( renderer, scene );
  	mirrorCube.visible = true;


    renderer.render(scene, camera)

    requestAnimationFrame(animate)

  }

  animate ()

  // Variables  ---------------------------------------------------
  let isMouseDown = false
  let startX = 0
  let startY = 0


// Functions  ---------------------------------------------------
  document.addEventListener("mousedown", function () {
    isMouseDown = true
    startX = event.pageX
    startY = event.pageY
    document.body.style.cursor = 'grabbing';
  })

  document.addEventListener("mouseup", function () {
    isMouseDown = false
    document.body.style.cursor = 'grab';
  })

    document.addEventListener("mousemove", function (event) {
        if (isMouseDown) {
            document.body.style.cursor = 'grabbing'
        }

        if(isMouseDown) {
          
            let currentRotation = new THREE.Matrix4();
            currentRotation.makeRotationFromEuler(group.rotation);

            let newEuler = new THREE.Euler(0, (event.pageX - startX) / 900, 0);
            let newRotation = new THREE.Matrix4();
            newRotation.makeRotationFromEuler(newEuler);
            
            let finalRotation = new THREE.Matrix4();
            finalRotation.multiplyMatrices(newRotation, currentRotation);
            
            group.rotation.setFromRotationMatrix(finalRotation); 
            
            startX = event.pageX;
            startY = event.pageY;
        }
    })

  window.addEventListener("resize", function () {
    camera.aspect = window.innerWidth / window.innerHeight
    camera.updateProjectionMatrix()
    renderer.setSize(window.innerWidth, window.innerHeight)
  })


}

doThree()
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tween.js/17.2.0/Tween.js"></script>
<div id="container"></div>
© www.soinside.com 2019 - 2024. All rights reserved.