Three.js - 绑定两个形状合为一体? [英] Three.js - bind two shapes together as one?

查看:1774
本文介绍了Three.js - 绑定两个形状合为一体?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的three.js世界...... 我的问题是:我可以绑定到形状合为一体的形状? 例如,结合球和圆筒一起作为一个?

I'm new to the three.js world... My question is: Can I bind to shapes together as one shape? for example binding sphere and cylinder together as one?

推荐答案

样的,是的,可以有多种选择:

Kind of, yes, there are multiple options:

  1. 在通过层次您可以简单地添加一个网到另一个使用添加()功能
  2. 通过GeometryUtil的合并()功能合并顶点和两个网格几何对象到一个
  3. 在使用支持网格和出口之间的布尔运算一个基本的3D编辑器。
  1. via hierarchy You can simply add one mesh to another using the add() function
  2. via GeometryUtil's merge() function to merge vertices and meshes of two Geometry objects into one
  3. using a basic 3D editor that supports Boolean operations between meshes and exporting.

方法1是pretty的直截了当:

Method 1 is pretty straight forward:

var sphere = new THREE.Mesh( new THREE.SphereGeometry(100,16,12),new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
                var cylinder = new THREE.Mesh(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ),new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
                cylinder.position.y = -100;
                scene.add(sphere);
                scene.add(cylinder);

请注意,16是重复的,所以细分水平在一个网格相匹配的其他(一个体面的样子)

Notice that 16 is repeated, so the subdivisions level in one mesh matches the other (for a decent look)

2.1的方法 - 通过GeometryUtils

Method 2.1 - via GeometryUtils

//make a sphere
                var sg = new THREE.SphereGeometry(100,16,12);
                //make cylinder - ideally the segmentation would be similar to predictable results
                var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false );
                //move vertices down for cylinder, so it maches half the sphere - offset pivot
                for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100;
                //merge meshes
                THREE.GeometryUtils.merge(sg,cg);
                var mesh = new THREE.Mesh( sg,new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ));
                scene.add(mesh);

方法2.2合并一个车床半球,并圆筒:

var pts = [];//points array
                var detail = .1;//half-circle detail - how many angle increments will be used to generate points
                var radius = 100;//radius for half_sphere
                var total = Math.PI * .51;
                for(var angle = 0.0; angle < total ; angle+= detail)//loop from 0.0 radians to PI (0 - 180 degrees)
                    pts.push(new THREE.Vector3(0,Math.cos(angle) * radius,Math.sin(angle) * radius));//angle/radius to x,z
                var lathe = new THREE.LatheGeometry( pts, 16 );//create the lathe with 12 radial repetitions of the profile
                //rotate vertices in lathe geometry by 90 degrees
                var rx90 = new THREE.Matrix4();
                rx90.setRotationFromEuler(new THREE.Vector3(-Math.PI * .5,0,0));
                lathe.applyMatrix(rx90);
                //make cylinder - ideally the segmentation would be similar for predictable results
                var cg = new THREE.CylinderGeometry(100, 100, 200, 16, 4, false );
                //move vertices down for cylinder, so it maches half the sphere
                for(var i = 0 ; i < cg.vertices.length; i++) cg.vertices[i].position.y -= 100;
                //merge meshes
                THREE.GeometryUtils.merge(lathe,cg);
                var mesh = new THREE.Mesh( lathe, new THREE.MeshLambertMaterial( { color: 0x2D303D, wireframe: true, shading: THREE.FlatShading } ) );
                mesh.position.y = 150;
                scene.add(mesh);

有一个问题,我不能满足的时刻来自于那些网格内的面孔。理想的情况是那些本来法线翻转,这样他们就不会呈现,但还没有找到一个快速的解决方案。

The one problem I can't address at the moment comes from the faces that are inside the mesh. Ideally those would have normals flipped so they wouldn't render, but haven't found a quick solution for that.

第三是相当简单的。大多数3D封装允许在网格布尔运算(例如合并两个网格连同ADD操作(米沙+ meshB))。尝试创建一个圆柱体,并在搅拌机(免费,开源)的球体,它已经具备了的three.js 出口国。另外,您可以从您的3D编辑器或选择导出合并网格的obj文件,并使用<一个href="https://github.com/mrdoob/three.js/blob/master/utils/exporters/convert_obj_three.py#L1">convert_obj_three脚本。

The 3rd is fairly straight forward. Most 3D packages allow Boolean operation on meshes (e.g. merging two meshes together with the ADD operation (meshA + meshB)). Try creating a cylinder and a sphere in Blender(free, opensource), which already has a three.js exporter. Alternatively you can export an .obj file of the merged meshes from your 3d editor or choice and use the convert_obj_three script.

更新

我找到了另一种方法,它可能是更容易/更直观。还记得我上面提到的布尔运算?

I've found yet another method, which might be easier/more intuitive. Remember the boolean operations I've mentioned above ?

原来有一个真棒JS库就是为了这一点:构造实体几何

Turns out there is an awesome js library just for that: Constructive Solid Geometry:

钱德勒普劳尔写了一些方便的功能来连接 CSG与three.js 。因此,与南玻库和 three.js包装它,你可以简单地这样做:

Chandler Prall wrote some handy functions to connect CSG with three.js. So with the CSG library and the three.js wrapper for it, you can simply do this:

var cylinder = THREE.CSG.toCSG(new THREE.CylinderGeometry(100, 100, 200, 16, 4, false ),new THREE.Vector3(0,-100,0));
var sphere   = THREE.CSG.toCSG(new THREE.SphereGeometry(100,16,12));
var geometry = cylinder.union(sphere);
var mesh     = new THREE.Mesh(THREE.CSG.fromCSG( geometry ),new THREE.MeshNormalMaterial());

它给你一个不错的结果(没有问题,多余的脸/翻转法线的/ etc。):

Which gives you a nice result(no problems with extra faces/flipping normals/etc.):

这篇关于Three.js - 绑定两个形状合为一体?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆