2015-05-14 8 views
19

Qui mi sono imbattuto nel problema poiché ho bisogno di unire due geometrie (o mesh) a una. Utilizzando le versioni precedenti di Three.js c'era una bella funzione:Come unire due geometrie o mesh usando three.js r71?

THREE.GeometryUtils.merge(pendulum, ball); 

Tuttavia, non è sulla nuova versione più.

Ho provato a fondere pendulum e ball con il seguente codice:

ball è una maglia.

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

Dopo tutto, ho ottenuto il seguente errore:

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 

risposta

16

Infine, ho trovato una possibile soluzione. Sto postando perché potrebbe essere utile per qualcun altro mentre io sprecavo un sacco di ore. La cosa più difficile è sulla manipolazione del concetto di maglie e geometrie:

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

_ "Inutile erano nessuna delle gesta di Tyler Crompton nella vita" _ - _Lady Galadriel_ Grazie per questo – LaughingMan

27

per spiegare la risposta di Dario più chiaramente (come ho lottato con esso, durante il tentativo di aggiornare una versione della città di procedura del sig Doob a lavorare con il Face3 caselle):

Essenzialmente si stanno unendo tutte le tue mesh in una singola geometria. Quindi, se, per esempio, desidera unire una scatola e sfera:

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

... in una sola geometria:

var singleGeometry = new THREE.Geometry(); 

... si potrebbe creare una mesh per ogni geometria:

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

... quindi chiamare il metodo di unione della singola struttura di ciascuna, passando la geometria e la matrice di ogni nel metodo:

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

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

Una volta fuse, creare una rete dal singolo geometria e aggiungere alla scena:

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

Un esempio di lavoro:

<!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) 
 
    \t 
 
    // 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); 
 
\t 
 
    // render 
 
    requestAnimationFrame(function animate(){ 
 
\t  requestAnimationFrame(animate); 
 
\t  renderer.render(scene, camera); \t \t 
 
    }) 
 
    </script> 
 
</body>

Almeno, è così che ho sto interpretando le cose; mi scuso con chiunque se ho qualcosa di sbagliato, dato che non sono vicino ad essere un esperto di three.js (attualmente sto imparando). Ho appena avuto la "sfortuna" di provare a personalizzare il codice procedurale di Mr. Doob, quando l'ultima versione rompe le cose (il materiale di fusione è uno di questi, il fatto che three.js non usi più i quad per cube -ahem - box geometry l'altro - che ha portato a tutti i tipi di divertimento ottenendo l'ombreggiatura e tale per funzionare di nuovo correttamente).

+0

grazie per questo. l'aggiornamento del codice che ho appena portato dall'avere 500.000 avvisi sembrava piuttosto scoraggiante. Non sono molto contento del modo in cui è stato gestito, trovando la risposta troppo difficile per qualcosa su cui non ho alcun controllo. – fluffybunny

3

Il messaggio di errore è corretto. CylinderGeometry non è un Object3D. La maglia è. Una rete è costruita da una geometria e da un materiale. Una mesh può essere aggiunta alla scena, mentre una Geometria non può.

Nelle versioni più recenti di tre.js, Geometry ha due metodi di unione: unione e mergeMesh.

  • unione prende un argomento obbligatorio geometria, e due argomenti facoltativi matrice e materialIndexOffset.
  • geom. mergeMesh (mesh) è fondamentalmente una scorciatoia per geom. unione (mesh geometria, mesh matrice), come in altre risposte. ('geom' e 'mesh' sono nomi arbitrari per una Geometria e una Maglia, rispettivamente.) Il Materiale della Maglia viene ignorato.