本地坐标系(局部坐标)
下面的代码
- 创建了一个外部的Box !
- Box 内部添加了一个 Sphere
- 然后把Box添加到Group,最后把Group 添加到场景中!
const group = new THREE.Group()
const parentGeometry = new THREE.BoxGeometry(5,5,5)
const childGeomerty = new THREE.SphereGeometry(1)
const material = new THREE.MeshBasicMaterial({color:0xfff0000, wireframe:true})
const parentMesh = new THREE.Mesh(parentGeometry,material)
const childMesh = new THREE.Mesh(childGeomerty,material)
parentMesh.add(childMesh)
group.add(parentMesh)
scene.add(group)
模型关系!
想了解本地坐标,也就是局部坐标,这个概念其实是相对于其父模型的坐标,如果最外层为scene那么就是最外层的世界坐标
首先先来移动parentMesh
,然后分别看一下parentMesh和childMesh的position属性!
parentMesh.position.x = 3
parentMesh.position.y = 3
parentMesh.position.z = 3
console.log(parentMesh.position) // _Vector3 {x: 3, y: 3, z: 3}
console.log(childMesh.position) // _Vector3 {x: 0, y: 0, z: 0}
可以看到,parent 的坐标是变换后的坐标,因为其外层没有父模型,parentMesh 就存在于世界坐标系中,所以parentMesh的世界坐标就是 _Vector3 {x: 3, y: 3, z: 3}
内部的 childMesh 明显跟着外部的parentMesh同样发生了位移!
但是输出的坐标是_Vector3 {x: 0, y: 0, z: 0}
原点坐标!但是球心明显不是在原点!
那这个其实就是本地坐标!相对于外部parentMesh的局部坐标,他的圆心坐标,相对于parentMesh在parentMesh模型的中心点!所以是 _Vector3 {x: 0, y: 0, z: 0}
那如果我们想得到 childMesh 在世界坐标系的真实坐标的话!应该如何做呢!
是不是自己相对于 parentMesh 的坐标和 parentMesh 中心点的世界坐标进行计算就能算出来呢!
parentMesh此时的中心点坐标是(3,3,3),childMesh的局部坐标是(0,0,0)所以childMesh最终的世界坐标就是(3,3,3)
稍微上点难度,给内部的childMesh也来点位移!
parentMesh.add(childMesh)
parentMesh.position.x = 3
parentMesh.position.y = 3
parentMesh.position.z = 3
childMesh.position.x = -1
childMesh.position.y = -1
childMesh.position.z = -1
那这个其实也很好计算!parentMesh 此时的中心点坐标是(3,3,3),childMesh的局部坐标是(-1,-1,-1)所以childMesh最终的世界坐标就是(2,2,2),先跟着parentMesh三个正方向位移+3,然后相对parentMesh位移 -1
其实ThreeJs 提供了这种情况下计算世界坐标的函数! getWorldPosition
const innerWorldPosition = new THREE.Vector3()
childMesh.getWorldPosition(innerWorldPosition)
console.log(innerWorldPosition)
group.add(parentMesh) //_Vector3 {x: 2, y: 2, z: 2}
结果就是 _Vector3 {x: 2, y: 2, z: 2}
完整代码
import { useEffect } from "react";
import { PerspectiveCamera } from "three";
import * as THREE from "three";
import { AxesHelper } from "three";
import { OrbitControls } from "three/examples/jsm/Addons.js";
const App = () => {
useEffect(() => {
const w = window.innerWidth;
const h = window.innerHeight;
// 场景
const scene = new THREE.Scene();
// 相机
const camera = new PerspectiveCamera(45, w / h, 1, 1000);
camera.position.set(20, 20, 20);
camera.lookAt(0, 0, 0);
// 渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);
// 辅助器
const axesHelper = new AxesHelper(10);
scene.add(axesHelper);
// 控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
controls.dampingFactor = 0.1;
// 动画帧渲染函数
const runRender = () => {
renderer.render(scene, camera);
camera.matrixWorldAutoUpdate = true;
controls.update();
requestAnimationFrame(runRender);
};
const group = new THREE.Group();
const parentGeometry = new THREE.BoxGeometry(5, 5, 5);
const childGeomerty = new THREE.SphereGeometry(1);
const material = new THREE.MeshBasicMaterial({
color: 0xfff0000,
wireframe: true,
});
const parentMesh = new THREE.Mesh(parentGeometry, material);
const childMesh = new THREE.Mesh(childGeomerty, material);
parentMesh.add(childMesh);
parentMesh.position.x = 3;
parentMesh.position.y = 3;
parentMesh.position.z = 3;
childMesh.position.x = -1;
childMesh.position.y = -1;
childMesh.position.z = -1;
const innerWorldPosition = new THREE.Vector3();
childMesh.getWorldPosition(innerWorldPosition);
console.log(innerWorldPosition);
group.add(parentMesh);
scene.add(group);
runRender();
return () => {
document.body.removeChild(renderer.domElement);
};
}, []);
return <></>;
};
export default App;
评论区