Patch to support texture loading for .MS3D files

You discovered a bug in the engine, and you are sure that it is not a problem of your code? Just post it in here. Please read the bug posting guidelines first.
Post Reply
atomice
Posts: 1
Joined: Tue Mar 23, 2004 4:05 pm

Patch to support texture loading for .MS3D files

Post 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;
Robomaniac
Posts: 602
Joined: Sat Aug 23, 2003 2:03 am
Location: Pottstown, PA
Contact:

Post by Robomaniac »

This would be perfect for the TPIM site.

Talk to saigumi about getting it up there
The Robomaniac
Project Head / Lead Programmer
Centaur Force
Homer
Posts: 58
Joined: Tue Nov 18, 2003 7:11 pm
Location: Germany

Post 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.
colin

Post by colin »

that seems like it would take a long time to cut and paste, can any of you upload the file?

thanks
Andi|xng
Posts: 83
Joined: Thu Mar 24, 2005 10:49 pm
Location: Schrobenhausen, Germany
Contact:

Post 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 :)
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

Yep, sorry. Thanks for posting this, going to add it. :)
hybrid

Post 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).
niko
Site Admin
Posts: 1759
Joined: Fri Aug 22, 2003 4:44 am
Location: Vienna, Austria
Contact:

Post by niko »

Cool, thanks for your work :)
Post Reply