[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [38905] branches/soc-2011-pepper/source/ gameengine/Converter: BGE Animations: BGEDeformVerts() now handles normals instead of relying on BL_MeshDeformer::RecalcNormals() , which BlenderDeformVerts() still uses.

Mitchell Stokes mogurijin at gmail.com
Tue Aug 2 01:02:11 CEST 2011


Revision: 38905
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=38905
Author:   moguri
Date:     2011-08-01 23:02:10 +0000 (Mon, 01 Aug 2011)
Log Message:
-----------
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).

Modified Paths:
--------------
    branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp
    branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.h

Modified: branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp
===================================================================
--- branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp	2011-08-01 20:56:53 UTC (rev 38904)
+++ branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.cpp	2011-08-01 23:02:10 UTC (rev 38905)
@@ -80,6 +80,7 @@
 							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 @@
 		//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 @@
 				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 @@
 		
 	// 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 @@
 
 	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 @@
 					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 @@
 		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 @@
 		
 			/* 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 @@
 				BlenderDeformVerts();
 		}
 
-#ifdef __NLA_DEFNORMALS
-		if (m_recalcNormal)
-			RecalcNormals();
-#endif
-
 		/* Update the current frame */
 		m_lastArmaUpdate=m_armobj->GetLastFrame();
 

Modified: branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.h
===================================================================
--- branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.h	2011-08-01 20:56:53 UTC (rev 38904)
+++ branches/soc-2011-pepper/source/gameengine/Converter/BL_SkinDeformer.h	2011-08-01 23:02:10 UTC (rev 38905)
@@ -109,6 +109,7 @@
 	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();




More information about the Bf-blender-cvs mailing list