Page 1 of 1

Patch to support texture loading for .MS3D files

Posted: Thu Apr 01, 2004 10:57 pm
by atomice
Not sure if this is the right place for patches but I couldn't see a "Patches" forum and none of the others seemed appropriate.
This patch causes the MS3D mesh loader to load textures along with the mesh.

Code: Select all

diff -x Makefile -x *.o -bBu3 irrlicht-0.6/source/CAnimatedMeshMS3D.cpp irrlicht/CAnimatedMeshMS3D.cpp
--- irrlicht-0.6/source/CAnimatedMeshMS3D.cpp	Sun Dec 28 08:31:04 2003
+++ irrlicht/CAnimatedMeshMS3D.cpp	Thu Apr  1 23:53:55 2004
@@ -93,9 +93,12 @@
 
 
 //! constructor
-CAnimatedMeshMS3D::CAnimatedMeshMS3D()
+CAnimatedMeshMS3D::CAnimatedMeshMS3D(video::IVideoDriver* driver) :
+	Driver(driver)
 {
 	lastCalculatedFrame = -1;
+	if (Driver)
+		Driver->grab();
 }
 
 
@@ -103,6 +106,8 @@
 //! destructor
 CAnimatedMeshMS3D::~CAnimatedMeshMS3D()
 {
+	if (Driver)
+		Driver->drop();
 }
 
 
@@ -173,19 +178,44 @@
 	//skip groups
 	for (i=0; i<numGroups; ++i)
 	{
+		Groups.push_back (SGroup ());
+		SGroup& grp = Groups[Groups.size()-1];
+
+		grp.Name = (const c8*) pPtr;
 		pPtr += 33; // name and 1 byte flags
 		u16 triangleCount = *(u16*)pPtr;
 		pPtr += sizeof(u16);
-		pPtr += sizeof(u16) * triangleCount; // triangle indices
 		
+		s32 j;
+		for (j=0;j<triangleCount;++j) {
+			grp.VertexIds.push_back (*(u16*)pPtr);
+			pPtr += sizeof (u16);
+		}
+
+		grp.MaterialIdx = *(u8*)pPtr;
 		pPtr += sizeof(c8); // material index
 	}
 	
 	// skip materials
 	u16 numMaterials = *(u16*)pPtr;
 	pPtr += sizeof(u16);
-	MS3DMaterial *materials = (MS3DMaterial*)pPtr;
-	pPtr += sizeof(MS3DMaterial) * numMaterials;
+	for (i=0; i<numMaterials; ++i)
+	{
+		MS3DMaterial *material = (MS3DMaterial*)pPtr;
+		pPtr += sizeof(MS3DMaterial);
+
+		Buffers.push_back (SMS3DMeshBuffer ());
+		SMS3DMeshBuffer& buffer = Buffers[Buffers.size()-1];
+		buffer.Material.MaterialType = video::EMT_SOLID;
+		buffer.Material.AmbientColor = video::SColorf(material->Ambient[0], material->Ambient[1], material->Ambient[2], material->Ambient[3]).toSColor ();
+		buffer.Material.DiffuseColor = video::SColorf(material->Diffuse[0], material->Diffuse[1], material->Diffuse[2], material->Diffuse[3]).toSColor ();
+		buffer.Material.EmissiveColor = video::SColorf(material->Emissive[0], material->Emissive[1], material->Emissive[2], material->Emissive[3]).toSColor ();
+		buffer.Material.SpecularColor = video::SColorf(material->Specular[0], material->Specular[1], material->Specular[2], material->Specular[3]).toSColor ();
+		buffer.Material.Shininess = material->Shininess;
+		buffer.Material.Texture1 = Driver->getTexture ((const c8 *) material->Texture);
+		buffer.BoundingBox = &BoundingBox;
+		buffer.Vertices = &AnimatedVertices;
+	}
 
 	// animation time
 	f32 framesPerSecond = *(f32*)pPtr;
@@ -321,6 +351,20 @@
 		Indices.push_back(Vertices.size()-1);
 	}
 
+	for (s32 i=0; i<Groups.size (); ++i)
+	{
+		SGroup& grp = Groups[i];
+		core::array<u16>& vertexIds = grp.VertexIds;
+		SMS3DMeshBuffer &buffer = Buffers[grp.MaterialIdx];
+		core::array<u16>& indices = buffer.Indices;
+		for (s32 j=0; j<grp.VertexIds.size (); ++j) {
+			u16 vertexId = vertexIds[j];
+			indices.push_back (vertexId * 3);
+			indices.push_back (vertexId * 3 + 1);
+			indices.push_back (vertexId * 3 + 2);
+		}
+	}
+
 	// calculate bounding box
 	if (!Vertices.empty())
 		BoundingBox.reset(Vertices[0].Pos);
@@ -475,7 +519,7 @@
 //! returns amount of mesh buffers.
 s32 CAnimatedMeshMS3D::getMeshBufferCount()
 {
-	return 1;
+	return Buffers.size();
 }
 
 
@@ -483,76 +527,7 @@
 //! returns pointer to a mesh buffer
 IMeshBuffer* CAnimatedMeshMS3D::getMeshBuffer(s32 nr)
 {
-	return this;
-}
-
-
-
-//! returns the material of this meshbuffer
-const video::SMaterial& CAnimatedMeshMS3D::getMaterial() const
-{
-	return Material;
-}
-
-
-
-//! returns the material of this meshbuffer
-video::SMaterial& CAnimatedMeshMS3D::getMaterial()
-{
-	return Material;
-}
-
-
-
-//! returns pointer to vertices
-const void* CAnimatedMeshMS3D::getVertices() const
-{
-	return AnimatedVertices.const_pointer();
-}
-
-
-//! returns pointer to vertices
-void* CAnimatedMeshMS3D::getVertices()
-{
-	return AnimatedVertices.pointer();
-}
-
-
-//! returns which type of vertex data is stored.
-video::E_VERTEX_TYPE CAnimatedMeshMS3D::getVertexType() const
-{
-	return video::EVT_STANDARD;
-}
-
-
-
-//! returns amount of vertices
-s32 CAnimatedMeshMS3D::getVertexCount() const
-{
-	return Vertices.size();
-}
-
-
-
-//! returns pointer to Indices
-const u16* CAnimatedMeshMS3D::getIndices() const
-{
-	return Indices.const_pointer();
-}
-
-
-//! returns pointer to Indices
-u16* CAnimatedMeshMS3D::getIndices()
-{
-	return Indices.pointer();
-}
-
-
-
-//! returns amount of indices
-s32 CAnimatedMeshMS3D::getIndexCount() const
-{
-	return Indices.size();
+	return &Buffers[nr];
 }
 
 
@@ -573,7 +548,8 @@
 //! sets a flag of all contained materials to a new value
 void CAnimatedMeshMS3D::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
 {
-	Material.Flags[flag] = newvalue;
+	for (s32 i=0; i < Buffers.size (); ++i)
+		Buffers[i].Material.Flags[flag] = newvalue;
 }
 
 
diff -x Makefile -x *.o -bBu3 irrlicht-0.6/source/CAnimatedMeshMS3D.h irrlicht/CAnimatedMeshMS3D.h
--- irrlicht-0.6/source/CAnimatedMeshMS3D.h	Sun Dec 28 08:31:04 2003
+++ irrlicht/CAnimatedMeshMS3D.h	Thu Apr  1 23:53:14 2004
@@ -7,7 +7,9 @@
 
 #include "IAnimatedMeshMS3D.h"
 #include "IReadFile.h"
+#include "IVideoDriver.h"
 #include "S3DVertex.h"
+#include "SMeshBuffer.h"
 #include "irrString.h"
 #include "matrix4.h"
 
@@ -16,12 +18,12 @@
 namespace scene
 {
 
-	class CAnimatedMeshMS3D : public IAnimatedMeshMS3D, IMesh, IMeshBuffer
+	class CAnimatedMeshMS3D : public IAnimatedMeshMS3D, IMesh
 	{
 	public:
 
 		//! constructor
-		CAnimatedMeshMS3D();
+		CAnimatedMeshMS3D(video::IVideoDriver* driver);
 
 		//! destructor
 		virtual ~CAnimatedMeshMS3D();
@@ -41,33 +43,6 @@
 		//! returns pointer to a mesh buffer
 		virtual IMeshBuffer* getMeshBuffer(s32 nr);
 
-		//! returns the material of this meshbuffer
-        virtual const video::SMaterial& getMaterial() const;
-
-		//! returns the material of this meshbuffer
-        virtual video::SMaterial& getMaterial();
-
-		//! returns pointer to vertices
-		virtual const void* getVertices() const; 
-
-		//! returns pointer to vertices
-		virtual void* getVertices();
-
-		//! returns which type of vertex data is stored.
-		virtual video::E_VERTEX_TYPE getVertexType() const;
-
-		//! returns amount of vertices
-		virtual s32 getVertexCount() const;
-
-		//! returns pointer to Indices
-		virtual const u16* getIndices() const;
-
-		//! returns pointer to Indices
-		virtual u16* getIndices();
-
-		//! returns amount of indices
-		virtual s32 getIndexCount() const;
-
 		//! returns an axis aligned bounding box
 		virtual const core::aabbox3d<f32>& getBoundingBox() const;
 
@@ -120,10 +95,105 @@
 			core::stringc ParentName;
 		};
 
+		struct SGroup
+		{
+			core::stringc Name;
+			core::array<u16> VertexIds;
+
+			u16 MaterialIdx;
+		};
+
+
+		//! Simple implementation of the IMeshBuffer interface with S3DVertex vertices.
+		struct SMS3DMeshBuffer : public IMeshBuffer
+		{
+			//! constructor
+			SMS3DMeshBuffer()
+			{
+				#ifdef _DEBUG
+				setDebugName("SMS3DMeshBuffer");
+				#endif
+			}
+
+			//! destructor
+			~SMS3DMeshBuffer() {};
+
+        	//! returns the material of this meshbuffer
+	        virtual const video::SMaterial& getMaterial() const
+			{
+				return Material;
+			}
+
+			//! returns the material of this meshbuffer
+	        virtual video::SMaterial& getMaterial()
+			{
+				return Material;
+			}
+
+			//! returns pointer to vertices
+			virtual const void* getVertices() const
+			{
+				return Vertices->const_pointer();
+			}
+
+			//! returns pointer to vertices
+			virtual void* getVertices()
+			{
+				return Vertices->pointer();
+			}
+
+			//! returns amount of vertices
+			virtual s32 getVertexCount() const
+			{
+				return Vertices->size();
+			}
+
+			//! returns pointer to Indices
+			virtual const u16* getIndices() const
+			{
+				return Indices.const_pointer();
+			}
+
+			//! returns pointer to Indices
+			virtual u16* getIndices()
+			{
+				return Indices.pointer();
+			}
+
+			//! returns amount of indices
+			virtual s32 getIndexCount() const
+			{
+				return Indices.size();
+			}
+
+			//! returns an axis aligned bounding box
+			virtual const core::aabbox3d<f32>& getBoundingBox() const
+			{
+				return *BoundingBox;
+			}
+
+			//! returns an axis aligned bounding box
+			virtual core::aabbox3d<f32>& getBoundingBox()
+			{
+				return *BoundingBox;
+			}
+
+			//! returns which type of vertex data is stored.
+			virtual video::E_VERTEX_TYPE getVertexType() const
+			{
+				return video::EVT_STANDARD;
+			}
+
+			video::SMaterial Material;						//! material for this meshBuffer.
+			core::array<video::S3DVertex> *Vertices;		//! Array of vertices
+			core::array<u16> Indices;	//! Array of the Indices.
+			core::aabbox3d<f32> *BoundingBox;
+		};
+
+
 		void animate(s32 frame);
 		void getKeyframeData(core::array<SKeyframe>& keys, f32 time, core::vector3df& outdata);
 
-		video::SMaterial Material;
 		core::aabbox3d<f32> BoundingBox;
 
 		core::array<video::S3DVertex> Vertices;
@@ -131,6 +201,11 @@
 		core::array<u16> Indices;
 		
 		core::array<SJoint> Joints;
+		core::array<SGroup> Groups;
+
+		core::array<SMS3DMeshBuffer> Buffers;
+
+		video::IVideoDriver* Driver;
 		
 		f32 totalTime;
 		bool HasAnimation;
diff -x Makefile -x *.o -bBu3 irrlicht-0.6/source/CDefaultMeshFormatLoader.cpp irrlicht/CDefaultMeshFormatLoader.cpp
--- irrlicht-0.6/source/CDefaultMeshFormatLoader.cpp	Fri Dec 12 19:46:52 2003
+++ irrlicht/CDefaultMeshFormatLoader.cpp	Thu Apr  1 15:48:56 2004
@@ -90,7 +90,7 @@
 	{
 		file->seek(0);
 
-		msh = new CAnimatedMeshMS3D();
+		msh = new CAnimatedMeshMS3D(Driver);
 		success = ((CAnimatedMeshMS3D*)msh)->loadFile(file);
 		if (success)
 			return msh;

Posted: Fri Apr 02, 2004 12:17 pm
by Robomaniac
This would be perfect for the TPIM site.

Talk to saigumi about getting it up there

Posted: Fri Apr 02, 2004 2:52 pm
by Homer
Thanks, this patch is great! There's just one small bug:

Code: Select all

+   for (s32 i=0; i<Groups.size (); ++i)
has to be

Code: Select all

+   for (i=0; i<Groups.size (); ++i)
Except this your code works very fine.

Posted: Tue Apr 27, 2004 2:53 am
by colin
that seems like it would take a long time to cut and paste, can any of you upload the file?

thanks

Posted: Mon Jul 18, 2005 11:41 am
by Andi|xng
As it seems, Irrlicht has still no texture loading support for MS3D?
Niko, why do you not add the code in the next Irrlicht version, if it works? That would be very great and not much work :)

Posted: Sun Jul 24, 2005 9:27 am
by niko
Yep, sorry. Thanks for posting this, going to add it. :)

Posted: Mon Jul 25, 2005 11:30 am
by hybrid
I've uploaded a working patch to http://parsys.informatik.uni-oldenburg. ... d/irrlicht. The onyl changes are three conversions from signed to unsigned int (probably those Homer mentioned, but a little different approach).

Posted: Fri Jul 29, 2005 8:48 pm
by niko
Cool, thanks for your work :)