Browse Source

Adding missing code for Extrude

David Catuhe 10 years ago
parent
commit
7ac9e33c44

+ 54 - 108
Babylon/Cameras/babylon.arcRotateCamera.js

@@ -26,6 +26,7 @@ var BABYLON;
             this.upperRadiusLimit = null;
             this.angularSensibility = 1000.0;
             this.wheelPrecision = 3.0;
+            this.pinchPrecision = 2.0;
             this.keysUp = [38];
             this.keysDown = [40];
             this.keysLeft = [37];
@@ -40,10 +41,6 @@ var BABYLON;
             this._previousPosition = BABYLON.Vector3.Zero();
             this._collisionVelocity = BABYLON.Vector3.Zero();
             this._newPosition = BABYLON.Vector3.Zero();
-            // Pinch
-            // value for pinch step scaling
-            // set to 20 by default
-            this.pinchPrecision = 20;
             this.getViewMatrix();
         }
         ArcRotateCamera.prototype._getTargetPosition = function () {
@@ -77,13 +74,9 @@ var BABYLON;
         // Methods
         ArcRotateCamera.prototype.attachControl = function (element, noPreventDefault) {
             var _this = this;
-            var previousPosition;
-            var pointerId;
-            // to know if pinch started
-            var pinchStarted = false;
-            // two pinch point on X
-            // that will use for find if user action is pinch open or pinch close
-            var pinchPointX1, pinchPointX2;
+            var cacheSoloPointer; // cache pointer object for better perf on camera rotation
+            var previousPinchDistance = 0;
+            var pointers = new BABYLON.SmartCollection();
             if (this._attachedElement) {
                 return;
             }
@@ -91,56 +84,68 @@ var BABYLON;
             var engine = this.getEngine();
             if (this._onPointerDown === undefined) {
                 this._onPointerDown = function (evt) {
-                    if (pointerId) {
-                        return;
-                    }
-                    pointerId = evt.pointerId;
-                    previousPosition = {
-                        x: evt.clientX,
-                        y: evt.clientY
-                    };
+                    pointers.add(evt.pointerId, { x: evt.clientX, y: evt.clientY, type: evt.pointerType });
+                    cacheSoloPointer = pointers.item(evt.pointerId);
                     if (!noPreventDefault) {
                         evt.preventDefault();
                     }
                 };
                 this._onPointerUp = function (evt) {
-                    previousPosition = null;
-                    pointerId = null;
+                    cacheSoloPointer = null;
+                    previousPinchDistance = 0;
+                    pointers.remove(evt.pointerId);
                     if (!noPreventDefault) {
                         evt.preventDefault();
                     }
                 };
                 this._onPointerMove = function (evt) {
-                    if (!previousPosition) {
-                        return;
-                    }
-                    if (pointerId !== evt.pointerId) {
-                        return;
-                    }
-                    // return pinch is started
-                    if (pinchStarted) {
-                        return;
-                    }
-                    var offsetX = evt.clientX - previousPosition.x;
-                    var offsetY = evt.clientY - previousPosition.y;
-                    _this.inertialAlphaOffset -= offsetX / _this.angularSensibility;
-                    _this.inertialBetaOffset -= offsetY / _this.angularSensibility;
-                    previousPosition = {
-                        x: evt.clientX,
-                        y: evt.clientY
-                    };
                     if (!noPreventDefault) {
                         evt.preventDefault();
                     }
+                    switch (pointers.count) {
+                        case 1:
+                            //var offsetX = evt.clientX - pointers.item(evt.pointerId).x;
+                            //var offsetY = evt.clientY - pointers.item(evt.pointerId).y;
+                            var offsetX = evt.clientX - cacheSoloPointer.x;
+                            var offsetY = evt.clientY - cacheSoloPointer.y;
+                            _this.inertialAlphaOffset -= offsetX / _this.angularSensibility;
+                            _this.inertialBetaOffset -= offsetY / _this.angularSensibility;
+                            //pointers.item(evt.pointerId).x = evt.clientX;
+                            //pointers.item(evt.pointerId).y = evt.clientY;
+                            cacheSoloPointer.x = evt.clientX;
+                            cacheSoloPointer.y = evt.clientY;
+                            break;
+                        case 2:
+                            //if (noPreventDefault) { evt.preventDefault(); } //if pinch gesture, could be usefull to force preventDefault to avoid html page scroll/zoom in some mobile browsers
+                            pointers.item(evt.pointerId).x = evt.clientX;
+                            pointers.item(evt.pointerId).y = evt.clientY;
+                            var direction = 1;
+                            var distX = pointers.getItemByIndex(0).x - pointers.getItemByIndex(1).x;
+                            var distY = pointers.getItemByIndex(0).y - pointers.getItemByIndex(1).y;
+                            var pinchSquaredDistance = (distX * distX) + (distY * distY);
+                            if (previousPinchDistance === 0) {
+                                previousPinchDistance = pinchSquaredDistance;
+                                return;
+                            }
+                            if (pinchSquaredDistance != previousPinchDistance) {
+                                if (pinchSquaredDistance > previousPinchDistance) {
+                                    direction = -1;
+                                }
+                                _this.inertialRadiusOffset += (pinchSquaredDistance - previousPinchDistance) / (_this.pinchPrecision * _this.wheelPrecision * _this.angularSensibility);
+                                previousPinchDistance = pinchSquaredDistance;
+                            }
+                            break;
+                        default:
+                            if (pointers.item(evt.pointerId)) {
+                                pointers.item(evt.pointerId).x = evt.clientX;
+                                pointers.item(evt.pointerId).y = evt.clientY;
+                            }
+                    }
                 };
                 this._onMouseMove = function (evt) {
                     if (!engine.isPointerLock) {
                         return;
                     }
-                    // return pinch is started
-                    if (pinchStarted) {
-                        return;
-                    }
                     var offsetX = evt.movementX || evt.mozMovementX || evt.webkitMovementX || evt.msMovementX || 0;
                     var offsetY = evt.movementY || evt.mozMovementY || evt.webkitMovementY || evt.msMovementY || 0;
                     _this.inertialAlphaOffset -= offsetX / _this.angularSensibility;
@@ -193,7 +198,9 @@ var BABYLON;
                 };
                 this._onLostFocus = function () {
                     _this._keys = [];
-                    pointerId = null;
+                    pointers.empty();
+                    previousPinchDistance = 0;
+                    cacheSoloPointer = null;
                 };
                 this._onGestureStart = function (e) {
                     if (window.MSGesture === undefined) {
@@ -219,62 +226,9 @@ var BABYLON;
                     _this.inertialAlphaOffset = 0;
                     _this.inertialBetaOffset = 0;
                     _this.inertialRadiusOffset = 0;
-                    previousPosition = null;
-                    pointerId = null;
-                };
-                this._touchStart = function (event) {
-                    if (event.touches.length === 2) {
-                        //-- start pinch if two fingers on the screen
-                        pinchStarted = true;
-                        _this._pinchStart(event);
-                    }
-                };
-                this._touchMove = function (event) {
-                    if (pinchStarted) {
-                        //-- make scaling
-                        _this._pinchMove(event);
-                    }
-                };
-                this._touchEnd = function (event) {
-                    if (pinchStarted) {
-                        //-- end of pinch
-                        _this._pinchEnd(event);
-                    }
-                };
-                this._pinchStart = function (event) {
-                    // save origin touch point
-                    pinchPointX1 = event.touches[0].clientX;
-                    pinchPointX2 = event.touches[1].clientX;
-                    // block the camera 
-                    // if not it rotate around target during pinch
-                    pinchStarted = true;
-                };
-                this._pinchMove = function (event) {
-                    // variable for new camera's radius
-                    var delta = 0;
-                    // variables to know if pinch open or pinch close
-                    var direction = 1;
-                    var distanceXOrigine, distanceXNow;
-                    if (event.touches.length !== 2)
-                        return;
-                    // calculate absolute distances of the two fingers
-                    distanceXOrigine = Math.abs(pinchPointX1 - pinchPointX2);
-                    distanceXNow = Math.abs(event.touches[0].clientX - event.touches[1].clientX);
-                    // if distanceXNow < distanceXOrigine -> pinch close so direction = -1
-                    if (distanceXNow < distanceXOrigine) {
-                        direction = -1;
-                    }
-                    // calculate new radius
-                    delta = (_this.pinchPrecision / (_this.wheelPrecision * 40)) * direction;
-                    // set new radius
-                    _this.inertialRadiusOffset -= delta;
-                    // save origin touch point
-                    pinchPointX1 = event.touches[0].clientX;
-                    pinchPointX2 = event.touches[1].clientX;
-                };
-                this._pinchEnd = function (event) {
-                    // cancel pinch and deblock camera rotation
-                    pinchStarted = false;
+                    pointers.empty();
+                    previousPinchDistance = 0;
+                    cacheSoloPointer = null;
                 };
             }
             element.addEventListener(eventPrefix + "down", this._onPointerDown, false);
@@ -286,10 +240,6 @@ var BABYLON;
             element.addEventListener("MSGestureChange", this._onGesture, false);
             element.addEventListener('mousewheel', this._wheel, false);
             element.addEventListener('DOMMouseScroll', this._wheel, false);
-            // pinch
-            element.addEventListener('touchstart', this._touchStart, false);
-            element.addEventListener('touchmove', this._touchMove, false);
-            element.addEventListener('touchend', this._touchEnd, false);
             BABYLON.Tools.RegisterTopRootEvents([
                 { name: "keydown", handler: this._onKeyDown },
                 { name: "keyup", handler: this._onKeyUp },
@@ -309,10 +259,6 @@ var BABYLON;
             element.removeEventListener("MSGestureChange", this._onGesture);
             element.removeEventListener('mousewheel', this._wheel);
             element.removeEventListener('DOMMouseScroll', this._wheel);
-            // pinch
-            element.removeEventListener('touchstart', this._touchStart);
-            element.removeEventListener('touchmove', this._touchMove);
-            element.removeEventListener('touchend', this._touchEnd);
             BABYLON.Tools.UnregisterTopRootEvents([
                 { name: "keydown", handler: this._onKeyDown },
                 { name: "keyup", handler: this._onKeyUp },

+ 1 - 1
Babylon/Cameras/babylon.arcRotateCamera.ts

@@ -485,4 +485,4 @@
             this.maxZ = distance * 2;
         }
     }
-} 
+} 

+ 28 - 2
Babylon/Mesh/babylon.mesh.js

@@ -1002,9 +1002,35 @@ var BABYLON;
             var extrudedCustom = Mesh._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, true, scene, updatable, sideOrientation);
             return extrudedCustom;
         };
-        Mesh._ExtrudeShapeGeneric = function (name, shape, curve, scale, rotation, scaleFunction, rotationFunction, rbCA, rbCP, custom, scene, updtbl, side) {
+        Mesh._ExtrudeShapeGeneric = function (name, shape, curve, scale, rotation, scaleFunction, rotateFunction, rbCA, rbCP, custom, scene, updtbl, side) {
             var path3D = new BABYLON.Path3D(curve);
-            var shapePaths = [];
+            var tangents = path3D.getTangents();
+            var normals = path3D.getNormals();
+            var binormals = path3D.getBinormals();
+            var distances = path3D.getDistances();
+            var shapePaths = new Array();
+            var angle = 0;
+            var returnScale = function (i, distance) {
+                return scale;
+            };
+            var returnRotation = function (i, distance) {
+                return rotation;
+            };
+            var rotate = custom ? rotateFunction : returnRotation;
+            var scl = custom ? scaleFunction : returnScale;
+            for (var i = 0; i < curve.length; i++) {
+                var shapePath = new Array();
+                var angleStep = rotate(i, distances[i]);
+                var scaleRatio = scl(i, distances[i]);
+                for (var p = 0; p < shape.length; p++) {
+                    var rotationMatrix = BABYLON.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 = BABYLON.Vector3.TransformCoordinates(planed, rotationMatrix).scaleInPlace(scaleRatio).add(curve[i]);
+                    shapePath.push(rotated);
+                }
+                shapePaths.push(shapePath);
+                angle += angleStep;
+            }
             var extrudedGeneric = Mesh.CreateRibbon(name, shapePaths, rbCA, rbCP, 0, scene, updtbl, side);
             return extrudedGeneric;
         };

+ 44 - 22
Babylon/Mesh/babylon.mesh.ts

@@ -766,7 +766,7 @@
 
                     this.delayLoadState = Engine.DELAYLOADSTATE_LOADED;
                     scene._removePendingData(this);
-                }, () => { }, scene.database, getBinaryData);
+                },() => { }, scene.database, getBinaryData);
             }
         }
 
@@ -923,7 +923,7 @@
                 }
             };
 
-            Tools.LoadImage(url, onload, () => { }, scene.database);
+            Tools.LoadImage(url, onload,() => { }, scene.database);
         }
 
         public applyDisplacementMapFromBuffer(buffer: Uint8Array, heightMapWidth: number, heightMapHeight: number, minHeight: number, maxHeight: number): void {
@@ -944,7 +944,7 @@
             for (var index = 0; index < positions.length; index += 3) {
                 Vector3.FromArrayToRef(positions, index, position);
                 Vector3.FromArrayToRef(normals, index, normal);
-                Vector2.FromArrayToRef(uvs, (index / 3) * 2, uv);
+                Vector2.FromArrayToRef(uvs,(index / 3) * 2, uv);
 
                 // Compute height
                 var u = ((Math.abs(uv.x) * heightMapWidth) % heightMapWidth) | 0;
@@ -1025,8 +1025,8 @@
                 indices[index + 2] = index + 2;
 
                 var p1 = Vector3.FromArray(positions, index * 3);
-                var p2 = Vector3.FromArray(positions, (index + 1) * 3);
-                var p3 = Vector3.FromArray(positions, (index + 2) * 3);
+                var p2 = Vector3.FromArray(positions,(index + 1) * 3);
+                var p3 = Vector3.FromArray(positions,(index + 2) * 3);
 
                 var p1p2 = p1.subtract(p2);
                 var p3p2 = p3.subtract(p2);
@@ -1105,7 +1105,7 @@
             }
             var dupes = [];
 
-            AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40, (iteration) => {
+            AsyncLoop.SyncAsyncForLoop(vectorPositions.length, 40,(iteration) => {
                 var realPos = vectorPositions.length - 1 - iteration;
                 var testedPosition = vectorPositions[realPos];
                 for (var j = 0; j < realPos; ++j) {
@@ -1115,19 +1115,19 @@
                         break;
                     }
                 }
-            },  () => {
-                for (var i = 0; i < indices.length; ++i) {
-                    indices[i] = dupes[indices[i]] || indices[i];
-                }
+            },() => {
+                    for (var i = 0; i < indices.length; ++i) {
+                        indices[i] = dupes[indices[i]] || indices[i];
+                    }
 
-                //indices are now reordered
-                var originalSubMeshes = this.subMeshes.slice(0);
-                this.setIndices(indices);
-                this.subMeshes = originalSubMeshes;
-                if (successCallback) {
-                    successCallback(this);
-                }
-            });
+                    //indices are now reordered
+                    var originalSubMeshes = this.subMeshes.slice(0);
+                    this.setIndices(indices);
+                    this.subMeshes = originalSubMeshes;
+                    if (successCallback) {
+                        successCallback(this);
+                    }
+                });
         }
 
         // Statics
@@ -1220,13 +1220,35 @@
             return extrudedCustom;
         }
 
-        private static _ExtrudeShapeGeneric(name: string, shape: Vector3[], curve: Vector3[], scale: number, rotation: number, scaleFunction, rotationFunction, rbCA: boolean, rbCP: boolean, custom: boolean, scene: Scene, updtbl: boolean, side: number): Mesh {
+        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);
+                }
+                shapePaths.push(shapePath);
+                angle += angleStep;
+            }
 
-            var shapePaths: Vector3[][] = [];
             var extrudedGeneric = Mesh.CreateRibbon(name, shapePaths, rbCA, rbCP, 0, scene, updtbl, side);
             return extrudedGeneric;
-
         }
 
         // Plane & ground
@@ -1295,7 +1317,7 @@
                 }
             };
 
-            Tools.LoadImage(url, onload, () => { }, scene.database);
+            Tools.LoadImage(url, onload,() => { }, scene.database);
 
             return ground;
         }

+ 92 - 0
Babylon/Tools/babylon.smartCollection.js

@@ -0,0 +1,92 @@
+var BABYLON;
+(function (BABYLON) {
+    var SmartCollection = (function () {
+        function SmartCollection(capacity) {
+            if (capacity === void 0) { capacity = 10; }
+            this.count = 0;
+            this._initialCapacity = capacity;
+            this.items = {};
+            this._keys = new Array(this._initialCapacity);
+        }
+        SmartCollection.prototype.add = function (key, item) {
+            if (this.items[key] != undefined) {
+                return -1;
+            }
+            this.items[key] = item;
+            //literal keys are always strings, but we keep source type of key in _keys array
+            this._keys[this.count++] = key;
+            if (this.count > this._keys.length) {
+                this._keys.length *= 2;
+            }
+            return this.count;
+        };
+        SmartCollection.prototype.remove = function (key) {
+            if (this.items[key] == undefined) {
+                return -1;
+            }
+            return this.removeItemOfIndex(this.indexOf(key));
+        };
+        SmartCollection.prototype.removeItemOfIndex = function (index) {
+            if (index < this.count && index > -1) {
+                delete this.items[this._keys[index]];
+                while (index < this.count) {
+                    this._keys[index] = this._keys[index + 1];
+                    index++;
+                }
+            }
+            else {
+                return -1;
+            }
+            return --this.count;
+        };
+        SmartCollection.prototype.indexOf = function (key) {
+            for (var i = 0; i !== this.count; i++) {
+                if (this._keys[i] === key) {
+                    return i;
+                }
+            }
+            return -1;
+        };
+        SmartCollection.prototype.item = function (key) {
+            return this.items[key];
+        };
+        SmartCollection.prototype.getAllKeys = function () {
+            if (this.count > 0) {
+                var keys = new Array(this.count);
+                for (var i = 0; i < this.count; i++) {
+                    keys[i] = this._keys[i];
+                }
+                return keys;
+            }
+            else {
+                return undefined;
+            }
+        };
+        SmartCollection.prototype.getKeyByIndex = function (index) {
+            if (index < this.count && index > -1) {
+                return this._keys[index];
+            }
+            else {
+                return undefined;
+            }
+        };
+        SmartCollection.prototype.getItemByIndex = function (index) {
+            if (index < this.count && index > -1) {
+                return this.items[this._keys[index]];
+            }
+            else {
+                return undefined;
+            }
+        };
+        SmartCollection.prototype.empty = function () {
+            if (this.count > 0) {
+                this.count = 0;
+                this.items = {};
+                this._keys = new Array(this._initialCapacity);
+            }
+        };
+        return SmartCollection;
+    })();
+    BABYLON.SmartCollection = SmartCollection;
+})(BABYLON || (BABYLON = {}));
+//# sourceMappingURL=babylon.smartCollection.js.map

+ 23 - 23
Babylon/Tools/babylon.smartCollection.ts

@@ -1,18 +1,18 @@
 module BABYLON {
     export class SmartCollection {
-        public count: number = 0;
+        public count = 0;
         public items: any;
-        
+
         private _keys: string[];
         private _initialCapacity: number;
-        
+
         constructor(capacity: number = 10) {
-            this._initialCapacity = capacity;    
+            this._initialCapacity = capacity;
             this.items = {};
             this._keys = new Array(this._initialCapacity);
         }
 
-        public add(key: any, item: any): number {        
+        public add(key: any, item: any): number {
             if (this.items[key] != undefined) {
                 return -1;
             }
@@ -23,43 +23,43 @@
             if (this.count > this._keys.length) {
                 this._keys.length *= 2;
             }
-            
+
             return this.count;
         }
-     
+
         public remove(key: any): number {
             if (this.items[key] == undefined) {
                 return -1;
             }
-            
+
             return this.removeItemOfIndex(this.indexOf(key));
         }
- 
+
         public removeItemOfIndex(index: number): number {
             if (index < this.count && index > -1) {
                 delete this.items[this._keys[index]];
                     
                 //here, shifting by hand is better optimised than .splice
-                while (index < this.count) { 
-                   this._keys[index] = this._keys[index+1]; index++;
+                while (index < this.count) {
+                    this._keys[index] = this._keys[index + 1]; index++;
                 }
             }
-            else { 
-                return -1; 
+            else {
+                return -1;
             }
-            
+
             return --this.count;
         }
-        
+
         public indexOf(key: any): number {
-            for (var i = 0 ; i != this.count ; i++) {
-                if (this._keys[i] === key) { 
-                    return i; 
+            for (var i = 0; i !== this.count; i++) {
+                if (this._keys[i] === key) {
+                    return i;
                 }
             }
             return -1;
         }
-        
+
         public item(key: any): any {
             return this.items[key];
         }
@@ -71,12 +71,12 @@
                     keys[i] = this._keys[i];
                 }
                 return keys;
-            } 
+            }
             else {
                 return undefined;
             }
         }
-        
+
         public getKeyByIndex(index: number): any {
             if (index < this.count && index > -1) {
                 return this._keys[index];
@@ -85,7 +85,7 @@
                 return undefined;
             }
         }
-    
+
         public getItemByIndex(index: number): any {
             if (index < this.count && index > -1) {
                 return this.items[this._keys[index]];
@@ -94,7 +94,7 @@
                 return undefined;
             }
         }
-    
+
         public empty(): void {
             if (this.count > 0) {
                 this.count = 0;

File diff suppressed because it is too large
+ 29831 - 22
babylon.2.1-alpha.debug.js


File diff suppressed because it is too large
+ 22 - 29768
babylon.2.1-alpha.js