Browse Source

Integrating CSG into build process

Deltakosh 11 years ago
parent
commit
cca4c98103

+ 97 - 96
Babylon/Mesh/babylon.csg.js

@@ -1,26 +1,23 @@
-"use strict";
+"use strict";
 
 var BABYLON = BABYLON || {};
 
 // Constructive Solid Geometry for BABYLON
 // Based on https://github.com/evanw/csg.js/
-(function() {
+(function () {
 
     // Unique ID when we import meshes from Babylon to CSG
     var _currentCSGMeshId = 0;
 
-    BABYLON.CSG = function() {
+    BABYLON.CSG = function () {
         this.polygons = [];
     };
 
     // Convert BABYLON.Mesh to BABYLON.CSG
-    BABYLON.CSG.FromMesh = function( mesh ) {
-        var vertex, normal, uv, position,
-            polygon,
-            polygons = [],
-            vertices;
+    BABYLON.CSG.FromMesh = function (mesh) {
+        var vertex, normal, uv, position, polygon, polygons = [], vertices;
 
-        if ( mesh instanceof BABYLON.Mesh ) {
+        if (mesh instanceof BABYLON.Mesh) {
             mesh.computeWorldMatrix(true);
             this.matrix = mesh.getWorldMatrix();
             this.position = mesh.position.clone();
@@ -37,53 +34,53 @@ var BABYLON = BABYLON || {};
 
         var subMeshes = mesh.subMeshes;
 
-        for ( var sm = 0, sml = subMeshes.length; sm < sml; sm++ ) {
-            for ( var i = subMeshes[sm].indexStart, il = subMeshes[sm].indexCount + subMeshes[sm].indexStart; i < il; i += 3 ) {
+        for (var sm = 0, sml = subMeshes.length; sm < sml; sm++) {
+            for (var i = subMeshes[sm].indexStart, il = subMeshes[sm].indexCount + subMeshes[sm].indexStart; i < il; i += 3) {
                 vertices = [];
                 for (var j = 0; j < 3; j++) {
                     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]);
-                    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, this.matrix);
                     normal = BABYLON.Vector3.TransformNormal(normal, this.matrix);
 
-                    vertex = new BABYLON.CSG.Vertex( position, normal, uv );
-                    vertices.push( vertex );
+                    vertex = new BABYLON.CSG.Vertex(position, normal, uv);
+                    vertices.push(vertex);
                 }
 
-                polygon = new BABYLON.CSG.Polygon(vertices, { subMeshId : sm, meshId : _currentCSGMeshId, materialIndex : subMeshes[sm].materialIndex });
-                polygons.push( polygon );
+                polygon = new BABYLON.CSG.Polygon(vertices, { subMeshId: sm, meshId: _currentCSGMeshId, materialIndex: subMeshes[sm].materialIndex });
+                polygons.push(polygon);
             }
         }
 
-        var csg = BABYLON.CSG.fromPolygons( polygons );
+        var csg = BABYLON.CSG.fromPolygons(polygons);
         csg.copyTransformAttributes(this);
-        _currentCSGMeshId++
+        _currentCSGMeshId++;
 
         return csg;
     };
 
 
     // Construct a BABYLON.CSG solid from a list of `BABYLON.CSG.Polygon` instances.
-    BABYLON.CSG.fromPolygons = function(polygons) {
+    BABYLON.CSG.fromPolygons = function (polygons) {
         var csg = new BABYLON.CSG();
         csg.polygons = polygons;
         return csg;
     };
 
     BABYLON.CSG.prototype = {
-        clone: function() {
+        clone: function () {
             var csg = new BABYLON.CSG();
-            csg.polygons = this.polygons.map(function(p) { return p.clone(); });
+            csg.polygons = this.polygons.map(function (p) { return p.clone(); });
             csg.copyTransformAttributes(this);
             return csg;
         },
 
-        toPolygons: function() {
+        toPolygons: function () {
             return this.polygons;
         },
 
-        union: function(csg) {
+        union: function (csg) {
             var a = new BABYLON.CSG.Node(this.clone().polygons);
             var b = new BABYLON.CSG.Node(csg.clone().polygons);
             a.clipTo(b);
@@ -95,7 +92,7 @@ var BABYLON = BABYLON || {};
             return BABYLON.CSG.fromPolygons(a.allPolygons()).copyTransformAttributes(this);
         },
 
-        subtract: function(csg) {
+        subtract: function (csg) {
             var a = new BABYLON.CSG.Node(this.clone().polygons);
             var b = new BABYLON.CSG.Node(csg.clone().polygons);
             a.invert();
@@ -109,7 +106,7 @@ var BABYLON = BABYLON || {};
             return BABYLON.CSG.fromPolygons(a.allPolygons()).copyTransformAttributes(this);
         },
 
-        intersect: function(csg) {
+        intersect: function (csg) {
             var a = new BABYLON.CSG.Node(this.clone().polygons);
             var b = new BABYLON.CSG.Node(csg.clone().polygons);
             a.invert();
@@ -124,9 +121,9 @@ var BABYLON = BABYLON || {};
 
         // Return a new BABYLON.CSG solid with solid and empty space switched. This solid is
         // not modified.
-        inverse: function() {
+        inverse: function () {
             var csg = this.clone();
-            csg.polygons.map(function(p) { p.flip(); });
+            csg.polygons.map(function (p) { p.flip(); });
             return csg;
         }
     };
@@ -134,27 +131,27 @@ var BABYLON = BABYLON || {};
     // This is used to keep meshes transformations so they can be restored
     // when we build back a Babylon Mesh
     // NB : All CSG operations are performed in world coordinates
-    BABYLON.CSG.prototype.copyTransformAttributes = function (object) {
+    BABYLON.CSG.prototype.copyTransformAttributes = function(object) {
         this.matrix = object.matrix;
         this.position = object.position;
         this.rotation = object.rotation;
         this.scaling = object.scaling;
 
         return this;
-    }
+    };
 
     // Build Raw mesh from CSG
     // Coordinates here are in world space
-    BABYLON.CSG.prototype.buildMeshGeometry = function(name, scene, keepSubMeshes) {
+    BABYLON.CSG.prototype.buildMeshGeometry = function (name, scene, keepSubMeshes) {
         var matrix = this.matrix.clone();
         matrix.invert();
 
         var mesh = new BABYLON.Mesh(name, scene),
-            vertices = [], 
-            indices = [], 
+            vertices = [],
+            indices = [],
             normals = [],
             uvs = [],
-            vertex, normal, uv, 
+            vertex, normal, uv,
             polygons = this.polygons,
             polygonIndices = [0, 0, 0],
             polygon,
@@ -166,15 +163,16 @@ var BABYLON = BABYLON || {};
 
         if (keepSubMeshes) {
             // Sort Polygons, since subMeshes are indices range
-            polygons.sort(function (a,b) { 
-                if (a.shared.meshId === b.shared.meshId)
-                    return a.shared.subMeshId - b.shared.subMeshId; 
-                else 
+            polygons.sort(function (a, b) {
+                if (a.shared.meshId === b.shared.meshId) {
+                    return a.shared.subMeshId - b.shared.subMeshId;
+                } else {
                     return a.shared.meshId - b.shared.meshId;
-            });            
+                }
+            });
         }
 
-        for ( var i = 0, il = polygons.length; i < il; i++ ) {
+        for (var i = 0, il = polygons.length; i < il; i++) {
             polygon = polygons[i];
 
             // Building SubMeshes
@@ -182,16 +180,17 @@ var BABYLON = BABYLON || {};
                 subMesh_dict[polygon.shared.meshId] = {};
             }
             if (!subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId]) {
-                subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId] = { indexStart : +Infinity, 
-                                                                                  indexEnd : -Infinity, 
-                                                                                  materialIndex : polygon.shared.materialIndex
-                                                                                };
+                subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId] = {
+                    indexStart: +Infinity,
+                    indexEnd: -Infinity,
+                    materialIndex: polygon.shared.materialIndex
+                };
             }
             subMesh_obj = subMesh_dict[polygon.shared.meshId][polygon.shared.subMeshId];
 
-            
-            for ( var j = 2, jl = polygon.vertices.length; j < jl; j++ ) {
-                
+
+            for (var j = 2, jl = polygon.vertices.length; j < jl; j++) {
+
                 polygonIndices[0] = 0;
                 polygonIndices[1] = j - 1;
                 polygonIndices[2] = j;
@@ -200,36 +199,35 @@ var BABYLON = BABYLON || {};
                     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 = 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_idx = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ];
+
+                    vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z];
 
                     // Check if 2 points can be merged
-                    if (!(typeof vertex_idx !== 'undefined' && 
+                    if (!(typeof vertex_idx !== 'undefined' &&
                          normals[vertex_idx * 3] === normal.x &&
                          normals[vertex_idx * 3 + 1] === normal.y &&
                          normals[vertex_idx * 3 + 2] === normal.z &&
                          uvs[vertex_idx * 2] === uv.x &&
-                         uvs[vertex_idx * 2 + 1] === uv.y)) 
-                    {
-                        vertices.push( vertex.x, vertex.y, vertex.z );
+                         uvs[vertex_idx * 2 + 1] === uv.y)) {
+                        vertices.push(vertex.x, vertex.y, vertex.z);
                         uvs.push(uv.x, uv.y);
                         normals.push(normal.x, normal.y, normal.z);
-                        vertex_idx = vertice_dict[ vertex.x + ',' + vertex.y + ',' + vertex.z ] = (vertices.length / 3) - 1;
+                        vertex_idx = vertice_dict[vertex.x + ',' + vertex.y + ',' + vertex.z] = (vertices.length / 3) - 1;
                     }
 
                     indices.push(vertex_idx);
 
                     subMesh_obj.indexStart = Math.min(currentIndex, subMesh_obj.indexStart);
                     subMesh_obj.indexEnd = Math.max(currentIndex, subMesh_obj.indexEnd);
-                    currentIndex++
+                    currentIndex++;
                 }
 
             }
-            
+
         }
 
         mesh.setVerticesData(vertices, BABYLON.VertexBuffer.PositionKind);
@@ -259,16 +257,16 @@ var BABYLON = BABYLON || {};
     };
 
     // Build Mesh from CSG taking material and transforms into account
-    BABYLON.CSG.prototype.toMesh = function( name, material, scene, keepSubMeshes ) {
+    BABYLON.CSG.prototype.toMesh = function (name, material, scene, keepSubMeshes) {
         var mesh = this.buildMeshGeometry(name, scene, keepSubMeshes);
-        
+
         mesh.material = material;
 
         mesh.position.copyFrom(this.position);
         mesh.rotation.copyFrom(this.rotation);
         mesh.scaling.copyFrom(this.scaling);
         mesh.computeWorldMatrix(true);
-        
+
         return mesh;
     };
 
@@ -282,7 +280,7 @@ var BABYLON = BABYLON || {};
     //         new BABYLON.CSG.Vector([1, 2, 3]);
     //         new BABYLON.CSG.Vector({ x: 1, y: 2, z: 3 });
 
-    BABYLON.CSG.Vector = function(x, y, z) {
+    BABYLON.CSG.Vector = function (x, y, z) {
         if (arguments.length == 3) {
             this.x = x;
             this.y = y;
@@ -299,47 +297,47 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.CSG.Vector.prototype = {
-        clone: function() {
+        clone: function () {
             return new BABYLON.CSG.Vector(this.x, this.y, this.z);
         },
 
-        negated: function() {
+        negated: function () {
             return new BABYLON.CSG.Vector(-this.x, -this.y, -this.z);
         },
 
-        plus: function(a) {
+        plus: function (a) {
             return new BABYLON.CSG.Vector(this.x + a.x, this.y + a.y, this.z + a.z);
         },
 
-        minus: function(a) {
+        minus: function (a) {
             return new BABYLON.CSG.Vector(this.x - a.x, this.y - a.y, this.z - a.z);
         },
 
-        times: function(a) {
+        times: function (a) {
             return new BABYLON.CSG.Vector(this.x * a, this.y * a, this.z * a);
         },
 
-        dividedBy: function(a) {
+        dividedBy: function (a) {
             return new BABYLON.CSG.Vector(this.x / a, this.y / a, this.z / a);
         },
 
-        dot: function(a) {
+        dot: function (a) {
             return this.x * a.x + this.y * a.y + this.z * a.z;
         },
 
-        lerp: function(a, t) {
+        lerp: function (a, t) {
             return this.plus(a.minus(this).times(t));
         },
 
-        length: function() {
+        length: function () {
             return Math.sqrt(this.dot(this));
         },
 
-        unit: function() {
+        unit: function () {
             return this.dividedBy(this.length());
         },
 
-        cross: function(a) {
+        cross: function (a) {
             return new BABYLON.CSG.Vector(
                 this.y * a.z - this.z * a.y,
                 this.z * a.x - this.x * a.z,
@@ -359,27 +357,27 @@ var BABYLON = BABYLON || {};
     // is not used anywhere else. 
     // Same goes for uv, it allows to keep the original vertex uv coordinates of the 2 meshes
 
-    BABYLON.CSG.Vertex = function(pos, normal, uv) {
+    BABYLON.CSG.Vertex = function (pos, normal, uv) {
         this.pos = new BABYLON.CSG.Vector(pos);
         this.normal = new BABYLON.CSG.Vector(normal);
         this.uv = new BABYLON.CSG.Vector(uv.x, uv.y, 0);
     };
 
     BABYLON.CSG.Vertex.prototype = {
-        clone: function() {
+        clone: function () {
             return new BABYLON.CSG.Vertex(this.pos.clone(), this.normal.clone(), this.uv.clone());
         },
 
         // Invert all orientation-specific data (e.g. vertex normal). Called when the
         // orientation of a polygon is flipped.
-        flip: function() {
+        flip: function () {
             this.normal = this.normal.negated();
         },
 
         // Create a new vertex between this vertex and `other` by linearly
         // interpolating all properties using a parameter of `t`. Subclasses should
         // override this to interpolate additional properties.
-        interpolate: function(other, t) {
+        interpolate: function (other, t) {
             return new BABYLON.CSG.Vertex(
                 this.pos.lerp(other.pos, t),
                 this.normal.lerp(other.normal, t),
@@ -392,7 +390,7 @@ var BABYLON = BABYLON || {};
 
     // Represents a plane in 3D space.
 
-    BABYLON.CSG.Plane = function(normal, w) {
+    BABYLON.CSG.Plane = function (normal, w) {
         this.normal = normal;
         this.w = w;
     };
@@ -401,17 +399,17 @@ var BABYLON = BABYLON || {};
     // point is on the plane.
     BABYLON.CSG.Plane.EPSILON = 1e-5;
 
-    BABYLON.CSG.Plane.fromPoints = function(a, b, c) {
+    BABYLON.CSG.Plane.fromPoints = function (a, b, c) {
         var n = c.minus(a).cross(b.minus(a)).unit();
         return new BABYLON.CSG.Plane(n, n.dot(a));
     };
 
     BABYLON.CSG.Plane.prototype = {
-        clone: function() {
+        clone: function () {
             return new BABYLON.CSG.Plane(this.normal.clone(), this.w);
         },
 
-        flip: function() {
+        flip: function () {
             this.normal = this.normal.negated();
             this.w = -this.w;
         },
@@ -421,7 +419,7 @@ var BABYLON = BABYLON || {};
         // `coplanarFront` or `coplanarBack` depending on their orientation with
         // respect to this plane. Polygons in front or in back of this plane go into
         // either `front` or `back`.
-        splitPolygon: function(polygon, coplanarFront, coplanarBack, front, back) {
+        splitPolygon: function (polygon, coplanarFront, coplanarBack, front, back) {
             var COPLANAR = 0;
             var FRONT = 1;
             var BACK = 2;
@@ -482,20 +480,20 @@ var BABYLON = BABYLON || {};
     // polygons that are clones of each other or were split from the same polygon.
     // This can be used to define per-polygon properties (such as surface color).
 
-    BABYLON.CSG.Polygon = function(vertices, shared) {
+    BABYLON.CSG.Polygon = function (vertices, shared) {
         this.vertices = vertices;
         this.shared = shared;
         this.plane = BABYLON.CSG.Plane.fromPoints(vertices[0].pos, vertices[1].pos, vertices[2].pos);
     };
 
     BABYLON.CSG.Polygon.prototype = {
-        clone: function() {
-            var vertices = this.vertices.map(function(v) { return v.clone(); });
+        clone: function () {
+            var vertices = this.vertices.map(function (v) { return v.clone(); });
             return new BABYLON.CSG.Polygon(vertices, this.shared);
         },
 
-        flip: function() {
-            this.vertices.reverse().map(function(v) { v.flip(); });
+        flip: function () {
+            this.vertices.reverse().map(function (v) { v.flip(); });
             this.plane.flip();
         }
     };
@@ -508,7 +506,7 @@ var BABYLON = BABYLON || {};
     // the front and/or back subtrees. This is not a leafy BSP tree since there is
     // no distinction between internal and leaf nodes.
 
-    BABYLON.CSG.Node = function(polygons) {
+    BABYLON.CSG.Node = function (polygons) {
         this.plane = null;
         this.front = null;
         this.back = null;
@@ -517,17 +515,17 @@ var BABYLON = BABYLON || {};
     };
 
     BABYLON.CSG.Node.prototype = {
-        clone: function() {
+        clone: function () {
             var node = new BABYLON.CSG.Node();
             node.plane = this.plane && this.plane.clone();
             node.front = this.front && this.front.clone();
             node.back = this.back && this.back.clone();
-            node.polygons = this.polygons.map(function(p) { return p.clone(); });
+            node.polygons = this.polygons.map(function (p) { return p.clone(); });
             return node;
         },
 
         // Convert solid space to empty space and empty space to solid space.
-        invert: function() {
+        invert: function () {
             for (var i = 0; i < this.polygons.length; i++) {
                 this.polygons[i].flip();
             }
@@ -541,28 +539,31 @@ var BABYLON = BABYLON || {};
 
         // Recursively remove all polygons in `polygons` that are inside this BSP
         // tree.
-        clipPolygons: function(polygons) {
+        clipPolygons: function (polygons) {
             if (!this.plane) return polygons.slice();
             var front = [], back = [];
             for (var i = 0; i < polygons.length; i++) {
                 this.plane.splitPolygon(polygons[i], front, back, front, back);
             }
             if (this.front) front = this.front.clipPolygons(front);
-            if (this.back) back = this.back.clipPolygons(back);
-            else back = [];
+            if (this.back) {
+                back = this.back.clipPolygons(back);
+            } else {
+                back = [];
+            }
             return front.concat(back);
         },
 
         // Remove all polygons in this BSP tree that are inside the other BSP tree
         // `bsp`.
-        clipTo: function(bsp) {
+        clipTo: function (bsp) {
             this.polygons = bsp.clipPolygons(this.polygons);
             if (this.front) this.front.clipTo(bsp);
             if (this.back) this.back.clipTo(bsp);
         },
 
         // Return a list of all polygons in this BSP tree.
-        allPolygons: function() {
+        allPolygons: function () {
             var polygons = this.polygons.slice();
             if (this.front) polygons = polygons.concat(this.front.allPolygons());
             if (this.back) polygons = polygons.concat(this.back.allPolygons());
@@ -573,7 +574,7 @@ var BABYLON = BABYLON || {};
         // new polygons are filtered down to the bottom of the tree and become new
         // nodes there. Each set of polygons is partitioned using the first polygon
         // (no heuristic is used to pick a good split).
-        build: function(polygons) {
+        build: function (polygons) {
             if (!polygons.length) return;
             if (!this.plane) this.plane = polygons[0].plane.clone();
             var front = [], back = [];

+ 1 - 0
Tools/BuildOurOwnBabylonJS/BuildOurOwnBabylonJS/babylonJS.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8" ?>
 <files xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="babylonJS.xsd">
+  <script src="Babylon/Mesh/babylon.csg.js"></script>
   <script src="Babylon/Tools/babylon.sceneSerializer.js"></script>
   <script src="Babylon/Physics/babylon.physicsEngine.js"></script>
   <script src="Babylon/Tools/babylon.filesInput.js"></script>

File diff suppressed because it is too large
+ 1 - 1
babylon.1.9.0.js