[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38045] branches/soc-2011-pepper/release/ scripts: Early commit of mocap constraint work.

Benjy Cook benjycook at hotmail.com
Sat Jul 2 20:24:05 CEST 2011


Revision: 38045
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38045
Author:   benjycook
Date:     2011-07-02 18:24:05 +0000 (Sat, 02 Jul 2011)
Log Message:
-----------
Early commit of mocap constraint work. Still very much a WIP, but Point constraints should work - but buggy.

Modified Paths:
--------------
    branches/soc-2011-pepper/release/scripts/modules/retarget.py
    branches/soc-2011-pepper/release/scripts/startup/ui_mocap.py

Added Paths:
-----------
    branches/soc-2011-pepper/release/scripts/modules/mocap_constraints.py

Added: branches/soc-2011-pepper/release/scripts/modules/mocap_constraints.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/modules/mocap_constraints.py	                        (rev 0)
+++ branches/soc-2011-pepper/release/scripts/modules/mocap_constraints.py	2011-07-02 18:24:05 UTC (rev 38045)
@@ -0,0 +1,141 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+import bpy
+from mathutils import *
+
+### Utility Functions
+
+
+def hasIKConstraint(pose_bone):
+    #utility function / predicate, returns True if given bone has IK constraint
+    return ("IK" in [constraint.type for constraint in pose_bone.constraints])
+
+
+def getConsObj(bone):
+    #utility function - returns related IK target if bone has IK
+    ik = [constraint for constraint in bone.constraints if constraint.type == "IK"]
+    if ik:
+        ik = ik[0]
+        cons_obj = ik.target
+        if ik.subtarget:
+            cons_obj = ik.target.pose.bones[ik.subtarget]
+    else:
+        cons_obj = bone
+    return cons_obj
+
+### And and Remove Constraints (called from operators)
+
+
+def addNewConstraint(m_constraint, cons_obj):
+    if m_constraint.type == "point" or m_constraint.type == "freeze":
+        c_type = "LIMIT_LOCATION"
+    if m_constraint.type == "distance":
+        c_type = "LIMIT_DISTANCE"
+    if m_constraint.type == "floor":
+        c_type = "FLOOR"
+    real_constraint = cons_obj.constraints.new(c_type)
+    real_constraint.name = "Mocap constraint " + str(len(cons_obj.constraints))
+    m_constraint.real_constraint_bone = cons_obj.name
+    m_constraint.real_constraint = real_constraint.name
+    setConstraint(m_constraint)
+
+
+def removeConstraint(m_constraint, cons_obj):
+    oldConstraint = cons_obj.constraints[m_constraint.real_constraint]
+    cons_obj.constraints.remove(oldConstraint)
+
+### Update functions. There are 3: UpdateType, UpdateBone
+### and update for the others.
+
+
+def updateConstraint(self, context):
+    setConstraint(self)
+
+
+def updateConstraintType(m_constraint, context):
+    pass
+    #If the constraint exists, we need to remove it
+    #Then create a new one.
+
+
+def updateConstraintTargetBone(m_constraint, context):
+    #If the constraint exists, we need to remove it
+    #from the old bone
+    obj = context.active_object
+    bones = obj.pose.bones
+    if m_constraint.real_constraint:
+        bone = bones[m_constraint.real_constraint_bone]
+        cons_obj = getConsObj(bone)
+        removeConstraint(m_constraint, cons_obj)
+    #Regardless, after that we create a new constraint
+    bone = bones[m_constraint.constrained_bone]
+    cons_obj = getConsObj(bone)
+    addNewConstraint(m_constraint, cons_obj)
+
+
+# Function that copies all settings from m_constraint to the real Blender constraints
+# Is only called when blender constraint already exists
+def setConstraint(m_constraint):
+    if not m_constraint.constrained_bone:
+        return
+    obj = bpy.context.active_object
+    bones = obj.pose.bones
+    bone = bones[m_constraint.constrained_bone]
+    cons_obj = getConsObj(bone)
+    real_constraint = cons_obj.constraints[m_constraint.real_constraint]
+
+    #frame changing section
+    fcurves = obj.animation_data.action.fcurves
+    influence_RNA = real_constraint.path_from_id("influence")
+    fcurve = [fcurve for fcurve in fcurves if fcurve.data_path == influence_RNA]
+    #clear the fcurve and set the frames.
+    if fcurve:
+        fcurve = fcurve[0]
+        for i in range(len(fcurve.keyframe_points) - 1, 0, -1):
+            fcurve.keyframe_points.remove(fcurve.keyframe_points[i])
+    s, e = bpy.context.scene.frame_start, bpy.context.scene.frame_end
+    real_constraint.influence = 0
+    real_constraint.keyframe_insert(data_path="influence", frame=s)
+    real_constraint.keyframe_insert(data_path="influence", frame=e)
+    s, e = m_constraint.s_frame, m_constraint.e_frame
+    real_constraint.influence = 1
+    real_constraint.keyframe_insert(data_path="influence", frame=s)
+    real_constraint.keyframe_insert(data_path="influence", frame=e)
+    real_constraint.influence = 0
+    real_constraint.keyframe_insert(data_path="influence", frame=s - 10)
+    real_constraint.keyframe_insert(data_path="influence", frame=e + 10)
+
+    #Set the blender constraint parameters
+    if m_constraint.type == "point":
+        real_constraint.target_space = "WORLD"  # temporary for now, just World is supported
+        x, y, z = m_constraint.targetPoint
+        real_constraint.max_x = x
+        real_constraint.max_y = y
+        real_constraint.max_z = z
+        real_constraint.min_x = x
+        real_constraint.min_y = y
+        real_constraint.min_z = z
+        real_constraint.use_max_x = True
+        real_constraint.use_max_y = True
+        real_constraint.use_max_z = True
+        real_constraint.use_min_x = True
+        real_constraint.use_min_y = True
+        real_constraint.use_min_z = True


Property changes on: branches/soc-2011-pepper/release/scripts/modules/mocap_constraints.py
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: branches/soc-2011-pepper/release/scripts/modules/retarget.py
===================================================================
--- branches/soc-2011-pepper/release/scripts/modules/retarget.py	2011-07-02 18:15:55 UTC (rev 38044)
+++ branches/soc-2011-pepper/release/scripts/modules/retarget.py	2011-07-02 18:24:05 UTC (rev 38045)
@@ -71,13 +71,13 @@
     #useful for storing the important data in the original motion
     #i.e. using this empty to IK the chain to that pos / DEBUG
     def locOfOriginal(inter_bone, perf_bone):
-        if not perf_bone.name + "Org" in bpy.data.objects:
+        if not inter_bone.name + "Org" in bpy.data.objects:
             bpy.ops.object.add()
             empty = bpy.context.active_object
-            empty.name = perf_bone.name + "Org"
+            empty.name = inter_bone.name + "Org"
             empty.empty_draw_size = 0.1
             #empty.parent = enduser_obj
-        empty = bpy.data.objects[perf_bone.name + "Org"]
+        empty = bpy.data.objects[inter_bone.name + "Org"]
         offset = perf_bone.vector
         if inter_bone.length == 0 or perf_bone.length == 0:
             scaling = 1
@@ -263,17 +263,17 @@
                 #end bone's delta
                 if endV.length != 0:
                     linearAvg.append(hipV.length / endV.length)
-    
+
     bpy.ops.object.add()
     stride_bone = bpy.context.active_object
     stride_bone.name = "stride_bone"
-    
+
     if linearAvg:
         avg = sum(linearAvg) / len(linearAvg)
         for t in range(s_frame, e_frame):
             scene.frame_set(t)
             newTranslation = (tailLoc(perf_bones[perfRoot]) / avg)
-            stride_bone.location = newTranslation
+            stride_bone.location = newTranslation * enduser_obj.matrix_world
             stride_bone.keyframe_insert("location")
     return stride_bone
 
@@ -287,7 +287,7 @@
             perf_bone = bonemapr[pose_bone.name]
             if isinstance(perf_bone, list):
                 perf_bone = bonemapr[pose_bone.name][-1]
-            end_empty = bpy.data.objects[perf_bone + "Org"]
+            end_empty = bpy.data.objects[pose_bone.name + "Org"]
             ik_constraint = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"][0]
             if not ik_constraint.target:
                 ik_constraint.target = end_empty
@@ -326,23 +326,26 @@
             ik_constraint = [constraint for constraint in pose_bone.constraints if constraint.type == "IK"][0]
             ik_constraint.mute = True
 
-def cleanAndStoreObjMat(performer_obj,enduser_obj):
+
+def cleanAndStoreObjMat(performer_obj, enduser_obj):
     perf_obj_mat = performer_obj.matrix_world.copy()
     enduser_obj_mat = enduser_obj.matrix_world.copy()
-    zero_mat = Matrix()#Matrix(((0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)))
+    zero_mat = Matrix()  # Matrix(((0,0,0,0),(0,0,0,0),(0,0,0,0),(0,0,0,0)))
     performer_obj.matrix_world = zero_mat
     enduser_obj.matrix_world = zero_mat
     return perf_obj_mat, enduser_obj_mat
 
-def restoreObjMat(performer_obj,enduser_obj,perf_obj_mat,enduser_obj_mat):
-    perf_bones = performer_obj.pose.bones
-    for perf_bone in perf_bones:
-        if perf_bone.name + "Org" in bpy.data.objects:
-            empty = bpy.data.objects[perf_bone.name + "Org"]
+
+def restoreObjMat(performer_obj, enduser_obj, perf_obj_mat, enduser_obj_mat, stride_bone):
+    pose_bones = enduser_obj.pose.bones
+    for pose_bone in pose_bones:
+        if pose_bone.name + "Org" in bpy.data.objects:
+            empty = bpy.data.objects[pose_bone.name + "Org"]
             empty.parent = enduser_obj
     performer_obj.matrix_world = perf_obj_mat
     enduser_obj.matrix_world = enduser_obj_mat
 
+
 def totalRetarget():
     print("retargeting...")
     enduser_obj = bpy.context.active_object
@@ -357,16 +360,16 @@
     s_frame = scene.frame_start
     e_frame = scene.frame_end
     bonemap, bonemapr, root = createDictionary(perf_arm)
-    perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj,enduser_obj)
+    perf_obj_mat, enduser_obj_mat = cleanAndStoreObjMat(performer_obj, enduser_obj)
     turnOffIK(enduser_obj)
     inter_obj, inter_arm = createIntermediate(performer_obj, enduser_obj, bonemap, bonemapr, root, s_frame, e_frame, scene)
     retargetEnduser(inter_obj, enduser_obj, root, s_frame, e_frame, scene)

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list