根据标准化的相机位置、向上和方向旋转 3D 对象
Rotate 3D object based on normalized camera position, up, and direction
我在我们的网站上有显示 3D 模型的第 3 方工具。我必须构建一个 cube
来控制这个 3D 查看器的相机。
像这样:
这个立方体应该根据观察者的相机旋转。
相机具有以下功能:
camera.getPosition()
camera.getDirection()
camera.getUp()
返回值如下所示:
camera.getPosition: {"x":-0.14815343916416168,"y":0.10964569449424744,"z":0.0968131348490715}
camera.getDirection: {"x":0.7116152048110962,"y":-0.5266535878181458,"z":-0.46501585841178894}
camera.getUp: {"x":0.38310256600379944,"y":0.8456945419311523,"z":-0.3715282082557678}
如何使用这些值计算立方体的旋转? (如果可能的话)
我的解决方案最终是这样的:
// http://www.fundza.com/vectors/normalize/index.html
const normalize = ({ x, y, z }) => {
const length = Math.sqrt(x * x + y * y + z * z)
return {
x: x / length,
y: y / length,
z: z / length
}
}
// https://mathjs.org/docs/reference/functions/cross.html
const cross = ({ x: a1, y: a2, z: a3 }, { x: b1, y: b2, z: b3 }) => ({
x: a2 * b3 - a3 * b2,
y: a3 * b1 - a1 * b3,
z: a1 * b2 - a2 * b1
})
const calculateRotation = (direction, up) => {
const right = normalize(cross(direction, up))
const matrix = [[right.x, right.y, right.z], [direction.x, direction.y, direction.z], [up.x, up.y, up.z]]
const angle = Math.acos((matrix[0][0] + matrix[1][1] + matrix[2][2] - 1) * 0.5)
const axis = (() => {
const k = Math.sqrt(
Math.pow(matrix[2][1] - matrix[1][2], 2) +
Math.pow(matrix[0][2] - matrix[2][0], 2) +
Math.pow(matrix[1][0] - matrix[0][1], 2)
)
return {
x: (matrix[2][1] - matrix[1][2]) / k,
y: (matrix[0][2] - matrix[2][0]) / k,
z: (matrix[1][0] - matrix[0][1]) / k
}
})()
return { angle, axis }
}
然后你可以旋转:
cubeGroup.setRotationFromAxisAngle(rotation.axis, rotation.angle)
而且我还必须旋转相机,这对于其他情况可能是可选的:
camera.rotateX(Math.PI / 2)
我在我们的网站上有显示 3D 模型的第 3 方工具。我必须构建一个 cube
来控制这个 3D 查看器的相机。
像这样:
这个立方体应该根据观察者的相机旋转。 相机具有以下功能:
camera.getPosition()
camera.getDirection()
camera.getUp()
返回值如下所示:
camera.getPosition: {"x":-0.14815343916416168,"y":0.10964569449424744,"z":0.0968131348490715}
camera.getDirection: {"x":0.7116152048110962,"y":-0.5266535878181458,"z":-0.46501585841178894}
camera.getUp: {"x":0.38310256600379944,"y":0.8456945419311523,"z":-0.3715282082557678}
如何使用这些值计算立方体的旋转? (如果可能的话)
我的解决方案最终是这样的:
// http://www.fundza.com/vectors/normalize/index.html
const normalize = ({ x, y, z }) => {
const length = Math.sqrt(x * x + y * y + z * z)
return {
x: x / length,
y: y / length,
z: z / length
}
}
// https://mathjs.org/docs/reference/functions/cross.html
const cross = ({ x: a1, y: a2, z: a3 }, { x: b1, y: b2, z: b3 }) => ({
x: a2 * b3 - a3 * b2,
y: a3 * b1 - a1 * b3,
z: a1 * b2 - a2 * b1
})
const calculateRotation = (direction, up) => {
const right = normalize(cross(direction, up))
const matrix = [[right.x, right.y, right.z], [direction.x, direction.y, direction.z], [up.x, up.y, up.z]]
const angle = Math.acos((matrix[0][0] + matrix[1][1] + matrix[2][2] - 1) * 0.5)
const axis = (() => {
const k = Math.sqrt(
Math.pow(matrix[2][1] - matrix[1][2], 2) +
Math.pow(matrix[0][2] - matrix[2][0], 2) +
Math.pow(matrix[1][0] - matrix[0][1], 2)
)
return {
x: (matrix[2][1] - matrix[1][2]) / k,
y: (matrix[0][2] - matrix[2][0]) / k,
z: (matrix[1][0] - matrix[0][1]) / k
}
})()
return { angle, axis }
}
然后你可以旋转:
cubeGroup.setRotationFromAxisAngle(rotation.axis, rotation.angle)
而且我还必须旋转相机,这对于其他情况可能是可选的:
camera.rotateX(Math.PI / 2)