[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15760] trunk/blender/source/gameengine: BGE patch: approve patch #17312: Multiple material IPOs per mesh in BGE.

Benoit Bolsee benoit.bolsee at online.be
Fri Jul 25 15:45:57 CEST 2008


Revision: 15760
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15760
Author:   ben2610
Date:     2008-07-25 15:45:57 +0200 (Fri, 25 Jul 2008)

Log Message:
-----------
BGE patch: approve patch #17312: Multiple material IPOs per mesh in BGE.

Modified Paths:
--------------
    trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    trunk/blender/source/gameengine/Converter/KX_IpoConvert.cpp
    trunk/blender/source/gameengine/Converter/KX_IpoConvert.h
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
    trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
    trunk/blender/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
    trunk/blender/source/gameengine/Ketsji/KX_MaterialIpoController.h
    trunk/blender/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
    trunk/blender/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
    trunk/blender/source/gameengine/Rasterizer/RAS_MeshObject.cpp
    trunk/blender/source/gameengine/Rasterizer/RAS_MeshObject.h

Modified: trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2008-07-25 10:55:10 UTC (rev 15759)
+++ trunk/blender/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2008-07-25 13:45:57 UTC (rev 15760)
@@ -1989,10 +1989,8 @@
 			gameobj->NodeUpdateGS(0,true);
 			
 			BL_ConvertIpos(blenderobject,gameobj,converter);
-			// TODO: expand to multiple ipos per mesh
-			Material *mat = give_current_material(blenderobject, 1);
-			if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);	
-	
+			BL_ConvertMaterialIpos(blenderobject, gameobj, converter);
+			
 			sumolist->Add(gameobj->AddRef());
 			
 			BL_ConvertProperties(blenderobject,gameobj,timemgr,kxscene,isInActiveLayer);
@@ -2171,9 +2169,7 @@
 							gameobj->NodeUpdateGS(0,true);
 							
 							BL_ConvertIpos(blenderobject,gameobj,converter);
-							// TODO: expand to multiple ipos per mesh
-							Material *mat = give_current_material(blenderobject, 1);
-							if(mat) BL_ConvertMaterialIpos(mat, gameobj, converter);	
+							BL_ConvertMaterialIpos(blenderobject,gameobj, converter);	
 					
 							sumolist->Add(gameobj->AddRef());
 							

Modified: trunk/blender/source/gameengine/Converter/KX_IpoConvert.cpp
===================================================================
--- trunk/blender/source/gameengine/Converter/KX_IpoConvert.cpp	2008-07-25 10:55:10 UTC (rev 15759)
+++ trunk/blender/source/gameengine/Converter/KX_IpoConvert.cpp	2008-07-25 13:45:57 UTC (rev 15760)
@@ -36,6 +36,7 @@
 #pragma warning (disable:4786)
 #endif
 
+#include "BKE_material.h" /* give_current_material */
 
 #include "KX_GameObject.h"
 #include "KX_IpoConvert.h"
@@ -68,6 +69,8 @@
 
 #include "SG_Node.h"
 
+#include "STR_HashedString.h"
+
 static BL_InterpolatorList *GetIpoList(struct Ipo *for_ipo, KX_BlenderSceneConverter *converter) {
 	BL_InterpolatorList *ipoList= converter->FindInterpolatorList(for_ipo);
 
@@ -560,16 +563,15 @@
 	}
 }
 
-
-void BL_ConvertMaterialIpos(
-	Material* blendermaterial, 
+static void ConvertMaterialIpos(
+	Material* blendermaterial,
+	dword matname_hash,
 	KX_GameObject* gameobj,  
 	KX_BlenderSceneConverter *converter
 	)
 {
 	if (blendermaterial->ipo) {
-	
-		KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController();
+		KX_MaterialIpoController* ipocontr = new KX_MaterialIpoController(matname_hash);
 		gameobj->GetSGNode()->AddSGController(ipocontr);
 		ipocontr->SetObject(gameobj->GetSGNode());
 		
@@ -596,7 +598,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_COL_R);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -610,7 +612,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_COL_G);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -624,7 +626,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_COL_B);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -638,7 +640,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_ALPHA);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -653,7 +655,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_SPEC_R );
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -667,7 +669,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_SPEC_G);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -681,7 +683,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_SPEC_B);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -696,7 +698,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_HARD);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -710,7 +712,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_SPEC);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -725,7 +727,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_REF);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -739,7 +741,7 @@
 		ipo = ipoList->GetScalarInterpolator(MA_EMIT);
 		if (ipo) {
 			if (!ipocontr) {
-				ipocontr = new KX_MaterialIpoController();
+				ipocontr = new KX_MaterialIpoController(matname_hash);
 				gameobj->GetSGNode()->AddSGController(ipocontr);
 				ipocontr->SetObject(gameobj->GetSGNode());
 			}
@@ -752,3 +754,28 @@
 	}		
 }
 
+void BL_ConvertMaterialIpos(
+	struct Object* blenderobject,
+	KX_GameObject* gameobj,  
+	KX_BlenderSceneConverter *converter
+	)
+{
+	if (blenderobject->totcol==1)
+	{
+		Material *mat = give_current_material(blenderobject, 1);
+		// if there is only one material attached to the mesh then set material_index in BL_ConvertMaterialIpos to NULL
+		// --> this makes the UpdateMaterialData function in KX_GameObject.cpp use the old hack of using SetObjectColor
+		// because this yields a better performance as not all the vertex colors need to be edited
+		if(mat) ConvertMaterialIpos(mat, NULL, gameobj, converter);
+	}
+	else
+	{
+		for (int material_index=1; material_index <= blenderobject->totcol; material_index++)
+		{
+			Material *mat = give_current_material(blenderobject, material_index);
+			STR_HashedString matname = mat->id.name;
+			if(mat) ConvertMaterialIpos(mat, matname.hash(), gameobj, converter);
+		}
+	}
+}
+

Modified: trunk/blender/source/gameengine/Converter/KX_IpoConvert.h
===================================================================
--- trunk/blender/source/gameengine/Converter/KX_IpoConvert.h	2008-07-25 10:55:10 UTC (rev 15759)
+++ trunk/blender/source/gameengine/Converter/KX_IpoConvert.h	2008-07-25 13:45:57 UTC (rev 15760)
@@ -46,7 +46,7 @@
 	class KX_GameObject* cameraobj, 
 	class KX_BlenderSceneConverter *converter);
 
-void BL_ConvertMaterialIpos(struct Material* blendermaterial,
+void BL_ConvertMaterialIpos(struct Object* blenderobject,
 	class KX_GameObject* materialobj, 
 	class KX_BlenderSceneConverter *converter);
 

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2008-07-25 10:55:10 UTC (rev 15759)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.cpp	2008-07-25 13:45:57 UTC (rev 15760)
@@ -442,6 +442,7 @@
 // IPO update
 void 
 KX_GameObject::UpdateMaterialData(
+		dword matname_hash,
 		MT_Vector4 rgba,
 		MT_Vector3 specrgb,
 		MT_Scalar hard,
@@ -460,9 +461,26 @@
 			RAS_IPolyMaterial* poly = (*mit)->GetPolyMaterial();
 			if(poly->GetFlag() & RAS_BLENDERMAT )
 			{
-				SetObjectColor(rgba);
 				KX_BlenderMaterial *m =  static_cast<KX_BlenderMaterial*>(poly);
-				m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+				
+				if (matname_hash == NULL)
+				{
+					m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+					// if mesh has only one material attached to it then use original hack with no need to edit vertices (better performance)
+					SetObjectColor(rgba);
+				}
+				else
+				{
+					if (matname_hash == poly->GetMaterialNameHash())
+					{
+						m->UpdateIPO(rgba, specrgb,hard,spec,ref,emit, alpha);
+						m_meshes[mesh]->SetVertexColor(poly,rgba);
+						
+						// no break here, because one blender material can be split into several game engine materials
+						// (e.g. one uvsphere material is split into one material at poles with ras_mode TRIANGLE and one material for the body
+						// if here was a break then would miss some vertices if material was split
+					}
+				}
 			}
 		}
 	}

Modified: trunk/blender/source/gameengine/Ketsji/KX_GameObject.h
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_GameObject.h	2008-07-25 10:55:10 UTC (rev 15759)
+++ trunk/blender/source/gameengine/Ketsji/KX_GameObject.h	2008-07-25 13:45:57 UTC (rev 15760)
@@ -521,6 +521,7 @@
 	 */
 		void 
 	UpdateMaterialData(
+		dword matname_hash,
 		MT_Vector4 rgba,
 		MT_Vector3 specrgb,
 		MT_Scalar hard,

Modified: trunk/blender/source/gameengine/Ketsji/KX_MaterialIpoController.cpp
===================================================================
--- trunk/blender/source/gameengine/Ketsji/KX_MaterialIpoController.cpp	2008-07-25 10:55:10 UTC (rev 15759)
+++ trunk/blender/source/gameengine/Ketsji/KX_MaterialIpoController.cpp	2008-07-25 13:45:57 UTC (rev 15760)
@@ -37,6 +37,7 @@
 
 		//kxgameobj->SetObjectColor(m_rgba);
 		kxgameobj->UpdateMaterialData( 
+			m_matname_hash,
 			m_rgba, 
 			m_specrgb, 
 			m_hard, 

Modified: trunk/blender/source/gameengine/Ketsji/KX_MaterialIpoController.h
===================================================================

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list