浏览代码

BugFix and GC optimisation on CSG

I add functions to make operation on the same csg element. It avoids the clone of all the polygons and avoids GC event.
Clément Levasseur 11 年之前
父节点
当前提交
dbbd72993d
共有 1 个文件被更改,包括 70 次插入18 次删除
  1. 70 18
      Babylon/Mesh/babylon.csg.js

+ 70 - 18
Babylon/Mesh/babylon.csg.js

@@ -1,4 +1,4 @@
-var BABYLON;
+var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     // Unique ID when we import meshes from Babylon to CSG
     // Unique ID when we import meshes from Babylon to CSG
     var currentCSGMeshId = 0;
     var currentCSGMeshId = 0;
@@ -52,7 +52,7 @@
                 return null;
                 return null;
             }
             }
 
 
-            var n = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(c.subtract(a), b.subtract(a)));
+            var n = BABYLON.Vector3.Normalize(BABYLON.Vector3.Cross(v0, v1));
             return new Plane(n, BABYLON.Vector3.Dot(n, a));
             return new Plane(n, BABYLON.Vector3.Dot(n, a));
         };
         };
 
 
@@ -61,7 +61,7 @@
         };
         };
 
 
         Plane.prototype.flip = function () {
         Plane.prototype.flip = function () {
-            this.normal = this.normal.scale(-1);
+            this.normal.scaleInPlace(-1);
             this.w = -this.w;
             this.w = -this.w;
         };
         };
 
 
@@ -114,10 +114,16 @@
                             b.push(v.clone());
                             b.push(v.clone());
                         }
                         }
                     }
                     }
-                    if (f.length >= 3)
-                        front.push(new Polygon(f, polygon.shared));
-                    if (b.length >= 3)
-                        back.push(new Polygon(b, polygon.shared));
+                    if (f.length >= 3) {
+                        var poly = new Polygon(f, polygon.shared);
+                        if (poly.plane)
+                            front.push(poly);
+                    }
+                    if (b.length >= 3) {
+                        var poly = new Polygon(b, polygon.shared);
+                        if (poly.plane)
+                            back.push(poly);
+                    }
                     break;
                     break;
             }
             }
         };
         };
@@ -186,7 +192,9 @@
             for (var i = 0; i < this.polygons.length; i++) {
             for (var i = 0; i < this.polygons.length; i++) {
                 this.polygons[i].flip();
                 this.polygons[i].flip();
             }
             }
-            this.plane.flip();
+            if (this.plane) {
+                this.plane.flip();
+            }
             if (this.front) {
             if (this.front) {
                 this.front.invert();
                 this.front.invert();
             }
             }
@@ -294,8 +302,8 @@
                         normal = new BABYLON.Vector3(normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
                         normal = new BABYLON.Vector3(normals[indices[i + j] * 3], normals[indices[i + j] * 3 + 1], normals[indices[i + j] * 3 + 2]);
                         uv = new BABYLON.Vector2(uvs[indices[i + j] * 2], uvs[indices[i + j] * 2 + 1]);
                         uv = new BABYLON.Vector2(uvs[indices[i + j] * 2], uvs[indices[i + j] * 2 + 1]);
                         position = new BABYLON.Vector3(positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
                         position = new BABYLON.Vector3(positions[indices[i + j] * 3], positions[indices[i + j] * 3 + 1], positions[indices[i + j] * 3 + 2]);
-                        position = BABYLON.Vector3.TransformCoordinates(position, matrix);
-                        normal = BABYLON.Vector3.TransformNormal(normal, matrix);
+                        BABYLON.Vector3.TransformCoordinatesToRef(position, matrix, position);
+                        BABYLON.Vector3.TransformNormalToRef(normal, matrix, normal);
 
 
                         vertex = new Vertex(position, normal, uv);
                         vertex = new Vertex(position, normal, uv);
                         vertices.push(vertex);
                         vertices.push(vertex);
@@ -340,6 +348,19 @@
             return this.polygons;
             return this.polygons;
         };
         };
 
 
+        CSG.prototype.unionInPlace = function (csg) {
+            var a = new Node(this.polygons);
+            var b = new Node(csg.polygons);
+            a.clipTo(b);
+            b.clipTo(a);
+            b.invert();
+            b.clipTo(a);
+            b.invert();
+            a.build(b.allPolygons());
+
+            this.polygons = a.allPolygons();
+        },
+
         CSG.prototype.union = function (csg) {
         CSG.prototype.union = function (csg) {
             var a = new Node(this.clone().polygons);
             var a = new Node(this.clone().polygons);
             var b = new Node(csg.clone().polygons);
             var b = new Node(csg.clone().polygons);
@@ -352,6 +373,21 @@
             return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
             return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
         };
         };
 
 
+        CSG.prototype.subtractInPlace = function (csg) {
+            var a = new Node(this.polygons);
+            var b = new Node(csg.polygons);
+            a.invert();
+            a.clipTo(b);
+            b.clipTo(a);
+            b.invert();
+            b.clipTo(a);
+            b.invert();
+            a.build(b.allPolygons());
+            a.invert();
+            
+            this.polygons = a.allPolygons();
+        },
+
         CSG.prototype.subtract = function (csg) {
         CSG.prototype.subtract = function (csg) {
             var a = new Node(this.clone().polygons);
             var a = new Node(this.clone().polygons);
             var b = new Node(csg.clone().polygons);
             var b = new Node(csg.clone().polygons);
@@ -366,6 +402,20 @@
             return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
             return CSG.FromPolygons(a.allPolygons()).copyTransformAttributes(this);
         };
         };
 
 
+        CSG.prototype.intersectInPlace = function (csg) {
+            var a = new Node(this.polygons);
+            var b = new Node(csg.polygons);
+            a.invert();
+            b.clipTo(a);
+            b.invert();
+            a.clipTo(b);
+            b.clipTo(a);
+            a.build(b.allPolygons());
+            a.invert();
+
+            this.polygons = a.allPolygons();
+        },
+
         CSG.prototype.intersect = function (csg) {
         CSG.prototype.intersect = function (csg) {
             var a = new Node(this.clone().polygons);
             var a = new Node(this.clone().polygons);
             var b = new Node(csg.clone().polygons);
             var b = new Node(csg.clone().polygons);
@@ -381,6 +431,10 @@
 
 
         // Return a new BABYLON.CSG solid with solid and empty space switched. This solid is
         // Return a new BABYLON.CSG solid with solid and empty space switched. This solid is
         // not modified.
         // not modified.
+        CSG.prototype.inverseInPlace = function () {
+            this.polygons.map(function (p) { p.flip(); });
+        }, 
+
         CSG.prototype.inverse = function () {
         CSG.prototype.inverse = function () {
             var csg = this.clone();
             var csg = this.clone();
             csg.polygons.map(function (p) {
             csg.polygons.map(function (p) {
@@ -407,7 +461,7 @@
             var matrix = this.matrix.clone();
             var matrix = this.matrix.clone();
             matrix.invert();
             matrix.invert();
 
 
-            var mesh = new BABYLON.Mesh(name, scene), vertices = [], indices = [], normals = [], uvs = [], vertex, normal, uv, polygons = this.polygons, polygonIndices = [0, 0, 0], polygon, vertice_dict = {}, vertex_idx, currentIndex = 0, subMesh_dict = {}, subMesh_obj;
+            var mesh = new BABYLON.Mesh(name, scene), vertices = [], indices = [], normals = [], uvs = [], vertex = BABYLON.Vector3.Zero(), normal = BABYLON.Vector3.Zero(), uv = BABYLON.Vector2.Zero(), polygons = this.polygons, polygonIndices = [0, 0, 0], polygon, vertice_dict = {}, vertex_idx, currentIndex = 0, subMesh_dict = {}, subMesh_obj;
 
 
             if (keepSubMeshes) {
             if (keepSubMeshes) {
                 // Sort Polygons, since subMeshes are indices range
                 // Sort Polygons, since subMeshes are indices range
@@ -442,13 +496,11 @@
                     polygonIndices[2] = j;
                     polygonIndices[2] = j;
 
 
                     for (var k = 0; k < 3; k++) {
                     for (var k = 0; k < 3; k++) {
-                        vertex = polygon.vertices[polygonIndices[k]].pos;
-                        normal = polygon.vertices[polygonIndices[k]].normal;
-                        uv = polygon.vertices[polygonIndices[k]].uv;
-                        vertex = new BABYLON.Vector3(vertex.x, vertex.y, vertex.z);
-                        normal = new BABYLON.Vector3(normal.x, normal.y, normal.z);
-                        vertex = BABYLON.Vector3.TransformCoordinates(vertex, matrix);
-                        normal = BABYLON.Vector3.TransformNormal(normal, matrix);
+                        vertex.copyFrom(polygon.vertices[polygonIndices[k]].pos);
+                        normal.copyFrom(polygon.vertices[polygonIndices[k]].normal);
+                        uv.copyFrom(polygon.vertices[polygonIndices[k]].uv);
+                        BABYLON.Vector3.TransformCoordinatesToRef(vertex, matrix, vertex);
+                        BABYLON.Vector3.TransformNormalToRef(normal, matrix, normal);
 
 
                         vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
                         vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];