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-08-02 03:02:10 +0400
committerMitchell Stokes <mogurijin@gmail.com>2011-08-02 03:02:10 +0400
commit03c1585e3a6516c640bec08094178d8c0860a8b6 (patch)
tree40dbae963ee4c6282d5d9ca86fd7cc8904284db4 /source
parent3e85ec432ef050563d75488eca3049b77497153d (diff)
BGE Animations: BGEDeformVerts() now handles normals instead of relying on BL_MeshDeformer::RecalcNormals(), which BlenderDeformVerts() still uses. As expected, the BGEDeformVerts() version isn't as accurate, but it avoids a sqrt per vertex. This gives about a 15~20% improvement in time spent on the rasterizer in my test scene, which resulted in about 5 more fps. However, the main reason for the new normal code is it will be easier to do on the GPU (doesn't rely on neighbor information).
Diffstat (limited to 'source')
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.cpp46
-rw-r--r--source/gameengine/Converter/BL_SkinDeformer.h1
2 files changed, 36 insertions, 11 deletions
diff --git a/source/gameengine/Converter/BL_SkinDeformer.cpp b/source/gameengine/Converter/BL_SkinDeformer.cpp
index 3f753b2a42c..3a379e8b0ed 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.cpp
+++ b/source/gameengine/Converter/BL_SkinDeformer.cpp
@@ -80,6 +80,7 @@ BL_SkinDeformer::BL_SkinDeformer(BL_DeformableGameObject *gameobj,
m_releaseobject(false),
m_poseApplied(false),
m_recalcNormal(true),
+ m_copyNormals(false),
m_dfnrToPC(NULL)
{
copy_m4_m4(m_obmat, bmeshobj->obmat);
@@ -99,6 +100,7 @@ BL_SkinDeformer::BL_SkinDeformer(
//m_defbase(&bmeshobj_old->defbase),
m_releaseobject(release_object),
m_recalcNormal(recalc_normal),
+ m_copyNormals(false),
m_dfnrToPC(NULL)
{
// this is needed to ensure correct deformation of mesh:
@@ -161,9 +163,14 @@ bool BL_SkinDeformer::Apply(RAS_IPolyMaterial *mat)
for(i=it.startvertex; i<it.endvertex; i++) {
RAS_TexVert& v = it.vertex[i];
v.SetXYZ(m_transverts[v.getOrigIndex()]);
+ if (m_copyNormals)
+ v.SetNormal(m_transnors[v.getOrigIndex()]);
}
}
}
+
+ if (m_copyNormals)
+ m_copyNormals = false;
}
return true;
}
@@ -200,6 +207,11 @@ void BL_SkinDeformer::BlenderDeformVerts()
// restore matrix
copy_m4_m4(m_objMesh->obmat, obmat);
+
+#ifdef __NLA_DEFNORMALS
+ if (m_recalcNormal)
+ RecalcNormals();
+#endif
}
void BL_SkinDeformer::BGEDeformVerts()
@@ -230,15 +242,17 @@ void BL_SkinDeformer::BGEDeformVerts()
for (int i=0; i<m_bmesh->totvert; ++i)
{
- float contrib = 0.f, weight;
+ float contrib = 0.f, weight, max_weight=0.f;
Bone *bone;
bPoseChannel *pchan=NULL;
MDeformVert *dvert;
- Eigen::Vector4f co(0.f, 0.f, 0.f, 1.f);
+ Eigen::Map<Eigen::Vector3f> norm(m_transnors[i]);
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];
+ Eigen::Matrix4f norm_chan_mat;
+ Eigen::Vector4f co(m_transverts[i][0],
+ m_transverts[i][1],
+ m_transverts[i][2],
+ 1.f);
dvert = dverts+i;
@@ -259,15 +273,26 @@ void BL_SkinDeformer::BGEDeformVerts()
Eigen::Vector4f cop(co);
Eigen::Matrix4f chan_mat = Eigen::Matrix4f::Map((float*)pchan->chan_mat);
+ // Update Vertex Position
cop = chan_mat*cop;
vec += (cop - co)*weight;
+ // Save the most influential channel so we can use it to update the vertex normal
+ if (weight > max_weight)
+ {
+ max_weight = weight;
+ norm_chan_mat = chan_mat;
+ }
+
contrib += weight;
}
}
}
-
+
+ // Update Vertex Normal
+ norm = norm_chan_mat.corner<3, 3>(Eigen::TopLeft)*norm;
+
if (contrib > 0.0001f)
{
vec *= 1.f/contrib;
@@ -278,6 +303,7 @@ void BL_SkinDeformer::BGEDeformVerts()
m_transverts[i][1] = co[1];
m_transverts[i][2] = co[2];
}
+ m_copyNormals = true;
}
bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
@@ -291,7 +317,10 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
/* duplicate */
for (int v =0; v<m_bmesh->totvert; v++)
+ {
VECCOPY(m_transverts[v], m_bmesh->mvert[v].co);
+ VECCOPY(m_transnors[v], m_bmesh->mvert[v].no);
+ }
}
m_armobj->ApplyPose();
@@ -306,11 +335,6 @@ bool BL_SkinDeformer::UpdateInternal(bool shape_applied)
BlenderDeformVerts();
}
-#ifdef __NLA_DEFNORMALS
- if (m_recalcNormal)
- RecalcNormals();
-#endif
-
/* Update the current frame */
m_lastArmaUpdate=m_armobj->GetLastFrame();
diff --git a/source/gameengine/Converter/BL_SkinDeformer.h b/source/gameengine/Converter/BL_SkinDeformer.h
index 59047387513..be974619281 100644
--- a/source/gameengine/Converter/BL_SkinDeformer.h
+++ b/source/gameengine/Converter/BL_SkinDeformer.h
@@ -109,6 +109,7 @@ protected:
bool m_releaseobject;
bool m_poseApplied;
bool m_recalcNormal;
+ bool m_copyNormals; // dirty flag so we know if Apply() needs to copy normal information (used for BGEDeformVerts())
struct bPoseChannel** m_dfnrToPC;
void BlenderDeformVerts();