diff options
-rw-r--r-- | release/scripts/startup/bl_ui/properties_data_armature.py | 3 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_armature_types.h | 10 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_armature.c | 11 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ArmatureObject.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_ArmatureObject.h | 6 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_BlenderDataConversion.cpp | 4 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.cpp | 125 | ||||
-rw-r--r-- | source/gameengine/Converter/BL_SkinDeformer.h | 3 | ||||
-rw-r--r-- | source/gameengine/Converter/CMakeLists.txt | 1 | ||||
-rw-r--r-- | source/gameengine/Converter/SConscript | 1 |
10 files changed, 149 insertions, 21 deletions
diff --git a/release/scripts/startup/bl_ui/properties_data_armature.py b/release/scripts/startup/bl_ui/properties_data_armature.py index eae7f9e9824..00ccd4ce08b 100644 --- a/release/scripts/startup/bl_ui/properties_data_armature.py +++ b/release/scripts/startup/bl_ui/properties_data_armature.py @@ -70,6 +70,9 @@ class DATA_PT_skeleton(ArmatureButtonsPanel, bpy.types.Panel): 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" diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 808db1f4843..1675fdd3e90 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -96,7 +96,9 @@ typedef struct bArmature { 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 @@ typedef enum eArmature_Drawtype { 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), diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index 3f58723a929..19a6b482621 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -818,6 +818,10 @@ static void rna_def_armature(BlenderRNA *brna) {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 @@ static void rna_def_armature(BlenderRNA *brna) 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); diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp index b58e6b462a8..72a31566e7c 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.cpp +++ b/source/gameengine/Converter/BL_ArmatureObject.cpp @@ -215,7 +215,8 @@ BL_ArmatureObject::BL_ArmatureObject( 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 @@ BL_ArmatureObject::BL_ArmatureObject( 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; diff --git a/source/gameengine/Converter/BL_ArmatureObject.h b/source/gameengine/Converter/BL_ArmatureObject.h index 2c3ca7404b3..1467f05c1bd 100644 --- a/source/gameengine/Converter/BL_ArmatureObject.h +++ b/source/gameengine/Converter/BL_ArmatureObject.h @@ -69,7 +69,8 @@ public: void* sgReplicationInfo, SG_Callbacks callbacks, Object *armature, - Scene *scene + Scene *scene, + int vert_deform_type ); virtual ~BL_ArmatureObject(); @@ -90,6 +91,8 @@ public: 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 @@ protected: 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 diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 7b9c5d4b4d6..9bea3f492c9 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -1807,11 +1807,13 @@ static KX_GameObject *gameobject_from_blenderobject( 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; diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp index 34f9cb56c27..fb25a55e30a 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.cpp +++ b/source/gameengine/Converter/BL_SkinDeformer.cpp @@ -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,17 +181,105 @@ void BL_SkinDeformer::ProcessReplica() 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 */ @@ -199,15 +292,15 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied) m_armobj->ApplyPose(); - // 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); + switch (m_armobj->GetVertDeformType()) + { + case ARM_VDEF_BGE_CPU: + BGEDeformVerts(); + break; + case ARM_VDEF_BLENDER: + default: + BlenderDeformVerts(); + } #ifdef __NLA_DEFNORMALS if (m_recalcNormal) diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h index e53e21e946f..36eff21c085 100644 --- a/source/gameengine/Converter/BL_SkinDeformer.h +++ b/source/gameengine/Converter/BL_SkinDeformer.h @@ -110,6 +110,9 @@ protected: bool m_poseApplied; bool m_recalcNormal; + void BlenderDeformVerts(); + void BGEDeformVerts(); + #ifdef WITH_CXX_GUARDEDALLOC public: diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt index 45a7701d404..3a217ce9d74 100644 --- a/source/gameengine/Converter/CMakeLists.txt +++ b/source/gameengine/Converter/CMakeLists.txt @@ -51,6 +51,7 @@ set(INC ../../blender/makesrna ../../blender/windowmanager ../../../extern/bullet2/src + ../../../extern/Eigen2 ../../../intern/container ../../../intern/guardedalloc ../../../intern/moto/include diff --git a/source/gameengine/Converter/SConscript b/source/gameengine/Converter/SConscript index 9cfc3410748..0ae22d548c5 100644 --- a/source/gameengine/Converter/SConscript +++ b/source/gameengine/Converter/SConscript @@ -20,6 +20,7 @@ incs += ' #source/blender/misc #source/blender/blenloader #source/blender/gpu' incs += ' #source/blender/windowmanager' incs += ' #source/blender/makesrna' incs += ' #source/blender/ikplugin' +incs += ' #extern/Eigen2' incs += ' ' + env['BF_BULLET_INC'] |