Quellcode durchsuchen

Skeleton serialization code

BearishSun vor 9 Jahren
Ursprung
Commit
df9c14373e

+ 1 - 0
Source/BansheeCore/CMakeSources.cmake

@@ -339,6 +339,7 @@ set(BS_BANSHEECORE_INC_RTTI
 	"Include/BsCAudioListenerRTTI.h"
 	"Include/BsAnimationClipRTTI.h"
 	"Include/BsAnimationCurveRTTI.h"
+	"Include/BsSkeletonRTTI.h"
 )
 
 set(BS_BANSHEECORE_SRC_RENDERER

+ 4 - 1
Source/BansheeCore/Include/BsCorePrerequisites.h

@@ -362,6 +362,7 @@ namespace BansheeEngine
 	class AnimationClip;
 	template <class T> class TAnimationCurve;
 	struct AnimationCurves;
+	class Skeleton;
 	// Asset import
 	class SpecificImporter;
 	class Importer;
@@ -516,7 +517,9 @@ namespace BansheeEngine
 		TID_AnimationClip = 1115,
 		TID_AnimationCurve = 1116,
 		TID_KeyFrame = 1117,
-		TID_NamedAnimationCurve = 1118
+		TID_NamedAnimationCurve = 1118,
+		TID_Skeleton = 1119,
+		TID_SkeletonBoneInfo = 1120
 	};
 }
 

+ 28 - 8
Source/BansheeCore/Include/BsSkeleton.h

@@ -3,6 +3,7 @@
 #pragma once
 
 #include "BsCorePrerequisites.h"
+#include "BsIReflectable.h"
 #include "BsMatrix4.h"
 
 namespace BansheeEngine
@@ -43,25 +44,44 @@ namespace BansheeEngine
 		UINT32 numBones;
 	};
 
-	class Skeleton // Note: Must be immutable in order to be usable on multiple threads
+	struct SkeletonBoneInfo
+	{
+		String name;
+		UINT32 parent;
+	};
+
+	class BS_CORE_EXPORT Skeleton : public IReflectable // Note: Must be immutable in order to be usable on multiple threads
 	{
 	public:
-		Skeleton(BONE_DESC* bones, UINT32 numBones);
 		~Skeleton();
 
 		void getPose(SkeletonPose& pose, const AnimationClip& clip, float time, bool loop = true);
 		void getPose(SkeletonPose& pose, const ANIMATION_STATE_DESC* states, UINT32 numStates, float time);
 
+		static SPtr<Skeleton> create(BONE_DESC* bones, UINT32 numBones);
+
 	private:
-		struct BoneInfo
-		{
-			String name;
-			UINT32 parent;
-		};
+		Skeleton();
+		Skeleton(BONE_DESC* bones, UINT32 numBones);
 
 		UINT32 mNumBones;
 		Matrix4* mBindPoses;
-		BoneInfo* mBoneInfo;
+		SkeletonBoneInfo* mBoneInfo;
+
+		/************************************************************************/
+		/* 								SERIALIZATION                      		*/
+		/************************************************************************/
+	public:
+		friend class SkeletonRTTI;
+		static RTTITypeBase* getRTTIStatic();
+		RTTITypeBase* getRTTI() const override;
+
+		/** 
+		 * Creates a Skeleton with no data. You must populate its data manually.
+		 *
+		 * @note	For serialization use only.
+		 */
+		static SPtr<Skeleton> createEmpty();
 	};
 
 	/** @} */

+ 112 - 0
Source/BansheeCore/Include/BsSkeletonRTTI.h

@@ -0,0 +1,112 @@
+//********************************** Banshee Engine (www.banshee3d.com) **************************************************//
+//**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
+#pragma once
+
+#include "BsCorePrerequisites.h"
+#include "BsRTTIType.h"
+#include "BsSkeleton.h"
+
+namespace BansheeEngine
+{
+	/** @cond RTTI */
+	/** @addtogroup RTTI-Impl-Core
+	 *  @{
+	 */
+
+	class BS_CORE_EXPORT SkeletonRTTI : public RTTIType <Skeleton, IReflectable, SkeletonRTTI>
+	{
+	private:
+		Matrix4& getBindPose(Skeleton* obj, UINT32 idx) { return obj->mBindPoses[idx]; }
+		void setBindPose(Skeleton* obj, UINT32 idx, Matrix4& value) { obj->mBindPoses[idx] = value; }
+
+		void setNumBindPoses(Skeleton* obj, UINT32 size)
+		{
+			obj->mNumBones = size;
+			
+			assert(obj->mBindPoses == nullptr);
+			obj->mBindPoses = bs_newN<Matrix4>(size);
+		}
+
+		SkeletonBoneInfo& getBoneInfo(Skeleton* obj, UINT32 idx) { return obj->mBoneInfo[idx]; }
+		void setBoneInfo(Skeleton* obj, UINT32 idx, SkeletonBoneInfo& value) { obj->mBoneInfo[idx] = value; }
+
+		void setNumBoneInfos(Skeleton* obj, UINT32 size)
+		{
+			obj->mNumBones = size;
+
+			assert(obj->mBoneInfo == nullptr);
+			obj->mBoneInfo = bs_newN<SkeletonBoneInfo>(size);
+		}
+
+		UINT32 getNumBones(Skeleton* obj) { return obj->mNumBones; }
+	public:
+		SkeletonRTTI()
+		{
+			addPlainArrayField("bindPoses", 0, &SkeletonRTTI::getBindPose, &SkeletonRTTI::getNumBones,
+				&SkeletonRTTI::setBindPose, &SkeletonRTTI::setNumBindPoses);
+			addPlainArrayField("boneInfo", 1, &SkeletonRTTI::getBoneInfo, &SkeletonRTTI::getNumBones,
+				&SkeletonRTTI::setBoneInfo, &SkeletonRTTI::setNumBoneInfos);
+		}
+
+		const String& getRTTIName() override
+		{
+			static String name = "Skeleton";
+			return name;
+		}
+
+		UINT32 getRTTIId() override
+		{
+			return TID_Skeleton;
+		}
+
+		SPtr<IReflectable> newRTTIObject() override
+		{
+			return Skeleton::createEmpty();
+		}
+	};
+
+	template<> struct RTTIPlainType<SkeletonBoneInfo>
+	{
+		enum { id = TID_SkeletonBoneInfo }; enum { hasDynamicSize = 1 };
+
+		/** @copydoc RTTIPlainType::toMemory */
+		static void toMemory(const SkeletonBoneInfo& data, char* memory)
+		{
+			UINT32 size = sizeof(UINT32);
+			char* memoryStart = memory;
+			memory += sizeof(UINT32);
+
+			memory = rttiWriteElem(data.name, memory, size);
+			memory = rttiWriteElem(data.parent, memory, size);
+
+			memcpy(memoryStart, &size, sizeof(UINT32));
+		}
+
+		/** @copydoc RTTIPlainType::fromMemory */
+		static UINT32 fromMemory(SkeletonBoneInfo& data, char* memory)
+		{
+			UINT32 size = 0;
+			memory = rttiReadElem(size, memory);
+
+			memory = rttiReadElem(data.name, memory);
+			memory = rttiReadElem(data.parent, memory);
+
+			return size;
+		}
+
+		/** @copydoc RTTIPlainType::getDynamicSize */
+		static UINT32 getDynamicSize(const SkeletonBoneInfo& data)
+		{
+			UINT64 dataSize = sizeof(UINT32);
+			dataSize += rttiGetElemSize(data.name);
+			dataSize += rttiGetElemSize(data.parent);
+
+			assert(dataSize <= std::numeric_limits<UINT32>::max());
+
+			return (UINT32)dataSize;
+		}
+	};
+
+	/** @} */
+	/** @endcond */
+}

+ 36 - 3
Source/BansheeCore/Source/BsSkeleton.cpp

@@ -1,11 +1,16 @@
 //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
 //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
 #include "BsSkeleton.h"
+#include "BsSkeletonRTTI.h"
 
 namespace BansheeEngine
 {
+	Skeleton::Skeleton()
+		:mBindPoses(nullptr), mBoneInfo(nullptr), mNumBones(0)
+	{ }
+
 	Skeleton::Skeleton(BONE_DESC* bones, UINT32 numBones)
-		:mBindPoses(bs_newN<Matrix4>(numBones)), mBoneInfo(bs_newN<BoneInfo>(numBones)), mNumBones(numBones)
+		:mBindPoses(bs_newN<Matrix4>(numBones)), mBoneInfo(bs_newN<SkeletonBoneInfo>(numBones)), mNumBones(numBones)
 	{
 		for(UINT32 i = 0; i < numBones; i++)
 		{
@@ -17,8 +22,18 @@ namespace BansheeEngine
 
 	Skeleton::~Skeleton()
 	{
-		bs_deleteN(mBindPoses, mNumBones);
-		bs_deleteN(mBoneInfo, mNumBones);
+		if(mBindPoses != nullptr)
+			bs_deleteN(mBindPoses, mNumBones);
+
+		if (mBoneInfo != nullptr)
+			bs_deleteN(mBoneInfo, mNumBones);
+	}
+
+	SPtr<Skeleton> Skeleton::create(BONE_DESC* bones, UINT32 numBones)
+	{
+		Skeleton* rawPtr = new (bs_alloc<Skeleton>()) Skeleton(bones, numBones);
+
+		return bs_shared_ptr<Skeleton>(rawPtr);
 	}
 
 	void Skeleton::getPose(SkeletonPose& pose, const AnimationClip& clip, float time, bool loop)
@@ -39,4 +54,22 @@ namespace BansheeEngine
 
 		// TODO
 	}
+
+	SPtr<Skeleton> Skeleton::createEmpty()
+	{
+		Skeleton* rawPtr = new (bs_alloc<Skeleton>()) Skeleton();
+
+		SPtr<Skeleton> newSkeleton = bs_shared_ptr<Skeleton>(rawPtr);
+		return newSkeleton;
+	}
+
+	RTTITypeBase* Skeleton::getRTTIStatic()
+	{
+		return SkeletonRTTI::instance();
+	}
+
+	RTTITypeBase* Skeleton::getRTTI() const
+	{
+		return getRTTIStatic();
+	}
 }