Kaynağa Gözat

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js

jerome 9 yıl önce
ebeveyn
işleme
68d4d0d7d1

BIN
Exporters/3ds Max/Max2Babylon-0.20.zip


+ 14 - 4
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Animation.cs

@@ -201,7 +201,7 @@ namespace Max2Babylon
 
         static float[] weightedLerp(int frame0, int frame1, int frame2, float[] value0, float[] value2)
         {
-            double weight2 = (double)(frame1 - frame0) / (double)(frame2 - frame0);
+            double weight2 = (frame1 - frame0) / (double)(frame2 - frame0);
             double weight0 = 1 - weight2;
             float[] result = new float[value0.Length];
             for (int i = 0; i < result.Length; ++i)
@@ -237,6 +237,8 @@ namespace Max2Babylon
 
         private static void ExportAnimation(string property, List<BabylonAnimation> animations, Func<int, float[]> extractValueFunc, BabylonAnimation.DataType dataType)
         {
+            var exportNonOptimizedAnimations = Loader.Core.RootNode.GetBoolProperty("babylonjs_exportnonoptimizedanimations");
+
             var start = Loader.Core.AnimRange.Start;
             var end = Loader.Core.AnimRange.End;
 
@@ -246,6 +248,10 @@ namespace Max2Babylon
             {
                 var current = extractValueFunc(key);
 
+                if (exportNonOptimizedAnimations && previous != null && previous.IsEqualTo(current))
+                {
+                    continue; // Do not add key
+                }
 
                 keys.Add(new BabylonAnimationKey()
                 {
@@ -253,11 +259,15 @@ namespace Max2Babylon
                     values = current
                 });
 
-
                 previous = current;
             }
-            RemoveLinearAnimationKeys(keys);
-            if (keys.Count > 0)
+
+            if (!exportNonOptimizedAnimations)
+            {
+                RemoveLinearAnimationKeys(keys);
+            }
+
+            if (keys.Count > 1)
             {
                 var animationPresent = true;
 

+ 3 - 1
Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Skeleton.cs

@@ -59,6 +59,8 @@ namespace Max2Babylon
             }
 
             // fix hierarchy an generate animation keys
+            var exportNonOptimizedAnimations = Loader.Core.RootNode.GetBoolProperty("babylonjs_exportnonoptimizedanimations");
+
             for (var index = 0; index < skin.TotalSkinBoneCount; index++)
             {
                 var gameBone = gameBones[index];
@@ -108,7 +110,7 @@ namespace Max2Babylon
                     }
 
                     var current = mat.ToArray();
-                    if (key == start || key == end || !(previous.IsEqualTo(current)))
+                    if (key == start || key == end || exportNonOptimizedAnimations || !(previous.IsEqualTo(current)))
                     {
                         keys.Add(new BabylonAnimationKey
                         {

Dosya farkı çok büyük olduğundan ihmal edildi
+ 14 - 14
dist/preview release/babylon.core.js


+ 358 - 359
dist/preview release/babylon.d.ts

@@ -750,6 +750,7 @@ declare module BABYLON {
         setTransformMatrix(view: Matrix, projection: Matrix): void;
         addMesh(newMesh: AbstractMesh): void;
         removeMesh(toRemove: AbstractMesh): number;
+        removeSkeleton(toRemove: Skeleton): number;
         removeLight(toRemove: Light): number;
         removeCamera(toRemove: Camera): number;
         addLight(newLight: Light): void;
@@ -1571,247 +1572,7 @@ declare module BABYLON {
         prepare(): void;
         getAnimatables(): IAnimatable[];
         clone(name: string, id: string): Skeleton;
-    }
-}
-
-declare module BABYLON {
-    class Collider {
-        radius: Vector3;
-        retry: number;
-        velocity: Vector3;
-        basePoint: Vector3;
-        epsilon: number;
-        collisionFound: boolean;
-        velocityWorldLength: number;
-        basePointWorld: Vector3;
-        velocityWorld: Vector3;
-        normalizedVelocity: Vector3;
-        initialVelocity: Vector3;
-        initialPosition: Vector3;
-        nearestDistance: number;
-        intersectionPoint: Vector3;
-        collidedMesh: AbstractMesh;
-        private _collisionPoint;
-        private _planeIntersectionPoint;
-        private _tempVector;
-        private _tempVector2;
-        private _tempVector3;
-        private _tempVector4;
-        private _edge;
-        private _baseToVertex;
-        private _destinationPoint;
-        private _slidePlaneNormal;
-        private _displacementVector;
-        _initialize(source: Vector3, dir: Vector3, e: number): void;
-        _checkPointInTriangle(point: Vector3, pa: Vector3, pb: Vector3, pc: Vector3, n: Vector3): boolean;
-        _canDoCollision(sphereCenter: Vector3, sphereRadius: number, vecMin: Vector3, vecMax: Vector3): boolean;
-        _testTriangle(faceIndex: number, trianglePlaneArray: Array<Plane>, p1: Vector3, p2: Vector3, p3: Vector3, hasMaterial: boolean): void;
-        _collide(trianglePlaneArray: Array<Plane>, pts: Vector3[], indices: number[], indexStart: number, indexEnd: number, decal: number, hasMaterial: boolean): void;
-        _getResponse(pos: Vector3, vel: Vector3): void;
-    }
-}
-
-declare module BABYLON {
-    var CollisionWorker: string;
-    interface ICollisionCoordinator {
-        getNewPosition(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh?: AbstractMesh) => void, collisionIndex: number): void;
-        init(scene: Scene): void;
-        destroy(): void;
-        onMeshAdded(mesh: AbstractMesh): any;
-        onMeshUpdated(mesh: AbstractMesh): any;
-        onMeshRemoved(mesh: AbstractMesh): any;
-        onGeometryAdded(geometry: Geometry): any;
-        onGeometryUpdated(geometry: Geometry): any;
-        onGeometryDeleted(geometry: Geometry): any;
-    }
-    interface SerializedMesh {
-        id: string;
-        name: string;
-        uniqueId: number;
-        geometryId: string;
-        sphereCenter: Array<number>;
-        sphereRadius: number;
-        boxMinimum: Array<number>;
-        boxMaximum: Array<number>;
-        worldMatrixFromCache: any;
-        subMeshes: Array<SerializedSubMesh>;
-        checkCollisions: boolean;
-    }
-    interface SerializedSubMesh {
-        position: number;
-        verticesStart: number;
-        verticesCount: number;
-        indexStart: number;
-        indexCount: number;
-        hasMaterial: boolean;
-        sphereCenter: Array<number>;
-        sphereRadius: number;
-        boxMinimum: Array<number>;
-        boxMaximum: Array<number>;
-    }
-    interface SerializedGeometry {
-        id: string;
-        positions: Float32Array;
-        indices: Int32Array;
-        normals: Float32Array;
-    }
-    interface BabylonMessage {
-        taskType: WorkerTaskType;
-        payload: InitPayload | CollidePayload | UpdatePayload;
-    }
-    interface SerializedColliderToWorker {
-        position: Array<number>;
-        velocity: Array<number>;
-        radius: Array<number>;
-    }
-    enum WorkerTaskType {
-        INIT = 0,
-        UPDATE = 1,
-        COLLIDE = 2,
-    }
-    interface WorkerReply {
-        error: WorkerReplyType;
-        taskType: WorkerTaskType;
-        payload?: any;
-    }
-    interface CollisionReplyPayload {
-        newPosition: Array<number>;
-        collisionId: number;
-        collidedMeshUniqueId: number;
-    }
-    interface InitPayload {
-    }
-    interface CollidePayload {
-        collisionId: number;
-        collider: SerializedColliderToWorker;
-        maximumRetry: number;
-        excludedMeshUniqueId?: number;
-    }
-    interface UpdatePayload {
-        updatedMeshes: {
-            [n: number]: SerializedMesh;
-        };
-        updatedGeometries: {
-            [s: string]: SerializedGeometry;
-        };
-        removedMeshes: Array<number>;
-        removedGeometries: Array<string>;
-    }
-    enum WorkerReplyType {
-        SUCCESS = 0,
-        UNKNOWN_ERROR = 1,
-    }
-    class CollisionCoordinatorWorker implements ICollisionCoordinator {
-        private _scene;
-        private _scaledPosition;
-        private _scaledVelocity;
-        private _collisionsCallbackArray;
-        private _init;
-        private _runningUpdated;
-        private _runningCollisionTask;
-        private _worker;
-        private _addUpdateMeshesList;
-        private _addUpdateGeometriesList;
-        private _toRemoveMeshesArray;
-        private _toRemoveGeometryArray;
-        constructor();
-        static SerializeMesh: (mesh: AbstractMesh) => SerializedMesh;
-        static SerializeGeometry: (geometry: Geometry) => SerializedGeometry;
-        getNewPosition(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh?: AbstractMesh) => void, collisionIndex: number): void;
-        init(scene: Scene): void;
-        destroy(): void;
-        onMeshAdded(mesh: AbstractMesh): void;
-        onMeshUpdated: (mesh: AbstractMesh) => void;
-        onMeshRemoved(mesh: AbstractMesh): void;
-        onGeometryAdded(geometry: Geometry): void;
-        onGeometryUpdated: (geometry: Geometry) => void;
-        onGeometryDeleted(geometry: Geometry): void;
-        private _afterRender;
-        private _onMessageFromWorker;
-    }
-    class CollisionCoordinatorLegacy implements ICollisionCoordinator {
-        private _scene;
-        private _scaledPosition;
-        private _scaledVelocity;
-        private _finalPosition;
-        getNewPosition(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh?: AbstractMesh) => void, collisionIndex: number): void;
-        init(scene: Scene): void;
-        destroy(): void;
-        onMeshAdded(mesh: AbstractMesh): void;
-        onMeshUpdated(mesh: AbstractMesh): void;
-        onMeshRemoved(mesh: AbstractMesh): void;
-        onGeometryAdded(geometry: Geometry): void;
-        onGeometryUpdated(geometry: Geometry): void;
-        onGeometryDeleted(geometry: Geometry): void;
-        private _collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh?);
-    }
-}
-
-declare module BABYLON {
-    var WorkerIncluded: boolean;
-    class CollisionCache {
-        private _meshes;
-        private _geometries;
-        getMeshes(): {
-            [n: number]: SerializedMesh;
-        };
-        getGeometries(): {
-            [s: number]: SerializedGeometry;
-        };
-        getMesh(id: any): SerializedMesh;
-        addMesh(mesh: SerializedMesh): void;
-        removeMesh(uniqueId: number): void;
-        getGeometry(id: string): SerializedGeometry;
-        addGeometry(geometry: SerializedGeometry): void;
-        removeGeometry(id: string): void;
-    }
-    class CollideWorker {
-        collider: Collider;
-        private _collisionCache;
-        private finalPosition;
-        private collisionsScalingMatrix;
-        private collisionTranformationMatrix;
-        constructor(collider: Collider, _collisionCache: CollisionCache, finalPosition: Vector3);
-        collideWithWorld(position: Vector3, velocity: Vector3, maximumRetry: number, excludedMeshUniqueId?: number): void;
-        private checkCollision(mesh);
-        private processCollisionsForSubMeshes(transformMatrix, mesh);
-        private collideForSubMesh(subMesh, transformMatrix, meshGeometry);
-        private checkSubmeshCollision(subMesh);
-    }
-    interface ICollisionDetector {
-        onInit(payload: InitPayload): void;
-        onUpdate(payload: UpdatePayload): void;
-        onCollision(payload: CollidePayload): void;
-    }
-    class CollisionDetectorTransferable implements ICollisionDetector {
-        private _collisionCache;
-        onInit(payload: InitPayload): void;
-        onUpdate(payload: UpdatePayload): void;
-        onCollision(payload: CollidePayload): void;
-    }
-}
-
-declare module BABYLON {
-    class IntersectionInfo {
-        bu: number;
-        bv: number;
-        distance: number;
-        faceId: number;
-        subMeshId: number;
-        constructor(bu: number, bv: number, distance: number);
-    }
-    class PickingInfo {
-        hit: boolean;
-        distance: number;
-        pickedPoint: Vector3;
-        pickedMesh: AbstractMesh;
-        bu: number;
-        bv: number;
-        faceId: number;
-        subMeshId: number;
-        pickedSprite: Sprite;
-        getNormal(useWorldCoordinates?: boolean, useVerticesNormals?: boolean): Vector3;
-        getTextureCoordinates(): Vector2;
+        dispose(): void;
     }
 }
 
@@ -2173,36 +1934,277 @@ declare module BABYLON {
         _updateRigCameras(): void;
         private _getRigCamPosition(halfSpace, result);
     }
-}
-
-declare module BABYLON {
-    class TouchCamera extends FreeCamera {
-        private _offsetX;
-        private _offsetY;
-        private _pointerCount;
-        private _pointerPressed;
-        private _attachedCanvas;
-        private _onPointerDown;
-        private _onPointerUp;
-        private _onPointerMove;
-        angularSensibility: number;
-        moveSensibility: number;
-        constructor(name: string, position: Vector3, scene: Scene);
-        attachControl(canvas: HTMLCanvasElement, noPreventDefault: boolean): void;
-        detachControl(canvas: HTMLCanvasElement): void;
-        _checkInputs(): void;
+}
+
+declare module BABYLON {
+    class TouchCamera extends FreeCamera {
+        private _offsetX;
+        private _offsetY;
+        private _pointerCount;
+        private _pointerPressed;
+        private _attachedCanvas;
+        private _onPointerDown;
+        private _onPointerUp;
+        private _onPointerMove;
+        angularSensibility: number;
+        moveSensibility: number;
+        constructor(name: string, position: Vector3, scene: Scene);
+        attachControl(canvas: HTMLCanvasElement, noPreventDefault: boolean): void;
+        detachControl(canvas: HTMLCanvasElement): void;
+        _checkInputs(): void;
+    }
+}
+
+declare module BABYLON {
+    class VirtualJoysticksCamera extends FreeCamera {
+        private _leftjoystick;
+        private _rightjoystick;
+        constructor(name: string, position: Vector3, scene: Scene);
+        getLeftJoystick(): VirtualJoystick;
+        getRightJoystick(): VirtualJoystick;
+        _checkInputs(): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class Collider {
+        radius: Vector3;
+        retry: number;
+        velocity: Vector3;
+        basePoint: Vector3;
+        epsilon: number;
+        collisionFound: boolean;
+        velocityWorldLength: number;
+        basePointWorld: Vector3;
+        velocityWorld: Vector3;
+        normalizedVelocity: Vector3;
+        initialVelocity: Vector3;
+        initialPosition: Vector3;
+        nearestDistance: number;
+        intersectionPoint: Vector3;
+        collidedMesh: AbstractMesh;
+        private _collisionPoint;
+        private _planeIntersectionPoint;
+        private _tempVector;
+        private _tempVector2;
+        private _tempVector3;
+        private _tempVector4;
+        private _edge;
+        private _baseToVertex;
+        private _destinationPoint;
+        private _slidePlaneNormal;
+        private _displacementVector;
+        _initialize(source: Vector3, dir: Vector3, e: number): void;
+        _checkPointInTriangle(point: Vector3, pa: Vector3, pb: Vector3, pc: Vector3, n: Vector3): boolean;
+        _canDoCollision(sphereCenter: Vector3, sphereRadius: number, vecMin: Vector3, vecMax: Vector3): boolean;
+        _testTriangle(faceIndex: number, trianglePlaneArray: Array<Plane>, p1: Vector3, p2: Vector3, p3: Vector3, hasMaterial: boolean): void;
+        _collide(trianglePlaneArray: Array<Plane>, pts: Vector3[], indices: number[], indexStart: number, indexEnd: number, decal: number, hasMaterial: boolean): void;
+        _getResponse(pos: Vector3, vel: Vector3): void;
+    }
+}
+
+declare module BABYLON {
+    var CollisionWorker: string;
+    interface ICollisionCoordinator {
+        getNewPosition(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh?: AbstractMesh) => void, collisionIndex: number): void;
+        init(scene: Scene): void;
+        destroy(): void;
+        onMeshAdded(mesh: AbstractMesh): any;
+        onMeshUpdated(mesh: AbstractMesh): any;
+        onMeshRemoved(mesh: AbstractMesh): any;
+        onGeometryAdded(geometry: Geometry): any;
+        onGeometryUpdated(geometry: Geometry): any;
+        onGeometryDeleted(geometry: Geometry): any;
+    }
+    interface SerializedMesh {
+        id: string;
+        name: string;
+        uniqueId: number;
+        geometryId: string;
+        sphereCenter: Array<number>;
+        sphereRadius: number;
+        boxMinimum: Array<number>;
+        boxMaximum: Array<number>;
+        worldMatrixFromCache: any;
+        subMeshes: Array<SerializedSubMesh>;
+        checkCollisions: boolean;
+    }
+    interface SerializedSubMesh {
+        position: number;
+        verticesStart: number;
+        verticesCount: number;
+        indexStart: number;
+        indexCount: number;
+        hasMaterial: boolean;
+        sphereCenter: Array<number>;
+        sphereRadius: number;
+        boxMinimum: Array<number>;
+        boxMaximum: Array<number>;
+    }
+    interface SerializedGeometry {
+        id: string;
+        positions: Float32Array;
+        indices: Int32Array;
+        normals: Float32Array;
+    }
+    interface BabylonMessage {
+        taskType: WorkerTaskType;
+        payload: InitPayload | CollidePayload | UpdatePayload;
+    }
+    interface SerializedColliderToWorker {
+        position: Array<number>;
+        velocity: Array<number>;
+        radius: Array<number>;
+    }
+    enum WorkerTaskType {
+        INIT = 0,
+        UPDATE = 1,
+        COLLIDE = 2,
+    }
+    interface WorkerReply {
+        error: WorkerReplyType;
+        taskType: WorkerTaskType;
+        payload?: any;
+    }
+    interface CollisionReplyPayload {
+        newPosition: Array<number>;
+        collisionId: number;
+        collidedMeshUniqueId: number;
+    }
+    interface InitPayload {
+    }
+    interface CollidePayload {
+        collisionId: number;
+        collider: SerializedColliderToWorker;
+        maximumRetry: number;
+        excludedMeshUniqueId?: number;
+    }
+    interface UpdatePayload {
+        updatedMeshes: {
+            [n: number]: SerializedMesh;
+        };
+        updatedGeometries: {
+            [s: string]: SerializedGeometry;
+        };
+        removedMeshes: Array<number>;
+        removedGeometries: Array<string>;
+    }
+    enum WorkerReplyType {
+        SUCCESS = 0,
+        UNKNOWN_ERROR = 1,
+    }
+    class CollisionCoordinatorWorker implements ICollisionCoordinator {
+        private _scene;
+        private _scaledPosition;
+        private _scaledVelocity;
+        private _collisionsCallbackArray;
+        private _init;
+        private _runningUpdated;
+        private _runningCollisionTask;
+        private _worker;
+        private _addUpdateMeshesList;
+        private _addUpdateGeometriesList;
+        private _toRemoveMeshesArray;
+        private _toRemoveGeometryArray;
+        constructor();
+        static SerializeMesh: (mesh: AbstractMesh) => SerializedMesh;
+        static SerializeGeometry: (geometry: Geometry) => SerializedGeometry;
+        getNewPosition(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh?: AbstractMesh) => void, collisionIndex: number): void;
+        init(scene: Scene): void;
+        destroy(): void;
+        onMeshAdded(mesh: AbstractMesh): void;
+        onMeshUpdated: (mesh: AbstractMesh) => void;
+        onMeshRemoved(mesh: AbstractMesh): void;
+        onGeometryAdded(geometry: Geometry): void;
+        onGeometryUpdated: (geometry: Geometry) => void;
+        onGeometryDeleted(geometry: Geometry): void;
+        private _afterRender;
+        private _onMessageFromWorker;
+    }
+    class CollisionCoordinatorLegacy implements ICollisionCoordinator {
+        private _scene;
+        private _scaledPosition;
+        private _scaledVelocity;
+        private _finalPosition;
+        getNewPosition(position: Vector3, velocity: Vector3, collider: Collider, maximumRetry: number, excludedMesh: AbstractMesh, onNewPosition: (collisionIndex: number, newPosition: Vector3, collidedMesh?: AbstractMesh) => void, collisionIndex: number): void;
+        init(scene: Scene): void;
+        destroy(): void;
+        onMeshAdded(mesh: AbstractMesh): void;
+        onMeshUpdated(mesh: AbstractMesh): void;
+        onMeshRemoved(mesh: AbstractMesh): void;
+        onGeometryAdded(geometry: Geometry): void;
+        onGeometryUpdated(geometry: Geometry): void;
+        onGeometryDeleted(geometry: Geometry): void;
+        private _collideWithWorld(position, velocity, collider, maximumRetry, finalPosition, excludedMesh?);
+    }
+}
+
+declare module BABYLON {
+    var WorkerIncluded: boolean;
+    class CollisionCache {
+        private _meshes;
+        private _geometries;
+        getMeshes(): {
+            [n: number]: SerializedMesh;
+        };
+        getGeometries(): {
+            [s: number]: SerializedGeometry;
+        };
+        getMesh(id: any): SerializedMesh;
+        addMesh(mesh: SerializedMesh): void;
+        removeMesh(uniqueId: number): void;
+        getGeometry(id: string): SerializedGeometry;
+        addGeometry(geometry: SerializedGeometry): void;
+        removeGeometry(id: string): void;
+    }
+    class CollideWorker {
+        collider: Collider;
+        private _collisionCache;
+        private finalPosition;
+        private collisionsScalingMatrix;
+        private collisionTranformationMatrix;
+        constructor(collider: Collider, _collisionCache: CollisionCache, finalPosition: Vector3);
+        collideWithWorld(position: Vector3, velocity: Vector3, maximumRetry: number, excludedMeshUniqueId?: number): void;
+        private checkCollision(mesh);
+        private processCollisionsForSubMeshes(transformMatrix, mesh);
+        private collideForSubMesh(subMesh, transformMatrix, meshGeometry);
+        private checkSubmeshCollision(subMesh);
+    }
+    interface ICollisionDetector {
+        onInit(payload: InitPayload): void;
+        onUpdate(payload: UpdatePayload): void;
+        onCollision(payload: CollidePayload): void;
+    }
+    class CollisionDetectorTransferable implements ICollisionDetector {
+        private _collisionCache;
+        onInit(payload: InitPayload): void;
+        onUpdate(payload: UpdatePayload): void;
+        onCollision(payload: CollidePayload): void;
     }
 }
 
 declare module BABYLON {
-    class VirtualJoysticksCamera extends FreeCamera {
-        private _leftjoystick;
-        private _rightjoystick;
-        constructor(name: string, position: Vector3, scene: Scene);
-        getLeftJoystick(): VirtualJoystick;
-        getRightJoystick(): VirtualJoystick;
-        _checkInputs(): void;
-        dispose(): void;
+    class IntersectionInfo {
+        bu: number;
+        bv: number;
+        distance: number;
+        faceId: number;
+        subMeshId: number;
+        constructor(bu: number, bv: number, distance: number);
+    }
+    class PickingInfo {
+        hit: boolean;
+        distance: number;
+        pickedPoint: Vector3;
+        pickedMesh: AbstractMesh;
+        bu: number;
+        bv: number;
+        faceId: number;
+        subMeshId: number;
+        pickedSprite: Sprite;
+        getNormal(useWorldCoordinates?: boolean, useVerticesNormals?: boolean): Vector3;
+        getTextureCoordinates(): Vector2;
     }
 }
 
@@ -4682,8 +4684,6 @@ declare module BABYLON {
         _pos: number;
         _model: ModelShape;
         shapeId: number;
-        previous: SolidParticle;
-        next: SolidParticle;
         idxInShape: number;
         constructor(particleIndex: number, positionIndex: number, model: ModelShape, shapeId: number, idxInShape: number);
     }
@@ -4733,7 +4733,6 @@ declare module BABYLON {
         private _axisZ;
         private _camera;
         private _particle;
-        private _previousParticle;
         private _fakeCamPos;
         private _rotMatrix;
         private _invertedMatrix;
@@ -4753,7 +4752,7 @@ declare module BABYLON {
         private _sinYaw;
         private _cosYaw;
         constructor(name: string, scene: Scene);
-        buildMesh(upgradable?: boolean): Mesh;
+        buildMesh(updatable?: boolean): Mesh;
         private _resetCopy();
         private _meshBuilder(p, shape, positions, meshInd, indices, meshUV, uvs, meshCol, colors, idx, idxInShape, options);
         private _posToShape(positions);
@@ -6243,6 +6242,38 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class VRDeviceOrientationFreeCamera extends FreeCamera {
+        _alpha: number;
+        _beta: number;
+        _gamma: number;
+        private _offsetOrientation;
+        private _deviceOrientationHandler;
+        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean);
+        _onOrientationEvent(evt: DeviceOrientationEvent): void;
+        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        detachControl(element: HTMLElement): void;
+    }
+}
+
+declare var HMDVRDevice: any;
+declare var PositionSensorVRDevice: any;
+declare module BABYLON {
+    class WebVRFreeCamera extends FreeCamera {
+        _hmdDevice: any;
+        _sensorDevice: any;
+        _cacheState: any;
+        _cacheQuaternion: Quaternion;
+        _cacheRotation: Vector3;
+        _vrEnabled: boolean;
+        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean);
+        private _getWebVRDevices(devices);
+        _checkInputs(): void;
+        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
+        detachControl(element: HTMLElement): void;
+    }
+}
+
+declare module BABYLON {
     interface IOctreeContainer<T> {
         blocks: Array<OctreeBlock<T>>;
     }
@@ -6290,38 +6321,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class VRDeviceOrientationFreeCamera extends FreeCamera {
-        _alpha: number;
-        _beta: number;
-        _gamma: number;
-        private _offsetOrientation;
-        private _deviceOrientationHandler;
-        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean);
-        _onOrientationEvent(evt: DeviceOrientationEvent): void;
-        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        detachControl(element: HTMLElement): void;
-    }
-}
-
-declare var HMDVRDevice: any;
-declare var PositionSensorVRDevice: any;
-declare module BABYLON {
-    class WebVRFreeCamera extends FreeCamera {
-        _hmdDevice: any;
-        _sensorDevice: any;
-        _cacheState: any;
-        _cacheQuaternion: Quaternion;
-        _cacheRotation: Vector3;
-        _vrEnabled: boolean;
-        constructor(name: string, position: Vector3, scene: Scene, compensateDistortion?: boolean);
-        private _getWebVRDevices(devices);
-        _checkInputs(): void;
-        attachControl(element: HTMLElement, noPreventDefault?: boolean): void;
-        detachControl(element: HTMLElement): void;
-    }
-}
-
-declare module BABYLON {
     class ShadowGenerator {
         private static _FILTER_NONE;
         private static _FILTER_VARIANCESHADOWMAP;
@@ -6577,6 +6576,62 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class CannonJSPlugin implements IPhysicsEnginePlugin {
+        private _world;
+        private _registeredMeshes;
+        private _physicsMaterials;
+        initialize(iterations?: number): void;
+        private _checkWithEpsilon(value);
+        runOneStep(delta: number): void;
+        setGravity(gravity: Vector3): void;
+        registerMesh(mesh: AbstractMesh, impostor: number, options?: PhysicsBodyCreationOptions): any;
+        private _createShape(mesh, impostor);
+        private _createConvexPolyhedron(rawVerts, rawFaces, mesh);
+        private _createHeightmap(mesh);
+        private _addMaterial(friction, restitution);
+        private _createRigidBodyFromShape(shape, mesh, options);
+        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        private _unbindBody(body);
+        unregisterMesh(mesh: AbstractMesh): void;
+        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        updateBodyPosition: (mesh: AbstractMesh) => void;
+        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3): boolean;
+        dispose(): void;
+        isSupported(): boolean;
+        getWorldObject(): any;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+    }
+}
+
+declare module BABYLON {
+    class OimoJSPlugin implements IPhysicsEnginePlugin {
+        private _world;
+        private _registeredMeshes;
+        private _checkWithEpsilon(value);
+        initialize(iterations?: number): void;
+        setGravity(gravity: Vector3): void;
+        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        private _createBodyAsCompound(part, options, initialMesh);
+        unregisterMesh(mesh: AbstractMesh): void;
+        private _unbindBody(body);
+        /**
+         * Update the body position according to the mesh position
+         * @param mesh
+         */
+        updateBodyPosition: (mesh: AbstractMesh) => void;
+        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        dispose(): void;
+        isSupported(): boolean;
+        getWorldObject(): any;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+        private _getLastShape(body);
+        runOneStep(time: number): void;
+    }
+}
+
+declare module BABYLON {
     class PostProcessRenderEffect {
         private _engine;
         private _postProcesses;
@@ -6675,62 +6730,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class CannonJSPlugin implements IPhysicsEnginePlugin {
-        private _world;
-        private _registeredMeshes;
-        private _physicsMaterials;
-        initialize(iterations?: number): void;
-        private _checkWithEpsilon(value);
-        runOneStep(delta: number): void;
-        setGravity(gravity: Vector3): void;
-        registerMesh(mesh: AbstractMesh, impostor: number, options?: PhysicsBodyCreationOptions): any;
-        private _createShape(mesh, impostor);
-        private _createConvexPolyhedron(rawVerts, rawFaces, mesh);
-        private _createHeightmap(mesh);
-        private _addMaterial(friction, restitution);
-        private _createRigidBodyFromShape(shape, mesh, options);
-        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        private _unbindBody(body);
-        unregisterMesh(mesh: AbstractMesh): void;
-        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        updateBodyPosition: (mesh: AbstractMesh) => void;
-        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3): boolean;
-        dispose(): void;
-        isSupported(): boolean;
-        getWorldObject(): any;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-    }
-}
-
-declare module BABYLON {
-    class OimoJSPlugin implements IPhysicsEnginePlugin {
-        private _world;
-        private _registeredMeshes;
-        private _checkWithEpsilon(value);
-        initialize(iterations?: number): void;
-        setGravity(gravity: Vector3): void;
-        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        private _createBodyAsCompound(part, options, initialMesh);
-        unregisterMesh(mesh: AbstractMesh): void;
-        private _unbindBody(body);
-        /**
-         * Update the body position according to the mesh position
-         * @param mesh
-         */
-        updateBodyPosition: (mesh: AbstractMesh) => void;
-        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        dispose(): void;
-        isSupported(): boolean;
-        getWorldObject(): any;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-        private _getLastShape(body);
-        runOneStep(time: number): void;
-    }
-}
-
-declare module BABYLON {
     class CustomProceduralTexture extends ProceduralTexture {
         private _animate;
         private _time;

Dosya farkı çok büyük olduğundan ihmal edildi
+ 20 - 20
dist/preview release/babylon.js


+ 41 - 16
dist/preview release/babylon.max.js

@@ -8203,6 +8203,8 @@ var BABYLON;
         };
         AbstractMesh.prototype.dispose = function (doNotRecurse) {
             var index;
+            // Animations
+            this.getScene().stopAnimation(this);
             // Physics
             if (this.getPhysicsImpostor() !== BABYLON.PhysicsEngine.NoImpostor) {
                 this.setPhysicsState(BABYLON.PhysicsEngine.NoImpostor);
@@ -8337,6 +8339,8 @@ var BABYLON;
                 this._shadowGenerator.dispose();
                 this._shadowGenerator = null;
             }
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             this.getScene().removeLight(this);
         };
@@ -9895,6 +9899,8 @@ var BABYLON;
             return this._projectionMatrix;
         };
         Camera.prototype.dispose = function () {
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             this.getScene().removeCamera(this);
             while (this._rigCameras.length > 0) {
@@ -12124,6 +12130,14 @@ var BABYLON;
             }
             return index;
         };
+        Scene.prototype.removeSkeleton = function (toRemove) {
+            var index = this.skeletons.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.skeletons.splice(index, 1);
+            }
+            return index;
+        };
         Scene.prototype.removeLight = function (toRemove) {
             var index = this.lights.indexOf(toRemove);
             if (index !== -1) {
@@ -15581,7 +15595,7 @@ var BABYLON;
             return MeshBuilder._ExtrudeShapeGeneric(name, shape, path, null, null, scaleFunction, rotationFunction, ribbonCloseArray, ribbonClosePath, cap, true, scene, updatable, sideOrientation, instance);
         };
         MeshBuilder.CreateLathe = function (name, options, scene) {
-            var arc = (options.arc <= 0) ? 1.0 : options.arc || 1.0;
+            var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var closed = (options.closed === undefined) ? true : options.closed;
             var shape = options.shape;
             var radius = options.radius || 1;
@@ -15692,7 +15706,7 @@ var BABYLON;
             var updatable = options.updatable;
             var sideOrientation = options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             var instance = options.instance;
-            options.arc = (options.arc < 0) ? 1 : options.arc || 1;
+            options.arc = (options.arc <= 0 || options.arc > 1) ? 1 : options.arc || 1;
             // tube geometry
             var tubePathArray = function (path, path3D, circlePaths, radius, tessellation, radiusFunction, cap, arc) {
                 var tangents = path3D.getTangents();
@@ -16137,6 +16151,8 @@ var BABYLON;
             }
         };
         BaseTexture.prototype.dispose = function () {
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             var index = this._scene.textures.indexOf(this);
             if (index >= 0) {
@@ -18234,6 +18250,8 @@ var BABYLON;
             return result;
         };
         Material.prototype.dispose = function (forceDisposeEffect) {
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             var index = this._scene.materials.indexOf(this);
             if (index >= 0) {
@@ -22468,6 +22486,12 @@ var BABYLON;
             }
             return result;
         };
+        Skeleton.prototype.dispose = function () {
+            // Animations
+            this.getScene().stopAnimation(this);
+            // Remove from scene
+            this.getScene().removeSkeleton(this);
+        };
         return Skeleton;
     })();
     BABYLON.Skeleton = Skeleton;
@@ -23369,7 +23393,7 @@ var BABYLON;
             var diameterX = options.diameterX || options.diameter || 1;
             var diameterY = options.diameterY || options.diameter || 1;
             var diameterZ = options.diameterZ || options.diameter || 1;
-            var arc = (options.arc <= 0) ? 1.0 : options.arc || 1.0;
+            var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var slice = (options.slice <= 0) ? 1.0 : options.slice || 1.0;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             var radius = new BABYLON.Vector3(diameterX / 2, diameterY / 2, diameterZ / 2);
@@ -23424,7 +23448,7 @@ var BABYLON;
             var diameterBottom = options.diameterBottom || options.diameter || 1;
             var tessellation = options.tessellation || 24;
             var subdivisions = options.subdivisions || 1;
-            var arc = (options.arc <= 0) ? 1.0 : options.arc || 1.0;
+            var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             var faceUV = options.faceUV || new Array(3);
             var faceColors = options.faceColors;
@@ -23860,7 +23884,7 @@ var BABYLON;
             var uvs = [];
             var radius = options.radius || 0.5;
             var tessellation = options.tessellation || 64;
-            var arc = (options.arc <= 0) ? 1.0 : options.arc || 1.0;
+            var arc = (options.arc <= 0 || options.arc > 1) ? 1.0 : options.arc || 1.0;
             var sideOrientation = (options.sideOrientation === 0) ? 0 : options.sideOrientation || BABYLON.Mesh.DEFAULTSIDE;
             // positions and uvs
             positions.push(0, 0, 0); // disc center first
@@ -24239,6 +24263,9 @@ var BABYLON;
             if (!tagsString) {
                 return;
             }
+            if (typeof tagsString !== "string") {
+                return;
+            }
             var tags = tagsString.split(" ");
             for (var t in tags) {
                 Tags._AddTagTo(obj, tags[t]);
@@ -35839,8 +35866,8 @@ var BABYLON;
             this._camera = scene.activeCamera;
         }
         // build the SPS mesh : returns the mesh
-        SolidParticleSystem.prototype.buildMesh = function (upgradable) {
-            if (upgradable === void 0) { upgradable = true; }
+        SolidParticleSystem.prototype.buildMesh = function (updatable) {
+            if (updatable === void 0) { updatable = true; }
             if (this.nbParticles === 0) {
                 var triangle = BABYLON.MeshBuilder.CreateDisc("", { radius: 1, tessellation: 3 }, this._scene);
                 this.addShape(triangle, 1);
@@ -35863,13 +35890,16 @@ var BABYLON;
                 vertexData.set(this._colors32, BABYLON.VertexBuffer.ColorKind);
             }
             var mesh = new BABYLON.Mesh(name, this._scene);
-            vertexData.applyToMesh(mesh, upgradable);
+            vertexData.applyToMesh(mesh, updatable);
             this.mesh = mesh;
             // free memory
             this._positions = null;
             this._normals = null;
             this._uvs = null;
             this._colors = null;
+            if (!updatable) {
+                this.particles.length = 0;
+            }
             return mesh;
         };
         //reset copy
@@ -35967,15 +35997,9 @@ var BABYLON;
             }
             return shapeUV;
         };
-        // adds a new particle object in the particles array and double links the particle (next/previous)
+        // adds a new particle object in the particles array
         SolidParticleSystem.prototype._addParticle = function (p, idxpos, model, shapeId, idxInShape) {
-            this._particle = new BABYLON.SolidParticle(p, idxpos, model, shapeId, idxInShape);
-            this.particles.push(this._particle);
-            this._particle.previous = this._previousParticle;
-            if (this._previousParticle) {
-                this._previousParticle.next = this._particle;
-            }
-            this._previousParticle = this._particle;
+            this.particles.push(new BABYLON.SolidParticle(p, idxpos, model, shapeId, idxInShape));
         };
         // add solid particles from a shape model in the particles array
         SolidParticleSystem.prototype.addShape = function (mesh, nb, options) {
@@ -36093,6 +36117,7 @@ var BABYLON;
             var uvidx = 0;
             var uvIndex = 0;
             // particle loop
+            end = (end > this.nbParticles - 1) ? this.nbParticles - 1 : end;
             for (var p = start; p <= end; p++) {
                 this._particle = this.particles[p];
                 this._shape = this._particle._model._shape;

Dosya farkı çok büyük olduğundan ihmal edildi
+ 20 - 20
dist/preview release/babylon.noworker.js


+ 1 - 1
dist/preview release/what's new.md

@@ -30,7 +30,7 @@
     - New `Material.getBindedMeshes()` function ([deltakosh](https://github.com/deltakosh))
     - OimoJS Plugin now uses Quaternions exclusively and calculates body rotations correctly. [PR](https://github.com/BabylonJS/Babylon.js/pull/761) ([RaananW](https://github.com/RaananW))
     - It is now possible to get the physics engine's body and wolrd objects using the physics engine. [PR](https://github.com/BabylonJS/Babylon.js/pull/761) ([RaananW](https://github.com/RaananW))
-    - new Heightmap Impostor for Cannon.js physics engine. [PR](https://github.com/BabylonJS/Babylon.js/pull/78), [Demo] (http://www.babylonjs-playground.com/#EXL6K#1) ([RaananW](https://github.com/RaananW))
+    - new Heightmap Impostor for Cannon.js physics engine. [PR](https://github.com/BabylonJS/Babylon.js/pull/78), [Demo] (http://www.babylonjs-playground.com/#D3LQD#3) ([RaananW](https://github.com/RaananW))
     - A plane mesh can be created with a source plane (math). [PR](https://github.com/BabylonJS/Babylon.js/pull/779) ([RaananW](https://github.com/RaananW))
   - **Bug fixes**
     - Fixed a bug with spherical mapping ([deltakosh](https://github.com/deltakosh)) 

BIN
exporters/3ds Max/Max2Babylon-0.21.zip


+ 6 - 0
src/Bones/babylon.skeleton.js

@@ -97,6 +97,12 @@ var BABYLON;
             }
             return result;
         };
+        Skeleton.prototype.dispose = function () {
+            // Animations
+            this.getScene().stopAnimation(this);
+            // Remove from scene
+            this.getScene().removeSkeleton(this);
+        };
         return Skeleton;
     })();
     BABYLON.Skeleton = Skeleton;

+ 8 - 0
src/Bones/babylon.skeleton.ts

@@ -128,5 +128,13 @@
 
             return result;
         }
+
+        public dispose() {
+            // Animations
+            this.getScene().stopAnimation(this);
+
+            // Remove from scene
+            this.getScene().removeSkeleton(this);
+        }
     }
 }

+ 2 - 0
src/Cameras/babylon.camera.js

@@ -406,6 +406,8 @@ var BABYLON;
             return this._projectionMatrix;
         };
         Camera.prototype.dispose = function () {
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             this.getScene().removeCamera(this);
             while (this._rigCameras.length > 0) {

+ 3 - 0
src/Cameras/babylon.camera.ts

@@ -450,6 +450,9 @@
         }
 
         public dispose(): void {
+            // Animations
+            this.getScene().stopAnimation(this);
+
             // Remove from scene
             this.getScene().removeCamera(this);
             while (this._rigCameras.length > 0) {

+ 2 - 0
src/Lights/babylon.light.js

@@ -68,6 +68,8 @@ var BABYLON;
                 this._shadowGenerator.dispose();
                 this._shadowGenerator = null;
             }
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             this.getScene().removeLight(this);
         };

+ 3 - 0
src/Lights/babylon.light.ts

@@ -104,6 +104,9 @@
                 this._shadowGenerator = null;
             }
 
+            // Animations
+            this.getScene().stopAnimation(this);
+
             // Remove from scene
             this.getScene().removeLight(this);
         }

+ 2 - 0
src/Materials/Textures/babylon.baseTexture.js

@@ -99,6 +99,8 @@ var BABYLON;
             }
         };
         BaseTexture.prototype.dispose = function () {
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             var index = this._scene.textures.indexOf(this);
             if (index >= 0) {

+ 3 - 0
src/Materials/Textures/babylon.baseTexture.ts

@@ -125,6 +125,9 @@
         }
 
         public dispose(): void {
+            // Animations
+            this.getScene().stopAnimation(this);
+
             // Remove from scene
             var index = this._scene.textures.indexOf(this);
 

+ 2 - 0
src/Materials/babylon.material.js

@@ -190,6 +190,8 @@ var BABYLON;
             return result;
         };
         Material.prototype.dispose = function (forceDisposeEffect) {
+            // Animations
+            this.getScene().stopAnimation(this);
             // Remove from scene
             var index = this._scene.materials.indexOf(this);
             if (index >= 0) {

+ 3 - 0
src/Materials/babylon.material.ts

@@ -219,6 +219,9 @@
         }
 
         public dispose(forceDisposeEffect?: boolean): void {
+            // Animations
+            this.getScene().stopAnimation(this);
+
             // Remove from scene
             var index = this._scene.materials.indexOf(this);
             if (index >= 0) {

+ 2 - 0
src/Mesh/babylon.abstractMesh.js

@@ -826,6 +826,8 @@ var BABYLON;
         };
         AbstractMesh.prototype.dispose = function (doNotRecurse) {
             var index;
+            // Animations
+            this.getScene().stopAnimation(this);
             // Physics
             if (this.getPhysicsImpostor() !== BABYLON.PhysicsEngine.NoImpostor) {
                 this.setPhysicsState(BABYLON.PhysicsEngine.NoImpostor);

+ 3 - 0
src/Mesh/babylon.abstractMesh.ts

@@ -980,6 +980,9 @@
         public dispose(doNotRecurse?: boolean): void {
             var index: number;
 
+            // Animations
+            this.getScene().stopAnimation(this);
+
             // Physics
             if (this.getPhysicsImpostor() !== PhysicsEngine.NoImpostor) {
                 this.setPhysicsState(PhysicsEngine.NoImpostor);

+ 1 - 0
src/Mesh/babylon.mesh.vertexData.ts

@@ -1676,3 +1676,4 @@
 
 
 
+

+ 1 - 0
src/Mesh/babylon.meshBuilder.ts

@@ -794,3 +794,4 @@
 }
 
 
+

+ 8 - 3
src/Particles/babylon.solidParticleSystem.ts

@@ -38,7 +38,6 @@ module BABYLON {
         private _axisZ: Vector3 = Axis.Z;
         private _camera: Camera;
         private _particle: SolidParticle;
-        private _previousParticle: SolidParticle;
         private _fakeCamPos: Vector3 = Vector3.Zero();
         private _rotMatrix: Matrix = new Matrix();
         private _invertedMatrix: Matrix = new Matrix();
@@ -66,7 +65,7 @@ module BABYLON {
         }
 
         // build the SPS mesh : returns the mesh
-        public buildMesh(upgradable: boolean = true): Mesh {
+        public buildMesh(updatable: boolean = true): Mesh {
             if (this.nbParticles === 0) {
                 var triangle = MeshBuilder.CreateDisc("", { radius: 1, tessellation: 3 }, this._scene);
                 this.addShape(triangle, 1);
@@ -88,7 +87,7 @@ module BABYLON {
                 vertexData.set(this._colors32, VertexBuffer.ColorKind);
             }
             var mesh = new Mesh(name, this._scene);
-            vertexData.applyToMesh(mesh, upgradable);
+            vertexData.applyToMesh(mesh, updatable);
             this.mesh = mesh;
 
             // free memory
@@ -97,6 +96,10 @@ module BABYLON {
             this._uvs = null;
             this._colors = null;
 
+            if (!updatable) {
+                this.particles.length = 0;
+            }
+
             return mesh;
         }
 
@@ -342,6 +345,7 @@ module BABYLON {
             var uvIndex = 0;
 
             // particle loop
+            end = (end > this.nbParticles - 1) ? this.nbParticles - 1 : end;
             for (var p = start; p <= end; p++) {
                 this._particle = this.particles[p];
                 this._shape = this._particle._model._shape;
@@ -543,3 +547,4 @@ module BABYLON {
 
 
 
+

+ 78 - 27
src/Physics/Plugins/babylon.cannonJSPlugin.js

@@ -16,7 +16,29 @@ var BABYLON;
                             var tmpQ = new CANNON.Quaternion(-0.7071067811865475, 0, 0, 0.7071067811865475);
                             body.quaternion = body.quaternion.mult(tmpQ);
                         }
-                        //TODO - If the body is heightmap-based, this won't work correctly. find a good fix.
+                        if (registeredMesh.heightmap) {
+                            //calculate the correct body position:
+                            var rotationQuaternion = mesh.rotationQuaternion;
+                            mesh.rotationQuaternion = new BABYLON.Quaternion();
+                            mesh.computeWorldMatrix(true);
+                            //get original center with no rotation
+                            var center = mesh.getBoundingInfo().boundingBox.center.clone();
+                            var oldPivot = mesh.getPivotMatrix() || BABYLON.Matrix.Translation(0, 0, 0);
+                            //rotation is back
+                            mesh.rotationQuaternion = rotationQuaternion;
+                            //calculate the new center using a pivot (since Cannon.js doesn't center height maps)
+                            var p = BABYLON.Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
+                            mesh.setPivotMatrix(p);
+                            mesh.computeWorldMatrix(true);
+                            //calculate the translation
+                            var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
+                            body.position = new CANNON.Vec3(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSize.y, translation.z);
+                            //add it inverted to the delta 
+                            registeredMesh.delta = mesh.getBoundingInfo().boundingBox.center.subtract(center);
+                            registeredMesh.delta.y += mesh.getBoundingInfo().boundingBox.extendSize.y;
+                            mesh.setPivotMatrix(oldPivot);
+                            mesh.computeWorldMatrix(true);
+                        }
                         return;
                     }
                 }
@@ -104,9 +126,10 @@ var BABYLON;
         CannonJSPlugin.prototype._createConvexPolyhedron = function (rawVerts, rawFaces, mesh) {
             var verts = [], faces = [];
             mesh.computeWorldMatrix(true);
+            //reuse this variable
+            var transformed = BABYLON.Vector3.Zero();
             // Get vertices
             for (var i = 0; i < rawVerts.length; i += 3) {
-                var transformed = BABYLON.Vector3.Zero();
                 BABYLON.Vector3.TransformNormalFromFloatsToRef(rawVerts[i], rawVerts[i + 1], rawVerts[i + 2], mesh.getWorldMatrix(), transformed);
                 verts.push(new CANNON.Vec3(transformed.x, transformed.y, transformed.z));
             }
@@ -117,41 +140,51 @@ var BABYLON;
             var shape = new CANNON.ConvexPolyhedron(verts, faces);
             return shape;
         };
-        CannonJSPlugin.prototype._createHeightmap = function (mesh) {
+        CannonJSPlugin.prototype._createHeightmap = function (mesh, pointDepth) {
             var pos = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
-            if (pos[0] !== pos[pos.length - 1]) {
-                console.log("ERROR");
-                return;
-            }
             var matrix = [];
-            //dimension
-            var dim = -pos[0];
-            //array size
-            var arraySize = -1;
-            for (var i = 0; i < pos.length; i = i + 3) {
-                if (pos[i + 2] === pos[2]) {
-                    arraySize++;
-                }
-                else {
-                    break;
-                }
-            }
-            //calculate element size
+            //For now pointDepth will not be used and will be automatically calculated.
+            //Future reference - try and find the best place to add a reference to the pointDepth variable.
+            var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
+            var dim = Math.min(mesh.getBoundingInfo().boundingBox.extendSize.x, mesh.getBoundingInfo().boundingBox.extendSize.z);
             var elementSize = dim * 2 / arraySize;
-            //calculate the matrix for cannon's heightfield
+            var minY = mesh.getBoundingInfo().boundingBox.extendSize.y;
             for (var i = 0; i < pos.length; i = i + 3) {
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
                 var z = Math.round(((pos[i + 2]) / elementSize - arraySize / 2) * -1);
+                var y = pos[i + 1] + minY;
                 if (!matrix[x]) {
                     matrix[x] = [];
                 }
-                matrix[x][z] = pos[i + 1];
+                if (!matrix[x][z]) {
+                    matrix[x][z] = y;
+                }
+                matrix[x][z] = Math.max(y, matrix[x][z]);
+            }
+            for (var x = 0; x <= arraySize; ++x) {
+                if (!matrix[x]) {
+                    var loc = 1;
+                    while (!matrix[(x + loc) % arraySize]) {
+                        loc++;
+                    }
+                    matrix[x] = matrix[(x + loc) % arraySize].slice();
+                }
+                for (var z = 0; z <= arraySize; ++z) {
+                    if (!matrix[x][z]) {
+                        var loc = 1;
+                        var newValue;
+                        while (newValue === undefined) {
+                            newValue = matrix[x][(z + loc++) % arraySize];
+                        }
+                        matrix[x][z] = newValue;
+                    }
+                }
             }
             var shape = new CANNON.Heightfield(matrix, {
                 elementSize: elementSize
             });
             //For future reference, needed for body transformation
-            shape.dim = dim;
+            shape.minY = minY;
             return shape;
         };
         CannonJSPlugin.prototype._addMaterial = function (friction, restitution) {
@@ -192,19 +225,37 @@ var BABYLON;
                 //-90 DEG in X, precalculated
                 var tmpQ = new CANNON.Quaternion(-0.7071067811865475, 0, 0, 0.7071067811865475);
                 body.quaternion = body.quaternion.mult(tmpQ);
-                //Invert!
+                //Invert! (Precalculated, 90 deg in X)
                 deltaRotation = new BABYLON.Quaternion(0.7071067811865475, 0, 0, 0.7071067811865475);
             }
             //If it is a heightfield, if should be centered.
             if (shape.type === CANNON.Shape.types.HEIGHTFIELD) {
-                body.position = new CANNON.Vec3(-shape.dim, 0, shape.dim).vadd(mesh.position);
+                //calculate the correct body position:
+                var rotationQuaternion = mesh.rotationQuaternion;
+                mesh.rotationQuaternion = new BABYLON.Quaternion();
+                mesh.computeWorldMatrix(true);
+                //get original center with no rotation
+                var center = mesh.getBoundingInfo().boundingBox.center.clone();
+                var oldPivot = mesh.getPivotMatrix() || BABYLON.Matrix.Translation(0, 0, 0);
+                //rotation is back
+                mesh.rotationQuaternion = rotationQuaternion;
+                //calculate the new center using a pivot (since Cannon.js doesn't center height maps)
+                var p = BABYLON.Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
+                mesh.setPivotMatrix(p);
+                mesh.computeWorldMatrix(true);
+                //calculate the translation
+                var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
+                body.position = new CANNON.Vec3(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSize.y, translation.z);
                 //add it inverted to the delta 
-                deltaPosition = mesh.position.add(new BABYLON.Vector3(shape.dim, 0, -shape.dim));
+                deltaPosition = mesh.getBoundingInfo().boundingBox.center.subtract(center);
+                deltaPosition.y += mesh.getBoundingInfo().boundingBox.extendSize.y;
+                mesh.setPivotMatrix(oldPivot);
+                mesh.computeWorldMatrix(true);
             }
             //add the shape
             body.addShape(shape);
             this._world.add(body);
-            this._registeredMeshes.push({ mesh: mesh, body: body, material: material, delta: deltaPosition, deltaRotation: deltaRotation });
+            this._registeredMeshes.push({ mesh: mesh, body: body, material: material, delta: deltaPosition, deltaRotation: deltaRotation, heightmap: shape.type === CANNON.Shape.types.HEIGHTFIELD });
             return body;
         };
         CannonJSPlugin.prototype.registerMeshesAsCompound = function (parts, options) {

+ 103 - 35
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -116,10 +116,10 @@
 
             mesh.computeWorldMatrix(true);
 
+            //reuse this variable
+            var transformed = Vector3.Zero();
             // Get vertices
             for (var i = 0; i < rawVerts.length; i += 3) {
-                var transformed = Vector3.Zero();
-
                 Vector3.TransformNormalFromFloatsToRef(rawVerts[i], rawVerts[i + 1], rawVerts[i + 2], mesh.getWorldMatrix(), transformed);
                 verts.push(new CANNON.Vec3(transformed.x, transformed.y, transformed.z));
             }
@@ -134,40 +134,54 @@
             return shape;
         }
 
-        private _createHeightmap(mesh: AbstractMesh) {
-            var pos = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
-
-            if (pos[0] !== pos[pos.length - 1]) {
-                console.log("ERROR");
-                return;
-            }
-
+        private _createHeightmap(mesh: AbstractMesh, pointDepth?: number) {
+            var pos = mesh.getVerticesData(VertexBuffer.PositionKind);
             var matrix = [];
-            
-            //dimension
-            var dim = -pos[0];
-
-            //array size
-            var arraySize = -1;
-            for (var i = 0; i < pos.length; i = i + 3) {
-                if (pos[i + 2] === pos[2]) {
-                    arraySize++;
-                } else {
-                    break;
-                }
-            }
-
-            //calculate element size
+    
+            //For now pointDepth will not be used and will be automatically calculated.
+            //Future reference - try and find the best place to add a reference to the pointDepth variable.
+            var arraySize = pointDepth || ~~(Math.sqrt(pos.length / 3) - 1);
+    
+            var dim = Math.min(mesh.getBoundingInfo().boundingBox.extendSize.x, mesh.getBoundingInfo().boundingBox.extendSize.z);
+    
             var elementSize = dim * 2 / arraySize;
-            
-            //calculate the matrix for cannon's heightfield
+    
+            var minY = mesh.getBoundingInfo().boundingBox.extendSize.y;
+    
             for (var i = 0; i < pos.length; i = i + 3) {
                 var x = Math.round((pos[i + 0]) / elementSize + arraySize / 2);
                 var z = Math.round(((pos[i + 2]) / elementSize - arraySize / 2) * -1);
+                var y = pos[i + 1] + minY;
                 if (!matrix[x]) {
                     matrix[x] = [];
                 }
-                matrix[x][z] = pos[i + 1];
+                if (!matrix[x][z]) {
+                    matrix[x][z] = y;
+                }
+                matrix[x][z] = Math.max(y, matrix[x][z]);
+            }
+    
+    
+            for (var x = 0; x <= arraySize; ++x) {
+                if (!matrix[x]) {
+                    var loc = 1;
+                    while (!matrix[(x + loc) % arraySize]) {
+                        loc++;
+                    }
+                    matrix[x] = matrix[(x + loc) % arraySize].slice();
+                    //console.log("missing x", x);
+                }
+                for (var z = 0; z <= arraySize; ++z) {
+                    if (!matrix[x][z]) {
+                        var loc = 1;
+                        var newValue;
+                        while (newValue === undefined) {
+                            newValue = matrix[x][(z + loc++) % arraySize];
+                        }
+                        matrix[x][z] = newValue;
+    
+                    }
+                }
             }
 
             var shape = new CANNON.Heightfield(matrix, {
@@ -175,7 +189,7 @@
             });
             
             //For future reference, needed for body transformation
-            shape.dim = dim;
+            shape.minY = minY;
 
             return shape;
         }
@@ -229,15 +243,41 @@
                 //-90 DEG in X, precalculated
                 var tmpQ = new CANNON.Quaternion(-0.7071067811865475, 0, 0, 0.7071067811865475);
                 body.quaternion = body.quaternion.mult(tmpQ);
-                //Invert!
+                //Invert! (Precalculated, 90 deg in X)
                 deltaRotation = new Quaternion(0.7071067811865475, 0, 0, 0.7071067811865475);
             }
             
             //If it is a heightfield, if should be centered.
             if (shape.type === CANNON.Shape.types.HEIGHTFIELD) {
-                body.position = new CANNON.Vec3(-shape.dim, 0, shape.dim).vadd(mesh.position);
+                
+                //calculate the correct body position:
+                var rotationQuaternion = mesh.rotationQuaternion;
+                mesh.rotationQuaternion = new BABYLON.Quaternion();
+                mesh.computeWorldMatrix(true);
+                
+                //get original center with no rotation
+                var center = mesh.getBoundingInfo().boundingBox.center.clone();
+        
+                var oldPivot = mesh.getPivotMatrix() || Matrix.Translation(0, 0, 0);
+                
+                //rotation is back
+                mesh.rotationQuaternion = rotationQuaternion;
+        
+                //calculate the new center using a pivot (since Cannon.js doesn't center height maps)
+                var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
+                mesh.setPivotMatrix(p);
+                mesh.computeWorldMatrix(true);
+        
+                //calculate the translation
+                var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
+                
+                body.position = new CANNON.Vec3(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSize.y, translation.z);
                 //add it inverted to the delta 
-                deltaPosition = mesh.position.add(new BABYLON.Vector3(shape.dim, 0, -shape.dim));
+                deltaPosition = mesh.getBoundingInfo().boundingBox.center.subtract(center);
+                deltaPosition.y += mesh.getBoundingInfo().boundingBox.extendSize.y;
+                
+                mesh.setPivotMatrix(oldPivot);
+                mesh.computeWorldMatrix(true);
             }
             
             //add the shape
@@ -245,7 +285,7 @@
 
             this._world.add(body);
 
-            this._registeredMeshes.push({ mesh: mesh, body: body, material: material, delta: deltaPosition, deltaRotation: deltaRotation });
+            this._registeredMeshes.push({ mesh: mesh, body: body, material: material, delta: deltaPosition, deltaRotation: deltaRotation, heightmap: shape.type === CANNON.Shape.types.HEIGHTFIELD });
 
             return body;
         }
@@ -332,8 +372,36 @@
                         body.quaternion = body.quaternion.mult(tmpQ);
                     }
                     
-                    //TODO - If the body is heightmap-based, this won't work correctly. find a good fix.
-                    
+                    if(registeredMesh.heightmap) {
+                        //calculate the correct body position:
+                        var rotationQuaternion = mesh.rotationQuaternion;
+                        mesh.rotationQuaternion = new BABYLON.Quaternion();
+                        mesh.computeWorldMatrix(true);
+                        
+                        //get original center with no rotation
+                        var center = mesh.getBoundingInfo().boundingBox.center.clone();
+                
+                        var oldPivot = mesh.getPivotMatrix() || Matrix.Translation(0, 0, 0);
+                        
+                        //rotation is back
+                        mesh.rotationQuaternion = rotationQuaternion;
+                
+                        //calculate the new center using a pivot (since Cannon.js doesn't center height maps)
+                        var p = Matrix.Translation(mesh.getBoundingInfo().boundingBox.extendSize.x, 0, -mesh.getBoundingInfo().boundingBox.extendSize.z);
+                        mesh.setPivotMatrix(p);
+                        mesh.computeWorldMatrix(true);
+                
+                        //calculate the translation
+                        var translation = mesh.getBoundingInfo().boundingBox.center.subtract(center).subtract(mesh.position).negate();
+                        
+                        body.position = new CANNON.Vec3(translation.x, translation.y - mesh.getBoundingInfo().boundingBox.extendSize.y, translation.z);
+                        //add it inverted to the delta 
+                        registeredMesh.delta = mesh.getBoundingInfo().boundingBox.center.subtract(center);
+                        registeredMesh.delta.y += mesh.getBoundingInfo().boundingBox.extendSize.y;
+                        
+                        mesh.setPivotMatrix(oldPivot);
+                        mesh.computeWorldMatrix(true);
+                    }
                     return;
                 }
             }

+ 3 - 0
src/Tools/babylon.tags.js

@@ -44,6 +44,9 @@ var BABYLON;
             if (!tagsString) {
                 return;
             }
+            if (typeof tagsString !== "string") {
+                return;
+            }
             var tags = tagsString.split(" ");
             for (var t in tags) {
                 Tags._AddTagTo(obj, tags[t]);

+ 4 - 0
src/Tools/babylon.tags.ts

@@ -50,6 +50,10 @@
                 return;
             }
 
+            if (typeof tagsString !== "string") {
+                return;
+            }
+
             var tags = tagsString.split(" ");
             for (var t in tags) {
                 Tags._AddTagTo(obj, tags[t]);

+ 8 - 0
src/babylon.scene.js

@@ -657,6 +657,14 @@ var BABYLON;
             }
             return index;
         };
+        Scene.prototype.removeSkeleton = function (toRemove) {
+            var index = this.skeletons.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.skeletons.splice(index, 1);
+            }
+            return index;
+        };
         Scene.prototype.removeLight = function (toRemove) {
             var index = this.lights.indexOf(toRemove);
             if (index !== -1) {

+ 10 - 0
src/babylon.scene.ts

@@ -877,6 +877,16 @@
             return index;
         }
 
+        public removeSkeleton(toRemove: Skeleton): number {
+            var index = this.skeletons.indexOf(toRemove);
+            if (index !== -1) {
+                // Remove from the scene if mesh found 
+                this.skeletons.splice(index, 1);
+            }
+
+            return index;
+        }
+
         public removeLight(toRemove: Light): number {
             var index = this.lights.indexOf(toRemove);
             if (index !== -1) {