three.js之组对象

文章目录

专栏目录请点击

简介

层级模型就是一个树的结构,他有一个组的概念,对于组我们可以进行旋转、平移等操作,那么组内的物体也会进行同样的操作,我们可以看下面的例子

例子

DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <style>
    body {
      margin: 0;
      overflow: hidden;

    }
  style>

  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js">script>

  <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js">script>
head>

<body>
  <script>

    var scene = new THREE.Scene();

    var geometry = new THREE.BoxGeometry(20, 20, 20);
    var material = new THREE.MeshLambertMaterial({ color: 0x0000ff });
    var mesh1 = new THREE.Mesh(geometry, material);
    var mesh2 = new THREE.Mesh(geometry, material);
    mesh2.translateX(25);

    var group = new THREE.Group();

    group.add(mesh1);
    group.add(mesh2);

    scene.add(group);

    group.translateY(100);

    var axesHelper = new THREE.AxesHelper(200);
    scene.add(axesHelper);

    var point = new THREE.PointLight(0xffffff);
    point.position.set(400, 200, 300);
    scene.add(point);

    var ambient = new THREE.AmbientLight(0x444444);
    scene.add(ambient);

    var width = window.innerWidth;
    var height = window.innerHeight;
    var k = width / height;
    var s = 150;

    var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
    camera.position.set(200, 300, 200);
    camera.lookAt(scene.position);

    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(width, height);
    renderer.setClearColor(0xb9d3ff, 1);
    document.body.appendChild(renderer.domElement);

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

    var controls = new THREE.OrbitControls(camera, renderer.domElement);

    controls.addEventListener('change', render);
  script>
body>

html>

渲染出来的效果如下

three.js之组对象

查看组对象


console.log(group.children);

three.js之组对象

当然,我们还可以查看场景的结构

console.log(scene.children);

three.js之组对象

组对象相关方法

add

group.add(mesh1);
group.add(mesh2);

group.add(mesh1,mesh2);

当前的add方式是继承自 Object3D,像场景 Secne、网络模型 Mesh、光源对象 Light的add方法都是继承的

remove

同样remove方法也是继承自 Object3D,他会删除父对象中的一个子对象,如下

group.remove(mesh1);
scene.remove(light,group);

层级模型节点命名、查找、遍历

模型命名

一般我们可以通过name属性进行命名,如下

group.add(Mesh)

Mesh.name = "眼睛"

group.name = "头"

例子

一个简单的机器人模型

DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <style>
        body {
            margin: 0;
            overflow: hidden;

        }
    style>

    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js">script>

    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js">script>
head>

<body>
    <script>

        var scene = new THREE.Scene();

        var headMesh = sphereMesh(10, 0, 0, 0);
        headMesh.name = "脑壳"
        var leftEyeMesh = sphereMesh(1, 8, 5, 4);
        leftEyeMesh.name = "左眼"
        var rightEyeMesh = sphereMesh(1, 8, 5, -4);
        rightEyeMesh.name = "右眼"
        var headGroup = new THREE.Group();
        headGroup.name = "头部"
        headGroup.add(headMesh, leftEyeMesh, rightEyeMesh);

        var neckMesh = cylinderMesh(3, 10, 0, -15, 0);
        neckMesh.name = "脖子"
        var bodyMesh = cylinderMesh(14, 30, 0, -35, 0);
        bodyMesh.name = "腹部"
        var leftLegMesh = cylinderMesh(4, 60, 0, -80, -7);
        leftLegMesh.name = "左腿"
        var rightLegMesh = cylinderMesh(4, 60, 0, -80, 7);
        rightLegMesh.name = "右腿"
        var legGroup = new THREE.Group();
        legGroup.name = "腿"
        legGroup.add(leftLegMesh, rightLegMesh);
        var bodyGroup = new THREE.Group();
        bodyGroup.name = "身体"
        bodyGroup.add(neckMesh, bodyMesh, legGroup);

        var personGroup = new THREE.Group();
        personGroup.name = "人"
        personGroup.add(headGroup, bodyGroup)
        personGroup.translateY(50)
        scene.add(personGroup);

        function sphereMesh(R, x, y, z) {
            var geometry = new THREE.SphereGeometry(R, 25, 25);
            var material = new THREE.MeshPhongMaterial({
                color: 0x0000ff
            });
            var mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(x, y, z);
            return mesh;
        }

        function cylinderMesh(R, h, x, y, z) {
            var geometry = new THREE.CylinderGeometry(R, R, h, 25, 25);
            var material = new THREE.MeshPhongMaterial({
                color: 0x0000ff
            });
            var mesh = new THREE.Mesh(geometry, material);
            mesh.position.set(x, y, z);
            return mesh;
        }

        var axesHelper = new THREE.AxesHelper(200);
        scene.add(axesHelper);

        var point = new THREE.PointLight(0xffffff);
        point.position.set(400, 200, 300);
        scene.add(point);

        var ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);

        var width = window.innerWidth;
        var height = window.innerHeight;
        var k = width / height;
        var s = 100;

        var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
        camera.position.set(200, 300, 200);
        camera.lookAt(scene.position);

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);

        document.body.appendChild(renderer.domElement);

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

        var controls = new THREE.OrbitControls(camera, renderer.domElement);

        controls.addEventListener('change', render);
    script>
body>

html>

渲染出来的结果如下

three.js之组对象

遍历

我们进行遍历的时候一般使用 traverse方法,也可以遍历外部加载的三维模型

scene.traverse(function (obj) {
    if (obj.type === "Group") {
      console.log(obj.name);
    }
    if (obj.type === "Mesh") {
      console.log('  ' + obj.name);
      obj.material.color.set(0xffff00);
    }
    if (obj.name === "左眼" | obj.name === "右眼") {
      obj.material.color.set(0x000000)
    }

    console.log(obj.id);

    console.log(obj.parent);

    console.log(obj.children);
})

最终的打印

three.js之组对象

查找

如果想要获取相应的模型,就要获取threejs的相应的获取方法,比如

  • getObjectById
  • getObjectByName

这些类似于前端获取DOM的方法,关于查找的更多的方法,我们可以查看官网


var nameNode = scene.getObjectByName ( "左腿" );
nameNode.material.color.set(0xff0000);
console.log(nameNode);

var idNode = scene.getObjectById ( 4 );
console.log(idNode);

打印如下

three.js之组对象

本地坐标与世界坐标

例子

DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <style>
        body {
            margin: 0;
            overflow: hidden;

        }
    style>

    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/build/three.js">script>

    <script src="http://www.yanhuangxueyuan.com/versions/threejsR92/examples/js/controls/OrbitControls.js">script>
head>

<body>
    <script>

        var scene = new THREE.Scene();

        var geometry = new THREE.BoxGeometry(20, 20, 20);
        var material = new THREE.MeshLambertMaterial({
            color: 0x0000ff
        });
        var mesh = new THREE.Mesh(geometry, material);
        mesh.position.set(50, 0, 0)
        var group = new THREE.Group();
        group.add(mesh);
        group.position.set(50, 0, 0)
        scene.add(group);

        scene.updateMatrixWorld(true);
        var worldPosition = new THREE.Vector3();
        mesh.getWorldPosition(worldPosition)
        console.log('世界坐标', worldPosition);
        console.log('本地坐标', mesh.position);

        var axesHelper = new THREE.AxesHelper(200);
        scene.add(axesHelper);

        var point = new THREE.PointLight(0xffffff);
        point.position.set(400, 200, 300);
        scene.add(point);

        var ambient = new THREE.AmbientLight(0x444444);
        scene.add(ambient);

        var width = window.innerWidth;
        var height = window.innerHeight;
        var k = width / height;
        var s = 150;

        var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
        camera.position.set(200, 300, 200);
        camera.lookAt(scene.position);

        var renderer = new THREE.WebGLRenderer();
        renderer.setSize(width, height);
        renderer.setClearColor(0xb9d3ff, 1);
        document.body.appendChild(renderer.domElement);

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

        var controls = new THREE.OrbitControls(camera, renderer.domElement);

        controls.addEventListener('change', render);
    script>
body>

html>

渲染后的效果如下

three.js之组对象
然后我们看看打印
three.js之组对象

本地坐标

我们会发现本地坐标是物体自己的设置的坐标,或者说物体相对于父对象设置的坐标,模型对象的 position就是模型的本地坐标

世界坐标

  • 我们观察上面的打印,就会发现世界坐标是组的坐标加上模型的本地坐标
  • 说白了世界坐标就是以场景建立的坐标系为最终坐标系出现的坐标

缩放系数

缩放属性 scale,也分为局部缩放(本地缩放),通过 getWorldScale可以获取一个模型的世界缩放系数,除此之外,还有本地矩阵 materix和世界矩阵 matrixWorld,都是相同的道理

Original: https://blog.csdn.net/youhebuke225/article/details/128268049
Author: youhebuke225
Title: three.js之组对象

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/723001/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球