目 录CONTENT

文章目录

Threejs 本地坐标系(局部坐标)和世界坐标系的关系

Hello!你好!我是村望~!
2024-02-22 / 0 评论 / 0 点赞 / 618 阅读 / 928 字
温馨提示:
我不想探寻任何东西的意义,我只享受当下思考的快乐~

本地坐标系(局部坐标)

下面的代码

  • 创建了一个外部的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)

模型关系!

image-20240222223444696

想了解本地坐标,也就是局部坐标,这个概念其实是相对于其父模型的坐标,如果最外层为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}
image-20240222223949321

可以看到,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
image-20240222225349561

那这个其实也很好计算!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;

0

评论区