Come faccio a ruotare alcune lune intorno a un pianeta con THREE.js?

Penso che questa immagine spiega meglio il mio problema:

Come faccio a ruotare alcune lune intorno a un pianeta con THREE.js?

Primo traduco la casella lungo la linea rossa. Avanti, voglio l’effetto di rotazione per essere la linea blu in a, ma quello che sta succedendo è di più, come la linea blu in b. Ci si sente come cambiare la rotazione è sempre relativa all’oggetto originale spazio, ma la traduzione (nonostante accadendo prima) è sempre relativa al genitore, e davvero non influisce sulla geometria dei punti in relazione all’oggetto nello spazio. Mi scuso se questo è fonte di confusione; chiaramente io sono nuovo a questo.

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

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 ho trovato è quello di avvolgere ogni dialogo in un altro spazio oggetti e ruota, ma mi sembra eccessivo lavoro. Qual è il metodo preferito per ottenere il risultato che sto cercando?

  • Non so Three.js ma per quanto riguarda solo la traduzione da Math.cos(rotation) * boxEdge / 2, Math.sin(rotation) * boxEdge / 2 nonché la rotazione?
  • Che si sente come un lavoro doppio, ruotare e traslare ogni casella. Davvero quello che voglio fare è ruotare ogni clone stesso punto, che è di origine prima della traduzione.

 

2 Replies
  1. 32

    Ci sono diversi modi per fare quello che vuoi, ma penso che la più semplice è così:

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

    Quindi nel tuo render loop:

    parent.rotation.z += 0.01;
    

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

    three.js r.70

    • Grazie per l’esempio. Come ho detto nella domanda, questo è quello che stavo pensando. Questa è una tipica soluzione al problema? Ho intenzione di sviluppare questo per un po ‘ e voglio solo per assicurarsi che io non sono la ripresa di me stesso in piedi.
    • Sì. È tipico. L’altra soluzione è quella di avere ogni casella di essere un figlio di scena, e calcolare il nuovo position e rotation vettore di ogni fotogramma usando la matematica.
  2. 6

    Creazione di un oggetto composto, il cui centro sarà il punto da cui interno gli oggetti di ruotare è una risposta ovvia, e sarebbe molto veloce a scrivere. Basta creare un Object3D e aggiungi la tua casella di.

    Un approccio simile è coperto da questa domanda. Sposta il punto di vertici di un oggetto, quindi è effettivamente un nuovo centro.

    In alternativa, si può pasticciare con le matrici a mano. 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 );
    

Lascia un commento