2013-03-05 11 views
27

Penso questa immagine spiega meglio il mio problema:Come faccio a ruotare alcune lune attorno a un pianeta con THREE.js?

hooray for optical illusions

Prima traduco la casella lungo la linea rossa. Successivamente, voglio che l'effetto di rotazione sia la linea blu in a, ma ciò che sta effettivamente accadendo è più simile alla linea blu in b. Sembra che cambiare la rotazione sia sempre relativa allo spazio dell'oggetto originale, ma la traduzione (nonostante si verifichi prima) è sempre relativa al genitore, e non influisce realmente sui punti geometrici in relazione allo spazio dell'oggetto. Mi scuso se questo è confuso; chiaramente sono nuovo in questo.

La parte importante del codice che produce questo effetto è di seguito. Si prega di tenere presente che l'orientamento dell'immagine è diverso da quello prodotto da questo codice; l'immagine è solo un esempio per mostrare chiaramente l'effetto.

var objectContainer = new THREE.Object3D(); 

var tubeRadius = 100; 
var tubeGeometry = new THREE.CylinderGeometry(tubeRadius, tubeRadius, tubeRadius * 3, 36, 1, false); 
var tube = new THREE.Mesh(tubeGeomtry, material); 
scene.add(tube); 

var boxes = new THREE.Object3D(); 
var boxEdge = 50; 
var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge); 
var box1 = new THREE.Mesh(boxGeometry, material); 
box1.translateX(tubeRadius + boxEdge/2 + 5); 
box1.translateY(boxEdge/2); 
box1.rotation = new THREE.Vector3(0, 2*Math.PI/3*0, 0); 
boxes.add(box1); 
var box2 = box1.clone(); 
box2.rotation = new THREE.Vector3(0, 2*Math.PI/3*1, 0); 
boxes.add(box2); 
var box3 = box1.clone(); 
box3.rotation = new THREE.Vector3(0, 2*Math.PI/3*2, 0); 
boxes.add(box3); 
scene.add(boxes); 

L'unica soluzione che viene in mente è quello di avvolgere ogni casella in un altro spazio oggetto e ruotare a tale proposito, ma sembra che il lavoro eccessivo. Qual è il metodo preferito per ottenere il risultato che sto cercando?

+0

Non conosco Three.js, ma per quanto riguarda la semplice traduzione da 'Math.cos (rotazione) * boxEdge/2, Math.sin (rotazione) * boxEdge/2' e rotazione locale? – Ryan

+0

Sembra doppio lavoro, ruota e traduce ogni scatola. Veramente quello che voglio fare è ruotare ogni clone sullo stesso punto, che è l'origine prima della traduzione. –

risposta

29

Ci sono diversi modi di fare ciò che si vuole, ma penso che il più semplice è in questo modo:

// parent 
parent = new THREE.Object3D(); 
scene.add(parent); 

// pivots 
var pivot1 = new THREE.Object3D(); 
var pivot2 = new THREE.Object3D(); 
var pivot3 = new THREE.Object3D(); 

pivot1.rotation.z = 0; 
pivot2.rotation.z = 2 * Math.PI/3; 
pivot3.rotation.z = 4 * Math.PI/3; 

parent.add(pivot1); 
parent.add(pivot2); 
parent.add(pivot3); 

// mesh 
var mesh1 = new THREE.Mesh(geometry, material); 
var mesh2 = new THREE.Mesh(geometry, material); 
var mesh3 = new THREE.Mesh(geometry, material); 

mesh1.position.y = 5; 
mesh2.position.y = 5; 
mesh3.position.y = 5; 

pivot1.add(mesh1); 
pivot2.add(mesh2); 
pivot3.add(mesh3); 

Poi, nel tuo ciclo di rendering:

parent.rotation.z += 0.01; 

EDIT : violino aggiornato: http://jsfiddle.net/hbt9c/317/

tre.js r.70

+0

Grazie per l'esempio. Come ho detto nella domanda, questo è quello che stavo pensando. Questa è una tipica soluzione al problema? Intendo sviluppare questo per un po 'e voglio solo assicurarmi di non spararmi ai piedi. –

+0

Sì. È tipico L'altra soluzione è far sì che ogni riquadro sia figlio della scena e calcola il nuovo vettore 'position' e' rotation' ogni frame usando la matematica. – WestLangley

5

Creare un oggetto composto il cui centro sarà il punto attorno al quale ruotano gli oggetti interni è una risposta ovvia e sarebbe molto veloce da scrivere. Basta creare un Object3D e aggiungerci la tua scatola.

Un approccio simile è coperto da this question. Sposta il punto dei vertici per un oggetto, quindi ha effettivamente un nuovo centro.

In alternativa, è possibile manipolare le matrici manualmente. Prova questo:

var boxGeometry = new THREE.CubeGeometry(boxEdge, boxEdge, boxEdge); 
var mr = new THREE.Matrix4(); 
var mt = new THREE.Matrix4(); 
mt.setPosition(new THREE.Vector3(0,tubeRadius,0)); 
var box1 = new THREE.Mesh(boxGeometry, material); 
box1.applyMatrix(mt); 
var box2 = box1.clone(); 
mr.makeRotationZ(2 * Math.PI /3); 
box2.applyMatrix(mr); 
boxes.add(box2); 
var box3 = box1.clone(); 
mr.makeRotationZ(4 * Math.PI /3); 
box3.applyMatrix(mr); 
boxes.add(box3); 
boxes.add(box1); 
scene.add(boxes); 
Problemi correlati