如何使用三r71合并两个几何或网格



在这里我遇到了问题,因为我需要将两个几何(或网格)合并到一个。使用trex.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

更清楚地解释了达里乌斯的答案(当我对此苦苦挣扎时,试图更新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>

至少,这就是我解释事物的方式;如果我有问题,请向任何人致歉,因为我没有一个即将成为三名JS专家(目前正在学习)的地方。我只是有"厄运"来尝试自定义杜布先生的过程城市代码,当时最新版本破坏了东西(合并的东西就是其中之一,这是三分之一的事实,即三个js不再使用Quads进行Cube -Ahem - 盒几何形状 - 另一个导致了各种乐趣,使阴影变得正确工作)。

最后,我找到了一个可能的解决方案。我发帖,因为当我浪费很多小时时,这对别人可能很有用。棘手的事情是关于操纵网格和几何形状的概念:

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

错误消息正确。圆柱体测定不是对象3D。网格是。网格是用几何形状和材料构造的。可以将网格添加到场景中,而几何不能。

在最新版本的三个.js中,几何形状具有两个合并方法: Merge Mergemesh 。。

  • Merge 采用强制性参数几何,两个可选的参数 matrix MiteralIndexOffset 。。
  • GEOM。 Mergemesh (网格)基本上是Geom的速记。 Merge (网格。几何,mesh。/em>),如其他答案所用。('geom'和'网格'分别是几何和网格的任意名称。)网格的材料被忽略。

这是我使用Mergemesh的四(或五个)行(或在其他地方定义的材料)中的最终紧凑版本(只要材料定义):

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。

我在此处发布的答案和代码不起作用,因为合并方法的第二个参数是整数,而不是矩阵。据我所知,合并方法并没有真正以有用的方式运行。因此,我使用以下方法制作了带鼻锥的简单火箭。

import * as BufferGeometryUtils from '../three.js/examples/jsm/utils/BufferGeometryUtils.js'
lengthSegments = 2
radius = 5
radialSegments = 32
const bodyLength = dParamWithUnits['launchVehicleBodyLength'].value
const noseConeLength = dParamWithUnits['launchVehicleNoseConeLength'].value
// Create the vehicle's body
const launchVehicleBodyGeometry = new THREE.CylinderGeometry(radius, radius, bodyLength, radialSegments, lengthSegments, false)
launchVehicleBodyGeometry.name = "body"
// Create the nose cone
const launchVehicleNoseConeGeometry = new THREE.CylinderGeometry(0, radius,  noseConeLength, radialSegments, lengthSegments, false)
launchVehicleNoseConeGeometry.name = "noseCone"
launchVehicleNoseConeGeometry.translate(0, (bodyLength+noseConeLength)/2, 0)
// Merge the nosecone into the body
const launchVehicleGeometry = BufferGeometryUtils.mergeBufferGeometries([launchVehicleBodyGeometry, launchVehicleNoseConeGeometry])
// Rotate the vehicle to horizontal
launchVehicleGeometry.rotateX(-Math.PI/2)
const launchVehicleMaterial = new THREE.MeshPhongMaterial( {color: 0x7f3f00})
const launchVehicleMesh = new THREE.Mesh(launchVehicleGeometry, launchVehicleMaterial)

最新更新