add some functions
This commit is contained in:
		| @ -21,7 +21,201 @@ namespace LibCmo::CK2::ObjImpls { | ||||
| 		bool suc = CKBeObject::Load(chunk, file); | ||||
| 		if (!suc) return false; | ||||
|  | ||||
| 		// clear  | ||||
|  | ||||
|  | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::CleanMesh() { | ||||
| 		// clear material channel first | ||||
| 		SetMtlChannelCount(0); | ||||
| 		// then clear other | ||||
| 		SetVertexCount(0); | ||||
| 		SetMaterialSlotCount(0); | ||||
| 		SetFaceCount(0); | ||||
| 		SetLineCount(0); | ||||
| 	} | ||||
|  | ||||
| #pragma region Vertex Section | ||||
|  | ||||
| 	CKDWORD CKMesh::GetVertexCount() { | ||||
| 		return m_VertexCount; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetVertexCount(CKDWORD count) { | ||||
| 		m_VertexCount = count; | ||||
| 		m_VertexPosition.resize(count); | ||||
| 		m_VertexNormal.resize(count); | ||||
| 		m_VertexUV.resize(count); | ||||
| 		m_VertexColor.resize(count, 0xFFFFFFFF); | ||||
| 		m_VertexSpecularColor.resize(count, 0x00000000); | ||||
| 		m_VertexWeight.resize(count, 0.0f); | ||||
|  | ||||
| 		// notify mtl channels refresh its custom uv | ||||
| 		SyncVertexCountToMtlChannel(); | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VxVector3* CKMesh::GetVertexPositions() { | ||||
| 		return m_VertexPosition.data(); | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VxVector3* CKMesh::GetVertexNormals() { | ||||
| 		return m_VertexNormal.data(); | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VxVector2* CKMesh::GetVertexUVs() { | ||||
| 		return m_VertexUV.data(); | ||||
| 	} | ||||
|  | ||||
| 	CKDWORD* CKMesh::GetVertexColors() { | ||||
| 		return m_VertexColor.data(); | ||||
| 	} | ||||
|  | ||||
| 	CKDWORD* CKMesh::GetVertexSpecularColors() { | ||||
| 		return m_VertexSpecularColor.data(); | ||||
| 	} | ||||
|  | ||||
| 	float* CKMesh::GetVertexWeights() { | ||||
| 		return m_VertexWeight.data(); | ||||
| 	} | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
| #pragma region Material Slot Section | ||||
|  | ||||
| 	CKDWORD CKMesh::GetMaterialSlotCount() { | ||||
| 		return m_MtlSlotCount; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetMaterialSlotCount(CKDWORD count) { | ||||
| 		m_MtlSlotCount = count; | ||||
| 		m_MaterialSlot.resize(count, nullptr); | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetMaterialSlot(CKMaterial* mtl, CKDWORD idx) { | ||||
| 		if (idx >= m_MtlSlotCount) return; | ||||
| 		m_MaterialSlot[idx] = mtl; | ||||
| 	} | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
| #pragma region Face Section | ||||
|  | ||||
| 	CKDWORD CKMesh::GetFaceCount() { | ||||
| 		return m_FaceCount; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetFaceCount(CKDWORD count) { | ||||
| 		m_FaceCount = count; | ||||
| 		m_FaceIndices.resize(count * 3, 0); | ||||
| 		m_FaceMtlIndex.resize(count, 0); | ||||
| 		m_Faces.resize(count); | ||||
| 	} | ||||
|  | ||||
| 	CKWORD* CKMesh::GetFaceIndices() { | ||||
| 		return m_FaceIndices.data(); | ||||
| 	} | ||||
|  | ||||
| 	CKWORD* CKMesh::GetFaceMaterialSlotIndexs() { | ||||
| 		return m_FaceIndices.data(); | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VxVector3* CKMesh::GetFaceNormals(CKDWORD& stride) { | ||||
| 		stride = CKSizeof(FaceData_t); | ||||
| 		return &m_Faces.data()->m_Normal; | ||||
| 	} | ||||
|  | ||||
| 	CKWORD* CKMesh::GetFaceChannelMasks(CKDWORD& stride) { | ||||
| 		stride = CKSizeof(FaceData_t); | ||||
| 		return &m_Faces.data()->m_ChannelMask; | ||||
| 	} | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
| #pragma region Line Section | ||||
|  | ||||
| 	CKDWORD CKMesh::GetLineCount() { | ||||
| 		return m_LineCount; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetLineCount(CKDWORD count) { | ||||
| 		m_LineCount = count; | ||||
| 		m_LineIndices.resize(count * 2, 0); | ||||
| 	} | ||||
|  | ||||
| 	CKWORD* CKMesh::GetLineIndices() { | ||||
| 		return m_LineIndices.data(); | ||||
| 	} | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
| #pragma region Mtl Channel Section | ||||
|  | ||||
| 	CKDWORD CKMesh::GetMtlChannelCount() { | ||||
| 		return m_MtlChannelCount; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetMtlChannelCount(CKDWORD count) { | ||||
| 		m_MtlChannelCount = count; | ||||
| 		m_MaterialChannels.resize(count); | ||||
|  | ||||
| 		// sync mask to each face. | ||||
| 		// each face accept all mask in default | ||||
| 		SyncMtlChannelToFaceMask(); | ||||
| 	} | ||||
|  | ||||
| 	CKMaterial** CKMesh::GetMtlChannelMaterials(CKDWORD& stride) { | ||||
| 		stride = CKSizeof(MaterialChannel_t); | ||||
| 		return &m_MaterialChannels.data()->m_Material; | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VXBLEND_MODE* CKMesh::GetMtlChannelSourceBlends(CKDWORD& stride) { | ||||
| 		stride = CKSizeof(MaterialChannel_t); | ||||
| 		return &m_MaterialChannels.data()->m_SourceBlend; | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VXBLEND_MODE* CKMesh::GetMtlChannelDestBlends(CKDWORD& stride) { | ||||
| 		stride = CKSizeof(MaterialChannel_t); | ||||
| 		return &m_MaterialChannels.data()->m_DestBlend; | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VxVector2* CKMesh::GetMtlChannelCustomUVs(CKDWORD idx) { | ||||
| 		if (idx >= m_MtlChannelCount) return nullptr; | ||||
| 		return m_MaterialChannels[idx].m_CustomUV.data(); | ||||
| 	} | ||||
|  | ||||
| 	VxMath::VXCHANNEL_FLAGS CKMesh::GetMtlChannelFlags(CKDWORD idx) { | ||||
| 		if (idx >= m_MtlChannelCount) return static_cast<VxMath::VXCHANNEL_FLAGS>(0); | ||||
| 		return m_MaterialChannels[idx].m_Flags; | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SetMtlChannelFlags(CKDWORD idx, VxMath::VXCHANNEL_FLAGS flags) { | ||||
| 		if (idx >= m_MtlChannelCount) return; | ||||
| 		m_MaterialChannels[idx].m_Flags = flags; | ||||
| 		 | ||||
| 		// refresh self custom uv | ||||
| 		SyncVertexCountToMtlChannel(); | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SyncVertexCountToMtlChannel() { | ||||
| 		for (auto& channel : m_MaterialChannels) { | ||||
| 			if (!EnumsHelper::Has(channel.m_Flags, VxMath::VXCHANNEL_FLAGS::VXCHANNEL_SAMEUV)) { | ||||
| 				channel.m_CustomUV.resize(m_VertexCount); | ||||
| 			} else { | ||||
| 				channel.m_CustomUV.clear(); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	void CKMesh::SyncMtlChannelToFaceMask() { | ||||
| 		CKWORD mask = static_cast<CKWORD>(~(0xFFFF << m_MtlChannelCount)); | ||||
| 		for (auto& face : m_Faces) { | ||||
| 			face.m_ChannelMask |= mask; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| #pragma endregion | ||||
|  | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -20,8 +20,105 @@ namespace LibCmo::CK2::ObjImpls { | ||||
| 		virtual bool Load(CKStateChunk* chunk, CKFileVisitor* file) override; | ||||
| 		//virtual void PostLoad() override; | ||||
| 		 | ||||
| 	protected: | ||||
| 		// ===== Misc Section ===== | ||||
| 	public: | ||||
| 		void CleanMesh(); | ||||
|  | ||||
| 		// ===== Line Section ===== | ||||
| 	public: | ||||
| 		CKDWORD GetVertexCount(); | ||||
| 		void SetVertexCount(CKDWORD count); | ||||
| 		VxMath::VxVector3* GetVertexPositions(); | ||||
| 		VxMath::VxVector3* GetVertexNormals(); | ||||
| 		VxMath::VxVector2* GetVertexUVs(); | ||||
| 		CKDWORD* GetVertexColors(); | ||||
| 		CKDWORD* GetVertexSpecularColors(); | ||||
| 		float* GetVertexWeights(); | ||||
| 	 | ||||
| 		// ===== Material Slot Section ===== | ||||
| 	public: | ||||
| 		CKDWORD GetMaterialSlotCount(); | ||||
| 		void SetMaterialSlotCount(CKDWORD count); | ||||
| 		void SetMaterialSlot(CKMaterial* mtl, CKDWORD idx); | ||||
|  | ||||
| 		// ===== Face Section ===== | ||||
| 	public: | ||||
| 		CKDWORD GetFaceCount(); | ||||
| 		void SetFaceCount(CKDWORD count); | ||||
| 		CKWORD* GetFaceIndices(); | ||||
| 		CKWORD* GetFaceMaterialSlotIndexs(); | ||||
| 		VxMath::VxVector3* GetFaceNormals(CKDWORD& stride); | ||||
| 		CKWORD* GetFaceChannelMasks(CKDWORD& stride); | ||||
|  | ||||
| 		// ===== Line Section ===== | ||||
| 	public: | ||||
| 		CKDWORD GetLineCount(); | ||||
| 		void SetLineCount(CKDWORD count); | ||||
| 		CKWORD* GetLineIndices(); | ||||
| 		 | ||||
| 		// ===== Material Channel Section ===== | ||||
| 	public: | ||||
| 		CKDWORD GetMtlChannelCount(); | ||||
| 		void SetMtlChannelCount(CKDWORD count); | ||||
| 		CKMaterial** GetMtlChannelMaterials(CKDWORD& stride); | ||||
| 		VxMath::VXBLEND_MODE* GetMtlChannelSourceBlends(CKDWORD& stride); | ||||
| 		VxMath::VXBLEND_MODE* GetMtlChannelDestBlends(CKDWORD& stride); | ||||
|  | ||||
| 		VxMath::VxVector2* GetMtlChannelCustomUVs(CKDWORD idx); | ||||
| 		VxMath::VXCHANNEL_FLAGS GetMtlChannelFlags(CKDWORD idx); | ||||
| 		void SetMtlChannelFlags(CKDWORD idx, VxMath::VXCHANNEL_FLAGS flags); | ||||
| 	protected: | ||||
| 		// 2 sync functions served for material channels. | ||||
| 		void SyncVertexCountToMtlChannel();	// setup material channel custom uv properly | ||||
| 		void SyncMtlChannelToFaceMask();	// request all face accept all material channels. | ||||
|  | ||||
| 	protected: | ||||
| 		struct FaceData_t { | ||||
| 			FaceData_t() : | ||||
| 				m_Normal(), | ||||
| 				m_ChannelMask(0xFFFF) | ||||
| 			{} | ||||
| 			VxMath::VxVector3 m_Normal; | ||||
| 			CKWORD m_ChannelMask; | ||||
| 		}; | ||||
| 		struct MaterialChannel_t { | ||||
| 			MaterialChannel_t() :  | ||||
| 				m_Material(nullptr), | ||||
| 				m_SourceBlend(VxMath::VXBLEND_MODE::VXBLEND_ZERO), | ||||
| 				m_DestBlend(VxMath::VXBLEND_MODE::VXBLEND_SRCCOLOR), | ||||
| 				m_CustomUV(), | ||||
| 				m_Flags(EnumsHelper::Merge({ VxMath::VXCHANNEL_FLAGS::VXCHANNEL_ACTIVE, VxMath::VXCHANNEL_FLAGS::VXCHANNEL_SAMEUV })) | ||||
| 			{} | ||||
| 			CKMaterial* m_Material; | ||||
| 			VxMath::VXBLEND_MODE m_SourceBlend; | ||||
| 			VxMath::VXBLEND_MODE m_DestBlend; | ||||
| 			XContainer::XArray<VxMath::VxVector2> m_CustomUV; | ||||
| 			VxMath::VXCHANNEL_FLAGS m_Flags; | ||||
| 		}; | ||||
|  | ||||
| 		VxMath::VXMESH_FLAGS m_Flags; | ||||
| 		CKDWORD m_VertexCount; | ||||
| 		CKDWORD m_LineCount; | ||||
| 		CKDWORD m_MtlSlotCount; | ||||
| 		CKDWORD m_FaceCount; | ||||
| 		CKDWORD m_MtlChannelCount; | ||||
|  | ||||
| 		XContainer::XArray<VxMath::VxVector3> m_VertexPosition; | ||||
| 		XContainer::XArray<VxMath::VxVector3> m_VertexNormal; | ||||
| 		XContainer::XArray<VxMath::VxVector2> m_VertexUV; | ||||
| 		XContainer::XArray<CKDWORD> m_VertexColor; | ||||
| 		XContainer::XArray<CKDWORD> m_VertexSpecularColor; | ||||
| 		XContainer::XArray<float> m_VertexWeight; | ||||
|  | ||||
| 		XContainer::XArray<CKMaterial*> m_MaterialSlot; | ||||
|  | ||||
| 		XContainer::XArray<CKWORD> m_FaceIndices; | ||||
| 		XContainer::XArray<CKWORD> m_FaceMtlIndex; | ||||
| 		XContainer::XArray<FaceData_t> m_Faces; | ||||
|  | ||||
| 		XContainer::XArray<CKWORD> m_LineIndices; | ||||
|  | ||||
| 		XContainer::XArray<MaterialChannel_t> m_MaterialChannels; | ||||
| 	}; | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -304,6 +304,24 @@ namespace LibCmo::VxMath { | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	template<class _Ty, std::enable_if_t<std::is_pointer_v<_Ty>, int> = 0> | ||||
| 	class VxStridedData { | ||||
| 	public: | ||||
| 		VxStridedData(_Ty ptr, CK2::CKDWORD stride) : | ||||
| 			m_Ptr(reinterpret_cast<CK2::CKBYTE*>(m_Ptr)), | ||||
| 			m_Stride(stride) | ||||
| 		{} | ||||
| 		~VxStridedData() {} | ||||
|  | ||||
| 		_Ty operator[](size_t idx) { | ||||
| 			return reinterpret_cast<_Ty>(m_Ptr + (m_Stride * idx)); | ||||
| 		} | ||||
|  | ||||
| 	private: | ||||
| 		CK2::CKBYTE* m_Ptr; | ||||
| 		CK2::CKDWORD m_Stride; | ||||
| 	}; | ||||
|  | ||||
| 	/** | ||||
| 	 * VxImageDescEx describe the height, width, | ||||
| 	 * and etc for image. | ||||
|  | ||||
		Reference in New Issue
	
	Block a user