소스 검색

New 3dsmax exporter (0.4) with support for poseMatrix

David Catuhe 9 년 전
부모
커밋
3fce20e8c9
30개의 변경된 파일811개의 추가작업 그리고 538개의 파일을 삭제
  1. 3 0
      Exporters/3ds Max/BabylonExport.Entities/BabylonSkeleton.cs
  2. BIN
      Exporters/3ds Max/Max2Babylon-0.25.zip
  3. 5 4
      Exporters/3ds Max/Max2Babylon/Exporter/BabylonExporter.Skeleton.cs
  4. 17 17
      dist/preview release/babylon.core.js
  5. 388 378
      dist/preview release/babylon.d.ts
  6. 21 21
      dist/preview release/babylon.js
  7. 110 30
      dist/preview release/babylon.max.js
  8. 23 23
      dist/preview release/babylon.noworker.js
  9. 9 12
      src/Bones/babylon.bone.js
  10. 13 16
      src/Bones/babylon.bone.ts
  11. 56 10
      src/Bones/babylon.skeleton.js
  12. 67 10
      src/Bones/babylon.skeleton.ts
  13. 1 1
      src/Lights/Shadows/babylon.shadowGenerator.js
  14. 1 1
      src/Lights/Shadows/babylon.shadowGenerator.ts
  15. 7 1
      src/Loading/Plugins/babylon.babylonFileLoader.js
  16. 5 1
      src/Loading/Plugins/babylon.babylonFileLoader.ts
  17. 1 1
      src/Materials/babylon.shaderMaterial.js
  18. 1 1
      src/Materials/babylon.shaderMaterial.ts
  19. 1 1
      src/Materials/babylon.standardMaterial.js
  20. 1 1
      src/Materials/babylon.standardMaterial.ts
  21. 31 0
      src/Mesh/babylon.abstractMesh.js
  22. 42 1
      src/Mesh/babylon.abstractMesh.ts
  23. 1 1
      src/Mesh/babylon.mesh.js
  24. 1 1
      src/Mesh/babylon.mesh.ts
  25. 1 1
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.js
  26. 1 1
      src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts
  27. 1 1
      src/Rendering/babylon.depthRenderer.js
  28. 1 1
      src/Rendering/babylon.depthRenderer.ts
  29. 1 1
      src/Rendering/babylon.outlineRenderer.js
  30. 1 1
      src/Rendering/babylon.outlineRenderer.ts

+ 3 - 0
Exporters/3ds Max/BabylonExport.Entities/BabylonSkeleton.cs

@@ -13,5 +13,8 @@ namespace BabylonExport.Entities
 
         [DataMember]
         public BabylonBone[] bones { get; set; }
+
+        [DataMember]
+        public bool needInitialSkinMatrix { get; set; }
     }
 }

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


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

@@ -30,8 +30,6 @@ namespace Max2Babylon
             RaiseMessage(babylonSkeleton.name, 1);
 
             var skinIndex = skins.IndexOf(skin);
-            var meshNode = skinnedNodes[skinIndex];
-            var skinInitMatrix = meshNode.GetObjectTM(0);
 
             var bones = new List<BabylonBone>();
             var gameBones = new List<IIGameNode>();
@@ -70,15 +68,17 @@ namespace Max2Babylon
                 {
                     babBone.parentBoneIndex = boneIds.IndexOf(parent.NodeID);
                 }
+
                 if (babBone.parentBoneIndex == -1)
                 {
-                    bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform.Multiply(skinInitMatrix.Inverse);
+                    bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform;
                 }
                 else
                 {
                     var parentBindPoseInfos = bindPoseInfos[babBone.parentBoneIndex];
                     bindPoseInfos[index].LocalTransform = bindPoseInfos[index].AbsoluteTransform.Multiply(parentBindPoseInfos.AbsoluteTransform.Inverse);
                 }
+
                 babBone.matrix = bindPoseInfos[index].LocalTransform.ToArray();
 
                 var babylonAnimation = new BabylonAnimation
@@ -102,7 +102,7 @@ namespace Max2Babylon
                     IGMatrix mat;
                     if (parentNode == null || babBone.parentBoneIndex == -1)
                     {
-                        mat = objectTM.Multiply(meshNode.GetObjectTM(key).Inverse);
+                        mat = objectTM;
                     }
                     else
                     {
@@ -126,6 +126,7 @@ namespace Max2Babylon
                 babBone.animation = babylonAnimation;
             }
 
+            babylonSkeleton.needInitialSkinMatrix = true;
             babylonSkeleton.bones = bones.ToArray();
 
             babylonScene.SkeletonsList.Add(babylonSkeleton);

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 17 - 17
dist/preview release/babylon.core.js


+ 388 - 378
dist/preview release/babylon.d.ts

@@ -1244,6 +1244,178 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class Analyser {
+        SMOOTHING: number;
+        FFT_SIZE: number;
+        BARGRAPHAMPLITUDE: number;
+        DEBUGCANVASPOS: {
+            x: number;
+            y: number;
+        };
+        DEBUGCANVASSIZE: {
+            width: number;
+            height: number;
+        };
+        private _byteFreqs;
+        private _byteTime;
+        private _floatFreqs;
+        private _webAudioAnalyser;
+        private _debugCanvas;
+        private _debugCanvasContext;
+        private _scene;
+        private _registerFunc;
+        private _audioEngine;
+        constructor(scene: Scene);
+        getFrequencyBinCount(): number;
+        getByteFrequencyData(): Uint8Array;
+        getByteTimeDomainData(): Uint8Array;
+        getFloatFrequencyData(): Uint8Array;
+        drawDebugCanvas(): void;
+        stopDebugCanvas(): void;
+        connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode): void;
+        dispose(): void;
+    }
+}
+
+declare module BABYLON {
+    class AudioEngine {
+        private _audioContext;
+        private _audioContextInitialized;
+        canUseWebAudio: boolean;
+        masterGain: GainNode;
+        private _connectedAnalyser;
+        WarnedWebAudioUnsupported: boolean;
+        audioContext: AudioContext;
+        constructor();
+        private _initializeAudioContext();
+        dispose(): void;
+        getGlobalVolume(): number;
+        setGlobalVolume(newVolume: number): void;
+        connectToAnalyser(analyser: Analyser): void;
+    }
+}
+
+declare module BABYLON {
+    class Sound {
+        name: string;
+        autoplay: boolean;
+        loop: boolean;
+        useCustomAttenuation: boolean;
+        soundTrackId: number;
+        spatialSound: boolean;
+        refDistance: number;
+        rolloffFactor: number;
+        maxDistance: number;
+        distanceModel: string;
+        private _panningModel;
+        onended: () => any;
+        private _playbackRate;
+        private _streaming;
+        private _startTime;
+        private _startOffset;
+        private _position;
+        private _localDirection;
+        private _volume;
+        private _isLoaded;
+        private _isReadyToPlay;
+        isPlaying: boolean;
+        isPaused: boolean;
+        private _isDirectional;
+        private _readyToPlayCallback;
+        private _audioBuffer;
+        private _soundSource;
+        private _streamingSource;
+        private _soundPanner;
+        private _soundGain;
+        private _inputAudioNode;
+        private _ouputAudioNode;
+        private _coneInnerAngle;
+        private _coneOuterAngle;
+        private _coneOuterGain;
+        private _scene;
+        private _connectedMesh;
+        private _customAttenuationFunction;
+        private _registerFunc;
+        private _isOutputConnected;
+        private _htmlAudioElement;
+        /**
+        * Create a sound and attach it to a scene
+        * @param name Name of your sound
+        * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer
+        * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
+        * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
+        */
+        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any);
+        dispose(): void;
+        private _soundLoaded(audioData);
+        setAudioBuffer(audioBuffer: AudioBuffer): void;
+        updateOptions(options: any): void;
+        private _createSpatialParameters();
+        private _updateSpatialParameters();
+        switchPanningModelToHRTF(): void;
+        switchPanningModelToEqualPower(): void;
+        private _switchPanningModel();
+        connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void;
+        /**
+        * Transform this sound into a directional source
+        * @param coneInnerAngle Size of the inner cone in degree
+        * @param coneOuterAngle Size of the outer cone in degree
+        * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
+        */
+        setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void;
+        setPosition(newPosition: Vector3): void;
+        setLocalDirectionToMesh(newLocalDirection: Vector3): void;
+        private _updateDirection();
+        updateDistanceFromListener(): void;
+        setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void;
+        /**
+        * Play the sound
+        * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
+        */
+        play(time?: number): void;
+        private _onended();
+        /**
+        * Stop the sound
+        * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
+        */
+        stop(time?: number): void;
+        pause(): void;
+        setVolume(newVolume: number, time?: number): void;
+        setPlaybackRate(newPlaybackRate: number): void;
+        getVolume(): number;
+        attachToMesh(meshToConnectTo: AbstractMesh): void;
+        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
+        clone(): Sound;
+        getAudioBuffer(): AudioBuffer;
+        static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound;
+    }
+}
+
+declare module BABYLON {
+    class SoundTrack {
+        private _outputAudioNode;
+        private _inputAudioNode;
+        private _trackConvolver;
+        private _scene;
+        id: number;
+        soundCollection: Array<Sound>;
+        private _isMainTrack;
+        private _connectedAnalyser;
+        private _options;
+        private _isInitialized;
+        constructor(scene: Scene, options?: any);
+        private _initializeSoundTrackAudioGraph();
+        dispose(): void;
+        AddSound(sound: Sound): void;
+        RemoveSound(sound: Sound): void;
+        setVolume(newVolume: number): void;
+        switchPanningModelToHRTF(): void;
+        switchPanningModelToEqualPower(): void;
+        connectToAnalyser(analyser: Analyser): void;
+    }
+}
+
+declare module BABYLON {
     class Animatable {
         target: any;
         fromFrame: number;
@@ -1436,185 +1608,13 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class Analyser {
-        SMOOTHING: number;
-        FFT_SIZE: number;
-        BARGRAPHAMPLITUDE: number;
-        DEBUGCANVASPOS: {
-            x: number;
-            y: number;
-        };
-        DEBUGCANVASSIZE: {
-            width: number;
-            height: number;
-        };
-        private _byteFreqs;
-        private _byteTime;
-        private _floatFreqs;
-        private _webAudioAnalyser;
-        private _debugCanvas;
-        private _debugCanvasContext;
-        private _scene;
-        private _registerFunc;
-        private _audioEngine;
-        constructor(scene: Scene);
-        getFrequencyBinCount(): number;
-        getByteFrequencyData(): Uint8Array;
-        getByteTimeDomainData(): Uint8Array;
-        getFloatFrequencyData(): Uint8Array;
-        drawDebugCanvas(): void;
-        stopDebugCanvas(): void;
-        connectAudioNodes(inputAudioNode: AudioNode, outputAudioNode: AudioNode): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
-    class AudioEngine {
-        private _audioContext;
-        private _audioContextInitialized;
-        canUseWebAudio: boolean;
-        masterGain: GainNode;
-        private _connectedAnalyser;
-        WarnedWebAudioUnsupported: boolean;
-        audioContext: AudioContext;
-        constructor();
-        private _initializeAudioContext();
-        dispose(): void;
-        getGlobalVolume(): number;
-        setGlobalVolume(newVolume: number): void;
-        connectToAnalyser(analyser: Analyser): void;
-    }
-}
-
-declare module BABYLON {
-    class Sound {
-        name: string;
-        autoplay: boolean;
-        loop: boolean;
-        useCustomAttenuation: boolean;
-        soundTrackId: number;
-        spatialSound: boolean;
-        refDistance: number;
-        rolloffFactor: number;
-        maxDistance: number;
-        distanceModel: string;
-        private _panningModel;
-        onended: () => any;
-        private _playbackRate;
-        private _streaming;
-        private _startTime;
-        private _startOffset;
-        private _position;
-        private _localDirection;
-        private _volume;
-        private _isLoaded;
-        private _isReadyToPlay;
-        isPlaying: boolean;
-        isPaused: boolean;
-        private _isDirectional;
-        private _readyToPlayCallback;
-        private _audioBuffer;
-        private _soundSource;
-        private _streamingSource;
-        private _soundPanner;
-        private _soundGain;
-        private _inputAudioNode;
-        private _ouputAudioNode;
-        private _coneInnerAngle;
-        private _coneOuterAngle;
-        private _coneOuterGain;
-        private _scene;
-        private _connectedMesh;
-        private _customAttenuationFunction;
-        private _registerFunc;
-        private _isOutputConnected;
-        private _htmlAudioElement;
-        /**
-        * Create a sound and attach it to a scene
-        * @param name Name of your sound
-        * @param urlOrArrayBuffer Url to the sound to load async or ArrayBuffer
-        * @param readyToPlayCallback Provide a callback function if you'd like to load your code once the sound is ready to be played
-        * @param options Objects to provide with the current available options: autoplay, loop, volume, spatialSound, maxDistance, rolloffFactor, refDistance, distanceModel, panningModel, streaming
-        */
-        constructor(name: string, urlOrArrayBuffer: any, scene: Scene, readyToPlayCallback?: () => void, options?: any);
-        dispose(): void;
-        private _soundLoaded(audioData);
-        setAudioBuffer(audioBuffer: AudioBuffer): void;
-        updateOptions(options: any): void;
-        private _createSpatialParameters();
-        private _updateSpatialParameters();
-        switchPanningModelToHRTF(): void;
-        switchPanningModelToEqualPower(): void;
-        private _switchPanningModel();
-        connectToSoundTrackAudioNode(soundTrackAudioNode: AudioNode): void;
-        /**
-        * Transform this sound into a directional source
-        * @param coneInnerAngle Size of the inner cone in degree
-        * @param coneOuterAngle Size of the outer cone in degree
-        * @param coneOuterGain Volume of the sound outside the outer cone (between 0.0 and 1.0)
-        */
-        setDirectionalCone(coneInnerAngle: number, coneOuterAngle: number, coneOuterGain: number): void;
-        setPosition(newPosition: Vector3): void;
-        setLocalDirectionToMesh(newLocalDirection: Vector3): void;
-        private _updateDirection();
-        updateDistanceFromListener(): void;
-        setAttenuationFunction(callback: (currentVolume: number, currentDistance: number, maxDistance: number, refDistance: number, rolloffFactor: number) => number): void;
-        /**
-        * Play the sound
-        * @param time (optional) Start the sound after X seconds. Start immediately (0) by default.
-        */
-        play(time?: number): void;
-        private _onended();
-        /**
-        * Stop the sound
-        * @param time (optional) Stop the sound after X seconds. Stop immediately (0) by default.
-        */
-        stop(time?: number): void;
-        pause(): void;
-        setVolume(newVolume: number, time?: number): void;
-        setPlaybackRate(newPlaybackRate: number): void;
-        getVolume(): number;
-        attachToMesh(meshToConnectTo: AbstractMesh): void;
-        private _onRegisterAfterWorldMatrixUpdate(connectedMesh);
-        clone(): Sound;
-        getAudioBuffer(): AudioBuffer;
-        static Parse(parsedSound: any, scene: Scene, rootUrl: string, sourceSound?: Sound): Sound;
-    }
-}
-
-declare module BABYLON {
-    class SoundTrack {
-        private _outputAudioNode;
-        private _inputAudioNode;
-        private _trackConvolver;
-        private _scene;
-        id: number;
-        soundCollection: Array<Sound>;
-        private _isMainTrack;
-        private _connectedAnalyser;
-        private _options;
-        private _isInitialized;
-        constructor(scene: Scene, options?: any);
-        private _initializeSoundTrackAudioGraph();
-        dispose(): void;
-        AddSound(sound: Sound): void;
-        RemoveSound(sound: Sound): void;
-        setVolume(newVolume: number): void;
-        switchPanningModelToHRTF(): void;
-        switchPanningModelToEqualPower(): void;
-        connectToAnalyser(analyser: Analyser): void;
-    }
-}
-
-declare module BABYLON {
     class Bone extends Node {
         name: string;
         children: Bone[];
         animations: Animation[];
         length: number;
         private _skeleton;
-        private _matrix;
+        _matrix: Matrix;
         private _restPose;
         private _baseMatrix;
         private _worldTransform;
@@ -1629,9 +1629,9 @@ declare module BABYLON {
         returnToRest(): void;
         getWorldMatrix(): Matrix;
         getInvertedAbsoluteTransform(): Matrix;
-        getAbsoluteMatrix(): Matrix;
+        getAbsoluteTransform(): Matrix;
         updateMatrix(matrix: Matrix): void;
-        private _updateDifferenceMatrix();
+        _updateDifferenceMatrix(rootMatrix?: Matrix): void;
         markAsDirty(): void;
         copyAnimationRange(source: Bone, rangeName: string, frameOffset: number, rescaleAsRequired?: boolean): boolean;
     }
@@ -1642,14 +1642,16 @@ declare module BABYLON {
         name: string;
         id: string;
         bones: Bone[];
+        needInitialSkinMatrix: boolean;
         private _scene;
         private _isDirty;
         private _transformMatrices;
+        private _meshesWithPoseMatrix;
         private _animatables;
         private _identity;
         private _ranges;
         constructor(name: string, id: string, scene: Scene);
-        getTransformMatrices(): Float32Array;
+        getTransformMatrices(mesh: AbstractMesh): Float32Array;
         getScene(): Scene;
         createAnimationRange(name: string, from: number, to: number): void;
         deleteAnimationRange(name: string, deleteFrames?: boolean): void;
@@ -1662,6 +1664,9 @@ declare module BABYLON {
         private _getHighestAnimationFrame();
         beginAnimation(name: string, loop?: boolean, speedRatio?: number, onAnimationEnd?: () => void): void;
         _markAsDirty(): void;
+        _registerMeshWithPoseMatrix(mesh: AbstractMesh): void;
+        _unregisterMeshWithPoseMatrix(mesh: AbstractMesh): void;
+        _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Matrix): void;
         prepare(): void;
         getAnimatables(): IAnimatable[];
         clone(name: string, id: string): Skeleton;
@@ -1913,6 +1918,66 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    class BoundingBox {
+        minimum: Vector3;
+        maximum: Vector3;
+        vectors: Vector3[];
+        center: Vector3;
+        extendSize: Vector3;
+        directions: Vector3[];
+        vectorsWorld: Vector3[];
+        minimumWorld: Vector3;
+        maximumWorld: Vector3;
+        private _worldMatrix;
+        constructor(minimum: Vector3, maximum: Vector3);
+        getWorldMatrix(): Matrix;
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        intersectsSphere(sphere: BoundingSphere): boolean;
+        intersectsMinMax(min: Vector3, max: Vector3): boolean;
+        static Intersects(box0: BoundingBox, box1: BoundingBox): boolean;
+        static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean;
+        static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
+        static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
+    }
+}
+
+declare module BABYLON {
+    class BoundingInfo {
+        minimum: Vector3;
+        maximum: Vector3;
+        boundingBox: BoundingBox;
+        boundingSphere: BoundingSphere;
+        constructor(minimum: Vector3, maximum: Vector3);
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
+        _checkCollision(collider: Collider): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        intersects(boundingInfo: BoundingInfo, precise: boolean): boolean;
+    }
+}
+
+declare module BABYLON {
+    class BoundingSphere {
+        minimum: Vector3;
+        maximum: Vector3;
+        center: Vector3;
+        radius: number;
+        centerWorld: Vector3;
+        radiusWorld: number;
+        private _tempRadiusVector;
+        constructor(minimum: Vector3, maximum: Vector3);
+        _update(world: Matrix): void;
+        isInFrustum(frustumPlanes: Plane[]): boolean;
+        intersectsPoint(point: Vector3): boolean;
+        static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean;
+    }
+}
+
+declare module BABYLON {
     class ArcRotateCamera extends TargetCamera {
         alpha: number;
         beta: number;
@@ -2314,66 +2379,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class BoundingBox {
-        minimum: Vector3;
-        maximum: Vector3;
-        vectors: Vector3[];
-        center: Vector3;
-        extendSize: Vector3;
-        directions: Vector3[];
-        vectorsWorld: Vector3[];
-        minimumWorld: Vector3;
-        maximumWorld: Vector3;
-        private _worldMatrix;
-        constructor(minimum: Vector3, maximum: Vector3);
-        getWorldMatrix(): Matrix;
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        intersectsSphere(sphere: BoundingSphere): boolean;
-        intersectsMinMax(min: Vector3, max: Vector3): boolean;
-        static Intersects(box0: BoundingBox, box1: BoundingBox): boolean;
-        static IntersectsSphere(minPoint: Vector3, maxPoint: Vector3, sphereCenter: Vector3, sphereRadius: number): boolean;
-        static IsCompletelyInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
-        static IsInFrustum(boundingVectors: Vector3[], frustumPlanes: Plane[]): boolean;
-    }
-}
-
-declare module BABYLON {
-    class BoundingInfo {
-        minimum: Vector3;
-        maximum: Vector3;
-        boundingBox: BoundingBox;
-        boundingSphere: BoundingSphere;
-        constructor(minimum: Vector3, maximum: Vector3);
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        isCompletelyInFrustum(frustumPlanes: Plane[]): boolean;
-        _checkCollision(collider: Collider): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        intersects(boundingInfo: BoundingInfo, precise: boolean): boolean;
-    }
-}
-
-declare module BABYLON {
-    class BoundingSphere {
-        minimum: Vector3;
-        maximum: Vector3;
-        center: Vector3;
-        radius: number;
-        centerWorld: Vector3;
-        radiusWorld: number;
-        private _tempRadiusVector;
-        constructor(minimum: Vector3, maximum: Vector3);
-        _update(world: Matrix): void;
-        isInFrustum(frustumPlanes: Plane[]): boolean;
-        intersectsPoint(point: Vector3): boolean;
-        static Intersects(sphere0: BoundingSphere, sphere1: BoundingSphere): boolean;
-    }
-}
-
-declare module BABYLON {
     class DebugLayer {
         private _scene;
         private _camera;
@@ -2497,6 +2502,38 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    interface ISceneLoaderPlugin {
+        extensions: string;
+        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
+        load: (scene: Scene, data: string, rootUrl: string) => boolean;
+    }
+    class SceneLoader {
+        private static _ForceFullSceneLoadingForIncremental;
+        private static _ShowLoadingScreen;
+        static ForceFullSceneLoadingForIncremental: boolean;
+        static ShowLoadingScreen: boolean;
+        private static _registeredPlugins;
+        private static _getPluginForFilename(sceneFilename);
+        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
+        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
+        /**
+        * Load a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param engine is the instance of BABYLON.Engine to use to create the scene
+        */
+        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+        /**
+        * Append a scene
+        * @param rootUrl a string that defines the root url for scene and resources
+        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
+        * @param scene is the instance of BABYLON.Scene to append to
+        */
+        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
+    }
+}
+
+declare module BABYLON {
     class DirectionalLight extends Light implements IShadowLight {
         direction: Vector3;
         position: Vector3;
@@ -2623,38 +2660,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    interface ISceneLoaderPlugin {
-        extensions: string;
-        importMesh: (meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => boolean;
-        load: (scene: Scene, data: string, rootUrl: string) => boolean;
-    }
-    class SceneLoader {
-        private static _ForceFullSceneLoadingForIncremental;
-        private static _ShowLoadingScreen;
-        static ForceFullSceneLoadingForIncremental: boolean;
-        static ShowLoadingScreen: boolean;
-        private static _registeredPlugins;
-        private static _getPluginForFilename(sceneFilename);
-        static RegisterPlugin(plugin: ISceneLoaderPlugin): void;
-        static ImportMesh(meshesNames: any, rootUrl: string, sceneFilename: string, scene: Scene, onsuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, progressCallBack?: () => void, onerror?: (scene: Scene, e: any) => void): void;
-        /**
-        * Load a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param engine is the instance of BABYLON.Engine to use to create the scene
-        */
-        static Load(rootUrl: string, sceneFilename: any, engine: Engine, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-        /**
-        * Append a scene
-        * @param rootUrl a string that defines the root url for scene and resources
-        * @param sceneFilename a string that defines the name of the scene file. can start with "data:" following by the stringified version of the scene
-        * @param scene is the instance of BABYLON.Scene to append to
-        */
-        static Append(rootUrl: string, sceneFilename: any, scene: Scene, onsuccess?: (scene: Scene) => void, progressCallBack?: any, onerror?: (scene: Scene) => void): void;
-    }
-}
-
-declare module BABYLON {
     class EffectFallbacks {
         private _defines;
         private _currentRank;
@@ -3497,7 +3502,6 @@ declare module BABYLON {
         showSubMeshesBoundingBox: boolean;
         onDispose: any;
         isBlocker: boolean;
-        skeleton: Skeleton;
         renderingGroupId: number;
         material: Material;
         receiveShadows: boolean;
@@ -3557,9 +3561,15 @@ declare module BABYLON {
         private _onAfterWorldMatrixUpdate;
         private _isWorldMatrixFrozen;
         _unIndexed: boolean;
+        _poseMatrix: Matrix;
         _waitingActions: any;
         _waitingFreezeWorldMatrix: boolean;
+        private _skeleton;
+        _bonesTransformMatrices: Float32Array;
+        skeleton: Skeleton;
         constructor(name: string, scene: Scene);
+        updatePoseMatrix(matrix: Matrix): void;
+        getPoseMatrix(): Matrix;
         disableEdgesRendering(): void;
         enableEdgesRendering(epsilon?: number, checkVerticesInsteadOfIndices?: boolean): void;
         isBlocked: boolean;
@@ -4810,6 +4820,65 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
+    interface IPhysicsEnginePlugin {
+        name: string;
+        initialize(iterations?: number): any;
+        setGravity(gravity: Vector3): void;
+        getGravity(): Vector3;
+        runOneStep(delta: number): void;
+        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        unregisterMesh(mesh: AbstractMesh): any;
+        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        dispose(): void;
+        isSupported(): boolean;
+        updateBodyPosition(mesh: AbstractMesh): void;
+        getWorldObject(): any;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+    }
+    interface PhysicsBodyCreationOptions {
+        mass: number;
+        friction: number;
+        restitution: number;
+    }
+    interface PhysicsCompoundBodyPart {
+        mesh: Mesh;
+        impostor: number;
+    }
+    class PhysicsEngine {
+        gravity: Vector3;
+        private _currentPlugin;
+        constructor(plugin?: IPhysicsEnginePlugin);
+        _initialize(gravity?: Vector3): void;
+        _runOneStep(delta: number): void;
+        _setGravity(gravity: Vector3): void;
+        _getGravity(): Vector3;
+        _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
+        _registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
+        _unregisterMesh(mesh: AbstractMesh): void;
+        _applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
+        _createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
+        _updateBodyPosition(mesh: AbstractMesh): void;
+        dispose(): void;
+        isSupported(): boolean;
+        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
+        getPhysicsPluginName(): string;
+        static NoImpostor: number;
+        static SphereImpostor: number;
+        static BoxImpostor: number;
+        static PlaneImpostor: number;
+        static MeshImpostor: number;
+        static CapsuleImpostor: number;
+        static ConeImpostor: number;
+        static CylinderImpostor: number;
+        static ConvexHullImpostor: number;
+        static HeightmapImpostor: number;
+        static Epsilon: number;
+    }
+}
+
+declare module BABYLON {
     class Particle {
         position: Vector3;
         direction: Vector3;
@@ -5138,61 +5207,23 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    interface IPhysicsEnginePlugin {
+    class ReflectionProbe {
         name: string;
-        initialize(iterations?: number): any;
-        setGravity(gravity: Vector3): void;
-        getGravity(): Vector3;
-        runOneStep(delta: number): void;
-        registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        unregisterMesh(mesh: AbstractMesh): any;
-        applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        dispose(): void;
-        isSupported(): boolean;
-        updateBodyPosition(mesh: AbstractMesh): void;
-        getWorldObject(): any;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-    }
-    interface PhysicsBodyCreationOptions {
-        mass: number;
-        friction: number;
-        restitution: number;
-    }
-    interface PhysicsCompoundBodyPart {
-        mesh: Mesh;
-        impostor: number;
-    }
-    class PhysicsEngine {
-        gravity: Vector3;
-        private _currentPlugin;
-        constructor(plugin?: IPhysicsEnginePlugin);
-        _initialize(gravity?: Vector3): void;
-        _runOneStep(delta: number): void;
-        _setGravity(gravity: Vector3): void;
-        _getGravity(): Vector3;
-        _registerMesh(mesh: AbstractMesh, impostor: number, options: PhysicsBodyCreationOptions): any;
-        _registerMeshesAsCompound(parts: PhysicsCompoundBodyPart[], options: PhysicsBodyCreationOptions): any;
-        _unregisterMesh(mesh: AbstractMesh): void;
-        _applyImpulse(mesh: AbstractMesh, force: Vector3, contactPoint: Vector3): void;
-        _createLink(mesh1: AbstractMesh, mesh2: AbstractMesh, pivot1: Vector3, pivot2: Vector3, options?: any): boolean;
-        _updateBodyPosition(mesh: AbstractMesh): void;
+        private _scene;
+        private _renderTargetTexture;
+        private _projectionMatrix;
+        private _viewMatrix;
+        private _target;
+        private _add;
+        private _attachedMesh;
+        position: Vector3;
+        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
+        refreshRate: number;
+        getScene(): Scene;
+        cubeTexture: RenderTargetTexture;
+        renderList: AbstractMesh[];
+        attachToMesh(mesh: AbstractMesh): void;
         dispose(): void;
-        isSupported(): boolean;
-        getPhysicsBodyOfMesh(mesh: AbstractMesh): any;
-        getPhysicsPluginName(): string;
-        static NoImpostor: number;
-        static SphereImpostor: number;
-        static BoxImpostor: number;
-        static PlaneImpostor: number;
-        static MeshImpostor: number;
-        static CapsuleImpostor: number;
-        static ConeImpostor: number;
-        static CylinderImpostor: number;
-        static ConvexHullImpostor: number;
-        static HeightmapImpostor: number;
-        static Epsilon: number;
     }
 }
 
@@ -5766,27 +5797,6 @@ declare module BABYLON {
 }
 
 declare module BABYLON {
-    class ReflectionProbe {
-        name: string;
-        private _scene;
-        private _renderTargetTexture;
-        private _projectionMatrix;
-        private _viewMatrix;
-        private _target;
-        private _add;
-        private _attachedMesh;
-        position: Vector3;
-        constructor(name: string, size: number, scene: Scene, generateMipMaps?: boolean);
-        refreshRate: number;
-        getScene(): Scene;
-        cubeTexture: RenderTargetTexture;
-        renderList: AbstractMesh[];
-        attachToMesh(mesh: AbstractMesh): void;
-        dispose(): void;
-    }
-}
-
-declare module BABYLON {
     class BoundingBoxRenderer {
         frontColor: Color3;
         backColor: Color3;
@@ -6625,38 +6635,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 {
     interface IOctreeContainer<T> {
         blocks: Array<OctreeBlock<T>>;
     }
@@ -6704,6 +6682,41 @@ 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.Internals {
+}
+
+declare module BABYLON {
     class ShadowGenerator {
         private static _FILTER_NONE;
         private static _FILTER_VARIANCESHADOWMAP;
@@ -6761,9 +6774,6 @@ declare module BABYLON {
     }
 }
 
-declare module BABYLON.Internals {
-}
-
 declare module BABYLON {
     class BaseTexture {
         name: string;

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 21 - 21
dist/preview release/babylon.js


+ 110 - 30
dist/preview release/babylon.max.js

@@ -7631,6 +7631,7 @@ var BABYLON;
 (function (BABYLON) {
     var AbstractMesh = (function (_super) {
         __extends(AbstractMesh, _super);
+        // Constructor
         function AbstractMesh(name, scene) {
             var _this = this;
             _super.call(this, name, scene);
@@ -7749,7 +7750,32 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "skeleton", {
+            get: function () {
+                return this._skeleton;
+            },
+            set: function (value) {
+                if (this._skeleton && this._skeleton.needInitialSkinMatrix) {
+                    this._skeleton._unregisterMeshWithPoseMatrix(this);
+                }
+                if (value && value.needInitialSkinMatrix) {
+                    value._registerMeshWithPoseMatrix(this);
+                }
+                this._skeleton = value;
+                if (!this._skeleton) {
+                    this._bonesTransformMatrices = null;
+                }
+            },
+            enumerable: true,
+            configurable: true
+        });
         // Methods
+        AbstractMesh.prototype.updatePoseMatrix = function (matrix) {
+            this._poseMatrix.copyFrom(matrix);
+        };
+        AbstractMesh.prototype.getPoseMatrix = function () {
+            return this._poseMatrix;
+        };
         AbstractMesh.prototype.disableEdgesRendering = function () {
             if (this._edgesRenderer !== undefined) {
                 this._edgesRenderer.dispose();
@@ -8113,6 +8139,9 @@ var BABYLON;
             for (var callbackIndex = 0; callbackIndex < this._onAfterWorldMatrixUpdate.length; callbackIndex++) {
                 this._onAfterWorldMatrixUpdate[callbackIndex](this);
             }
+            if (!this._poseMatrix) {
+                this._poseMatrix = BABYLON.Matrix.Invert(this._worldMatrix);
+            }
             return this._worldMatrix;
         };
         /**
@@ -8451,6 +8480,8 @@ var BABYLON;
         };
         AbstractMesh.prototype.dispose = function (doNotRecurse) {
             var index;
+            // Skeleton
+            this.skeleton = null;
             // Animations
             this.getScene().stopAnimation(this);
             // Physics
@@ -9075,7 +9106,7 @@ var BABYLON;
                     }
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     if (_this.forceBackFacesOnly) {
                         engine.setState(true, 0, false, true);
@@ -16124,7 +16155,7 @@ var BABYLON;
             var needExtras = this.numBoneInfluencers > 4;
             var matricesIndicesExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind) : null;
             var matricesWeightsExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind) : null;
-            var skeletonMatrices = skeleton.getTransformMatrices();
+            var skeletonMatrices = skeleton.getTransformMatrices(this);
             var tempVector3 = BABYLON.Vector3.Zero();
             var finalMatrix = new BABYLON.Matrix();
             var tempMatrix = new BABYLON.Matrix();
@@ -19846,7 +19877,7 @@ var BABYLON;
             this.bindOnlyWorldMatrix(world);
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
             if (scene.getCachedMaterial() !== this) {
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
@@ -20577,13 +20608,16 @@ var BABYLON;
                         currentMesh._waitingParentId = undefined;
                     }
                 }
-                // freeze world matrix application
+                // freeze and compute world matrix application
                 for (index = 0, cache = scene.meshes.length; index < cache; index++) {
                     currentMesh = scene.meshes[index];
                     if (currentMesh._waitingFreezeWorldMatrix) {
                         currentMesh.freezeWorldMatrix();
                         currentMesh._waitingFreezeWorldMatrix = undefined;
                     }
+                    else {
+                        currentMesh.computeWorldMatrix(true);
+                    }
                 }
                 // Particles
                 if (parsedData.particleSystems) {
@@ -20797,6 +20831,9 @@ var BABYLON;
                         currentMesh.freezeWorldMatrix();
                         currentMesh._waitingFreezeWorldMatrix = undefined;
                     }
+                    else {
+                        currentMesh.computeWorldMatrix(true);
+                    }
                 }
                 // Particles Systems
                 if (parsedData.particleSystems) {
@@ -22632,27 +22669,24 @@ var BABYLON;
         Bone.prototype.getInvertedAbsoluteTransform = function () {
             return this._invertedAbsoluteTransform;
         };
-        Bone.prototype.getAbsoluteMatrix = function () {
-            var matrix = this._matrix.clone();
-            var parent = this._parent;
-            while (parent) {
-                matrix = matrix.multiply(parent.getLocalMatrix());
-                parent = parent.getParent();
-            }
-            return matrix;
+        Bone.prototype.getAbsoluteTransform = function () {
+            return this._absoluteTransform;
         };
         // Methods
         Bone.prototype.updateMatrix = function (matrix) {
-            this._matrix = matrix;
+            this._baseMatrix = matrix.clone();
             this._skeleton._markAsDirty();
             this._updateDifferenceMatrix();
         };
-        Bone.prototype._updateDifferenceMatrix = function () {
+        Bone.prototype._updateDifferenceMatrix = function (rootMatrix) {
+            if (!rootMatrix) {
+                rootMatrix = this._baseMatrix;
+            }
             if (this._parent) {
-                this._matrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
+                rootMatrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
             }
             else {
-                this._absoluteTransform.copyFrom(this._matrix);
+                this._absoluteTransform.copyFrom(rootMatrix);
             }
             this._absoluteTransform.invertToRef(this._invertedAbsoluteTransform);
             for (var index = 0; index < this.children.length; index++) {
@@ -22717,7 +22751,9 @@ var BABYLON;
             this.name = name;
             this.id = id;
             this.bones = new Array();
+            this.needInitialSkinMatrix = false;
             this._isDirty = true;
+            this._meshesWithPoseMatrix = new Array();
             this._identity = BABYLON.Matrix.Identity();
             this._ranges = {};
             this.bones = [];
@@ -22728,7 +22764,10 @@ var BABYLON;
             this._isDirty = true;
         }
         // Members
-        Skeleton.prototype.getTransformMatrices = function () {
+        Skeleton.prototype.getTransformMatrices = function (mesh) {
+            if (this.needInitialSkinMatrix && mesh._bonesTransformMatrices) {
+                return mesh._bonesTransformMatrices;
+            }
             return this._transformMatrices;
         };
         Skeleton.prototype.getScene = function () {
@@ -22817,13 +22856,16 @@ var BABYLON;
         Skeleton.prototype._markAsDirty = function () {
             this._isDirty = true;
         };
-        Skeleton.prototype.prepare = function () {
-            if (!this._isDirty) {
-                return;
-            }
-            if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
-                this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
+        Skeleton.prototype._registerMeshWithPoseMatrix = function (mesh) {
+            this._meshesWithPoseMatrix.push(mesh);
+        };
+        Skeleton.prototype._unregisterMeshWithPoseMatrix = function (mesh) {
+            var index = this._meshesWithPoseMatrix.indexOf(mesh);
+            if (index > -1) {
+                this._meshesWithPoseMatrix.splice(index, 1);
             }
+        };
+        Skeleton.prototype._computeTransformMatrices = function (targetMatrix, initialSkinMatrix) {
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
                 var parentBone = bone.getParent();
@@ -22831,11 +22873,46 @@ var BABYLON;
                     bone.getLocalMatrix().multiplyToRef(parentBone.getWorldMatrix(), bone.getWorldMatrix());
                 }
                 else {
-                    bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
+                    if (initialSkinMatrix) {
+                        bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getWorldMatrix());
+                    }
+                    else {
+                        bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
+                    }
+                }
+                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), targetMatrix, index * 16);
+            }
+            this._identity.copyToArray(targetMatrix, this.bones.length * 16);
+        };
+        Skeleton.prototype.prepare = function () {
+            if (!this._isDirty) {
+                return;
+            }
+            if (this.needInitialSkinMatrix) {
+                for (var index = 0; index < this._meshesWithPoseMatrix.length; index++) {
+                    var mesh = this._meshesWithPoseMatrix[index];
+                    if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {
+                        mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));
+                    }
+                    var poseMatrix = mesh.getPoseMatrix();
+                    // Prepare bones
+                    for (var boneIndex = 0; boneIndex < this.bones.length; boneIndex++) {
+                        var bone = this.bones[boneIndex];
+                        if (!bone.getParent()) {
+                            var matrix = bone.getBaseMatrix();
+                            matrix.multiplyToRef(poseMatrix, BABYLON.Tmp.Matrix[0]);
+                            bone._updateDifferenceMatrix(BABYLON.Tmp.Matrix[0]);
+                        }
+                    }
+                    this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);
+                }
+            }
+            else {
+                if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
+                    this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
                 }
-                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), this._transformMatrices, index * 16);
+                this._computeTransformMatrices(this._transformMatrices, null);
             }
-            this._identity.copyToArray(this._transformMatrices, this.bones.length * 16);
             this._isDirty = false;
             this._scene._activeBones += this.bones.length;
         };
@@ -22863,6 +22940,7 @@ var BABYLON;
             return result;
         };
         Skeleton.prototype.dispose = function () {
+            this._meshesWithPoseMatrix = [];
             // Animations
             this.getScene().stopAnimation(this);
             // Remove from scene
@@ -22873,6 +22951,7 @@ var BABYLON;
             serializationObject.name = this.name;
             serializationObject.id = this.id;
             serializationObject.bones = [];
+            serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
                 var serializedBone = {
@@ -22901,6 +22980,7 @@ var BABYLON;
         };
         Skeleton.Parse = function (parsedSkeleton, scene) {
             var skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);
+            skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;
             for (var index = 0; index < parsedSkeleton.bones.length; index++) {
                 var parsedBone = parsedSkeleton.bones[index];
                 var parentBone = null;
@@ -29138,7 +29218,7 @@ var BABYLON;
                 }
                 // Bones
                 if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                 }
                 // Texture
                 for (var name in this._textures) {
@@ -32161,7 +32241,7 @@ var BABYLON;
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
             mesh._bind(subMesh, this._effect, BABYLON.Material.TriangleFillMode);
             // Alpha test
@@ -35420,7 +35500,7 @@ var BABYLON;
                     }
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     // Draw
                     mesh._processRendering(subMesh, _this._effect, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._effect.setMatrix("world", world); });
@@ -35950,7 +36030,7 @@ var BABYLON;
                     }
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     // Draw
                     mesh._processRendering(subMesh, _this._volumetricLightScatteringPass, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._volumetricLightScatteringPass.setMatrix("world", world); });

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 23 - 23
dist/preview release/babylon.noworker.js


+ 9 - 12
src/Bones/babylon.bone.js

@@ -51,27 +51,24 @@ var BABYLON;
         Bone.prototype.getInvertedAbsoluteTransform = function () {
             return this._invertedAbsoluteTransform;
         };
-        Bone.prototype.getAbsoluteMatrix = function () {
-            var matrix = this._matrix.clone();
-            var parent = this._parent;
-            while (parent) {
-                matrix = matrix.multiply(parent.getLocalMatrix());
-                parent = parent.getParent();
-            }
-            return matrix;
+        Bone.prototype.getAbsoluteTransform = function () {
+            return this._absoluteTransform;
         };
         // Methods
         Bone.prototype.updateMatrix = function (matrix) {
-            this._matrix = matrix;
+            this._baseMatrix = matrix.clone();
             this._skeleton._markAsDirty();
             this._updateDifferenceMatrix();
         };
-        Bone.prototype._updateDifferenceMatrix = function () {
+        Bone.prototype._updateDifferenceMatrix = function (rootMatrix) {
+            if (!rootMatrix) {
+                rootMatrix = this._baseMatrix;
+            }
             if (this._parent) {
-                this._matrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
+                rootMatrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
             }
             else {
-                this._absoluteTransform.copyFrom(this._matrix);
+                this._absoluteTransform.copyFrom(rootMatrix);
             }
             this._absoluteTransform.invertToRef(this._invertedAbsoluteTransform);
             for (var index = 0; index < this.children.length; index++) {

+ 13 - 16
src/Bones/babylon.bone.ts

@@ -5,7 +5,7 @@
         public length: number;
 
         private _skeleton: Skeleton;
-        private _matrix: Matrix;
+        public _matrix: Matrix;
         private _restPose: Matrix;
         private _baseMatrix: Matrix;
         private _worldTransform = new Matrix();
@@ -47,7 +47,7 @@
 
         public getRestPose(): Matrix {
             return this._restPose;
-        }
+        }      
 
         public returnToRest(): void {
             this.updateMatrix(this._restPose.clone());
@@ -61,31 +61,28 @@
             return this._invertedAbsoluteTransform;
         }
 
-        public getAbsoluteMatrix(): Matrix {
-            var matrix = this._matrix.clone();
-            var parent = this._parent;
-
-            while (parent) {
-                matrix = matrix.multiply(parent.getLocalMatrix());
-                parent = parent.getParent();
-            }
-
-            return matrix;
+        public getAbsoluteTransform(): Matrix {
+            return this._absoluteTransform;
         }
 
         // Methods
         public updateMatrix(matrix: Matrix): void {
-            this._matrix = matrix;
+            this._baseMatrix = matrix.clone();
+
             this._skeleton._markAsDirty();
 
             this._updateDifferenceMatrix();
         }
 
-        private _updateDifferenceMatrix(): void {
+        public _updateDifferenceMatrix(rootMatrix?: Matrix): void {
+            if (!rootMatrix) {
+                rootMatrix = this._baseMatrix;
+            }
+
             if (this._parent) {
-                this._matrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
+                rootMatrix.multiplyToRef(this._parent._absoluteTransform, this._absoluteTransform);
             } else {
-                this._absoluteTransform.copyFrom(this._matrix);
+                this._absoluteTransform.copyFrom(rootMatrix);
             }
 
             this._absoluteTransform.invertToRef(this._invertedAbsoluteTransform);

+ 56 - 10
src/Bones/babylon.skeleton.js

@@ -5,7 +5,9 @@ var BABYLON;
             this.name = name;
             this.id = id;
             this.bones = new Array();
+            this.needInitialSkinMatrix = false;
             this._isDirty = true;
+            this._meshesWithPoseMatrix = new Array();
             this._identity = BABYLON.Matrix.Identity();
             this._ranges = {};
             this.bones = [];
@@ -16,7 +18,10 @@ var BABYLON;
             this._isDirty = true;
         }
         // Members
-        Skeleton.prototype.getTransformMatrices = function () {
+        Skeleton.prototype.getTransformMatrices = function (mesh) {
+            if (this.needInitialSkinMatrix && mesh._bonesTransformMatrices) {
+                return mesh._bonesTransformMatrices;
+            }
             return this._transformMatrices;
         };
         Skeleton.prototype.getScene = function () {
@@ -105,13 +110,16 @@ var BABYLON;
         Skeleton.prototype._markAsDirty = function () {
             this._isDirty = true;
         };
-        Skeleton.prototype.prepare = function () {
-            if (!this._isDirty) {
-                return;
-            }
-            if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
-                this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
+        Skeleton.prototype._registerMeshWithPoseMatrix = function (mesh) {
+            this._meshesWithPoseMatrix.push(mesh);
+        };
+        Skeleton.prototype._unregisterMeshWithPoseMatrix = function (mesh) {
+            var index = this._meshesWithPoseMatrix.indexOf(mesh);
+            if (index > -1) {
+                this._meshesWithPoseMatrix.splice(index, 1);
             }
+        };
+        Skeleton.prototype._computeTransformMatrices = function (targetMatrix, initialSkinMatrix) {
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
                 var parentBone = bone.getParent();
@@ -119,11 +127,46 @@ var BABYLON;
                     bone.getLocalMatrix().multiplyToRef(parentBone.getWorldMatrix(), bone.getWorldMatrix());
                 }
                 else {
-                    bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
+                    if (initialSkinMatrix) {
+                        bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getWorldMatrix());
+                    }
+                    else {
+                        bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
+                    }
+                }
+                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), targetMatrix, index * 16);
+            }
+            this._identity.copyToArray(targetMatrix, this.bones.length * 16);
+        };
+        Skeleton.prototype.prepare = function () {
+            if (!this._isDirty) {
+                return;
+            }
+            if (this.needInitialSkinMatrix) {
+                for (var index = 0; index < this._meshesWithPoseMatrix.length; index++) {
+                    var mesh = this._meshesWithPoseMatrix[index];
+                    if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {
+                        mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));
+                    }
+                    var poseMatrix = mesh.getPoseMatrix();
+                    // Prepare bones
+                    for (var boneIndex = 0; boneIndex < this.bones.length; boneIndex++) {
+                        var bone = this.bones[boneIndex];
+                        if (!bone.getParent()) {
+                            var matrix = bone.getBaseMatrix();
+                            matrix.multiplyToRef(poseMatrix, BABYLON.Tmp.Matrix[0]);
+                            bone._updateDifferenceMatrix(BABYLON.Tmp.Matrix[0]);
+                        }
+                    }
+                    this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);
+                }
+            }
+            else {
+                if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
+                    this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
                 }
-                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), this._transformMatrices, index * 16);
+                this._computeTransformMatrices(this._transformMatrices, null);
             }
-            this._identity.copyToArray(this._transformMatrices, this.bones.length * 16);
             this._isDirty = false;
             this._scene._activeBones += this.bones.length;
         };
@@ -151,6 +194,7 @@ var BABYLON;
             return result;
         };
         Skeleton.prototype.dispose = function () {
+            this._meshesWithPoseMatrix = [];
             // Animations
             this.getScene().stopAnimation(this);
             // Remove from scene
@@ -161,6 +205,7 @@ var BABYLON;
             serializationObject.name = this.name;
             serializationObject.id = this.id;
             serializationObject.bones = [];
+            serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
                 var serializedBone = {
@@ -189,6 +234,7 @@ var BABYLON;
         };
         Skeleton.Parse = function (parsedSkeleton, scene) {
             var skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);
+            skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;
             for (var index = 0; index < parsedSkeleton.bones.length; index++) {
                 var parsedBone = parsedSkeleton.bones[index];
                 var parentBone = null;

+ 67 - 10
src/Bones/babylon.skeleton.ts

@@ -2,9 +2,12 @@
     export class Skeleton {
         public bones = new Array<Bone>();
 
+        public needInitialSkinMatrix = false;
+
         private _scene: Scene;
         private _isDirty = true;
         private _transformMatrices: Float32Array;
+        private _meshesWithPoseMatrix = new Array<AbstractMesh>();
         private _animatables: IAnimatable[];
         private _identity = Matrix.Identity();
 
@@ -23,7 +26,10 @@
         }
 
         // Members
-        public getTransformMatrices(): Float32Array {
+        public getTransformMatrices(mesh: AbstractMesh): Float32Array {
+            if (this.needInitialSkinMatrix && mesh._bonesTransformMatrices) {
+                return mesh._bonesTransformMatrices;
+            }
             return this._transformMatrices;
         }
 
@@ -123,15 +129,19 @@
             this._isDirty = true;
         }
 
-        public prepare(): void {
-            if (!this._isDirty) {
-                return;
-            }
+        public _registerMeshWithPoseMatrix(mesh: AbstractMesh): void {
+            this._meshesWithPoseMatrix.push(mesh);
+        }
+
+        public _unregisterMeshWithPoseMatrix(mesh: AbstractMesh): void {
+            var index = this._meshesWithPoseMatrix.indexOf(mesh);
 
-            if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
-                this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
+            if (index > -1) {
+                this._meshesWithPoseMatrix.splice(index, 1);
             }
+        }
 
+        public _computeTransformMatrices(targetMatrix: Float32Array, initialSkinMatrix: Matrix): void {
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
                 var parentBone = bone.getParent();
@@ -139,13 +149,54 @@
                 if (parentBone) {
                     bone.getLocalMatrix().multiplyToRef(parentBone.getWorldMatrix(), bone.getWorldMatrix());
                 } else {
-                    bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
+                    if (initialSkinMatrix) {
+                        bone.getLocalMatrix().multiplyToRef(initialSkinMatrix, bone.getWorldMatrix());
+                    } else {
+                        bone.getWorldMatrix().copyFrom(bone.getLocalMatrix());
+                    }
                 }
 
-                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), this._transformMatrices, index * 16);
+                bone.getInvertedAbsoluteTransform().multiplyToArray(bone.getWorldMatrix(), targetMatrix, index * 16);
             }
 
-            this._identity.copyToArray(this._transformMatrices, this.bones.length * 16);
+            this._identity.copyToArray(targetMatrix, this.bones.length * 16);
+        }
+
+        public prepare(): void {
+            if (!this._isDirty) {
+                return;
+            }
+
+            if (this.needInitialSkinMatrix) {
+                for (var index = 0; index < this._meshesWithPoseMatrix.length; index++) {
+                    var mesh = this._meshesWithPoseMatrix[index];
+
+                    if (!mesh._bonesTransformMatrices || mesh._bonesTransformMatrices.length !== 16 * (this.bones.length + 1)) {
+                        mesh._bonesTransformMatrices = new Float32Array(16 * (this.bones.length + 1));
+                    }
+
+                    var poseMatrix = mesh.getPoseMatrix();
+
+                    // Prepare bones
+                    for (var boneIndex = 0; boneIndex < this.bones.length; boneIndex++) {
+                        var bone = this.bones[boneIndex];
+
+                        if (!bone.getParent()) {
+                            var matrix = bone.getBaseMatrix();
+                            matrix.multiplyToRef(poseMatrix, Tmp.Matrix[0]);
+                            bone._updateDifferenceMatrix(Tmp.Matrix[0]);
+                        }
+                    }
+
+                    this._computeTransformMatrices(mesh._bonesTransformMatrices, poseMatrix);
+                }
+            } else {
+                if (!this._transformMatrices || this._transformMatrices.length !== 16 * (this.bones.length + 1)) {
+                    this._transformMatrices = new Float32Array(16 * (this.bones.length + 1));
+                }
+
+                this._computeTransformMatrices(this._transformMatrices, null);
+            }
 
             this._isDirty = false;
 
@@ -184,6 +235,8 @@
         }
 
         public dispose() {
+            this._meshesWithPoseMatrix = [];
+
             // Animations
             this.getScene().stopAnimation(this);
 
@@ -199,6 +252,8 @@
 
             serializationObject.bones = [];
 
+            serializationObject.needInitialSkinMatrix = this.needInitialSkinMatrix;
+
             for (var index = 0; index < this.bones.length; index++) {
                 var bone = this.bones[index];
 
@@ -234,6 +289,8 @@
         public static Parse(parsedSkeleton: any, scene: Scene): Skeleton {
             var skeleton = new Skeleton(parsedSkeleton.name, parsedSkeleton.id, scene);
 
+            skeleton.needInitialSkinMatrix = parsedSkeleton.needInitialSkinMatrix;
+
             for (var index = 0; index < parsedSkeleton.bones.length; index++) {
                 var parsedBone = parsedSkeleton.bones[index];
 

+ 1 - 1
src/Lights/Shadows/babylon.shadowGenerator.js

@@ -79,7 +79,7 @@ var BABYLON;
                     }
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     if (_this.forceBackFacesOnly) {
                         engine.setState(true, 0, false, true);

+ 1 - 1
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -207,7 +207,7 @@
 
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
 
                     if (this.forceBackFacesOnly) {

+ 7 - 1
src/Loading/Plugins/babylon.babylonFileLoader.js

@@ -142,13 +142,16 @@ var BABYLON;
                         currentMesh._waitingParentId = undefined;
                     }
                 }
-                // freeze world matrix application
+                // freeze and compute world matrix application
                 for (index = 0, cache = scene.meshes.length; index < cache; index++) {
                     currentMesh = scene.meshes[index];
                     if (currentMesh._waitingFreezeWorldMatrix) {
                         currentMesh.freezeWorldMatrix();
                         currentMesh._waitingFreezeWorldMatrix = undefined;
                     }
+                    else {
+                        currentMesh.computeWorldMatrix(true);
+                    }
                 }
                 // Particles
                 if (parsedData.particleSystems) {
@@ -362,6 +365,9 @@ var BABYLON;
                         currentMesh.freezeWorldMatrix();
                         currentMesh._waitingFreezeWorldMatrix = undefined;
                     }
+                    else {
+                        currentMesh.computeWorldMatrix(true);
+                    }
                 }
                 // Particles Systems
                 if (parsedData.particleSystems) {

+ 5 - 1
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -151,12 +151,14 @@
                 }
             }
 
-            // freeze world matrix application
+            // freeze and compute world matrix application
             for (index = 0, cache = scene.meshes.length; index < cache; index++) {
                 currentMesh = scene.meshes[index];
                 if (currentMesh._waitingFreezeWorldMatrix) {
                     currentMesh.freezeWorldMatrix();
                     currentMesh._waitingFreezeWorldMatrix = undefined;
+                } else {
+                    currentMesh.computeWorldMatrix(true);
                 }
             }
 
@@ -393,6 +395,8 @@
                 if (currentMesh._waitingFreezeWorldMatrix) {
                     currentMesh.freezeWorldMatrix();
                     currentMesh._waitingFreezeWorldMatrix = undefined;
+                } else {
+                    currentMesh.computeWorldMatrix(true);
                 }
             }
 

+ 1 - 1
src/Materials/babylon.shaderMaterial.js

@@ -165,7 +165,7 @@ var BABYLON;
                 }
                 // Bones
                 if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                 }
                 // Texture
                 for (var name in this._textures) {

+ 1 - 1
src/Materials/babylon.shaderMaterial.ts

@@ -214,7 +214,7 @@
 
                 // Bones
                 if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                    this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                 }
 
                 // Texture

+ 1 - 1
src/Materials/babylon.standardMaterial.js

@@ -682,7 +682,7 @@ var BABYLON;
             this.bindOnlyWorldMatrix(world);
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
             if (scene.getCachedMaterial() !== this) {
                 this._effect.setMatrix("viewProjection", scene.getTransformMatrix());

+ 1 - 1
src/Materials/babylon.standardMaterial.ts

@@ -809,7 +809,7 @@
 
             // Bones
             if (mesh && mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
 
             if (scene.getCachedMaterial() !== this) {

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

@@ -7,6 +7,7 @@ var BABYLON;
 (function (BABYLON) {
     var AbstractMesh = (function (_super) {
         __extends(AbstractMesh, _super);
+        // Constructor
         function AbstractMesh(name, scene) {
             var _this = this;
             _super.call(this, name, scene);
@@ -125,7 +126,32 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        Object.defineProperty(AbstractMesh.prototype, "skeleton", {
+            get: function () {
+                return this._skeleton;
+            },
+            set: function (value) {
+                if (this._skeleton && this._skeleton.needInitialSkinMatrix) {
+                    this._skeleton._unregisterMeshWithPoseMatrix(this);
+                }
+                if (value && value.needInitialSkinMatrix) {
+                    value._registerMeshWithPoseMatrix(this);
+                }
+                this._skeleton = value;
+                if (!this._skeleton) {
+                    this._bonesTransformMatrices = null;
+                }
+            },
+            enumerable: true,
+            configurable: true
+        });
         // Methods
+        AbstractMesh.prototype.updatePoseMatrix = function (matrix) {
+            this._poseMatrix.copyFrom(matrix);
+        };
+        AbstractMesh.prototype.getPoseMatrix = function () {
+            return this._poseMatrix;
+        };
         AbstractMesh.prototype.disableEdgesRendering = function () {
             if (this._edgesRenderer !== undefined) {
                 this._edgesRenderer.dispose();
@@ -489,6 +515,9 @@ var BABYLON;
             for (var callbackIndex = 0; callbackIndex < this._onAfterWorldMatrixUpdate.length; callbackIndex++) {
                 this._onAfterWorldMatrixUpdate[callbackIndex](this);
             }
+            if (!this._poseMatrix) {
+                this._poseMatrix = BABYLON.Matrix.Invert(this._worldMatrix);
+            }
             return this._worldMatrix;
         };
         /**
@@ -827,6 +856,8 @@ var BABYLON;
         };
         AbstractMesh.prototype.dispose = function (doNotRecurse) {
             var index;
+            // Skeleton
+            this.skeleton = null;
             // Animations
             this.getScene().stopAnimation(this);
             // Physics

+ 42 - 1
src/Mesh/babylon.abstractMesh.ts

@@ -43,7 +43,6 @@
         public showSubMeshesBoundingBox = false;
         public onDispose = null;
         public isBlocker = false;
-        public skeleton: Skeleton;
         public renderingGroupId = 0;
         public material: Material;
         public receiveShadows = false;
@@ -122,10 +121,37 @@
 
         public _unIndexed = false;
 
+        public _poseMatrix: Matrix;
+
         // Loading properties
         public _waitingActions: any;
         public _waitingFreezeWorldMatrix: boolean;
 
+        // Skeleton
+        private _skeleton: Skeleton;
+        public _bonesTransformMatrices: Float32Array;
+
+        public set skeleton(value: Skeleton) {
+            if (this._skeleton && this._skeleton.needInitialSkinMatrix) {
+                this._skeleton._unregisterMeshWithPoseMatrix(this);
+            }
+
+            if (value && value.needInitialSkinMatrix) {
+                value._registerMeshWithPoseMatrix(this);
+            }
+
+            this._skeleton = value;
+
+            if (!this._skeleton) {
+                this._bonesTransformMatrices = null;
+            }
+        }
+
+        public get skeleton(): Skeleton {
+            return this._skeleton;
+        }
+
+        // Constructor
         constructor(name: string, scene: Scene) {
             super(name, scene);
 
@@ -133,6 +159,14 @@
         }
 
         // Methods
+        public updatePoseMatrix(matrix: Matrix) {
+            this._poseMatrix.copyFrom(matrix);
+        }
+
+        public getPoseMatrix(): Matrix {
+            return this._poseMatrix;
+        }
+
         public disableEdgesRendering(): void {
             if (this._edgesRenderer !== undefined) {
                 this._edgesRenderer.dispose();
@@ -544,6 +578,10 @@
                 this._onAfterWorldMatrixUpdate[callbackIndex](this);
             }
 
+            if (!this._poseMatrix) {
+                this._poseMatrix = Matrix.Invert(this._worldMatrix);
+            }
+
             return this._worldMatrix;
         }
 
@@ -983,6 +1021,9 @@
         public dispose(doNotRecurse?: boolean): void {
             var index: number;
 
+            // Skeleton
+            this.skeleton = null;
+
             // Animations
             this.getScene().stopAnimation(this);
 

+ 1 - 1
src/Mesh/babylon.mesh.js

@@ -1581,7 +1581,7 @@ var BABYLON;
             var needExtras = this.numBoneInfluencers > 4;
             var matricesIndicesExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesIndicesExtraKind) : null;
             var matricesWeightsExtraData = needExtras ? this.getVerticesData(BABYLON.VertexBuffer.MatricesWeightsExtraKind) : null;
-            var skeletonMatrices = skeleton.getTransformMatrices();
+            var skeletonMatrices = skeleton.getTransformMatrices(this);
             var tempVector3 = BABYLON.Vector3.Zero();
             var finalMatrix = new BABYLON.Matrix();
             var tempMatrix = new BABYLON.Matrix();

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

@@ -1868,7 +1868,7 @@
             var matricesIndicesExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesIndicesExtraKind) : null;
             var matricesWeightsExtraData = needExtras ? this.getVerticesData(VertexBuffer.MatricesWeightsExtraKind) : null;
 
-            var skeletonMatrices = skeleton.getTransformMatrices();
+            var skeletonMatrices = skeleton.getTransformMatrices(this);
 
             var tempVector3 = Vector3.Zero();
             var finalMatrix = new Matrix();

+ 1 - 1
src/PostProcess/babylon.volumetricLightScatteringPostProcess.js

@@ -246,7 +246,7 @@ var BABYLON;
                     }
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     // Draw
                     mesh._processRendering(subMesh, _this._volumetricLightScatteringPass, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._volumetricLightScatteringPass.setMatrix("world", world); });

+ 1 - 1
src/PostProcess/babylon.volumetricLightScatteringPostProcess.ts

@@ -291,7 +291,7 @@
 
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        this._volumetricLightScatteringPass.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
 
                     // Draw

+ 1 - 1
src/Rendering/babylon.depthRenderer.js

@@ -48,7 +48,7 @@ var BABYLON;
                     }
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        _this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
                     // Draw
                     mesh._processRendering(subMesh, _this._effect, BABYLON.Material.TriangleFillMode, batch, hardwareInstancedRendering, function (isInstance, world) { return _this._effect.setMatrix("world", world); });

+ 1 - 1
src/Rendering/babylon.depthRenderer.ts

@@ -64,7 +64,7 @@
 
                     // Bones
                     if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                        this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                        this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
                     }
 
                     // Draw

+ 1 - 1
src/Rendering/babylon.outlineRenderer.js

@@ -21,7 +21,7 @@ var BABYLON;
             this._effect.setMatrix("viewProjection", scene.getTransformMatrix());
             // Bones
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
             mesh._bind(subMesh, this._effect, BABYLON.Material.TriangleFillMode);
             // Alpha test

+ 1 - 1
src/Rendering/babylon.outlineRenderer.ts

@@ -28,7 +28,7 @@
 
             // Bones
             if (mesh.useBones && mesh.computeBonesUsingShaders) {
-                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices());
+                this._effect.setMatrices("mBones", mesh.skeleton.getTransformMatrices(mesh));
             }
 
             mesh._bind(subMesh, this._effect, Material.TriangleFillMode);