2015-02-26 9 views
6

Sto provando a scaricare alcuni Geometry caricamento ed elaborazione in un web worker. Per rimandarlo al thread principale, l'istanza Geometry deve essere serializzata e sembra che lo Geometry.prototype.toJSON() sia stato concepito esattamente per questo tipo di cose.Three.js - Come deserializzare geometry.toJSON()? (dove è geometry.fromJSON?)

Ma non riesco a capire come trasformare quell'oggetto in un'istanza Geometry nel thread principale. Come si suppone che venga utilizzato l'output toJSON()?

PS: ho visto this related question, ma sembra datato. toJSON() non era ancora nell'API. La risposta accettata è un po 'complicata e mi impone di fare ancora del lavoro grezzo nel thread principale.

+0

si dovrebbe guardare intorno alle classi caricatore nella documentazione: http://threejs.org/docs/# Riferimento/Caricatori/ObjectLoader – nemesv

+1

@nemesv: Ho guardato e guardato. Queste classi non possono essere utilizzate per trasformare l'output 'toJSON() in una' Geometria'. In teoria, potrei provare a comprendere tutto il loro codice sorgente e scrivere una soluzione completa da zero, ma ciò richiederebbe molto tempo. Per lo più, non posso credere che esista un metodo di serializzazione 'toJSON(), senza un modo per deserializzare. : -/ – mhelvens

+0

Vedere se questo aiuta: http://stackoverflow.com/questions/27992147/three-js-include-mesh-data-in-code/27996338#27996338 – WestLangley

risposta

2

Perché non usi semplicemente JSONLoader?

myloader = new THREE.JSONLoader() 
myloader.load("path/to/json", function(geometry,material){ 
    mesh = new THREE.Mesh(geometry,material) 
    scene.add(mesh) 
}) 

o il caricamento di un file JSON stesso modo

+0

I * am * utilizzando JSONLoader.Ma lo sto facendo in un thread di lavoro e ora sto cercando un modo per comunicare la geometria risultante (dopo la modifica) al thread principale. – mhelvens

3

Se ho capito bene il problema è:

  • Hai un file che si desidera caricare come una geometria (obj, stl, eccetera.).
  • Si desidera caricare questo file in un WebWorker.
  • Quindi si desidera inviare nuovamente la geometria allo script principale.
  • Quindi stai pensando di inviare il file al thread principale come JSON, poiché l'invio di oggetti non è supportato.
  • Quindi si converte il json in una geometria sul thread principale.

Il problema di questo è che la conversione da una stringa JSON a una geometria è un'altra operazione di carico (che è il motivo per cui c'è JSONLoader), così a quel punto si può anche avete appena fatto il carico sul thread principale.

L'approccio che ho usato è di caricare il file in array flat di vertici e normali, quindi li rimando al thread principale da aggiungere a un BufferGeometry. Puoi anche usare oggetti trasferibili per guadagnare ancora più velocità.

// worker.js 

var vertices = new Float32Array(faces * 3 * 3); 
var normals = new Float32Array(faces * 3 * 3); 

// Load your file into the arrays somehow. 

var message = { 
    status:'complete', 
    vertices: vertices, 
    normals: normals 
}; 

postMessage(message, [message.vertices.buffer, message.normals.buffer]); 

// app.js 

onmessage = function (event) { 

    var vertices = event.data.vertices; 
    var normals = event.data.normals; 

    var geometry = new THREE.BufferGeometry(); 
    geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3)); 
    geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3)); 

    var material = new THREE.MeshPhongMaterial(); 

    var mesh = new THREE.Mesh(geometry, material); 

    // Do something with it. 

}; 
+0

Ho utilizzato un thread di lavoro perché la geometria doveva ancora essere elaborata/trasformata, il che avrebbe notevolmente bloccato il thread principale. La tua soluzione sembra ragionevole a prima vista, ma è passato troppo tempo da quando stavo lavorando al problema. Non posso davvero giudicare in questo momento. (In ogni caso, in realtà non risponde alla domanda come posta.) – mhelvens

+0

La domanda posta è "Dov'è geometry.fromJSON()?" ma sembra che quello che volevi veramente sapere fosse come passare la geometria da un WebWorker allo script principale senza bloccare/stallo. La tecnica che ho spiegato lo fa, anche se invece di caricarti stavi elaborando. La creazione di BufferGeometry dagli array digitati trasferiti è quasi istantanea. Ho trovato questa domanda cercando come fare questo. – DylanVann

+0

Certo, è una risposta utile (ho fatto +1). Ma funziona solo se i vertici e le normali sono le uniche parti di dati in una geometria, il che non è necessariamente il caso (come per i modelli animati 3d). Sì, potremmo aggiungere anche questo, ma idealmente ci dovrebbero essere strutture di serializzazione/deserializzazione che gestiscano tutti i possibili modelli, quindi non dobbiamo codificarci e mantenerci da soli. – mhelvens

1

È possibile utilizzare JSONLoader geometria unserialize in questo modo:

var geometry = new THREE.Geometry(); 
var serializedGeometry = geometry.toJSON(); 
var jsonLoader = new THREE.JSONLoader(); 

var result = jsonLoader.parse(serializedGeometry.data); 

var unserializedGeometry = result.geometry;