2016-03-30 6 views
2

Ich lade über dat.gui ein 3D * .obj (z. B. ein Würfel) mit 8 Vertices und 6 Flächen (Vertex-Indizes) hoch. Obwohl ich meine Punkte erfolgreich zu den Scheitelpunkten verschieben kann, kann ich sie nicht gleichmäßig auf die Seiten des Modells verteilen.bewegliche Partikel auf dem Gesicht von importierten * .obj in threejs

Das ist mein Prozess so weit:

(1) LOAD FILE OBJECT

Das Beispiel * OBJ ist ganz einfach:

v 5.526871 -3.827843 1.523720 
v 5.526871 -1.827843 1.523720 
v 5.526871 -3.827843 -0.476280 
v 5.526871 -1.827843 -0.476280 
v 7.526871 -3.827843 1.523720 
v 7.526871 -1.827843 1.523720 
v 7.526871 -3.827843 -0.476280 
v 7.526871 -1.827843 -0.476280 
s off 
f 2 4 3 1 
f 4 8 7 3 
f 8 6 5 7 
f 6 2 1 5 
f 1 3 7 5 
f 6 8 4 2 

(2) TRIM seine Ecken & FACES

Ich verwende RegEx-Muster zu Trimm die Ecken und Flächen und drücke sie dann zu meiner Geometrie.

var faces_pattern1 = /f(+[\d]+)([\d]+)([\d]+)([\d]+)?/g; // f vertex vertex vertex ... 
if ((result = faces_pattern1.exec(line)) !== null) { 
    faces_pattern1.exec(line); 
    if (result[ 4 ] === undefined) { 
     faces1.push([ 
      parseInt(result[ 1 ]) - 1, 
      parseInt(result[ 2 ]) - 1, 
      parseInt(result[ 3 ]) - 1 
     ]); 
    } else { 
     faces1.push([ 
      parseInt(result[ 1 ]) - 1, 
      parseInt(result[ 2 ]) - 1, 
      parseInt(result[ 3 ]) - 1, 
      parseInt(result[ 4 ]) - 1 
     ]); 
    } 
} 
// push faces to geometry 
for (var i = 0; i < faces1.length; i++) { 
    this.renderer.geometry.faces.push(new THREE.Face3(faces1[i][0], faces1[i][1], faces1[i][2], faces1[i][3])); 
} 

(3) MOVE Partikel auf VERTICES

Ich habe eine Anzahl von Teilchen, die i-Stellung zu den Scheitelpunkten. Das funktioniert gut.

var lg = allParticle.length; 
for(var i = 0; i < lg; i++){ 
    var p = allParticle[i]; 
    p.diffX = (vertices[h][0] * scale - p.x); 
    p.diffY = (-vertices[h][1] * scale - p.y); 
    p.diffZ = (-vertices[h][2] * scale - p.z); 
    h += 1; 
    if(h > nbVertices - 1) h = 0; 
} 

(4) VERTEILEN VON PARTIKELN auf Gesichter

Ich habe jetzt einen Knebel, wo ich will die gleichen Teilchen auf den Flächen des Würfels gleichmäßig verteilen. Ich versuche, dies mit GeometryUtils.randomPointsInGeometry

var randomPointPositions = THREE.GeometryUtils.randomPointsInGeometry(this.renderer.geometry, lg ); 
this.renderer.geometry.computeBoundingBox(); 
for(var i = 0; i < randomPointPositions.length; i++){ 

    var p = allParticle[i]; 
    p.diffX = randomPointPositions[i].x * scale ; 
    p.diffY = randomPointPositions[i].y * scale; 
    p.diffZ = randomPointPositions[i].z * scale ; 
} 

Dieser verteilt die Punkte auf der x-Achse nur zu tun und nicht gleichmäßig auf der Fläche des Gesichts. Irgendwelche Hinweise?

- Dies sind die Gesichter (THREE.Face3) Ich erhalte:

{a: 1, b: 3, c: 2, normal: T…E.Vector3, vertexNormals: Array[0]…} 
{a: 3, b: 7, c: 6, normal: T…E.Vector3, vertexNormals: Array[0]…} 
{a: 7, b: 5, c: 4, normal: T…E.Vector3, vertexNormals: Array[0]…} 
{a: 5, b: 1, c: 0, normal: T…E.Vector3, vertexNormals: Array[0]…} 
{a: 0, b: 2, c: 6, normal: T…E.Vector3, vertexNormals: Array[0]…} 
{a: 5, b: 7, c: 3, normal: T…E.Vector3, vertexNormals: Array[0]…} 

ihre berechneten _area immer Null ist.

ähnliche Frage: THREE.js - position particles evenly on objects faces rather than verticies

+0

Ich erinnere mich three.js ein OBJ-Parser hat so sollten Sie nicht müssen die Arbeit duplizieren. Sobald Sie das Mesh geladen haben, können Sie wählen, es nicht zu rendern, können aber trotzdem auf Vertices/Faces/Compute Normals/etc zugreifen. –

+0

danke! Ich lade tatsächlich das Objekt, ohne es zu rendern und lese einfach seine Vertices/Faces Werte. Das funktioniert großartig; Ich stecke jedoch im vierten Schritt fest. –

+0

Ich habe auch die OBJLoader-Methode ausprobiert. Das Mesh lädt richtig, dann mache ich: object.traverse (function (child)) { \t if (untergeordnete Instanz von THREE.Netz) { \t \t var randomPointPositions = THREE.GeometryUtils.randomPointsInBufferGeometry (Kind, 5000); } aber get "kann nicht lesen Eigenschaft 'Position' von undefined" in GeometryUtils.js: 190 (Vertices = geometry.attributes.position.array) –

Antwort

3

ok - es dauerte eine Weile, aber ich löste es.

Ich versuchte die OBJLoader-Methode wie von G.Profenza vorgeschlagen.

Im Grunde das Objekt laden, dessen Gitter erhalten, die GeometryUtils.randomPointsinBufferGeometry verwenden und dann die Partikel auf die vector3 bewegen Sie erhalten:

OBJLoader: function() { 
     var manager = new THREE.LoadingManager(); 
     manager.onProgress = function (item, loaded, total) { 
      console.log(item, loaded, total); 
     }; 

     var onProgress = function (xhr) { 
      if (xhr.lengthComputable) { 
       var percentComplete = xhr.loaded/xhr.total * 100; 
       console.log(Math.round(percentComplete, 2) + '% downloaded'); 
      } 
     }; 

     var onError = function (xhr) { 
      console.log ("ERROR", xhr); 
     }; 

     var loader = new THREE.OBJLoader(manager); 
     var allParticle = this.scene.getParticles(); 
     var lg = allParticle.length; 
     var scale = this.renderer.scale;  
     loader.load('/data/cube_02.obj', function (object) { 
      object.traverse(function (child) { 
      if (child instanceof THREE.Mesh) { 
       console.log (" === CHILD === "); 
       console.log (child.geometry); 
       var randomPointPositions = THREE.GeometryUtils.randomPointsInBufferGeometry(child.geometry, lg ); 


       console.log (randomPointPositions[0].x, randomPointPositions[0].y, randomPointPositions[0].z); 


       for(var i = 0; i < randomPointPositions.length; i++){ 

        var p = allParticle[i]; 
        p.diffX = randomPointPositions[i].x * scale -p.x ; 
        p.diffY = randomPointPositions[i].y * scale -p.y; 
        p.diffZ = randomPointPositions[i].z * scale -p.z; 
       } 

      } 

     }); 


     //object.position.y = - 95; 
     //this.renderer.sceneGL.add(object); 

     }, onProgress, onError); 



    }