Подтвердить что ты не робот

Как объединить две геометрии или сетки, используя three.js r71?

Здесь я столкнулся с проблемой, так как мне нужно объединить две геометрии (или сетки) в одну. Используя более ранние версии three.js, была хорошая функция:

THREE.GeometryUtils.merge(pendulum, ball);

Однако он больше не находится в новой версии.

Я попытался объединить pendulum и ball со следующим кодом:

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
4b9b3361

Ответ 1

Наконец, я нашел возможное решение. Я отправляю сообщения, так как это может быть полезно для кого-то еще, пока я потратил много времени. Трудность в том, чтобы манипулировать концепцией сеток и геометрий:

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

Чтобы объяснить ответ Дария более четко (поскольку я боролся с ним, пытаясь обновить версию процедурного города г-на Дуба для работы с ящиками Face3):

По сути, вы объединяете все свои Меши в единую геометрию. Итак, если вы, например, хотите объединить поле и сферу:

var box = new THREE.BoxGeometry(1, 1, 1);
var sphere = new THREE.SphereGeometry(.65, 32, 32);

... в одну геометрию:

var singleGeometry = new THREE.Geometry();

... вы создадите Mesh для каждой геометрии:

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>

Ответ 3

Сообщение об ошибке правильное. Цилиндровая геометрия - это не объект3D. Сетка есть. Сетка построена из геометрии и материала. Сетка может быть добавлена ​​к сцене, в то время как геометрия не может.

В новейших версиях three.js у Geometry есть два метода слияния: merge и mergeMesh.

  • merge принимает обязательную геометрию аргумента и две необязательные аргументы matrix и materialIndexOffset.
  • geom.mergeMesh(mesh) является в основном сокращением для geom.merge(mesh.geometry, mesh.matrix), как используется в других ответах. ('geom' и 'mesh' - произвольные имена для геометрии и Mesh соответственно.) Материал Mesh игнорируется.