/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #ifndef CRYINCLUDE_CRY3DENGINE_RENDERMESHMERGER_H #define CRYINCLUDE_CRY3DENGINE_RENDERMESHMERGER_H #pragma once ////////////////////////////////////////////////////////////////////////// // Input structure for RenderMesh merger ////////////////////////////////////////////////////////////////////////// struct SRenderMeshInfoInput { _smart_ptr pMesh; _smart_ptr pMat; IRenderNode* pSrcRndNode; Matrix34 mat; int nSubObjectIndex; int nChunkId; bool bIdentityMatrix; SRenderMeshInfoInput() : pMesh(0) , pMat(0) , nChunkId(-1) , nSubObjectIndex(0) , pSrcRndNode(0) , bIdentityMatrix(false) { mat.SetIdentity(); } void GetMemoryUsage(ICrySizer* pSizer) const {} }; struct SDecalClipInfo { Vec3 vPos; float fRadius; Vec3 vProjDir; }; struct SMergeInfo { const char* sMeshType; const char* sMeshName; bool bCompactVertBuffer; bool bPrintDebugMessages; bool bMakeNewMaterial; bool bMergeToOneRenderMesh; bool bPlaceInstancePositionIntoVertexNormal; _smart_ptr pUseMaterial; // Force to use this material SDecalClipInfo* pDecalClipInfo; AABB* pClipCellBox; Vec3 vResultOffset; // this offset will be subtracted from output vertex positions SMergeInfo() : sMeshType("") , sMeshName("") , bCompactVertBuffer(false) , bPrintDebugMessages(false) , bMakeNewMaterial(true) , bMergeToOneRenderMesh(false) , bPlaceInstancePositionIntoVertexNormal(0) , pUseMaterial(0) , pDecalClipInfo(0) , pClipCellBox(0) , vResultOffset(0, 0, 0) {} }; struct SMergedChunk { CRenderChunk rChunk; _smart_ptr pMaterial; SRenderMeshInfoInput* pFromMesh; void GetMemoryUsage(ICrySizer* pSizer) const {} }; struct SMergeBuffersData { int nPosStride; int nTexStride; int nColorStride; int nTangsStride; int nIndCount; uint8* pPos; uint8* pTex; uint8* pColor; uint8* pTangs; vtx_idx* pSrcInds; #if ENABLE_NORMALSTREAM_SUPPORT int nNormStride; uint8* pNorm; #endif }; class CRenderMeshMerger : public Cry3DEngineBase { public: CRenderMeshMerger(void); ~CRenderMeshMerger(void); void Reset(); _smart_ptr MergeRenderMeshes(SRenderMeshInfoInput* pRMIArray, int nRMICount, PodArray& outRenderMeshes, SMergeInfo& info); _smart_ptr MergeRenderMeshes(SRenderMeshInfoInput* pRMIArray, int nRMICount, SMergeInfo& info); public: void GetMemoryUsage(ICrySizer* pSizer) const { pSizer->AddObject(this, sizeof(*this)); pSizer->AddObject(m_lstRMIChunks); pSizer->AddObject(m_lstVerts); pSizer->AddObject(m_lstTangBasises); pSizer->AddObject(m_lstIndices); pSizer->AddObject(m_lstChunks); pSizer->AddObject(m_lstChunksAll); pSizer->AddObject(m_lstNewVerts); pSizer->AddObject(m_lstNewTangBasises); pSizer->AddObject(m_lstNewIndices); pSizer->AddObject(m_lstNewChunks); pSizer->AddObject(m_lstChunksMergedTemp); pSizer->AddObject(m_tmpRenderChunkArray); pSizer->AddObject(m_tmpClipContext); } void MergeBuffersImpl(AABB* pBounds, SMergeBuffersData* arrMergeBuffersData); protected: PodArray m_lstRMIChunks; PodArray m_lstVerts; PodArray m_lstTangBasises; PodArray m_lstIndices; PodArray m_lstChunks; PodArray m_lstChunksAll; PodArray m_lstNewVerts; PodArray m_lstNewTangBasises; PodArray m_lstNewIndices; PodArray m_lstNewChunks; #if ENABLE_NORMALSTREAM_SUPPORT PodArray m_lstNormals; PodArray m_lstNewNormals; #endif PodArray m_lstChunksMergedTemp; TRenderChunkArray m_tmpRenderChunkArray; PodArray m_lstMergeBuffersData; AABB m_tmpAABB; CPolygonClipContext m_tmpClipContext; int m_nTotalVertexCount; int m_nTotalIndexCount; private: bool GenerateRenderChunks(SRenderMeshInfoInput* pRMIArray, int nRMICount); void MergeRenderChunks(); void MergeBuffers(AABB& bounds); void MakeRenderMeshInfoListOfAllChunks(SRenderMeshInfoInput* pRMIArray, int nRMICount, SMergeInfo& info); void MakeListOfAllCRenderChunks(SMergeInfo& info); void IsChunkValid(const CRenderChunk& Ch, PodArray& lstVerts, PodArray& lstIndices); void ClipByAABB(SMergeInfo& info); void ClipDecals(SMergeInfo& info); void CompactVertices(SMergeInfo& info); void TryMergingChunks(SMergeInfo& info); bool ClipTriangle(int nStartIdxId, Plane* pPlanes, int nPlanesNum); static int Cmp_Materials(_smart_ptr pMat1, _smart_ptr pMat2); static int Cmp_RenderChunks_(const void* v1, const void* v2); static int Cmp_RenderChunksInfo(const void* v1, const void* v2); }; #endif // CRYINCLUDE_CRY3DENGINE_RENDERMESHMERGER_H