首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用three.js r71合并两个几何图形或网格?

如何使用three.js r71合并两个几何图形或网格?
EN

Stack Overflow用户
提问于 2015-05-15 03:44:09
回答 3查看 42.7K关注 0票数 32

在这里,我遇到了问题,因为我需要将两个几何图形(或网格)合并为一个。使用早期版本的three.js有一个很好的函数:

代码语言:javascript
运行
复制
THREE.GeometryUtils.merge(pendulum, ball);

然而,它不再在新版本中。

我尝试用以下代码合并pendulumball

ball是一个网格。

代码语言:javascript
运行
复制
var ballGeo = new THREE.SphereGeometry(24,35,35);
var ballMat = new THREE.MeshPhongMaterial({color: 0xF7FE2E}); 
var ball = new THREE.Mesh(ballGeo, ballMat); 
ball.position.set(0,0,0);

var pendulum = new THREE.CylinderGeometry(1, 1, 20, 16);
ball.updateMatrix();
pendulum.merge(ball.geometry, ball.matrix);
scene.add(pendulum);

毕竟,我得到了以下错误:

代码语言:javascript
运行
复制
THREE.Object3D.add: object not an instance of THREE.Object3D. THREE.CylinderGeometry {uuid: "688B0EB1-70F7-4C51-86DB-5B1B90A8A24C", name: "", type: "CylinderGeometry", vertices: Array[1332], colors: Array[0]…}THREE.error @ three_r71.js:35THREE.Object3D.add @ three_r71.js:7770(anonymous function) @ pendulum.js:20
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-05-15 03:54:24

最后,我找到了一个可能的解决方案。我发帖子是因为我浪费了很多时间,但它对其他人很有用。棘手的事情是关于处理网格和几何的概念:

代码语言:javascript
运行
复制
var ballGeo = new THREE.SphereGeometry(10,35,35);
var material = new THREE.MeshPhongMaterial({color: 0xF7FE2E}); 
var ball = new THREE.Mesh(ballGeo, material);

var pendulumGeo = new THREE.CylinderGeometry(1, 1, 50, 16);
ball.updateMatrix();
pendulumGeo.merge(ball.geometry, ball.matrix);

var pendulum = new THREE.Mesh(pendulumGeo, material);
scene.add(pendulum);
票数 23
EN

Stack Overflow用户

发布于 2015-10-29 00:12:57

为了更清楚地解释大流士的答案(当我试图更新Doob先生的过程城市的一个版本以使用Face3盒子时,我一直在努力解决这个问题):

从本质上讲,您是将所有网格合并到一个几何体中。因此,例如,如果您想要合并长方体和球体:

代码语言:javascript
运行
复制
var box = new THREE.BoxGeometry(1, 1, 1);
var sphere = new THREE.SphereGeometry(.65, 32, 32);

...into单个几何体:

代码语言:javascript
运行
复制
var singleGeometry = new THREE.Geometry();

...you将为每个几何体创建一个网格:

代码语言:javascript
运行
复制
var boxMesh = new THREE.Mesh(box);
var sphereMesh = new THREE.Mesh(sphere);

...then为每个调用单个几何体的合并方法,将每个几何体的几何体和矩阵传递给该方法:

代码语言:javascript
运行
复制
boxMesh.updateMatrix(); // as needed
singleGeometry.merge(boxMesh.geometry, boxMesh.matrix);

sphereMesh.updateMatrix(); // as needed
singleGeometry.merge(sphereMesh.geometry, sphereMesh.matrix);

合并后,从单个几何体创建网格并添加到场景中:

代码语言:javascript
运行
复制
var material = new THREE.MeshPhongMaterial({color: 0xFF0000});
var mesh = new THREE.Mesh(singleGeometry, material);
scene.add(mesh);

下面是一个工作示例:

代码语言:javascript
运行
复制
<!DOCTYPE html>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r77/three.js"></script>
<!-- OrbitControls.js is not versioned and may stop working with r77 -->
<script src='http://threejs.org/examples/js/controls/OrbitControls.js'></script>

<body style='margin: 0px; background-color: #bbbbbb; overflow: hidden;'>
  <script>
    // init renderer
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    document.body.appendChild(renderer.domElement);

    // init scene and camera
    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 3000);
    camera.position.z = 5;
    var controls = new THREE.OrbitControls(camera)
   	
    // our code
    var box = new THREE.BoxGeometry(1, 1, 1);
    var sphere = new THREE.SphereGeometry(.65, 32, 32);

    var singleGeometry = new THREE.Geometry();

    var boxMesh = new THREE.Mesh(box);
    var sphereMesh = new THREE.Mesh(sphere);

    boxMesh.updateMatrix(); // as needed
    singleGeometry.merge(boxMesh.geometry, boxMesh.matrix);

    sphereMesh.updateMatrix(); // as needed
    singleGeometry.merge(sphereMesh.geometry, sphereMesh.matrix);

    var material = new THREE.MeshPhongMaterial({color: 0xFF0000});
    var mesh = new THREE.Mesh(singleGeometry, material);
    scene.add(mesh);

    // a light
    var light = new THREE.HemisphereLight(0xfffff0, 0x101020, 1.25);
    light.position.set(0.75, 1, 0.25);
    scene.add(light);
	
    // render
    requestAnimationFrame(function animate(){
	    requestAnimationFrame(animate);
	    renderer.render(scene, camera);		
    })
  </script>
</body>

至少,这是我对事情的解释;如果我做错了什么,请向任何人道歉,因为我离成为three.js专家(目前正在学习)还差得远。当最新的版本打破了一些东西(合并的东西是其中之一,事实是three.js不再使用四边形来处理立方体-嗯-盒几何图形-这导致了获得阴影等各种乐趣)的时候,我只是“倒霉”了。

票数 40
EN

Stack Overflow用户

发布于 2018-07-30 04:35:12

这是我的终极精简版本,只有四(或五)行(只要材料在其他地方定义),使用了mergeMesh:

代码语言:javascript
运行
复制
var geom = new THREE.Geometry();
geom.mergeMesh(new THREE.Mesh(new THREE.BoxGeometry(2,20,2)));
geom.mergeMesh(new THREE.Mesh(new THREE.BoxGeometry(5,5,5)));
geom.mergeVertices(); // optional
scene.add(new THREE.Mesh(geom, material));

编辑:添加了可选的附加线,以删除重复的顶点,这将有助于提高性能。

编辑2:我使用的是最新版本94。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30245990

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档