【问题标题】:THREE.js rotate object vertex by vertexTHREE.js 逐顶点旋转对象
【发布时间】:2019-07-26 22:58:52
【问题描述】:

我有一张卡片的两半,我需要为卡片的开口设置动画。因此,我需要围绕该部分的最左边而不是中心旋转卡片的正面,获取“围绕一个点旋转”的代码会产生糟糕的结果:

//geometry for each half
var geometry1 = new THREE.PlaneGeometry( 10, 15 );
//rotation, offset by half width
...
  else if (e.keyCode == '87'){
        openAng+=0.1;
        rotCusAxis(card, new THREE.Vector3( -5, 0, 0 ),new THREE.Vector3(0,1,0),openAng,false);
        }

...
function rotCusAxis(obj, point, axis, theta, pointIsWorld){
    pointIsWorld = (pointIsWorld === undefined)? false : pointIsWorld;

    if(pointIsWorld){
        obj.parent.localToWorld(obj.position); // compensate for world coordinate
    }

    obj.position.sub(point); // remove the offset
    obj.position.applyAxisAngle(axis, theta); // rotate the POSITION
    obj.position.add(point); // re-add the offset

    if(pointIsWorld){
        obj.parent.worldToLocal(obj.position); // undo world coordinates compensation
    }

    obj.rotateOnAxis(axis, theta); // rotate the OBJECT
}

我可以用什么替代方法来解决这个问题?

【问题讨论】:

  • 不清楚你想如何展开卡片,但我假设它不是这样的examples,是吗?
  • 不,这是两个 THREE.PlaneGeometry 类型的 THREE.Mesh。我正在尝试 var x = Math.cos(rot)*(width/2); var z = Math.cos(rot)*(width/2); card.applyMatrix(new THREE.Matrix4().makeTranslation(-x, 0, -z)); card.applyMatrix(new THREE.Matrix4().makeRotationY(openAng)); card.applyMatrix(new THREE.Matrix4().makeTranslation(x, 0, z));但它只是围绕一个圆圈旋转它,我知道它会但认为它看起来会正确(即两个卡片的一半看起来仍然相连)

标签: javascript three.js


【解决方案1】:

你在正确的轨道上。 “减去,旋转,添加”模式是正确的。但是three.js 提供了一些很好的便利功能,使执行这些任务变得更加容易。

欲了解更多信息,请查看此答案:Three JS Pivot point

const W = window.innerWidth
const H = window.innerHeight

const renderer = new THREE.WebGLRenderer({
  antialias: true
})
renderer.setSize(W, H)
renderer.setClearColor(0xfafafa)

document.body.appendChild(renderer.domElement)

const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(28, W / H, 50, 150)
camera.position.set(0, 25, 100)
camera.lookAt(scene.position)
scene.add(camera)

const light = new THREE.DirectionalLight(0xffffff, 1)
light.position.z = -1
camera.add(light)

const cardGeo = new THREE.PlaneBufferGeometry(15, 25)
const leftMat = new THREE.MeshLambertMaterial({
  color: "orange",
  side: THREE.DoubleSide
})
const rightMat = new THREE.MeshLambertMaterial({
  color: "blue",
  side: THREE.DoubleSide
})

const left = new THREE.Mesh(cardGeo, leftMat)
left.position.x = -7.5

const right = new THREE.Mesh(cardGeo, rightMat)
right.position.x = 7.5

scene.add(left)
scene.add(right)

function render() {
  renderer.render(scene, camera)
}

const rotateCard = (function(){
  const hingeAxis = new THREE.Vector3(0, 1, 0)
  let angle = 0
  let direction = 1
  let motion = 0
  return function(){
    // For me, the pivot point is at the origin.
    // See https://stackoverflow.com/questions/42812861/three-js-pivot-point/42866733#42866733
    // for non-origin pivot points
    motion = 0.025 * direction
    left.position.applyAxisAngle(hingeAxis, motion) // rotate position
    left.rotateOnAxis(hingeAxis, motion) // rotate object
    if(angle + motion <= 0 || angle + motion >= Math.PI){
      direction *= -1
    }
    angle += motion
  }
})()

const axis = new THREE.Vector3(0, 1, 0)
function animate(){
  requestAnimationFrame(animate)
  camera.position.applyAxisAngle( axis, 0.005 )
	camera.lookAt( scene.position )
  rotateCard()
  render()
}
animate()
html,
body {
  margin: 0;
  padding: 0;
}
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.min.js"&gt;&lt;/script&gt;

【讨论】:

    猜你喜欢
    • 2013-08-06
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2020-06-19
    • 2019-10-18
    • 2015-01-06
    • 2013-06-17
    • 2017-07-14
    相关资源
    最近更新 更多