Revision: 38719
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38719
Author:   moguri
Date:     2011-07-26 06:10:05 +0000 (Tue, 26 Jul 2011)
Log Message:
-----------
BGE Animations: Adding a new choice for vertex deformation for armatures, which 
can be found in the Armature's Skeleton panel by the Deform options. Before 
only Blender's armature_deform_verts() was used. Now users can choose a vertex 
deformation function that is optimized for the BGE. At the moment it is mostly 
a copy of armature_deform_verts() with various chunks of code removed, and the 
BLI_math code was replaced with Eigen2. In my test scene, the new function 
offered about a 40% improvement over armature_deform_verts() (17~19ms 
rasterizer to 11~12ms). The only current limitation that I'm aware of if that 
B-Bone segments are not supported in the BGE version, and I will probably leave 
it out. I would like to also limit the BGE version to 4 weights to make things 
easier for a GPU version, but this may just make things slower (sorting weights 
to find the top 4).

Modified Paths:
--------------
    
branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py
    branches/soc-2011-pepper/source/blender/makesdna/DNA_armature_types.h
    branches/soc-2011-pepper/source/blender/makesrna/intern/rna_armature.c
    branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.cpp
    branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.h
    
branches/soc-2011-pepper/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp
    branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.h
    branches/soc-2011-pepper/source/gameengine/Converter/CMakeLists.txt
    branches/soc-2011-pepper/source/gameengine/Converter/SConscript

Modified: 
branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py
===================================================================
--- 
branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py
  2011-07-26 04:31:59 UTC (rev 38718)
+++ 
branches/soc-2011-pepper/release/scripts/startup/bl_ui/properties_data_armature.py
  2011-07-26 06:10:05 UTC (rev 38719)
@@ -70,6 +70,9 @@
         flow.prop(arm, "use_deform_envelopes", text="Envelopes")
         flow.prop(arm, "use_deform_preserve_volume", text="Quaternion")
 
+        if context.scene.render.engine == "BLENDER_GAME":
+            col = layout.column()
+            col.prop(arm, "vert_deformer")
 
 class DATA_PT_display(ArmatureButtonsPanel, bpy.types.Panel):
     bl_label = "Display"

Modified: branches/soc-2011-pepper/source/blender/makesdna/DNA_armature_types.h
===================================================================
--- branches/soc-2011-pepper/source/blender/makesdna/DNA_armature_types.h       
2011-07-26 04:31:59 UTC (rev 38718)
+++ branches/soc-2011-pepper/source/blender/makesdna/DNA_armature_types.h       
2011-07-26 06:10:05 UTC (rev 38719)
@@ -96,7 +96,9 @@
        void            *sketch;                                /* sketch 
struct for etch-a-ton */
        
        int                     flag;
-       int                     drawtype;                       
+       int                     drawtype;
+       int                     gevertdeformer;                 /* how vertex 
deformation is handled in the ge */
+       int                     pad;
        short           deformflag; 
        short           pathflag;
        
@@ -140,6 +142,12 @@
        ARM_WIRE
 } eArmature_Drawtype;
 
+/* armature->gevertdeformer */
+typedef enum eArmature_VertDeformer {
+       ARM_VDEF_BLENDER,
+       ARM_VDEF_BGE_CPU
+} eArmature_VertDeformer;
+
 /* armature->deformflag */
 typedef enum eArmature_DeformFlag {
        ARM_DEF_VGROUP                  = (1<<0),

Modified: branches/soc-2011-pepper/source/blender/makesrna/intern/rna_armature.c
===================================================================
--- branches/soc-2011-pepper/source/blender/makesrna/intern/rna_armature.c      
2011-07-26 04:31:59 UTC (rev 38718)
+++ branches/soc-2011-pepper/source/blender/makesrna/intern/rna_armature.c      
2011-07-26 06:10:05 UTC (rev 38719)
@@ -818,6 +818,10 @@
                {ARM_ENVELOPE, "ENVELOPE", 0, "Envelope", "Display bones as 
extruded spheres, showing deformation influence volume"},
                {ARM_WIRE, "WIRE", 0, "Wire", "Display bones as thin wires, 
showing subdivision and B-Splines"},
                {0, NULL, 0, NULL, NULL}};
+       static EnumPropertyItem prop_vdeformer[] = {
+               {ARM_VDEF_BLENDER, "BLENDER", 0, "Blender", "Uses Blender's 
armature vertex deformation"},
+               {ARM_VDEF_BGE_CPU, "BGE_CPU", 0, "BGE", "Uses vertex 
deformation code optimized for the BGE"},
+               {0, NULL, 0, NULL, NULL}};
        static EnumPropertyItem prop_ghost_type_items[] = {
                {ARM_GHOST_CUR, "CURRENT_FRAME", 0, "Around Frame", "Display 
Ghosts of poses within a fixed number of frames around the current frame"},
                {ARM_GHOST_RANGE, "RANGE", 0, "In Range", "Display Ghosts of 
poses within specified range"},
@@ -864,6 +868,13 @@
        RNA_def_property_ui_text(prop, "Draw Type", "");
        RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
        RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
+
+       prop= RNA_def_property(srna, "vert_deformer", PROP_ENUM, PROP_NONE);
+       RNA_def_property_enum_sdna(prop, NULL, "gevertdeformer");
+       RNA_def_property_enum_items(prop, prop_vdeformer);
+       RNA_def_property_ui_text(prop, "Vertex Deformer", "");
+       RNA_def_property_update(prop, 0, "rna_Armature_redraw_data");
+       RNA_def_property_flag(prop, PROP_LIB_EXCEPTION);
        
 // XXX depreceated ....... old animviz for armatures only
        prop= RNA_def_property(srna, "ghost_type", PROP_ENUM, PROP_NONE);

Modified: 
branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.cpp
===================================================================
--- branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.cpp  
2011-07-26 04:31:59 UTC (rev 38718)
+++ branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.cpp  
2011-07-26 06:10:05 UTC (rev 38719)
@@ -215,7 +215,8 @@
                                void* sgReplicationInfo, 
                                SG_Callbacks callbacks, 
                                Object *armature,
-                               Scene *scene)
+                               Scene *scene,
+                               int vert_deform_type)
 
 :      KX_GameObject(sgReplicationInfo,callbacks),
        m_controlledConstraints(),
@@ -229,7 +230,8 @@
        m_activePriority(999),
        m_constraintNumber(0),
        m_channelNumber(0),
-       m_lastapplyframe(0.0)
+       m_lastapplyframe(0.0),
+       m_vert_deform_type(vert_deform_type)
 {
        m_armature = (bArmature *)armature->data;
 

Modified: 
branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.h
===================================================================
--- branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.h    
2011-07-26 04:31:59 UTC (rev 38718)
+++ branches/soc-2011-pepper/source/gameengine/Converter/BL_ArmatureObject.h    
2011-07-26 06:10:05 UTC (rev 38719)
@@ -69,7 +69,8 @@
                void* sgReplicationInfo,
                SG_Callbacks callbacks,
                Object *armature,
-               Scene *scene
+               Scene *scene,
+               int vert_deform_type
        );
        virtual ~BL_ArmatureObject();
 
@@ -90,6 +91,8 @@
        
        Object* GetArmatureObject() {return m_objArma;}
 
+       int GetVertDeformType() {return m_vert_deform_type;}
+
        // for constraint python API
        void LoadConstraints(KX_BlenderSceneConverter* converter);
        size_t GetConstraintNumber() const { return m_constraintNumber; }
@@ -136,6 +139,7 @@
        double  m_timestep;             // delta since last pose evaluation.
        class BL_ActionActuator *m_activeAct;
        short   m_activePriority;
+       int             m_vert_deform_type;
        size_t  m_constraintNumber;
        size_t  m_channelNumber;
        // store the original armature object matrix

Modified: 
branches/soc-2011-pepper/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- 
branches/soc-2011-pepper/source/gameengine/Converter/BL_BlenderDataConversion.cpp
   2011-07-26 04:31:59 UTC (rev 38718)
+++ 
branches/soc-2011-pepper/source/gameengine/Converter/BL_BlenderDataConversion.cpp
   2011-07-26 06:10:05 UTC (rev 38719)
@@ -1807,11 +1807,13 @@
        
        case OB_ARMATURE:
        {
+               bArmature *arm = (bArmature*)ob->data;
                gameobj = new BL_ArmatureObject(
                        kxscene,
                        KX_Scene::m_callbacks,
                        ob,
-                       kxscene->GetBlenderScene() // handle
+                       kxscene->GetBlenderScene(), // handle
+                       arm->gevertdeformer
                );
                /* Get the current pose from the armature object and apply it 
as the rest pose */
                break;

Modified: 
branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp
===================================================================
--- branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp    
2011-07-26 04:31:59 UTC (rev 38718)
+++ branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp    
2011-07-26 06:10:05 UTC (rev 38719)
@@ -36,6 +36,10 @@
 #pragma warning (disable : 4786)
 #endif //WIN32
 
+// Eigen2 stuff used for BGEDeformVerts
+#include <Eigen/Core>
+#include <Eigen/LU>
+
 #include "BL_SkinDeformer.h"
 #include "CTR_Map.h"
 #include "STR_HashedString.h"
@@ -54,6 +58,7 @@
 
 extern "C"{
        #include "BKE_lattice.h"
+       #include "BKE_deform.h"
 }
  
 
@@ -176,18 +181,106 @@
        m_releaseobject = false;
 }
 
-//void where_is_pose (Object *ob);
-//void armature_deform_verts(Object *armOb, Object *target, float 
(*vertexCos)[3], int numVerts, int deformflag); 
+void BL_SkinDeformer::BlenderDeformVerts()
+{
+       float obmat[4][4];      // the original object matrix
+       Object* par_arma = m_armobj->GetArmatureObject();
+
+       // save matrix first
+       copy_m4_m4(obmat, m_objMesh->obmat);
+       // set reference matrix
+       copy_m4_m4(m_objMesh->obmat, m_obmat);
+
+       armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, NULL, 
m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
+               
+       // restore matrix 
+       copy_m4_m4(m_objMesh->obmat, obmat);
+}
+
+void BL_SkinDeformer::BGEDeformVerts()
+{
+       Object *par_arma = m_armobj->GetArmatureObject();
+       MDeformVert *dverts = m_bmesh->dvert;
+       MDeformVert *dvert;
+       bDeformGroup *dg;
+       bPoseChannel *pchan=NULL;
+       bPoseChannel **dfnrToPC;
+       int numGroups = BLI_countlist(&m_objMesh->defbase);
+
+       if (!dverts)
+               return;
+
+       dfnrToPC = new bPoseChannel*[numGroups];
+       int i;
+       for (i=0, dg=(bDeformGroup*)m_objMesh->defbase.first;
+               dg;
+               ++i, dg=(bDeformGroup*)dg->next)
+       {
+               dfnrToPC[i] = get_pose_channel(par_arma->pose, dg->name);
+
+               if (dfnrToPC[i] && dfnrToPC[i]->bone->flag & BONE_NO_DEFORM)
+                       dfnrToPC[i] = NULL;
+       }
+
+
+       for (int i=0; i<m_bmesh->totvert; ++i)
+       {
+               float contrib = 0.f, weight;
+               Bone *bone;
+               Eigen::Vector4f co(0.f, 0.f, 0.f, 1.f);
+               Eigen::Vector4f vec(0, 0, 0, 1);
+               co[0] = m_transverts[i][0];
+               co[1] = m_transverts[i][1];
+               co[2] = m_transverts[i][2];
+
+               dvert = dverts+i;
+
+               if (!dvert->totweight)
+                       continue;
+
+               for (int j=0; j<dvert->totweight; ++j)
+               {
+                       int index = dvert->dw[j].def_nr;
+
+                       if (index < numGroups && (pchan=dfnrToPC[index]))
+                       {
+                               weight = dvert->dw[j].weight;
+                               bone = pchan->bone;
+
+                               if (weight)
+                               {
+                                       Eigen::Vector4f cop(co);
+                                       Eigen::Matrix4f chan_mat = 
Eigen::Matrix4f::Map((float*)pchan->chan_mat);
+
+                                       cop = chan_mat*cop;
+                                       vec += (cop - co)*weight;
+
+                                       contrib += weight;
+                               }
+                       }
+               }
+
+
+               if (contrib > 0.0001f)
+               {
+                       vec *= 1.f/contrib;
+                       co += vec;
+               }
+
+               m_transverts[i][0] = co[0];
+               m_transverts[i][1] = co[1];
+               m_transverts[i][2] = co[2];
+       }
+
+       if (dfnrToPC)
+               delete [] dfnrToPC;
+}
+
 bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
 {
        /* See if the armature has been updated for this frame */
        if (PoseUpdated()){     
-               float obmat[4][4];      // the original object matrice 
 
-               /* XXX note: where_is_pose() (from BKE_armature.h) calculates 
all matrices needed to start deforming */
-               /* but it requires the blender object pointer... */
-               Object* par_arma = m_armobj->GetArmatureObject();
-
                if(!shape_applied) {
                        /* store verts locally */
                        VerifyStorage();
@@ -199,16 +292,16 @@
 
                m_armobj->ApplyPose();
 
-               // save matrix first
-               copy_m4_m4(obmat, m_objMesh->obmat);
-               // set reference matrix
-               copy_m4_m4(m_objMesh->obmat, m_obmat);
+               switch (m_armobj->GetVertDeformType())
+               {
+                       case ARM_VDEF_BGE_CPU:
+                               BGEDeformVerts();
+                               break;
+                       case ARM_VDEF_BLENDER:
+                       default:
+                               BlenderDeformVerts();
+               }
 
-               armature_deform_verts( par_arma, m_objMesh, NULL, m_transverts, 
NULL, m_bmesh->totvert, ARM_DEF_VGROUP, NULL, NULL );
-               
-               // restore matrix 
-               copy_m4_m4(m_objMesh->obmat, obmat);
-
 #ifdef __NLA_DEFNORMALS
                if (m_recalcNormal)
                        RecalcNormals();


@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to