You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
329 lines
10 KiB
C++
329 lines
10 KiB
C++
/*
|
|
* 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.
|
|
|
|
// Description : Manages static meshes for geometry caches
|
|
|
|
|
|
#include "Cry3DEngine_precompiled.h"
|
|
|
|
#if defined(USE_GEOM_CACHES)
|
|
|
|
#include "GeomCacheMeshManager.h"
|
|
#include "GeomCacheDecoder.h"
|
|
|
|
void CGeomCacheMeshManager::Reset()
|
|
{
|
|
stl::free_container(m_meshMap);
|
|
}
|
|
|
|
bool CGeomCacheMeshManager::ReadMeshStaticData(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, SGeomCacheStaticMeshData& staticMeshData) const
|
|
{
|
|
LOADING_TIME_PROFILE_SECTION;
|
|
|
|
if (staticMeshData.m_constantStreams & GeomCacheFile::eStream_Indices)
|
|
{
|
|
if (!ReadMeshIndices(reader, meshInfo, staticMeshData, staticMeshData.m_indices))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_Positions) != 0)
|
|
{
|
|
staticMeshData.m_positions.resize(staticMeshData.m_numVertices);
|
|
|
|
strided_pointer<Vec3> positions(&staticMeshData.m_positions[0], sizeof(Vec3));
|
|
if (!ReadMeshPositions(reader, meshInfo, positions))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_Texcoords) != 0)
|
|
{
|
|
staticMeshData.m_texcoords.resize(staticMeshData.m_numVertices);
|
|
|
|
strided_pointer<Vec2> texcoords(&staticMeshData.m_texcoords[0], sizeof(Vec2));
|
|
if (!ReadMeshTexcoords(reader, meshInfo, texcoords))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_QTangents) != 0)
|
|
{
|
|
staticMeshData.m_tangents.resize(staticMeshData.m_numVertices);
|
|
|
|
strided_pointer<SPipTangents> tangents(&staticMeshData.m_tangents[0], sizeof(SPipTangents));
|
|
if (!ReadMeshQTangents(reader, meshInfo, tangents))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if ((staticMeshData.m_constantStreams & GeomCacheFile::eStream_Colors) != 0)
|
|
{
|
|
UCol defaultColor;
|
|
defaultColor.dcolor = 0xFFFFFFFF;
|
|
staticMeshData.m_colors.resize(staticMeshData.m_numVertices, defaultColor);
|
|
|
|
strided_pointer<UCol> colors(&staticMeshData.m_colors[0], sizeof(UCol));
|
|
if (!ReadMeshColors(reader, meshInfo, colors))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
if (staticMeshData.m_bUsePredictor)
|
|
{
|
|
uint32 predictorDataSize;
|
|
if (!reader.Read(&predictorDataSize))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
staticMeshData.m_predictorData.resize(predictorDataSize);
|
|
if (!reader.Read(&staticMeshData.m_predictorData[0], predictorDataSize))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
_smart_ptr<IRenderMesh> CGeomCacheMeshManager::ConstructStaticRenderMesh(CGeomCacheStreamReader& reader,
|
|
const GeomCacheFile::SMeshInfo& meshInfo, SGeomCacheStaticMeshData& staticMeshData, const char* pFileName)
|
|
{
|
|
LOADING_TIME_PROFILE_SECTION;
|
|
|
|
std::vector<char> vertexData(staticMeshData.m_numVertices * sizeof(SVF_P3F_C4B_T2F), 0);
|
|
std::vector<SPipTangents> tangentData(staticMeshData.m_numVertices);
|
|
|
|
std::vector<vtx_idx> indices;
|
|
strided_pointer<Vec3> positions((Vec3*)(&vertexData[0] + offsetof(SVF_P3F_C4B_T2F, xyz)), sizeof(SVF_P3F_C4B_T2F));
|
|
strided_pointer<UCol> colors((UCol*)(&vertexData[0] + offsetof(SVF_P3F_C4B_T2F, color)), sizeof(SVF_P3F_C4B_T2F));
|
|
strided_pointer<Vec2> texcoords((Vec2*)(&vertexData[0] + offsetof(SVF_P3F_C4B_T2F, st)), sizeof(SVF_P3F_C4B_T2F));
|
|
strided_pointer<SPipTangents> tangents((SPipTangents*)((char*)(&tangentData[0])), sizeof(SPipTangents));
|
|
|
|
if (!ReadMeshIndices(reader, meshInfo, staticMeshData, indices)
|
|
|| !ReadMeshPositions(reader, meshInfo, positions)
|
|
|| !ReadMeshTexcoords(reader, meshInfo, texcoords)
|
|
|| !ReadMeshQTangents(reader, meshInfo, tangents))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
if (meshInfo.m_constantStreams & GeomCacheFile::eStream_Colors)
|
|
{
|
|
if (!ReadMeshColors(reader, meshInfo, colors))
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
UCol defaultColor;
|
|
defaultColor.dcolor = 0xFFFFFFFF;
|
|
|
|
const uint numVertices = meshInfo.m_numVertices;
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
{
|
|
colors[i] = defaultColor;
|
|
}
|
|
}
|
|
|
|
TMeshMap::iterator findIter = m_meshMap.find(staticMeshData.m_hash);
|
|
if (findIter != m_meshMap.end())
|
|
{
|
|
++findIter->second.m_refCount;
|
|
return findIter->second.m_pRenderMesh;
|
|
}
|
|
|
|
_smart_ptr<IRenderMesh> pRenderMesh = gEnv->pRenderer->CreateRenderMeshInitialized(&vertexData[0], meshInfo.m_numVertices,
|
|
eVF_P3F_C4B_T2F, &indices[0], indices.size(), prtTriangleList, "GeomCacheConstantMesh", pFileName, eRMT_Static, 1, 0,
|
|
NULL, NULL, false, false, &tangentData[0]);
|
|
|
|
CRenderChunk chunk;
|
|
chunk.nNumVerts = meshInfo.m_numVertices;
|
|
uint32 currentIndexOffset = 0;
|
|
|
|
for (unsigned int i = 0; i < meshInfo.m_numMaterials; ++i)
|
|
{
|
|
chunk.nFirstIndexId = currentIndexOffset;
|
|
chunk.nNumIndices = staticMeshData.m_numIndices[i];
|
|
chunk.m_nMatID = staticMeshData.m_materialIds[i];
|
|
chunk.m_vertexFormat = eVF_P3F_C4B_T2F;
|
|
pRenderMesh->SetChunk(i, chunk);
|
|
currentIndexOffset += chunk.nNumIndices;
|
|
}
|
|
|
|
SMeshMapInfo meshMapInfo;
|
|
meshMapInfo.m_refCount = 1;
|
|
meshMapInfo.m_pRenderMesh = pRenderMesh;
|
|
|
|
m_meshMap[staticMeshData.m_hash] = meshMapInfo;
|
|
return pRenderMesh;
|
|
}
|
|
|
|
_smart_ptr<IRenderMesh> CGeomCacheMeshManager::GetStaticRenderMesh(const uint64 hash) const
|
|
{
|
|
TMeshMap::const_iterator findIter = m_meshMap.find(hash);
|
|
if (findIter != m_meshMap.end())
|
|
{
|
|
return findIter->second.m_pRenderMesh;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void CGeomCacheMeshManager::RemoveReference(SGeomCacheStaticMeshData& staticMeshData)
|
|
{
|
|
TMeshMap::iterator findIter = m_meshMap.find(staticMeshData.m_hash);
|
|
if (findIter != m_meshMap.end())
|
|
{
|
|
uint& refCount = findIter->second.m_refCount;
|
|
--refCount;
|
|
|
|
if (refCount == 0)
|
|
{
|
|
m_meshMap.erase(findIter);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CGeomCacheMeshManager::ReadMeshIndices(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo,
|
|
SGeomCacheStaticMeshData& staticMeshData, std::vector<vtx_idx>& indices) const
|
|
{
|
|
const uint16 numMaterials = meshInfo.m_numMaterials;
|
|
staticMeshData.m_numIndices.reserve(numMaterials);
|
|
|
|
for (unsigned int i = 0; i < numMaterials; ++i)
|
|
{
|
|
uint32 numIndices;
|
|
if (!reader.Read(&numIndices))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
staticMeshData.m_numIndices.push_back(numIndices);
|
|
|
|
const uint indicesStart = indices.size();
|
|
indices.resize(indicesStart + numIndices);
|
|
if (!reader.Read(&indices[indicesStart], numIndices))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGeomCacheMeshManager::ReadMeshPositions(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer<Vec3> positions) const
|
|
{
|
|
const Vec3 aabbMin = Vec3(meshInfo.m_aabbMin[0], meshInfo.m_aabbMin[1], meshInfo.m_aabbMin[2]);
|
|
const Vec3 aabbMax = Vec3(meshInfo.m_aabbMax[0], meshInfo.m_aabbMax[1], meshInfo.m_aabbMax[2]);
|
|
const AABB meshAABB(aabbMin, aabbMax);
|
|
const Vec3 aabbSize = meshAABB.GetSize();
|
|
const Vec3 posConvertFactor = Vec3(1.0f / float((2 << (meshInfo.m_positionPrecision[0] - 1)) - 1),
|
|
1.0f / float((2 << (meshInfo.m_positionPrecision[1] - 1)) - 1),
|
|
1.0f / float((2 << (meshInfo.m_positionPrecision[2] - 1)) - 1));
|
|
|
|
const uint numVertices = meshInfo.m_numVertices;
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
{
|
|
GeomCacheFile::Position position;
|
|
|
|
if (!reader.Read(&position))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
positions[i] = GeomCacheDecoder::DecodePosition(aabbMin, aabbSize, position, posConvertFactor);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGeomCacheMeshManager::ReadMeshTexcoords(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer<Vec2> texcoords) const
|
|
{
|
|
const uint numVertices = meshInfo.m_numVertices;
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
{
|
|
GeomCacheFile::Texcoords texcoord;
|
|
|
|
if (!reader.Read(&texcoord))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
texcoords[i] = GeomCacheDecoder::DecodeTexcoord(texcoord, meshInfo.m_uvMax);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGeomCacheMeshManager::ReadMeshQTangents(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer<SPipTangents> tangents) const
|
|
{
|
|
const uint numVertices = meshInfo.m_numVertices;
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
{
|
|
GeomCacheFile::QTangent qTangent;
|
|
|
|
if (!reader.Read(&qTangent))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Quat qDecodedTangent = GeomCacheDecoder::DecodeQTangent(qTangent);
|
|
GeomCacheDecoder::ConvertToTangentAndBitangent(qDecodedTangent, tangents[i]);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool CGeomCacheMeshManager::ReadMeshColors(CGeomCacheStreamReader& reader, const GeomCacheFile::SMeshInfo& meshInfo, strided_pointer<UCol> colors) const
|
|
{
|
|
const uint numVertices = meshInfo.m_numVertices;
|
|
for (int colorIndex = 2; colorIndex >= 0; --colorIndex)
|
|
{
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
{
|
|
GeomCacheFile::Color color;
|
|
|
|
if (!reader.Read(&color))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
colors[i].bcolor[colorIndex] = color;
|
|
}
|
|
}
|
|
|
|
for (uint i = 0; i < numVertices; ++i)
|
|
{
|
|
GeomCacheFile::Color color;
|
|
|
|
if (!reader.Read(&color))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
colors[i].bcolor[3] = color;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif
|