Bladeren bron

Merge pull request #489 from jbousquie/fix.Path3D.SamePositionPoints

Fix.path3 d.same position points
David Catuhe 10 jaren geleden
bovenliggende
commit
1f9f8d8544
2 gewijzigde bestanden met toevoegingen van 128 en 64 verwijderingen
  1. 62 26
      Babylon/Math/babylon.math.ts
  2. 66 38
      Babylon/Mesh/babylon.mesh.vertexData.ts

+ 62 - 26
Babylon/Math/babylon.math.ts

@@ -3281,9 +3281,11 @@
         private _normals = new Array<Vector3>();
         private _binormals = new Array<Vector3>();
 
-        constructor(public path: Vector3[]) {
-            this._curve = path.slice();   // copy array  
-            this._compute();
+        constructor(public path: Vector3[], firstNormal?: Vector3) {
+            for (var p = 0; p < path.length; p++) {
+                this._curve[p] = path[p].clone(); // hard copy
+            }  
+            this._compute(firstNormal);
         }
 
         public getCurve(): Vector3[] {
@@ -3306,31 +3308,33 @@
             return this._distances;
         }
 
-        public update(path: Vector3[]): Path3D {
-            for (var i = 0; i < path.length; i++) {
-                this._curve[i] = path[i];
-            }
-            this._compute();
+        public update(path: Vector3[], firstNormal?: Vector3): Path3D {
+            for (var p = 0; p < path.length; p++) {
+                this._curve[p].x = path[p].x;
+                this._curve[p].y = path[p].y;
+                this._curve[p].z = path[p].z;
+            }  
+            this._compute(firstNormal);
             return this;
         }
 
         // private function compute() : computes tangents, normals and binormals
-        private _compute() {
+        private _compute(firstNormal) {
             var l = this._curve.length;
 
             // first and last tangents
-            this._tangents[0] = this._curve[1].subtract(this._curve[0]);
+            this._tangents[0] = this._getFirstNonNullVector(0);
             this._tangents[0].normalize();
             this._tangents[l - 1] = this._curve[l - 1].subtract(this._curve[l - 2]);
             this._tangents[l - 1].normalize();
             
             // normals and binormals at first point : arbitrary vector with _normalVector()
             var tg0 = this._tangents[0];
-            var pp0 = this._normalVector(this._curve[0], tg0);
+            var pp0 = this._normalVector(this._curve[0], tg0, firstNormal);
             this._normals[0] = pp0;
             this._normals[0].normalize();
             this._binormals[0] = Vector3.Cross(tg0, this._normals[0]);
-            this._normals[0].normalize();
+            this._binormals[0].normalize();
             this._distances[0] = 0;
 
             // normals and binormals : next points
@@ -3342,9 +3346,9 @@
 
             for (var i = 1; i < l; i++) {
                 // tangents
-                prev = this._curve[i].subtract(this._curve[i - 1]);
+                prev = this._getLastNonNullVector(i);
                 if (i < l - 1) {
-                    cur = this._curve[i + 1].subtract(this._curve[i]);
+                    cur = this._getFirstNonNullVector(i);
                     this._tangents[i] = prev.add(cur);
                     this._tangents[i].normalize();
                 }
@@ -3362,22 +3366,54 @@
             }
         }
 
-        // private function normalVector(v0, vt) :
-        // returns an arbitrary point in the plane defined by the point v0 and the vector vt orthogonal to this plane
-        private _normalVector(v0: Vector3, vt: Vector3): Vector3 {
-            var point: Vector3;
+        // private function getFirstNonNullVector(index)
+        // returns the first non null vector from index : curve[index + N].subtract(curve[index])
+        private _getFirstNonNullVector(index: number): Vector3 {
+            var i = 1;
+            var nNVector: Vector3 = this._curve[index + i].subtract(this._curve[index]);
+            while (nNVector.length() == 0 && index + i + 1 < this._curve.length) {
+                i++;
+                nNVector = this._curve[index + i].subtract(this._curve[index]);
+            }
+            return nNVector;
+        }
 
-            if (vt.x !== 1) {     // search for a point in the plane
-                point = new Vector3(1, 0, 0);
+        // private function getLastNonNullVector(index)
+        // returns the last non null vector from index : curve[index].subtract(curve[index - N])
+        private _getLastNonNullVector(index: number): Vector3 {
+            var i = 1;
+            var nLVector: Vector3 = this._curve[index].subtract(this._curve[index - i]);
+            while (nLVector.length() == 0 && index > i + 1) {
+                i++;
+                nLVector = this._curve[index].subtract(this._curve[index - i]);
             }
-            else if (vt.y !== 1) {
-                point = new Vector3(0, 1, 0);
+            return nLVector;
+        }
+
+        // private function normalVector(v0, vt, va) :
+        // returns an arbitrary point in the plane defined by the point v0 and the vector vt orthogonal to this plane
+        // if va is passed, it returns the va projection on the plane orthogonal to vt at the point v0
+        private _normalVector(v0: Vector3, vt: Vector3, va: Vector3): Vector3 {
+            var normal0: Vector3;
+            if (va === undefined || va === null) {
+                var point: Vector3;
+                if (vt.x !== 1) {     // search for a point in the plane
+                    point = new Vector3(1, 0, 0);
+                }
+                else if (vt.y !== 1) {
+                    point = new Vector3(0, 1, 0);
+                }
+                else if (vt.z !== 1) {
+                    point = new Vector3(0, 0, 1);
+                }
+                normal0 = Vector3.Cross(vt, point);
             }
-            else if (vt.z !== 1) {
-                point = new Vector3(0, 0, 1);
+            else {
+                normal0 = Vector3.Cross(vt, va);
+                Vector3.CrossToRef(normal0, vt, normal0);
+                //normal0 = Vector3.Cross(normal0, vt);
             }
-            var normal0: Vector3 = Vector3.Cross(vt, point);
-            normal0.normalize();
+            normal0.normalize();       
             return normal0;
         }
     }

+ 66 - 38
Babylon/Mesh/babylon.mesh.vertexData.ts

@@ -1161,48 +1161,76 @@
          * @param {any} - normals   (number[] or Float32Array)
          */
         public static ComputeNormals(positions: any, indices: any, normals: any) {
-            var positionVectors = [];
-            var facesOfVertices = [];
-            var index;
-
-            for (index = 0; index < positions.length; index += 3) {
-                var vector3 = new Vector3(<number> positions[index], <number> positions[index + 1], <number> positions[index + 2]);
-                positionVectors.push(vector3);
-                facesOfVertices.push([]);
-            }
-            // Compute normals
-            var facesNormals = [];
-            for (index = 0; index < indices.length / 3; index++) {
+            var index = 0;
+            
+            // temp Vector3
+            var p1 = BABYLON.Vector3.Zero();
+            var p2 = BABYLON.Vector3.Zero();
+            var p3 = BABYLON.Vector3.Zero();
+            var p1p2 = BABYLON.Vector3.Zero();
+            var p3p2 = BABYLON.Vector3.Zero();
+            var faceNormal = BABYLON.Vector3.Zero();
+            
+            var vertexNormali1 = BABYLON.Vector3.Zero();
+            var vertexNormali2 = BABYLON.Vector3.Zero();
+            var vertexNormali3 = BABYLON.Vector3.Zero();
+            
+            // indice triplet = 1 face
+            var nbFaces = indices.length / 3;
+            for (index = 0; index < nbFaces; index++) {
                 var i1 = indices[index * 3];
                 var i2 = indices[index * 3 + 1];
                 var i3 = indices[index * 3 + 2];
-
-                var p1 = positionVectors[i1];
-                var p2 = positionVectors[i2];
-                var p3 = positionVectors[i3];
-
-                var p1p2 = p1.subtract(p2);
-                var p3p2 = p3.subtract(p2);
-
-                facesNormals[index] = Vector3.Normalize(Vector3.Cross(p1p2, p3p2));
-                facesOfVertices[i1].push(index);
-                facesOfVertices[i2].push(index);
-                facesOfVertices[i3].push(index);
+                
+                // setting the temp V3
+                BABYLON.Vector3.FromFloatsToRef(positions[i1 * 3], positions[i1 * 3 + 1], positions[i1 * 3 + 2] , p1);
+                BABYLON.Vector3.FromFloatsToRef(positions[i2 * 3], positions[i2 * 3 + 1], positions[i2 * 3 + 2] , p2);
+                BABYLON.Vector3.FromFloatsToRef(positions[i3 * 3], positions[i3 * 3 + 1], positions[i3 * 3 + 2] , p3);
+                
+                p1.subtractToRef(p2, p1p2);
+                p3.subtractToRef(p2, p3p2);
+                
+                BABYLON.Vector3.CrossToRef(p1p2, p3p2, faceNormal);
+                faceNormal.normalize();
+    
+                // All intermediate results are stored in the normals array :
+                // get the normals at i1, i2 and i3 indexes
+                normals[i1 * 3]     = normals[i1 * 3]     || 0.0;
+                normals[i1 * 3 + 1] = normals[i1 * 3 + 1] || 0.0;
+                normals[i1 * 3 + 2] = normals[i1 * 3 + 2] || 0.0;
+                normals[i2 * 3]     = normals[i2 * 3]     || 0.0;
+                normals[i2 * 3 + 1] = normals[i2 * 3 + 1] || 0.0;
+                normals[i2 * 3 + 2] = normals[i2 * 3 + 2] || 0.0; 
+                normals[i3 * 3]     = normals[i3 * 3]     || 0.0;
+                normals[i3 * 3 + 1] = normals[i3 * 3 + 1] || 0.0;
+                normals[i3 * 3 + 2] = normals[i3 * 3 + 2] || 0.0;
+                // make intermediate vectors3 from normals values
+                BABYLON.Vector3.FromFloatsToRef(normals[i1 * 3], normals[i1 * 3 + 1], normals[i1 * 3 + 2] , vertexNormali1);
+                BABYLON.Vector3.FromFloatsToRef(normals[i2 * 3], normals[i2 * 3 + 1], normals[i2 * 3 + 2] , vertexNormali2);
+                BABYLON.Vector3.FromFloatsToRef(normals[i3 * 3], normals[i3 * 3 + 1], normals[i3 * 3 + 2] , vertexNormali3);
+                // add the current face normals to these intermediate vectors3
+                vertexNormali1 = vertexNormali1.addInPlace(faceNormal);
+                vertexNormali2 = vertexNormali2.addInPlace(faceNormal);
+                vertexNormali3 = vertexNormali3.addInPlace(faceNormal);
+                // store back intermediate vectors3 into the normals array
+                normals[i1 * 3]     = vertexNormali1.x;
+                normals[i1 * 3 + 1] = vertexNormali1.y;
+                normals[i1 * 3 + 2] = vertexNormali1.z;
+                normals[i2 * 3]     = vertexNormali2.x;
+                normals[i2 * 3 + 1] = vertexNormali2.y;
+                normals[i2 * 3 + 2] = vertexNormali2.z;
+                normals[i3 * 3]     = vertexNormali3.x;
+                normals[i3 * 3 + 1] = vertexNormali3.y;
+                normals[i3 * 3 + 2] = vertexNormali3.z;
             }
-
-            for (index = 0; index < positionVectors.length; index++) {
-                var faces = facesOfVertices[index];
-
-                var normal = Vector3.Zero();
-                for (var faceIndex = 0; faceIndex < faces.length; faceIndex++) {
-                    normal.addInPlace(facesNormals[faces[faceIndex]]);
-                }
-
-                normal = Vector3.Normalize(normal.scale(1.0 / faces.length));
-
-                normals[index * 3] = normal.x;
-                normals[index * 3 + 1] = normal.y;
-                normals[index * 3 + 2] = normal.z;
+            
+            // last normalization
+            for (index = 0; index < normals.length / 3; index++) {
+                BABYLON.Vector3.FromFloatsToRef(normals[index * 3], normals[index * 3 + 1], normals[index * 3 + 2] , vertexNormali1);
+                vertexNormali1.normalize();
+                normals[index * 3]     = vertexNormali1.x;
+                normals[index * 3 + 1] = vertexNormali1.y;
+                normals[index * 3 + 2] = vertexNormali1.z;    
             }
         }