Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorMitchell Stokes <mogurijin@gmail.com>2011-07-26 10:10:05 +0400
committerMitchell Stokes <mogurijin@gmail.com>2011-07-26 10:10:05 +0400
commit1f65b3b1a8f5ccc54a794ed0d6f8cf2d3e2c5a36 (patch)
tree236c1d8475709b45962fd5efa901626a78fedbe0 /source
parent1e0e0ff5c4e88f2ee21c849b151a1899ae4c714f (diff)
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).
Diffstat (limited to 'source')
-rw-r--r--source/blender/makesdna/DNA_armature_types.h10
-rw-r--r--source/blender/makesrna/intern/rna_armature.c11
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp6
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.h6
-rw-r--r--source/gameengine/Converter/BL_BlenderDataConversion.cpp4
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp125
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h3
-rw-r--r--source/gameengine/Converter/CMakeLists.txt1
-rw-r--r--source/gameengine/Converter/SConscript1
9 files changed, 146 insertions, 21 deletions
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']