浏览代码

Merge pull request #457 from jbousquie/feature.updateOtherMeshPositions

Feature.update other mesh positions
David Catuhe 10 年之前
父节点
当前提交
b00ec97b1d
共有 1 个文件被更改,包括 141 次插入68 次删除
  1. 141 68
      Babylon/Mesh/babylon.mesh.ts

+ 141 - 68
Babylon/Mesh/babylon.mesh.ts

@@ -434,14 +434,16 @@
         // updates the mesh positions according to the positionFunction returned values.
         // The positionFunction argument must be a javascript function accepting the mesh "positions" array as parameter.
         // This dedicated positionFunction computes new mesh positions according to the given mesh type.
-        public updateMeshPositions(positionFunction): void {
+        public updateMeshPositions(positionFunction, computeNormals: boolean = true): void {
             var positions = this.getVerticesData(BABYLON.VertexBuffer.PositionKind);
             positionFunction(positions);
-            var indices = this.getIndices();
-            var normals = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
             this.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions, false, false);
-            BABYLON.VertexData.ComputeNormals(positions, indices, normals);
-            this.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals, false, false);
+            if (computeNormals) {
+                var indices = this.getIndices();
+                var normals = this.getVerticesData(BABYLON.VertexBuffer.NormalKind);
+                BABYLON.VertexData.ComputeNormals(positions, indices, normals);
+                this.updateVerticesData(BABYLON.VertexBuffer.NormalKind, normals, false, false);
+            }
         }
 
 
@@ -1195,7 +1197,7 @@
                 };
                 var sideOrientation = ribbonInstance.sideOrientation;
                 var positionFunction = positionsOfRibbon(pathArray, sideOrientation);
-                ribbonInstance.updateMeshPositions(positionFunction);
+                ribbonInstance.updateMeshPositions(positionFunction, true);
 
                 return ribbonInstance;
 
@@ -1270,58 +1272,105 @@
         }
 
         // Lines
-        public static CreateLines(name: string, points: Vector3[], scene: Scene, updatable?: boolean): LinesMesh {
-            var lines = new LinesMesh(name, scene, updatable);
+        public static CreateLines(name: string, points: Vector3[], scene: Scene, updatable?: boolean, linesInstance: LinesMesh = null): LinesMesh {
+            if (linesInstance) { // lines update
+                var positionsOfLines = function(points) {
+                    var positionFunction = function(positions) {
+                        var i = 0;
+                        for(var p = 0; p < points.length; p++) {
+                            positions[i] = points[p].x;
+                            positions[i + 1] = points[p].y;
+                            positions[i + 2] = points[p].z;
+                            i += 3;
+                        }
+                    };
+                    return positionFunction;
+                };
+                var positionFunction = positionsOfLines(points);
+                linesInstance.updateMeshPositions(positionFunction, false);
+
+                return linesInstance;
 
-            var vertexData = VertexData.CreateLines(points);
+            }
+            else { // lines creation
+
+                var lines = new LinesMesh(name, scene, updatable);
 
-            vertexData.applyToMesh(lines, updatable);
+                var vertexData = VertexData.CreateLines(points);
 
-            return lines;
+                vertexData.applyToMesh(lines, updatable);
+
+                return lines;
+            }
         }
 
         // Extrusion
-        public static ExtrudeShape(name: string, shape: Vector3[], path: Vector3[], scale: number, rotation: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
+        public static ExtrudeShape(name: string, shape: Vector3[], path: Vector3[], scale: number, rotation: number, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE, extrudedInstance: Mesh = null): Mesh {
             scale = scale || 1;
             rotation = rotation || 0;
-            var extruded = Mesh._ExtrudeShapeGeneric(name, shape, path, scale, rotation, null, null, false, false, false, scene, updatable, sideOrientation);
+            var extruded = Mesh._ExtrudeShapeGeneric(name, shape, path, scale, rotation, null, null, false, false, false, scene, updatable, sideOrientation, extrudedInstance);
             return extruded;
         }
 
-        public static ExtrudeShapeCustom(name: string, shape: Vector3[], path: Vector3[], scaleFunction, rotationFunction, ribbonCloseArray: boolean, ribbonClosePath: boolean, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
-            var extrudedCustom = Mesh._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, true, scene, updatable, sideOrientation);
+        public static ExtrudeShapeCustom(name: string, shape: Vector3[], path: Vector3[], scaleFunction, rotationFunction, ribbonCloseArray: boolean, ribbonClosePath: boolean, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE, extrudedInstance: Mesh = null): Mesh {
+            var extrudedCustom = Mesh._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, true, scene, updatable, sideOrientation, extrudedInstance);
             return extrudedCustom;
         }
 
-        private static _ExtrudeShapeGeneric(name: string, shape: Vector3[], curve: Vector3[], scale: number, rotation: number, scaleFunction: { (i: number, distance: number): number; }, rotateFunction: { (i: number, distance: number): number; }, rbCA: boolean, rbCP: boolean, custom: boolean, scene: Scene, updtbl: boolean, side: number): Mesh {
-            var path3D = new Path3D(curve);
-            var tangents = path3D.getTangents();
-            var normals = path3D.getNormals();
-            var binormals = path3D.getBinormals();
-            var distances = path3D.getDistances();
-            var shapePaths = new Array<Array<Vector3>>();
-            var angle = 0;
-            var returnScale: { (i: number, distance: number): number; } = (i, distance) => { return scale; };
-            var returnRotation: { (i: number, distance: number): number; } = (i, distance) => { return rotation; };
-            var rotate: { (i: number, distance: number): number; } = custom ? rotateFunction : returnRotation;
-            var scl: { (i: number, distance: number): number; } = custom ? scaleFunction : returnScale;
-
-            for (var i = 0; i < curve.length; i++) {
-                var shapePath = new Array<Vector3>();
-                var angleStep = rotate(i, distances[i]);
-                var scaleRatio = scl(i, distances[i]);
-                for (var p = 0; p < shape.length; p++) {
-                    var rotationMatrix = Matrix.RotationAxis(tangents[i], angle);
-                    var planed = ((tangents[i].scale(shape[p].z)).add(normals[i].scale(shape[p].x)).add(binormals[i].scale(shape[p].y)));
-                    var rotated = Vector3.TransformCoordinates(planed, rotationMatrix).scaleInPlace(scaleRatio).add(curve[i]);
-                    shapePath.push(rotated);
+        private static _ExtrudeShapeGeneric(name: string, shape: Vector3[], curve: Vector3[], scale: number, rotation: number, scaleFunction: { (i: number, distance: number): number; }, rotateFunction: { (i: number, distance: number): number; }, rbCA: boolean, rbCP: boolean, custom: boolean, scene: Scene, updtbl: boolean, side: number, instance: Mesh): Mesh {
+            
+            // extrusion geometry
+            var extrusionPathArray = function(shape, curve, path3D, shapePaths, scale, rotation, scaleFunction, rotateFunction, custom) {
+                var tangents = path3D.getTangents();
+                var normals = path3D.getNormals();
+                var binormals = path3D.getBinormals();
+                var distances = path3D.getDistances();
+                
+                var angle = 0;
+                var returnScale: { (i: number, distance: number): number; } = (i, distance) => { return scale; };
+                var returnRotation: { (i: number, distance: number): number; } = (i, distance) => { return rotation; };
+                var rotate: { (i: number, distance: number): number; } = custom ? rotateFunction : returnRotation;
+                var scl: { (i: number, distance: number): number; } = custom ? scaleFunction : returnScale;
+                var index = 0;
+
+                for (var i = 0; i < curve.length; i++) {
+                    var shapePath = new Array<Vector3>();
+                    var angleStep = rotate(i, distances[i]);
+                    var scaleRatio = scl(i, distances[i]);
+                    for (var p = 0; p < shape.length; p++) {
+                        var rotationMatrix = Matrix.RotationAxis(tangents[i], angle);
+                        var planed = ((tangents[i].scale(shape[p].z)).add(normals[i].scale(shape[p].x)).add(binormals[i].scale(shape[p].y)));
+                        var rotated = Vector3.TransformCoordinates(planed, rotationMatrix).scaleInPlace(scaleRatio).add(curve[i]);
+                        shapePath.push(rotated);
+                    }
+                    shapePaths[index] = shapePath;
+                    angle += angleStep;
+                    index++;
                 }
-                shapePaths.push(shapePath);
-                angle += angleStep;
+                return shapePaths;
+            };
+
+            if (instance) { // instance update
+                
+                var path3D = ((<any>instance).path3D).update(curve);
+                var pathArray = extrusionPathArray(shape, curve, (<any>instance).path3D, (<any>instance).pathArray, scale, rotation, scaleFunction, rotateFunction, custom);
+                instance = Mesh.CreateRibbon(null, pathArray, null, null, null, null, null, null, instance);
+
+                return instance;
+            }
+            else { // extruded shape creation
+
+                var path3D = <any>new Path3D(curve);
+                var newShapePaths = new Array<Array<Vector3>>();
+                var pathArray = extrusionPathArray(shape, curve, path3D, newShapePaths, scale, rotation, scaleFunction, rotateFunction, custom);
+
+                var extrudedGeneric = Mesh.CreateRibbon(name, pathArray, rbCA, rbCP, 0, scene, updtbl, side);
+                (<any>extrudedGeneric).pathArray = pathArray;
+                (<any>extrudedGeneric).path3D = path3D;
+
+                return extrudedGeneric;
             }
 
-            var extrudedGeneric = Mesh.CreateRibbon(name, shapePaths, rbCA, rbCP, 0, scene, updtbl, side);
-            return extrudedGeneric;
         }
 
         // Plane & ground
@@ -1395,35 +1444,59 @@
             return ground;
         }
 
-        public static CreateTube(name: string, path: Vector3[], radius: number, tesselation: number, radiusFunction: { (i: number, distance: number): number; }, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE): Mesh {
-            var path3D = new Path3D(path);
-            var tangents = path3D.getTangents();
-            var normals = path3D.getNormals();
-            var distances = path3D.getDistances();
-            var pi2 = Math.PI * 2;
-            var step = pi2 / tesselation;
-            var returnRadius: { (i: number, distance: number): number; } = (i, distance) => radius;
-            var radiusFunctionFinal: { (i: number, distance: number): number; } = radiusFunction || returnRadius;
-
-            var circlePaths = new Array<Array<Vector3>>();
-            var circlePath: Vector3[];
-            var rad: number;
-            var normal: Vector3;
-            var rotated: Vector3;
-            var rotationMatrix: Matrix;
-            for (var i = 0; i < path.length; i++) {
-                rad = radiusFunctionFinal(i, distances[i]); // current radius
-                circlePath = Array<Vector3>();              // current circle array
-                normal = normals[i];                        // current normal  
-                for (var ang = 0; ang < pi2; ang += step) {
-                    rotationMatrix = Matrix.RotationAxis(tangents[i], ang);
-                    rotated = Vector3.TransformCoordinates(normal, rotationMatrix).scaleInPlace(rad).add(path[i]);
-                    circlePath.push(rotated);
+        public static CreateTube(name: string, path: Vector3[], radius: number, tessellation: number, radiusFunction: { (i: number, distance: number): number; }, scene: Scene, updatable?: boolean, sideOrientation: number = Mesh.DEFAULTSIDE, tubeInstance: Mesh = null): Mesh {
+            
+            // tube geometry
+            var tubePathArray = function(path, path3D, circlePaths, radius, tessellation, radiusFunction) {
+                var tangents = path3D.getTangents();
+                var normals = path3D.getNormals();
+                var distances = path3D.getDistances();
+                var pi2 = Math.PI * 2;
+                var step = pi2 / tessellation;
+                var returnRadius: { (i: number, distance: number): number; } = (i, distance) => radius;
+                var radiusFunctionFinal: { (i: number, distance: number): number; } = radiusFunction || returnRadius;
+
+                var circlePath: Vector3[];
+                var rad: number;
+                var normal: Vector3;
+                var rotated: Vector3;
+                var rotationMatrix: Matrix;
+                var index = 0;
+                for (var i = 0; i < path.length; i++) {
+                    rad = radiusFunctionFinal(i, distances[i]); // current radius
+                    circlePath = Array<Vector3>();              // current circle array
+                    normal = normals[i];                        // current normal  
+                    for (var ang = 0; ang < pi2; ang += step) {
+                        rotationMatrix = Matrix.RotationAxis(tangents[i], ang);
+                        rotated = Vector3.TransformCoordinates(normal, rotationMatrix).scaleInPlace(rad).add(path[i]);
+                        circlePath.push(rotated);
+                    }
+                    circlePaths[index] = circlePath;
+                    index++;
                 }
-                circlePaths.push(circlePath);
+                return circlePaths;
+            };
+
+            if (tubeInstance) { // tube update
+                var path3D = ((<any>tubeInstance).path3D).update(path);
+                var pathArray = tubePathArray(path, path3D, (<any>tubeInstance).pathArray, radius, (<any>tubeInstance).tessellation, radiusFunction);
+                tubeInstance = Mesh.CreateRibbon(null, pathArray, null, null, null, null, null, null, tubeInstance);
+
+                return tubeInstance;        
+            
+            }
+            else { // tube creation
+
+                var path3D = <any>new Path3D(path);
+                var newPathArray = new Array<Array<Vector3>>();
+                var pathArray = tubePathArray(path, path3D, newPathArray, radius, tessellation, radiusFunction);
+                var tube = Mesh.CreateRibbon(name, pathArray, false, true, 0, scene, updatable, sideOrientation);
+                (<any>tube).pathArray = pathArray;
+                (<any>tube).path3D = path3D;
+                (<any>tube).tessellation = tessellation;
+
+                return tube;
             }
-            var tube = Mesh.CreateRibbon(name, circlePaths, false, true, 0, scene, updatable, sideOrientation);
-            return tube;
         }
 
         // Decals