我有两张卡片,我需要设置卡片开口的动画。因此,因此,我需要将卡的前部围绕该片的最左点而不是中心旋转,获取代码以“围绕某点旋转”会产生较差的结果:
//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
}
我可以采取其他替代方法来解决此问题吗?
答案 0 :(得分: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;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/106/three.min.js"></script>