2014-12-31 15 views
5

Ho una scena Three.js visualizzata e vorrei esportare come appare dopo il rendering delle animazioni. Ad esempio, dopo che l'animazione è passata a ~ 100 fotogrammi, l'utente esegue l'esportazione e la scena deve essere esportata in STL esattamente come è in quel momento.Esportare la scena Three.js in STL mantenendo intatte le animazioni

Da quello che ho provato (utilizzando STLExporter.js), sembra esportare il modello utilizzando solo le posizioni iniziali.

Se c'è già un modo per fare questo, o un lavoro semplice, apprezzerei una spinta in quella direzione.

Aggiornamento: Dopo aver scavato un po 'di più negli interni, ho scoperto (almeno in modo superficiale) perché STLExporter non ha funzionato. STLExporter trova tutti gli oggetti e chiede loro i vertici e le facce dell'oggetto Geometry. La mia modella ha un mucchio di ossa che sono pelate. Durante la fase di animazione, le ossa vengono aggiornate, ma questi aggiornamenti non si propagano all'oggetto originale Geometry. So che questi vertici trasformati vengono calcolati ed esistono da qualche parte (vengono visualizzati sulla tela).

La domanda è dove sono questi vertici trasformati e volti memorizzati e posso accedervi per esportarli come un STL?

+0

Vedere [questo] (http://stackoverflow.com/questions/14874730/three-js-what-do-the-matrices-in-a-3d-object-represent) QUINTA domanda che spiega i diversi tipi di 3D matrici. –

+0

Il tag STL è utilizzato per la libreria di modelli standard C++, è stato questo il tuo intento? – sashoalm

+0

No. Tag di correzione ora. – KevinL

risposta

7

La domanda è dove sono memorizzati questi vertici e volti trasformati e posso accedervi per esportarli come un STL?

La risposta a questo, purtroppo, non è da nessuna parte. Questi sono tutti calcolati sulla GPU attraverso chiamate a funzioni WebGL passando in diversi array di grandi dimensioni.

Per spiegare come calcolare questo, vediamo prima come funziona l'animazione, usando this knight example come riferimento. L'oggetto SkinnedMesh contiene, tra le altre cose, uno scheletro (composto da molti Bone s) e un mucchio di vertici. Iniziano organizzati in quello che è noto come bind pose. Ogni vertice è vincolato a 0-4 ossa e se quelle ossa si muovono, i vertici si sposteranno, creando l'animazione.

Bind image

Se si dovesse prendere il nostro esempio cavaliere, mettere in pausa l'animazione metà swing, e provare la standard STL exporter, il file STL generato sarebbe esattamente questa posizione, non quello animato. Perché? Perché guarda semplicemente mesh.geometry.vertices, che non vengono modificati dalla posa di bind originale durante l'animazione. Cambiano solo le ossa e la GPU fa un po 'di matematica per spostare i vertici corrispondenti a ciascun osso.

Quella matematica per spostare ogni vertice è piuttosto semplice: trasformare la posizione del vertice di posa del legamento nello spazio dell'osso e quindi dallo spazio dell'osso allo spazio globale prima dell'esportazione.
Adattare il codice here, aggiungiamo questo all'esportatore originale:

vector.copy(vertices[ vertexIndex ]); 
boneIndices = []; //which bones we need 
boneIndices[0] = mesh.geometry.skinIndices[vertexIndex].x; 
boneIndices[1] = mesh.geometry.skinIndices[vertexIndex].y; 
boneIndices[2] = mesh.geometry.skinIndices[vertexIndex].z; 
boneIndices[3] = mesh.geometry.skinIndices[vertexIndex].w; 

weights = []; //some bones impact the vertex more than others 
weights[0] = mesh.geometry.skinWeights[vertexIndex].x; 
weights[1] = mesh.geometry.skinWeights[vertexIndex].y; 
weights[2] = mesh.geometry.skinWeights[vertexIndex].z; 
weights[3] = mesh.geometry.skinWeights[vertexIndex].w; 

inverses = []; //boneInverses are the transform from bind-pose to some "bone space" 
inverses[0] = mesh.skeleton.boneInverses[ boneIndices[0] ]; 
inverses[1] = mesh.skeleton.boneInverses[ boneIndices[1] ]; 
inverses[2] = mesh.skeleton.boneInverses[ boneIndices[2] ]; 
inverses[3] = mesh.skeleton.boneInverses[ boneIndices[3] ]; 

skinMatrices = []; //each bone's matrix world is the transform from "bone space" to the "global space" 
skinMatrices[0] = mesh.skeleton.bones[ boneIndices[0] ].matrixWorld; 
skinMatrices[1] = mesh.skeleton.bones[ boneIndices[1] ].matrixWorld; 
skinMatrices[2] = mesh.skeleton.bones[ boneIndices[2] ].matrixWorld; 
skinMatrices[3] = mesh.skeleton.bones[ boneIndices[3] ].matrixWorld; 

var finalVector = new THREE.Vector4(); 
for(var k = 0; k<4; k++) { 
    var tempVector = new THREE.Vector4(vector.x, vector.y, vector.z); 
    //weight the transformation 
    tempVector.multiplyScalar(weights[k]); 
    //the inverse takes the vector into local bone space 
    tempVector.applyMatrix4(inverses[k]) 
    //which is then transformed to the appropriate world space 
    .applyMatrix4(skinMatrices[k]); 
    finalVector.add(tempVector); 
} 

output += '\t\t\tvertex ' + finalVector.x + ' ' + finalVector.y + ' ' + finalVector.z + '\n'; 

Questo produce file STL che assomigliano:

enter image description here

Il codice completo è disponibile presso https://gist.github.com/kjlubick/fb6ba9c51df63ba0951f

3

Dopo una settimana di estrazione dei capelli sono riuscito a modificare il codice per includere i dati di morphTarget nel file stl finale. è possibile trovare il codice modificato per il cambio di Kevin al https://gist.github.com/jcarletto27/e271bbb7639c4bed2427

Poiché JS non è il mio linguaggio preferito, non è bello ma, riesce a funzionare senza molto clamore. Spero che qualcuno mi possa aiutare oltre a me!

+0

Ho anche modificato lo script OBJExporter che funziona con bufferGeometry per funzionare in modo simile. https://gist.github.com/jcarletto27/35b19f811c657ec73b0238d78413f88d – Jcarletto27

Problemi correlati