Three.js入门学习笔记11:Three.js-Group组合对象

参考学习
http://www.yanhuangxueyuan.com/doc/Three.js/Group.html
https://blog.csdn.net/ithanmang/article/details/80965712
http://www.yanhuangxueyuan.com/Three.js/
https://www.cnblogs.com/guxingy/p/11956390.html
https://www.cnblogs.com/richardwlee/p/10573663.html

一.概念

以机器人模型说明层级概念,一个整体机器人通过一个组对象Group1,然后一条腿用一个组对象Group2表示,一条腿假设包含大腿和小腿两个网格模型Mesh,则大腿和小腿的两个网格对象可以作为父对象腿Group2的两个子对象,Group2表示的两条腿又可以作为机器人Group1的两个子对象,层级如下
机器人-腿-大腿,小腿 三个层级。

如果跟对象机器人位置变化,腿也会变化。Mesh如果是Group的子对象,则,Mesh会随着Group变化。

Group的基类是Object3D,可以通过Object3D创建一个父对象。建议使用Group作为点,线,网络等模型的父对象。

二.add()和.remove()方法

1.add()
var mesh = new THREE.Mesh();
var group = new THREE.Group();
//将网格模型添加到组中,是group的子对象
group.add(mesh);
//group添加到场景中, group作为场景的子对象
scene.add(group);
//如果有多个可以同时插入多个
group.add(mesh1,mesh2);
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);
2.remove()

场景Scene或组对象Group的.remove()方法使用规则可以查看它们的基类Object3D。

scene.remove(light, group);

只去掉灯光就黑黑的
在这里插入图片描述

三.递归遍历方法.traverse()

可以通过递归遍历的算法去遍历Threejs一个模型对象的所有后代,可以通过下面代码递归遍历上面创建一个机器人模型或者一个外部加载的三维模型。

scene.traverse(function(obj){
if(obj.type === "Group"){
console.log(obj.name);
}
console.log(obj.id);
console.log(obj.parent);
console.log(obj.childeren);
})

四.查找某个模型

// 遍历查找对象的子对象,返回name对应的对象(name是可以重名的,返回第一个)
var nameNode = scene.getObjectByName("leftLeg");
nameNode.material.color.set(0xff0000);
// 遍历查找对象的子对象,并返回id对应的对象
var idNode = scene.getObjectById(4);
console.log(idNode);
例子

设置mesh的名字为“hello”,让名为hello的mesh变绿色

var mesh = new THREE.Mesh(new THREE.CubeGeometry(5, 10, 20), 
            new THREE.MeshLambertMaterial({
                color: 0xffff00
                })
            );
            scene.add(mesh);  
            
            mesh.material = new THREE.MeshLambertMaterial({
                color:0xff0000
                
            });
            
            mesh.position.set(10,10,10);
            mesh.scale.set(0.1,0.1,0.1);
            mesh.rotation.x = 90;
            
            mesh.name = "hello";

            var group = new THREE.Group();
            group.name = "test";
            group.add(mesh);
            scene.add(group);
            
            }
            var nameNode = scene.getObjectByName("hello");
            nameNode.material.color.set(0x00ff00);

五.外部模型拾取时的Group问题

参考:
https://blog.csdn.net/ithanmang/article/details/80965712

在解析外部模型例如 obj模型的时候我们经常会发现、匿名函数中的加载解析后的参数object是一个Group,或者当前我们加载外部模型obj为例,然后通过Raycaster射线拾取数组的时候对象,当传递进去是scene.children发现并不会选中模型,但我们自己创建一些简单的模型会被选中。
这是因为,加载的外部模型会是在一个Group组对象中,如果直接scene.children是无法获取的,我们自己创建的模型并没有放进Group中,是属于scene.children的,所以可以获取到。 例如我们加载一个obj模型,看下他的children属性。
页面加载后的Scene对象

在这里插入图片描述
children是一个数组类型,有三个元素,两个灯光,一个Group对象,其中Group对象中的数据就是obj模型。

例子
var geometry = new THREE.BoxBufferGeometry( 1, 1, 1 );
var material = new THREE.MeshBasicMaterial( {color: 0x00ff00} );

var cubeA = new THREE.Mesh( geometry, material );
cubeA.position.set( 100, 100, 0 );

var cubeB = new THREE.Mesh( geometry, material );
cubeB.position.set( -100, -100, 0 );

//创建一个组对象,添加两个立方体
//作为一个组对象这些立方体对象可以被旋转、缩放、等等... 
var group = new THREE.Group();
group.add( cubeA );
group.add( cubeB );

scene.add( group );
构造函数

这里没看明白

function Group() {

	Object3D.call( this );
	
	this.type = 'Group';

}

Group.prototype = Object.assign( Object.create( Object3D.prototype ), {

	constructor: Group,

	isGroup: true

} );

参考Object3D对象中的,公共方法。
.type string返回对象的类型。

问题待解决
如何使用Raycaster拾取到Group对象

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在三维空间中,一条直线可以由两个点确定。我们可以使用 `THREE.Line` 来定义一条直线,并将其添加到场景中。 ```javascript // 创建两个点 var point1 = new THREE.Vector3(-5, 0, 0); var point2 = new THREE.Vector3(5, 0, 0); // 创建直线 var geometry = new THREE.Geometry(); geometry.vertices.push(point1, point2); var material = new THREE.LineBasicMaterial({ color: 0xff0000 }); var line = new THREE.Line(geometry, material); // 将直线添加到场景中 scene.add(line); ``` 上述代码创建了一条以两个点 `-5, 0, 0` 和 `5, 0, 0` 为端点的红色直线,并将其添加到场景中。 如果你想让这条直线在场景中保持不变,不会随着相机的移动而移动,可以将其添加到场景的静态物体中。 ```javascript var staticObject = new THREE.Object3D(); staticObject.add(line); scene.add(staticObject); ``` 这样,当相机移动时,这条直线将保持不变。 当然,你也可以在直线上加入一些动画效果,让它动起来。你可以通过设置直线的顶点坐标来使其运动。以下是一个简单的例子: ```javascript function animate() { requestAnimationFrame(animate); // 使直线的第二个点沿着 y 轴移动 line.geometry.vertices[1].y += 0.1; line.geometry.verticesNeedUpdate = true; renderer.render(scene, camera); } ``` 上述代码中,`animate` 函数每帧调用一次,使直线的第二个点沿着 y 轴移动了 `0.1` 的距离。`verticesNeedUpdate` 标记告诉 three.js 更新直线的顶点坐标。 希望这些能帮助你入门 three.js 中的直线绘制。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值