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

时间:2015-05-14 19:44:09

标签: javascript merge three.js

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

THREE.GeometryUtils.merge(pendulum, ball);

但是,它不再是新版本了。

我尝试将pendulumball合并为以下代码:

ball是一个网格。

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);

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

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

4 个答案:

答案 0 :(得分:30)

解释Darius'更清楚地回答(当我努力尝试更新Doob先生的程序城市版本以使用Face3框时):

基本上,您将所有网格合并为单个几何体。所以,例如,如果你想合并一个盒子和球体:

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);

一个工作示例:



<!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>
&#13;
&#13;
&#13;

至少,这就是我如何解释事物;如果我有什么不对的话,向任何人道歉,因为我不是一个接近成为three.js专家(目前正在学习)的地方。我只是运气不好&#34;尝试自定义Doob先生的程序城市代码,当最新版本破坏事物时(合并的东西就是其中之一,事实上three.js不再使用四边形的多维数据集 - 几何形状其他 - 这使得阴影得到各种乐趣,并且再次正常工作)。

答案 1 :(得分:17)

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

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);

答案 2 :(得分:5)

错误消息是正确的。 CylinderGeometry不是Object3D。网格是。网格由几何和材质构成。可以将Mesh添加到场景中,而Geometry则不能。

在最新版本的three.js中,Geometry有两种合并方法: merge mergeMes​​h

  • merge 采用强制参数 geometry ,以及两个可选参数 matrix materialIndexOffset
  • geom。 mergeMes​​h (网格)基本上是geom的缩写。 merge (网格。几何,网格。矩阵< / em>),用于其他答案。 (&#39; geom&#39;网格&#39;分别是几何和网格的任意名称。)网格的材质被忽略。

答案 3 :(得分:1)

这是我的最终精简版,使用mergeMes​​h分为四(或五)行(只要在其他地方定义了材料):

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。