浏览代码

Mesh save/load works

Marko Pintera 13 年之前
父节点
当前提交
bc4b1b0d9a

+ 1 - 1
CamelotRenderer/Include/CmMeshData.h

@@ -39,7 +39,7 @@ namespace CamelotEngine
 			/* 								SERIALIZATION                      		*/
 			/* 								SERIALIZATION                      		*/
 			/************************************************************************/
 			/************************************************************************/
 		public:
 		public:
-			friend class VertexDataST;
+			friend class VertexDataRTTI;
 			static RTTITypeBase* getRTTIStatic();
 			static RTTITypeBase* getRTTIStatic();
 			virtual RTTITypeBase* getRTTI() const;
 			virtual RTTITypeBase* getRTTI() const;
 		};
 		};

+ 34 - 20
CamelotRenderer/Include/CmMeshDataRTTI.h

@@ -7,32 +7,45 @@
 
 
 namespace CamelotEngine
 namespace CamelotEngine
 {
 {
-	class CM_EXPORT VertexDataST : public RTTIType<MeshData::VertexData, IReflectable, VertexDataST>
+	class CM_EXPORT VertexDataRTTI : public RTTIType<MeshData::VertexData, IReflectable, VertexDataRTTI>
 	{
 	{
 	private:
 	private:
-		CM_SETGET_DATABLOCK_MEMBER(vertex, vertexCount, Vector3, MeshData::VertexData)
-		CM_SETGET_DATABLOCK_MEMBER(color, vertexCount, Color, MeshData::VertexData)
-		CM_SETGET_DATABLOCK_MEMBER(normal, vertexCount, Vector3, MeshData::VertexData)
-		CM_SETGET_DATABLOCK_MEMBER(tangent, vertexCount, Vector3, MeshData::VertexData)
-		CM_SETGET_DATABLOCK_MEMBER(bitangent, vertexCount, Vector3, MeshData::VertexData)
-		CM_SETGET_DATABLOCK_MEMBER(uv0, vertexCount, Vector2, MeshData::VertexData)
-		CM_SETGET_DATABLOCK_MEMBER(uv1, vertexCount, Vector2, MeshData::VertexData)
+		ManagedDataBlock getVertex(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->vertex, obj->vertexCount * sizeof(Vector3), false); }	
+		void setVertex(MeshData::VertexData* obj, ManagedDataBlock val) { obj->vertex = (Vector3*)val.getData(); } 
+
+		ManagedDataBlock getColor(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->color, obj->vertexCount * sizeof(Color), false); }	
+		void setColor(MeshData::VertexData* obj, ManagedDataBlock val) { obj->color = (Color*)val.getData(); } 
+
+		ManagedDataBlock getNormal(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->normal, obj->vertexCount * sizeof(Vector3), false); }	
+		void setNormal(MeshData::VertexData* obj, ManagedDataBlock val) { obj->normal = (Vector3*)val.getData(); } 
+
+		ManagedDataBlock getTangent(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->tangent, obj->vertexCount * sizeof(Vector3), false); }	
+		void setTangent(MeshData::VertexData* obj, ManagedDataBlock val) { obj->tangent = (Vector3*)val.getData(); } 
+
+		ManagedDataBlock getBitangent(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->bitangent, obj->vertexCount * sizeof(Vector3), false); }	
+		void setBitangent(MeshData::VertexData* obj, ManagedDataBlock val) { obj->bitangent = (Vector3*)val.getData(); } 
+
+		ManagedDataBlock getUV0(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->uv0, obj->vertexCount * sizeof(Vector2), false); }	
+		void setUV0(MeshData::VertexData* obj, ManagedDataBlock val) { obj->uv0 = (Vector2*)val.getData(); } 
+
+		ManagedDataBlock getUV1(MeshData::VertexData* obj) { return ManagedDataBlock((UINT8*)obj->uv1, obj->vertexCount * sizeof(Vector2), false); }	
+		void setUV1(MeshData::VertexData* obj, ManagedDataBlock val) { obj->uv1 = (Vector2*)val.getData(); } 
 
 
 		CM_SETGET_MEMBER(vertexCount, UINT32, MeshData::VertexData);
 		CM_SETGET_MEMBER(vertexCount, UINT32, MeshData::VertexData);
 		CM_SETGET_MEMBER(streamIdx, UINT32, MeshData::VertexData);
 		CM_SETGET_MEMBER(streamIdx, UINT32, MeshData::VertexData);
 	public:
 	public:
-		VertexDataST()
+		VertexDataRTTI()
 		{
 		{
-			CM_ADD_DATABLOCKFIELD(vertex, 0, VertexDataST)
-			CM_ADD_DATABLOCKFIELD(color, 1, VertexDataST)
-			CM_ADD_DATABLOCKFIELD(normal, 2, VertexDataST)
-			CM_ADD_DATABLOCKFIELD(tangent, 3, VertexDataST)
-			CM_ADD_DATABLOCKFIELD(bitangent, 4, VertexDataST)
-			CM_ADD_DATABLOCKFIELD(uv0, 5, VertexDataST)
-			CM_ADD_DATABLOCKFIELD(uv1, 6, VertexDataST)
+			addDataBlockField("vertex", 0, &VertexDataRTTI::getVertex, &VertexDataRTTI::setVertex);
+			addDataBlockField("color", 1, &VertexDataRTTI::getColor, &VertexDataRTTI::setColor);
+			addDataBlockField("normal", 2, &VertexDataRTTI::getNormal, &VertexDataRTTI::setNormal);
+			addDataBlockField("tangent", 3, &VertexDataRTTI::getTangent, &VertexDataRTTI::setTangent);
+			addDataBlockField("bitangent", 4, &VertexDataRTTI::getBitangent, &VertexDataRTTI::setBitangent);
+			addDataBlockField("uv0", 5, &VertexDataRTTI::getUV0, &VertexDataRTTI::setUV0);
+			addDataBlockField("uv1", 6, &VertexDataRTTI::getUV1, &VertexDataRTTI::setUV1);
 
 
-			CM_ADD_PLAINFIELD(vertexCount, 7, VertexDataST)
-			CM_ADD_PLAINFIELD(streamIdx, 8, VertexDataST)
+			CM_ADD_PLAINFIELD(vertexCount, 7, VertexDataRTTI)
+			CM_ADD_PLAINFIELD(streamIdx, 8, VertexDataRTTI)
 		}
 		}
 
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 
@@ -58,7 +71,8 @@ namespace CamelotEngine
 		CM_SETGET_MEMBER(indexCount, INT32, MeshData)
 		CM_SETGET_MEMBER(indexCount, INT32, MeshData)
 		CM_SETGET_MEMBER(vertexCount, INT32, MeshData);
 		CM_SETGET_MEMBER(vertexCount, INT32, MeshData);
 
 
-		CM_SETGET_DATABLOCK_MEMBER(index, indexCount, int, MeshData)
+		ManagedDataBlock getIndex(MeshData* obj) { return ManagedDataBlock((UINT8*)obj->index, obj->indexCount * sizeof(int), false); }	
+		void setIndex(MeshData* obj, ManagedDataBlock val) { obj->index = (int*)val.getData(); } 
 
 
 		/************************************************************************/
 		/************************************************************************/
 		/* 								subMeshes                      			*/
 		/* 								subMeshes                      			*/
@@ -124,7 +138,7 @@ namespace CamelotEngine
 	public:
 	public:
 		MeshDataRTTI()
 		MeshDataRTTI()
 		{
 		{
-			CM_ADD_DATABLOCKFIELD(index, 0, MeshDataRTTI)
+			addDataBlockField("index", 0, &MeshDataRTTI::getIndex, &MeshDataRTTI::setIndex);
 
 
 			CM_ADD_PLAINFIELD(indexCount, 1, MeshDataRTTI)
 			CM_ADD_PLAINFIELD(indexCount, 1, MeshDataRTTI)
 			CM_ADD_PLAINFIELD(vertexCount, 2, MeshDataRTTI)
 			CM_ADD_PLAINFIELD(vertexCount, 2, MeshDataRTTI)

+ 7 - 2
CamelotRenderer/Source/CmApplication.cpp

@@ -46,7 +46,7 @@ namespace CamelotEngine
 		mCamera = mCameraGO->addComponent<Camera>();
 		mCamera = mCameraGO->addComponent<Camera>();
 
 
 		mCamera->init(mRenderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
 		mCamera->init(mRenderWindow, 0.0f, 0.0f, 1.0f, 1.0f, 0);
-		mCameraGO->setPosition(Vector3(0,50,240));
+		mCameraGO->setPosition(Vector3(0,50,1240));
 		mCameraGO->lookAt(Vector3(0,50,-300));
 		mCameraGO->lookAt(Vector3(0,50,-300));
 		mCamera->setNearClipDistance(5);
 		mCamera->setNearClipDistance(5);
 		mCamera->setAspectRatio(800.0f / 600.0f);
 		mCamera->setAspectRatio(800.0f / 600.0f);
@@ -153,12 +153,17 @@ namespace CamelotEngine
 
 
 		//mDbgTexture = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
 		//mDbgTexture = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
 		TexturePtr testTex = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
 		TexturePtr testTex = std::static_pointer_cast<Texture>(Importer::instance().import("C:\\ImportTest.tga"));
-		mDbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\BarrelMesh.fbx"));
+		mDbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\X_Arena_Tower.FBX"));
+		//mDbgMesh = std::static_pointer_cast<Mesh>(Importer::instance().import("C:\\TestFBX.fbx"));
 
 
 		Resources::startUp(new Resources());
 		Resources::startUp(new Resources());
 
 
 		gResources().save(testTex, "C:\\ExportTest.tex");
 		gResources().save(testTex, "C:\\ExportTest.tex");
+		gResources().save(mDbgMesh, "C:\\ExportMesh.mesh");
+
 		mDbgTexture = std::static_pointer_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
 		mDbgTexture = std::static_pointer_cast<Texture>(gResources().load("C:\\ExportTest.tex"));
+		mDbgMesh = std::static_pointer_cast<Mesh>(gResources().load("C:\\ExportMesh.mesh"));
+
 		mDbgTexture = testTex;
 		mDbgTexture = testTex;
 	}
 	}
 
 

+ 9 - 9
CamelotRenderer/Source/CmMesh.cpp

@@ -51,7 +51,7 @@ namespace CamelotEngine
 			UINT16* idxData = static_cast<UINT16*>(mIndexData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
 			UINT16* idxData = static_cast<UINT16*>(mIndexData->indexBuffer->lock(HardwareBuffer::HBL_READ_ONLY));
 
 
 			for(UINT32 i = 0; i < mIndexData->indexCount; i++)
 			for(UINT32 i = 0; i < mIndexData->indexCount; i++)
-				mMeshData->index[i] = (UINT32)idxData[i];
+				meshData->index[i] = (UINT32)idxData[i];
 
 
 			mIndexData->indexBuffer->unlock();
 			mIndexData->indexBuffer->unlock();
 		}
 		}
@@ -85,39 +85,39 @@ namespace CamelotEngine
 					switch(semantic)
 					switch(semantic)
 					{
 					{
 					case VES_POSITION:
 					case VES_POSITION:
-						vertexData->vertex = new Vector3[mMeshData->vertexCount];
+						vertexData->vertex = new Vector3[meshData->vertexCount];
 						dest = (UINT8*)vertexData->vertex;
 						dest = (UINT8*)vertexData->vertex;
 
 
 						break;
 						break;
 					case VES_DIFFUSE:
 					case VES_DIFFUSE:
-						vertexData->color = new Color[mMeshData->vertexCount];
+						vertexData->color = new Color[meshData->vertexCount];
 						dest = (UINT8*)vertexData->color;
 						dest = (UINT8*)vertexData->color;
 
 
 						break;
 						break;
 					case VES_NORMAL:
 					case VES_NORMAL:
-						vertexData->normal = new Vector3[mMeshData->vertexCount];
+						vertexData->normal = new Vector3[meshData->vertexCount];
 						dest = (UINT8*)vertexData->normal;	
 						dest = (UINT8*)vertexData->normal;	
 
 
 						break;
 						break;
 					case VES_TANGENT:
 					case VES_TANGENT:
-						vertexData->tangent = new Vector3[mMeshData->vertexCount];
+						vertexData->tangent = new Vector3[meshData->vertexCount];
 						dest = (UINT8*)vertexData->tangent;	
 						dest = (UINT8*)vertexData->tangent;	
 
 
 						break;
 						break;
 					case VES_BITANGENT:
 					case VES_BITANGENT:
-						vertexData->bitangent = new Vector3[mMeshData->vertexCount];
+						vertexData->bitangent = new Vector3[meshData->vertexCount];
 						dest = (UINT8*)vertexData->bitangent;	
 						dest = (UINT8*)vertexData->bitangent;	
 
 
 						break;
 						break;
 					case VES_TEXTURE_COORDINATES:
 					case VES_TEXTURE_COORDINATES:
 						if(element->getIndex() == 0)
 						if(element->getIndex() == 0)
 						{
 						{
-							vertexData->uv0 = new Vector2[mMeshData->vertexCount];
+							vertexData->uv0 = new Vector2[meshData->vertexCount];
 							dest = (UINT8*)vertexData->uv0;	
 							dest = (UINT8*)vertexData->uv0;	
 						}
 						}
 						else if(element->getIndex() == 1)
 						else if(element->getIndex() == 1)
 						{
 						{
-							vertexData->uv1 = new Vector2[mMeshData->vertexCount];
+							vertexData->uv1 = new Vector2[meshData->vertexCount];
 							dest = (UINT8*)vertexData->uv1;	
 							dest = (UINT8*)vertexData->uv1;	
 						}
 						}
 
 
@@ -139,7 +139,7 @@ namespace CamelotEngine
 			}
 			}
 		}		
 		}		
 
 
-		return nullptr;
+		return meshData;
 	}
 	}
 
 
 	RenderOperation Mesh::getRenderOperation(UINT32 subMeshIdx) const
 	RenderOperation Mesh::getRenderOperation(UINT32 subMeshIdx) const

+ 1 - 1
CamelotRenderer/Source/CmMeshData.cpp

@@ -39,7 +39,7 @@ namespace CamelotEngine
 
 
 	RTTITypeBase* MeshData::VertexData::getRTTIStatic()
 	RTTITypeBase* MeshData::VertexData::getRTTIStatic()
 	{
 	{
-		return VertexDataST::instance();
+		return VertexDataRTTI::instance();
 	}
 	}
 
 
 	RTTITypeBase* MeshData::VertexData::getRTTI() const
 	RTTITypeBase* MeshData::VertexData::getRTTI() const

+ 4 - 1
CamelotRenderer/Source/CmMeshRTTI.h

@@ -8,10 +8,13 @@ namespace CamelotEngine
 {
 {
 	class MeshRTTI : public RTTIType<Mesh, Resource, MeshRTTI>
 	class MeshRTTI : public RTTIType<Mesh, Resource, MeshRTTI>
 	{
 	{
+		MeshDataPtr getMeshData(Mesh* obj) { return obj->getMeshData(); }
+		void setMeshData(Mesh* obj, MeshDataPtr meshData) { obj->setMeshData(meshData); }
+
 	public:
 	public:
 		MeshRTTI()
 		MeshRTTI()
 		{
 		{
-
+			addReflectablePtrField("mMeshData", 0, &MeshRTTI::getMeshData, &MeshRTTI::setMeshData);
 		}
 		}
 
 
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 
 		virtual std::shared_ptr<IReflectable> newRTTIObject() 

+ 4 - 1
CamelotRenderer/TODO.txt

@@ -46,6 +46,10 @@ TODO:
  - OpenGL too
  - OpenGL too
 
 
 TOMORROW:
 TOMORROW:
+ - Mesh loading:
+   - GetRenderOperation doesn't consider sub-meshes
+   - FBX importer only imports the first mesh, while it should import them all
+   - Imported FBX meshes are too big
  - Remove template from RTTIType and move it to IReflectable? This way i can hopefully move GetRTTITypeStatic and GetRTTIType to IReflectable so I don't
  - Remove template from RTTIType and move it to IReflectable? This way i can hopefully move GetRTTITypeStatic and GetRTTIType to IReflectable so I don't
    need to manually implement those for every method.
    need to manually implement those for every method.
  - Are resource getting properly unloaded? e.g. when shared_ptr destroys a texture is it removed from gpu?
  - Are resource getting properly unloaded? e.g. when shared_ptr destroys a texture is it removed from gpu?
@@ -55,7 +59,6 @@ TOMORROW:
  - How do I serialize derived classes, without rewriting all the base class serialization?
  - How do I serialize derived classes, without rewriting all the base class serialization?
    - Unless something better dawns on me by Monday, just inherit from parents SerializableType and manually make sure no IDs overlap.
    - Unless something better dawns on me by Monday, just inherit from parents SerializableType and manually make sure no IDs overlap.
      - We can improve later if needed. I though about it too much for now.
      - We can improve later if needed. I though about it too much for now.
- Continue working on Importer, Resources (IMPORTANT - AssetDatabase in a single file probably won't work. Multiple people won't be able to work on it. Unless we make it part of a local cache?)
  Try to fully implement free image and maybe FBX importers
  Try to fully implement free image and maybe FBX importers
   - Less important notes:
   - Less important notes:
     - All of this must be thread safe to allow for background loading
     - All of this must be thread safe to allow for background loading

+ 1 - 1
CamelotUtility/Include/CmManagedDataBlock.h

@@ -44,7 +44,7 @@ namespace CamelotEngine
 		}
 		}
 
 
 		UINT8* getData() { return mData; }
 		UINT8* getData() { return mData; }
-		UINT32 getSize() { return mSize; }
+		UINT32 getSize() { return mData ? mSize : 0; }
 
 
 	private:
 	private:
 		UINT8* mData;
 		UINT8* mData;

+ 0 - 7
CamelotUtility/Include/CmRTTIType.h

@@ -24,16 +24,9 @@ namespace CamelotEngine
 	type##& get##name(parentType##* obj) { return obj->##name; }				\
 	type##& get##name(parentType##* obj) { return obj->##name; }				\
 	void set##name(parentType##* obj, type##& val) { obj->##name = val; } 
 	void set##name(parentType##* obj, type##& val) { obj->##name = val; } 
 
 
-#define CM_SETGET_DATABLOCK_MEMBER(name, sizeField, type, parentType)								\
-	ManagedDataBlock get##name(parentType##* obj) { return ManagedDataBlock((UINT8*)obj->##name, obj->##sizeField, false); }				\
-	void set##name(parentType##* obj, ManagedDataBlock val) { obj->##name = (##type##*)val.getData(); } 
-
 #define CM_ADD_PLAINFIELD(name, id, parentType) \
 #define CM_ADD_PLAINFIELD(name, id, parentType) \
 	addPlainField(#name, id##, &##parentType##::get##name, &##parentType##::set##name);
 	addPlainField(#name, id##, &##parentType##::get##name, &##parentType##::set##name);
 
 
-#define CM_ADD_DATABLOCKFIELD(name, id, parentType) \
-	addDataBlockField(#name, id##, &##parentType##::get##name, &##parentType##::set##name);
-
 	/**
 	/**
 	 * @brief	Provides an interface for accessing fields of a certain class.
 	 * @brief	Provides an interface for accessing fields of a certain class.
 	 * 			Data can be easily accessed by getter and setter methods.
 	 * 			Data can be easily accessed by getter and setter methods.

+ 11 - 8
CamelotUtility/Source/CmBinarySerializer.cpp

@@ -22,7 +22,7 @@
  * @param	dataPtr	Pointer to data which to copy.
  * @param	dataPtr	Pointer to data which to copy.
  * @param	size   	Size of the data to copy
  * @param	size   	Size of the data to copy
  */
  */
-#define COPY_TO_BUFFER(dataPtr, size)									\
+#define COPY_TO_BUFFER(dataIter, size)									\
 if((*bytesWritten + size##) > bufferLength)								\
 if((*bytesWritten + size##) > bufferLength)								\
 {																		\
 {																		\
 	mTotalBytesWritten += *bytesWritten;								\
 	mTotalBytesWritten += *bytesWritten;								\
@@ -31,7 +31,7 @@ if((*bytesWritten + size##) > bufferLength)								\
 	*bytesWritten = 0;													\
 	*bytesWritten = 0;													\
 }																		\
 }																		\
 																		\
 																		\
-memcpy(buffer, dataPtr##, size##);										\
+memcpy(buffer, dataIter##, size##);										\
 buffer += size##;														\
 buffer += size##;														\
 *bytesWritten += size##;
 *bytesWritten += size##;
 
 
@@ -74,15 +74,17 @@ namespace CamelotEngine
 					continue; // Already processed
 					continue; // Already processed
 
 
 				std::shared_ptr<IReflectable> curObject = iter->object;
 				std::shared_ptr<IReflectable> curObject = iter->object;
-				buffer = encodeInternal(curObject.get(), iter->objectId, buffer, bufferLength, bytesWritten, flushBufferCallback);
+				UINT32 curObjectid = iter->objectId;
+				serializedObjects.insert(curObjectid);
+				mObjectsToEncode.erase(iter);
+
+				buffer = encodeInternal(curObject.get(), curObjectid, buffer, bufferLength, bytesWritten, flushBufferCallback);
 				if(buffer == nullptr)
 				if(buffer == nullptr)
 				{
 				{
 					CM_EXCEPT(InternalErrorException, 
 					CM_EXCEPT(InternalErrorException, 
 						"Destination buffer is null or not large enough.");
 						"Destination buffer is null or not large enough.");
 				}
 				}
 
 
-				serializedObjects.insert(iter->objectId);
-				mObjectsToEncode.erase(iter);
 				foundObjectToProcess = true;
 				foundObjectToProcess = true;
 				break; // Need to start over as mObjectsToSerialize was possibly modified
 				break; // Need to start over as mObjectsToSerialize was possibly modified
 			}
 			}
@@ -128,9 +130,10 @@ namespace CamelotEngine
 		// Create initial object + all other objects that are being referenced.
 		// Create initial object + all other objects that are being referenced.
 		// Use fields to find the type of referenced object.
 		// Use fields to find the type of referenced object.
 		UINT32 bytesRead = 0;
 		UINT32 bytesRead = 0;
-		while(decodeInternal(object, data, dataLength, bytesRead))
+		UINT8* dataIter = data + bytesRead;
+		while(decodeInternal(object, dataIter, dataLength, bytesRead))
 		{
 		{
-			data += bytesRead;
+			dataIter = data + bytesRead;
 
 
 			if((bytesRead + sizeof(UINT32)) > dataLength)
 			if((bytesRead + sizeof(UINT32)) > dataLength)
 			{
 			{
@@ -140,7 +143,7 @@ namespace CamelotEngine
 
 
 			objectMetaData.objectMeta = 0;
 			objectMetaData.objectMeta = 0;
 			objectMetaData.typeId = 0;
 			objectMetaData.typeId = 0;
-			memcpy(&objectMetaData, data, sizeof(ObjectMetaData));
+			memcpy(&objectMetaData, dataIter, sizeof(ObjectMetaData));
 
 
 			objectId = 0;
 			objectId = 0;
 			objectTypeId = 0;
 			objectTypeId = 0;