فهرست منبع

Blender 4.2.1

-fixed typo with Blender Nodes
-allow more IK Bones to ignore
-added rest pose. No really working, but cannot spend any more time
right now. User waiting for nodes fix.
jeff 10 سال پیش
والد
کامیت
71c17cff30
3فایلهای تغییر یافته به همراه56 افزوده شده و 18 حذف شده
  1. 34 13
      Exporters/Blender/io_export_babylon.py
  2. 11 1
      src/Bones/babylon.bone.ts
  3. 11 4
      src/Bones/babylon.skeleton.ts

+ 34 - 13
Exporters/Blender/io_export_babylon.py

@@ -1,7 +1,7 @@
 bl_info = {
     'name': 'Babylon.js',
     'author': 'David Catuhe, Jeff Palmer',
-    'version': (4, 2, 0),
+    'version': (4, 2, 1),
     'blender': (2, 75, 0),
     'location': 'File > Export > Babylon.js (.babylon)',
     'description': 'Export Babylon.js scenes (.babylon)',
@@ -169,7 +169,7 @@ class ExporterSettingsPanel(bpy.types.Panel):
         )
     bpy.types.Scene.ignoreIKBones = bpy.props.BoolProperty(
         name="Ignore IK Bones",
-        description="Do not export bones with '.ik' in the name",
+        description="Do not export bones with either '.ik' or 'ik.'(not case sensitive) in the name",
         default = False,
         )
 
@@ -531,7 +531,6 @@ class World:
             write_float(file_handler, 'fogStart', self.fogStart)
             write_float(file_handler, 'fogEnd', self.fogEnd)
             write_float(file_handler, 'fogDensity', self.fogDensity)
-
 #===============================================================================
 class Sound:
     def __init__(self, name, autoplay, loop, connectedMesh = None):
@@ -1239,7 +1238,7 @@ class MeshInstance:
 class Node(FCurveAnimatable):
     def __init__(self, node):
         Main.log('processing begun of node:  ' + node.name)
-        self.define_animations(object, True, True, True)  #Should animations be done when forcedParent
+        self.define_animations(node, True, True, True)  #Should animations be done when forcedParent
         self.name = node.name
 
         if node.parent and node.parent.type != 'ARMATURE':
@@ -1304,11 +1303,11 @@ class Bone:
         self.name = bone.name
         self.length = bone.length
         self.index = index
-        self.blenderBoneObj = bone # record so can be used by get_matrix, called by append_animation_pose
+        self.posedBone = bone # record so can be used by get_matrix, called by append_animation_pose
         self.parentBone = bone.parent
 
         self.matrix_world = skeleton.matrix_world
-        self.matrix = self.get_matrix()
+        self.matrix = self.get_bone_matrix()
 
         parentId = -1
         if (bone.parent):
@@ -1325,32 +1324,40 @@ class Bone:
             self.previousBoneMatrix = None
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def append_animation_pose(self, frame, force = False):
-        currentBoneMatrix = self.get_matrix()
+        currentBoneMatrix = self.get_bone_matrix()
 
         if (force or not same_matrix4(currentBoneMatrix, self.previousBoneMatrix)):
             self.animation.frames.append(frame)
             self.animation.values.append(currentBoneMatrix)
             self.previousBoneMatrix = currentBoneMatrix
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-    def get_matrix(self):
+    def set_rest_pose(self, editBone, matrix_world):
+        self.rest = Bone.get_matrix(editBone, self.matrix_world)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    def get_bone_matrix(self):
+        return Bone.get_matrix(self.posedBone, self.matrix_world)
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+    @staticmethod
+    def get_matrix(bone, matrix_world):
         SystemMatrix = mathutils.Matrix.Scale(-1, 4, mathutils.Vector((0, 0, 1))) * mathutils.Matrix.Rotation(math.radians(-90), 4, 'X')
 
-        if (self.parentBone):
-            return (SystemMatrix * self.matrix_world * self.parentBone.matrix).inverted() * (SystemMatrix * self.matrix_world * self.blenderBoneObj.matrix)
+        if (bone.parent):
+            return (SystemMatrix * matrix_world * bone.parent.matrix).inverted() * (SystemMatrix * matrix_world * bone.matrix)
         else:
-            return  SystemMatrix * self.matrix_world * self.blenderBoneObj.matrix
+            return SystemMatrix * matrix_world * bone.matrix
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     def to_scene_file(self, file_handler):
         file_handler.write('\n{')
         write_string(file_handler, 'name', self.name, True)
         write_int(file_handler, 'index', self.index)
         write_matrix4(file_handler, 'matrix', self.matrix)
+        write_matrix4(file_handler, 'rest', self.rest)
         write_int(file_handler, 'parentBoneIndex', self.parentBoneIndex)
         write_float(file_handler, 'length', self.length)
 
         #animation
         if hasattr(self, 'animation'):
-            file_handler.write(',"animation":')
+            file_handler.write('\n,"animation":')
             self.animation.to_scene_file(file_handler)
 
         file_handler.write('}')
@@ -1363,7 +1370,7 @@ class Skeleton:
         self.bones = []
 
         for bone in skeleton.pose.bones:
-            if scene.ignoreIKBones and '.ik' in bone.name:
+            if scene.ignoreIKBones and ('.ik' in bone.name.lower() or 'ik.' in bone.name.lower() ):
                 Main.log('Ignoring IK bone:  ' + bone.name, 2)
                 continue
 
@@ -1388,6 +1395,20 @@ class Skeleton:
                         bone.append_animation_pose(frame + frameOffset, frame == animationRange.highest_frame)
 
                 frameOffset = animationRange.frame_end + 1
+                
+        # mode_set's only work when there is an active object, switch bones to edit mode to rest position
+        scene.objects.active = skeleton
+        bpy.ops.object.mode_set(mode='EDIT')
+        matrix_world = skeleton.matrix_world
+
+        # you need to access edit_bones from skeleton.data not skeleton.pose when in edit mode
+        for editBone in skeleton.data.edit_bones:
+            for myBoneObj in self.bones:
+                if editBone.name == myBoneObj.name:
+                    myBoneObj.set_rest_pose(editBone, matrix_world)
+                    break
+           
+        bpy.ops.object.mode_set(mode='OBJECT')
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     # Since IK bones could be being skipped, looking up index of bone in second pass of mesh required
     def get_index_of_bone(self, boneName):

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

@@ -6,17 +6,19 @@
 
         private _skeleton: Skeleton;
         private _matrix: Matrix;
+        private _restPose: Matrix;
         private _baseMatrix: Matrix;
         private _worldTransform = new Matrix();
         private _absoluteTransform = new Matrix();
         private _invertedAbsoluteTransform = new Matrix();
         private _parent: Bone;
 
-        constructor(public name: string, skeleton: Skeleton, parentBone: Bone, matrix: Matrix) {
+        constructor(public name: string, skeleton: Skeleton, parentBone: Bone, matrix: Matrix, restPose? : Matrix) {
             super(name, skeleton.getScene());
             this._skeleton = skeleton;
             this._matrix = matrix;
             this._baseMatrix = matrix;
+            this._restPose = restPose ? restPose : matrix.clone();
 
             skeleton.bones.push(this);
 
@@ -43,6 +45,14 @@
             return this._baseMatrix;
         }
 
+        public getRestPose(): Matrix {
+            return this._restPose;
+        }
+        
+        public returnToRest(): void {
+            this.updateMatrix(this._restPose.clone());
+        }
+
         public getWorldMatrix(): Matrix {
             return this._worldTransform;
         }

+ 11 - 4
src/Bones/babylon.skeleton.ts

@@ -90,6 +90,12 @@
             return ret;
         }
 
+        public returnToRest(): void {
+            for (var index = 0; index < this.bones.length; index++) {
+                this.bones[index].returnToRest();
+            }
+        }
+
         private _getHighestAnimationFrame(): number {
             var ret = 0;
             for (var i = 0, nBones = this.bones.length; i < nBones; i++) {
@@ -170,7 +176,7 @@
                     parentBone = result.bones[parentIndex];
                 }
 
-                var bone = new Bone(source.name, result, parentBone, source.getBaseMatrix().clone());
+                var bone = new Bone(source.name, result, parentBone, source.getBaseMatrix().clone(), source.getRestPose().clone());
                 Tools.DeepCopy(source.animations, bone.animations);
             }
 
@@ -199,7 +205,8 @@
                 var serializedBone: any = {
                     parentBoneIndex: bone.getParent() ? this.bones.indexOf(bone.getParent()) : -1,
                     name: bone.name,
-                    matrix: bone.getLocalMatrix().toArray()
+                    matrix: bone.getLocalMatrix().toArray(),
+                    rest: bone.getRestPose().toArray()
                 };
 
                 serializationObject.bones.push(serializedBone);
@@ -234,8 +241,8 @@
                 if (parsedBone.parentBoneIndex > -1) {
                     parentBone = skeleton.bones[parsedBone.parentBoneIndex];
                 }
-
-                var bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix));
+                var rest : Matrix = parsedBone.rest ? Matrix.FromArray(parsedBone.rest) : null;
+                var bone = new Bone(parsedBone.name, skeleton, parentBone, Matrix.FromArray(parsedBone.matrix), rest);
 
                 if (parsedBone.length) {
                     bone.length = parsedBone.length;