浏览代码

Added SkeletonViewer

David Catuhe 9 年之前
父节点
当前提交
edac41a317

+ 2 - 1
Tools/Gulp/config.json

@@ -191,7 +191,8 @@
       "../../src/tools/hdr/babylon.tools.panoramatocubemap.js",
       "../../src/tools/hdr/babylon.tools.hdr.js",
       "../../src/tools/hdr/babylon.tools.pmremGenerator.js",
-      "../../src/materials/textures/babylon.hdrcubetexture.js"
+      "../../src/materials/textures/babylon.hdrcubetexture.js",
+      "../../debug/babylon.skeletonViewer.js"
     ]
   }
 }

文件差异内容过多而无法显示
+ 9 - 9
dist/preview release/babylon.core.js


文件差异内容过多而无法显示
+ 1873 - 1841
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 14 - 14
dist/preview release/babylon.js


+ 52 - 5
dist/preview release/babylon.max.js

@@ -23683,6 +23683,7 @@ var BABYLON;
             // all animation may be coming from a library skeleton, so may need to create animation
             if (this.animations.length === 0) {
                 this.animations.push(new BABYLON.Animation(this.name, "_matrix", source.animations[0].framePerSecond, BABYLON.Animation.ANIMATIONTYPE_MATRIX, 0));
+                this.animations[0].setKeys([{}]);
             }
             // get animation info / verify there is such a range from the source bone
             var sourceRange = source.animations[0].getRange(rangeName);
@@ -24465,10 +24466,16 @@ var BABYLON;
             this._bodyUpdateRequired = true;
         };
         /**
-         * Set the body's velocity.
+         * Set the body's linear velocity.
          */
-        PhysicsImpostor.prototype.setVelocity = function (velocity) {
-            this._physicsEngine.getPhysicsPlugin().setVelocity(this, velocity);
+        PhysicsImpostor.prototype.setLinearVelocity = function (velocity) {
+            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+        };
+        /**
+         * Set the body's linear velocity.
+         */
+        PhysicsImpostor.prototype.setAngularVelocity = function (velocity) {
+            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
         };
         /**
          * Execute a function with the physics plugin native code.
@@ -29470,6 +29477,7 @@ var BABYLON;
             this._displayStatistics = true;
             this._displayTree = false;
             this._displayLogs = false;
+            this._skeletonViewers = new Array();
             this._identityMatrix = BABYLON.Matrix.Identity();
             this.axisRatio = 0.02;
             this.accentColor = "orange";
@@ -29723,6 +29731,13 @@ var BABYLON;
             this._scene.renderTargetsEnabled = true;
             this._scene.probesEnabled = true;
             engine.getRenderingCanvas().removeEventListener("click", this._onCanvasClick);
+            this._clearSkeletonViewers();
+        };
+        DebugLayer.prototype._clearSkeletonViewers = function () {
+            for (var index = 0; index < this._skeletonViewers.length; index++) {
+                this._skeletonViewers[index].dispose();
+            }
+            this._skeletonViewers = [];
         };
         DebugLayer.prototype.show = function (showUI, camera, rootElement) {
             if (showUI === void 0) { showUI = true; }
@@ -30017,6 +30032,32 @@ var BABYLON;
                     });
                 }
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));
+                this._generateTexBox(this._optionsSubsetDiv, "<b>Viewers:</b>", this.accentColor);
+                this._generateCheckBox(this._optionsSubsetDiv, "Skeletons", false, function (element) {
+                    if (!element.checked) {
+                        _this._clearSkeletonViewers();
+                        return;
+                    }
+                    for (var index = 0; index < _this._scene.meshes.length; index++) {
+                        var mesh = _this._scene.meshes[index];
+                        if (mesh.skeleton) {
+                            var found = false;
+                            for (var sIndex = 0; sIndex < _this._skeletonViewers.length; sIndex++) {
+                                if (_this._skeletonViewers[sIndex].skeleton === mesh.skeleton) {
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if (found) {
+                                continue;
+                            }
+                            var viewer = new BABYLON.Debug.SkeletonViewer(mesh.skeleton, mesh, _this._scene);
+                            viewer.isEnabled = true;
+                            _this._skeletonViewers.push(viewer);
+                        }
+                    }
+                });
+                this._optionsSubsetDiv.appendChild(document.createElement("br"));
                 this._generateTexBox(this._optionsSubsetDiv, "<b>Tools:</b>", this.accentColor);
                 this._generateButton(this._optionsSubsetDiv, "Dump rendertargets", function (element) { _this._scene.dumpNextRenderTargets = true; });
                 this._generateButton(this._optionsSubsetDiv, "Run SceneOptimizer", function (element) { BABYLON.SceneOptimizer.OptimizeAsync(_this._scene); });
@@ -31386,9 +31427,12 @@ var BABYLON;
         CannonJSPlugin.prototype.isSupported = function () {
             return window.CANNON !== undefined;
         };
-        CannonJSPlugin.prototype.setVelocity = function (impostor, velocity) {
+        CannonJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
             impostor.physicsBody.velocity.copy(velocity);
         };
+        CannonJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
+            impostor.physicsBody.angularVelocity.copy(velocity);
+        };
         CannonJSPlugin.prototype.sleepBody = function (impostor) {
             impostor.physicsBody.sleep();
         };
@@ -31663,9 +31707,12 @@ var BABYLON;
             }
             return lastShape;
         };
-        OimoJSPlugin.prototype.setVelocity = function (impostor, velocity) {
+        OimoJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
             impostor.physicsBody.linearVelocity.init(velocity.x, velocity.y, velocity.z);
         };
+        OimoJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
+            impostor.physicsBody.angularVelocity.init(velocity.x, velocity.y, velocity.z);
+        };
         OimoJSPlugin.prototype.sleepBody = function (impostor) {
             impostor.physicsBody.sleep();
         };

文件差异内容过多而无法显示
+ 17 - 17
dist/preview release/babylon.noworker.js


+ 1 - 0
src/Bones/babylon.bone.js

@@ -85,6 +85,7 @@ var BABYLON;
             // all animation may be coming from a library skeleton, so may need to create animation
             if (this.animations.length === 0) {
                 this.animations.push(new BABYLON.Animation(this.name, "_matrix", source.animations[0].framePerSecond, BABYLON.Animation.ANIMATIONTYPE_MATRIX, 0));
+                this.animations[0].setKeys([{}]);
             }
             // get animation info / verify there is such a range from the source bone
             var sourceRange = source.animations[0].getRange(rangeName);

+ 1 - 0
src/Bones/babylon.bone.ts

@@ -102,6 +102,7 @@
             // all animation may be coming from a library skeleton, so may need to create animation
             if (this.animations.length === 0) {
                 this.animations.push(new Animation(this.name, "_matrix", source.animations[0].framePerSecond, Animation.ANIMATIONTYPE_MATRIX, 0));
+                this.animations[0].setKeys([{}]);
             }
 
             // get animation info / verify there is such a range from the source bone

+ 34 - 0
src/Debug/babylon.debugLayer.js

@@ -9,6 +9,7 @@ var BABYLON;
             this._displayStatistics = true;
             this._displayTree = false;
             this._displayLogs = false;
+            this._skeletonViewers = new Array();
             this._identityMatrix = BABYLON.Matrix.Identity();
             this.axisRatio = 0.02;
             this.accentColor = "orange";
@@ -262,6 +263,13 @@ var BABYLON;
             this._scene.renderTargetsEnabled = true;
             this._scene.probesEnabled = true;
             engine.getRenderingCanvas().removeEventListener("click", this._onCanvasClick);
+            this._clearSkeletonViewers();
+        };
+        DebugLayer.prototype._clearSkeletonViewers = function () {
+            for (var index = 0; index < this._skeletonViewers.length; index++) {
+                this._skeletonViewers[index].dispose();
+            }
+            this._skeletonViewers = [];
         };
         DebugLayer.prototype.show = function (showUI, camera, rootElement) {
             if (showUI === void 0) { showUI = true; }
@@ -556,6 +564,32 @@ var BABYLON;
                     });
                 }
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));
+                this._generateTexBox(this._optionsSubsetDiv, "<b>Viewers:</b>", this.accentColor);
+                this._generateCheckBox(this._optionsSubsetDiv, "Skeletons", false, function (element) {
+                    if (!element.checked) {
+                        _this._clearSkeletonViewers();
+                        return;
+                    }
+                    for (var index = 0; index < _this._scene.meshes.length; index++) {
+                        var mesh = _this._scene.meshes[index];
+                        if (mesh.skeleton) {
+                            var found = false;
+                            for (var sIndex = 0; sIndex < _this._skeletonViewers.length; sIndex++) {
+                                if (_this._skeletonViewers[sIndex].skeleton === mesh.skeleton) {
+                                    found = true;
+                                    break;
+                                }
+                            }
+                            if (found) {
+                                continue;
+                            }
+                            var viewer = new BABYLON.Debug.SkeletonViewer(mesh.skeleton, mesh, _this._scene);
+                            viewer.isEnabled = true;
+                            _this._skeletonViewers.push(viewer);
+                        }
+                    }
+                });
+                this._optionsSubsetDiv.appendChild(document.createElement("br"));
                 this._generateTexBox(this._optionsSubsetDiv, "<b>Tools:</b>", this.accentColor);
                 this._generateButton(this._optionsSubsetDiv, "Dump rendertargets", function (element) { _this._scene.dumpNextRenderTargets = true; });
                 this._generateButton(this._optionsSubsetDiv, "Run SceneOptimizer", function (element) { BABYLON.SceneOptimizer.OptimizeAsync(_this._scene); });

+ 43 - 0
src/Debug/babylon.debugLayer.ts

@@ -21,6 +21,8 @@
         private _drawingContext: CanvasRenderingContext2D;
         private _rootElement: HTMLElement;
 
+        private _skeletonViewers = new Array<Debug.SkeletonViewer>();
+
         public _syncPositions: () => void;
         private _syncData: () => void;
         private _syncUI: () => void;
@@ -368,6 +370,16 @@
             this._scene.probesEnabled = true;
 
             engine.getRenderingCanvas().removeEventListener("click", this._onCanvasClick);
+
+            this._clearSkeletonViewers();
+        }
+
+        private _clearSkeletonViewers(): void {
+            for (var index = 0; index < this._skeletonViewers.length; index++) {
+                this._skeletonViewers[index].dispose();
+            }
+
+            this._skeletonViewers = [];
         }
 
         public show(showUI: boolean = true, camera: Camera = null, rootElement: HTMLElement = null) {
@@ -699,6 +711,37 @@
                     });
                 }
                 this._optionsSubsetDiv.appendChild(document.createElement("br"));
+                this._generateTexBox(this._optionsSubsetDiv, "<b>Viewers:</b>", this.accentColor);
+                this._generateCheckBox(this._optionsSubsetDiv, "Skeletons", false, (element) => {
+
+                    if (!element.checked) {
+                        this._clearSkeletonViewers();
+                        return;
+                    }
+
+                    for (var index = 0; index < this._scene.meshes.length; index++) {
+                        var mesh = this._scene.meshes[index];
+
+                        if (mesh.skeleton) {
+                            var found = false;
+                            for (var sIndex = 0; sIndex < this._skeletonViewers.length; sIndex++) {
+                                if (this._skeletonViewers[sIndex].skeleton === mesh.skeleton) {
+                                    found = true;
+                                    break;
+                                }
+                            }
+
+                            if (found) {
+                                continue;
+                            }
+
+                            var viewer = new BABYLON.Debug.SkeletonViewer(mesh.skeleton, mesh, this._scene);
+                            viewer.isEnabled = true;
+                            this._skeletonViewers.push(viewer);
+                        }
+                    }
+                });
+                this._optionsSubsetDiv.appendChild(document.createElement("br"));
                 this._generateTexBox(this._optionsSubsetDiv, "<b>Tools:</b>", this.accentColor);
                 this._generateButton(this._optionsSubsetDiv, "Dump rendertargets", (element) => { this._scene.dumpNextRenderTargets = true; });
                 this._generateButton(this._optionsSubsetDiv, "Run SceneOptimizer", (element) => { SceneOptimizer.OptimizeAsync(this._scene); });

+ 134 - 0
src/Debug/babylon.skeletonViewer.js

@@ -0,0 +1,134 @@
+var BABYLON;
+(function (BABYLON) {
+    var Debug;
+    (function (Debug) {
+        var SkeletonViewer = (function () {
+            function SkeletonViewer(skeleton, mesh, scene, autoUpdateBonesMatrices, renderingGroupId) {
+                if (autoUpdateBonesMatrices === void 0) { autoUpdateBonesMatrices = true; }
+                if (renderingGroupId === void 0) { renderingGroupId = 1; }
+                this.skeleton = skeleton;
+                this.mesh = mesh;
+                this.autoUpdateBonesMatrices = autoUpdateBonesMatrices;
+                this.renderingGroupId = renderingGroupId;
+                this.color = BABYLON.Color3.White();
+                this._debugLines = [];
+                this._isEnabled = false;
+                this._scene = scene;
+                this.update();
+                this._renderFunction = this.update.bind(this);
+            }
+            Object.defineProperty(SkeletonViewer.prototype, "isEnabled", {
+                get: function () {
+                    return this._isEnabled;
+                },
+                set: function (value) {
+                    if (this._isEnabled === value) {
+                        return;
+                    }
+                    this._isEnabled = value;
+                    if (value) {
+                        this._scene.registerBeforeRender(this._renderFunction);
+                    }
+                    else {
+                        this._scene.unregisterBeforeRender(this._renderFunction);
+                    }
+                },
+                enumerable: true,
+                configurable: true
+            });
+            SkeletonViewer.prototype._getBonePosition = function (position, bone, meshMat, x, y, z) {
+                if (x === void 0) { x = 0; }
+                if (y === void 0) { y = 0; }
+                if (z === void 0) { z = 0; }
+                var tmat = BABYLON.Tmp.Matrix[0];
+                var parentBone = bone.getParent();
+                tmat.copyFrom(bone.getLocalMatrix());
+                if (x !== 0 || y !== 0 || z !== 0) {
+                    var tmat2 = BABYLON.Tmp.Matrix[1];
+                    BABYLON.Matrix.IdentityToRef(tmat2);
+                    tmat2.m[12] = x;
+                    tmat2.m[13] = y;
+                    tmat2.m[14] = z;
+                    tmat2.multiplyToRef(tmat, tmat);
+                }
+                if (parentBone) {
+                    tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
+                }
+                tmat.multiplyToRef(meshMat, tmat);
+                position.x = tmat.m[12];
+                position.y = tmat.m[13];
+                position.z = tmat.m[14];
+            };
+            SkeletonViewer.prototype._getLinesForBonesWithLength = function (bones, meshMat) {
+                var len = bones.length;
+                for (var i = 0; i < len; i++) {
+                    var bone = bones[i];
+                    var points = this._debugLines[i];
+                    if (!points) {
+                        points = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
+                        this._debugLines[i] = points;
+                    }
+                    this._getBonePosition(points[0], bone, meshMat);
+                    this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
+                }
+            };
+            SkeletonViewer.prototype._getLinesForBonesNoLength = function (bones, meshMat) {
+                var len = bones.length;
+                var boneNum = 0;
+                for (var i = len - 1; i >= 0; i--) {
+                    var childBone = bones[i];
+                    var parentBone = childBone.getParent();
+                    if (!parentBone) {
+                        continue;
+                    }
+                    var points = this._debugLines[boneNum];
+                    if (!points) {
+                        points = [BABYLON.Vector3.Zero(), BABYLON.Vector3.Zero()];
+                        this._debugLines[boneNum] = points;
+                    }
+                    this._getBonePosition(points[0], childBone, meshMat);
+                    this._getBonePosition(points[1], parentBone, meshMat);
+                    boneNum++;
+                }
+            };
+            SkeletonViewer.prototype.update = function () {
+                if (this.autoUpdateBonesMatrices) {
+                    this._updateBoneMatrix(this.skeleton.bones[0]);
+                }
+                if (this.skeleton.bones[0].length === undefined) {
+                    this._getLinesForBonesNoLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+                }
+                else {
+                    this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+                }
+                if (!this._debugMesh) {
+                    this._debugMesh = BABYLON.MeshBuilder.CreateLineSystem(null, { lines: this._debugLines, updatable: true }, this._scene);
+                    this._debugMesh.renderingGroupId = this.renderingGroupId;
+                    this._debugMesh.color = this.color;
+                }
+                else {
+                    BABYLON.MeshBuilder.CreateLineSystem(null, { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
+                }
+            };
+            SkeletonViewer.prototype._updateBoneMatrix = function (bone) {
+                if (bone.getParent()) {
+                    bone.getLocalMatrix().multiplyToRef(bone.getParent().getAbsoluteTransform(), bone.getAbsoluteTransform());
+                }
+                var children = bone.children;
+                var len = children.length;
+                for (var i = 0; i < len; i++) {
+                    this._updateBoneMatrix(children[i]);
+                }
+            };
+            SkeletonViewer.prototype.dispose = function () {
+                if (this._debugMesh) {
+                    this.isEnabled = false;
+                    this._debugMesh.dispose();
+                    this._debugMesh = null;
+                }
+            };
+            return SkeletonViewer;
+        })();
+        Debug.SkeletonViewer = SkeletonViewer;
+    })(Debug = BABYLON.Debug || (BABYLON.Debug = {}));
+})(BABYLON || (BABYLON = {}));

+ 137 - 0
src/Debug/babylon.skeletonViewer.ts

@@ -0,0 +1,137 @@
+module BABYLON.Debug {
+    export class SkeletonViewer {
+        public color: Color3 = Color3.White();
+
+        private _scene: Scene;
+        private _debugLines = []; 
+        private _debugMesh: LinesMesh;
+        private _isEnabled = false;
+        private _renderFunction: () => void;
+
+        constructor(public skeleton: Skeleton, public mesh: AbstractMesh, scene: Scene, public autoUpdateBonesMatrices = true, public renderingGroupId = 1) {
+            this._scene = scene;
+
+            this.update();
+
+            this._renderFunction = this.update.bind(this);
+        }
+
+        public set isEnabled(value: boolean) {
+            if (this._isEnabled === value) {
+                return;
+            }
+
+            this._isEnabled = value;
+
+            if (value) {
+                this._scene.registerBeforeRender(this._renderFunction);
+            } else {
+                this._scene.unregisterBeforeRender(this._renderFunction);
+            }
+        }
+
+        public get isEnabled(): boolean {
+            return this._isEnabled;
+        }
+
+        private _getBonePosition(position: Vector3, bone: Bone, meshMat: Matrix, x = 0, y = 0, z = 0): void {
+            var tmat = Tmp.Matrix[0];
+            var parentBone = bone.getParent();
+            tmat.copyFrom(bone.getLocalMatrix());
+
+            if (x !== 0 || y !== 0 || z !== 0) {
+                var tmat2 = Tmp.Matrix[1];
+                BABYLON.Matrix.IdentityToRef(tmat2);
+                tmat2.m[12] = x;
+                tmat2.m[13] = y;
+                tmat2.m[14] = z;
+                tmat2.multiplyToRef(tmat, tmat);
+            }
+
+            if (parentBone) {
+                tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
+            }
+
+            tmat.multiplyToRef(meshMat, tmat);
+
+            position.x = tmat.m[12];
+            position.y = tmat.m[13];
+            position.z = tmat.m[14];
+        }
+
+        private _getLinesForBonesWithLength(bones: Bone[], meshMat: Matrix): void {
+            var len = bones.length;
+            for (var i = 0; i < len; i++) {
+                var bone = bones[i];
+                var points = this._debugLines[i];
+                if (!points) {
+                    points = [Vector3.Zero(), Vector3.Zero()];
+                    this._debugLines[i] = points;
+                }
+                this._getBonePosition(points[0], bone, meshMat);
+                this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
+            }
+        }
+
+        private _getLinesForBonesNoLength(bones: Bone[], meshMat: Matrix): void {
+            var len = bones.length;
+            var boneNum = 0;
+            for (var i = len - 1; i >= 0; i--) {
+                var childBone = bones[i];
+                var parentBone = childBone.getParent();
+                if (!parentBone) {
+                    continue;
+                }
+                var points = this._debugLines[boneNum];
+                if (!points) {
+                    points = [Vector3.Zero(), Vector3.Zero()];
+                    this._debugLines[boneNum] = points;
+                }
+                this._getBonePosition(points[0], childBone, meshMat);
+                this._getBonePosition(points[1], parentBone, meshMat);
+                boneNum++;
+            }
+        }
+
+        public update() {
+            if (this.autoUpdateBonesMatrices) {
+                this._updateBoneMatrix(this.skeleton.bones[0]);
+            }
+
+            if (this.skeleton.bones[0].length === undefined) {
+                this._getLinesForBonesNoLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+            } else {
+                this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+            }
+
+            if (!this._debugMesh) {
+                this._debugMesh = BABYLON.MeshBuilder.CreateLineSystem(null, { lines: this._debugLines, updatable: true }, this._scene);
+                this._debugMesh.renderingGroupId = this.renderingGroupId;
+                this._debugMesh.color = this.color;
+            } else {
+                BABYLON.MeshBuilder.CreateLineSystem(null, { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
+            }
+        }
+
+        private _updateBoneMatrix(bone: Bone) {
+            if (bone.getParent()) {
+                bone.getLocalMatrix().multiplyToRef(bone.getParent().getAbsoluteTransform(), bone.getAbsoluteTransform());
+            }
+
+            var children = bone.children;
+            var len = children.length;
+
+            for (var i = 0; i < len; i++) {
+                this._updateBoneMatrix(children[i]);
+            }
+        }
+
+        public dispose() {
+            if (this._debugMesh) {
+                this.isEnabled = false;
+                this._debugMesh.dispose();
+                this._debugMesh = null;
+            }
+        }
+    }
+}

+ 4 - 1
src/Physics/Plugins/babylon.cannonJSPlugin.js

@@ -365,9 +365,12 @@ var BABYLON;
         CannonJSPlugin.prototype.isSupported = function () {
             return window.CANNON !== undefined;
         };
-        CannonJSPlugin.prototype.setVelocity = function (impostor, velocity) {
+        CannonJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
             impostor.physicsBody.velocity.copy(velocity);
         };
+        CannonJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
+            impostor.physicsBody.angularVelocity.copy(velocity);
+        };
         CannonJSPlugin.prototype.sleepBody = function (impostor) {
             impostor.physicsBody.sleep();
         };

+ 1 - 3
src/Physics/Plugins/babylon.cannonJSPlugin.ts

@@ -430,7 +430,7 @@
         public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
             impostor.physicsBody.velocity.copy(velocity);
         }
-        
+
         public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
             impostor.physicsBody.angularVelocity.copy(velocity);
         }
@@ -450,5 +450,3 @@
 }
 
 
-
-

+ 4 - 1
src/Physics/Plugins/babylon.oimoJSPlugin.js

@@ -258,9 +258,12 @@ var BABYLON;
             }
             return lastShape;
         };
-        OimoJSPlugin.prototype.setVelocity = function (impostor, velocity) {
+        OimoJSPlugin.prototype.setLinearVelocity = function (impostor, velocity) {
             impostor.physicsBody.linearVelocity.init(velocity.x, velocity.y, velocity.z);
         };
+        OimoJSPlugin.prototype.setAngularVelocity = function (impostor, velocity) {
+            impostor.physicsBody.angularVelocity.init(velocity.x, velocity.y, velocity.z);
+        };
         OimoJSPlugin.prototype.sleepBody = function (impostor) {
             impostor.physicsBody.sleep();
         };

+ 2 - 3
src/Physics/Plugins/babylon.oimoJSPlugin.ts

@@ -319,7 +319,7 @@ module BABYLON {
         public setLinearVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
             impostor.physicsBody.linearVelocity.init(velocity.x, velocity.y, velocity.z);
         }
-        
+
         public setAngularVelocity(impostor: PhysicsImpostor, velocity: Vector3) {
             impostor.physicsBody.angularVelocity.init(velocity.x, velocity.y, velocity.z);
         }
@@ -336,5 +336,4 @@ module BABYLON {
             this.world.clear();
         }
     }
-}
-
+}

+ 1 - 2
src/Physics/babylon.physicsEngine.ts

@@ -167,5 +167,4 @@
         wakeUpBody(impostor: PhysicsImpostor);
         dispose();
     }
-}
-
+}

+ 9 - 3
src/Physics/babylon.physicsImpostor.js

@@ -157,10 +157,16 @@ var BABYLON;
             this._bodyUpdateRequired = true;
         };
         /**
-         * Set the body's velocity.
+         * Set the body's linear velocity.
          */
-        PhysicsImpostor.prototype.setVelocity = function (velocity) {
-            this._physicsEngine.getPhysicsPlugin().setVelocity(this, velocity);
+        PhysicsImpostor.prototype.setLinearVelocity = function (velocity) {
+            this._physicsEngine.getPhysicsPlugin().setLinearVelocity(this, velocity);
+        };
+        /**
+         * Set the body's linear velocity.
+         */
+        PhysicsImpostor.prototype.setAngularVelocity = function (velocity) {
+            this._physicsEngine.getPhysicsPlugin().setAngularVelocity(this, velocity);
         };
         /**
          * Execute a function with the physics plugin native code.