From 3b417062bb8b2bf7a5488f7ccff64716eccec0ec Mon Sep 17 00:00:00 2001 From: vladislavbelov Date: Fri, 3 Sep 2021 20:11:52 +0000 Subject: [PATCH] Reduces the number of possible allocations for models with multiple UV sets during loading. Tested By: Stan Differential Revision: https://code.wildfiregames.com/D4247 This was SVN commit r25890. --- source/graphics/ModelDef.cpp | 6 +++--- source/graphics/ModelDef.h | 7 +++++-- source/renderer/MikktspaceWrap.cpp | 18 ++++++++++-------- source/renderer/ModelRenderer.cpp | 9 +++++---- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/source/graphics/ModelDef.cpp b/source/graphics/ModelDef.cpp index f641480b4e..ea7f157da9 100644 --- a/source/graphics/ModelDef.cpp +++ b/source/graphics/ModelDef.cpp @@ -338,7 +338,8 @@ CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name) mdef->m_NumUVsPerVertex = unpacker.UnpackSize(); } - mdef->m_pVertices=new SModelVertex[mdef->m_NumVertices]; + mdef->m_pVertices = new SModelVertex[mdef->m_NumVertices]; + mdef->m_UVCoordinates.reserve(mdef->m_NumVertices * mdef->m_NumUVsPerVertex); for (size_t i = 0; i < mdef->m_NumVertices; ++i) { @@ -349,8 +350,7 @@ CModelDef* CModelDef::Load(const VfsPath& filename, const VfsPath& name) { float uv[2]; unpacker.UnpackRaw(&uv[0], 8); - mdef->m_pVertices[i].m_UVs.push_back(uv[0]); - mdef->m_pVertices[i].m_UVs.push_back(uv[1]); + mdef->m_UVCoordinates.emplace_back(uv[0], uv[1]); } unpacker.UnpackRaw(&mdef->m_pVertices[i].m_Blend, sizeof(SVertexBlend)); diff --git a/source/graphics/ModelDef.h b/source/graphics/ModelDef.h index 1144c0c7a6..a5cb5e3006 100644 --- a/source/graphics/ModelDef.h +++ b/source/graphics/ModelDef.h @@ -25,6 +25,7 @@ #include "maths/BoundingBoxAligned.h" #include "maths/Matrix3D.h" #include "maths/Quaternion.h" +#include "maths/Vector2D.h" #include "maths/Vector3D.h" #include "lib/file/vfs/vfs_path.h" #include "ps/CStr.h" @@ -33,6 +34,7 @@ #include #include #include +#include class CBoneState; class CSkeletonAnimDef; @@ -108,8 +110,6 @@ struct SModelVertex CVector3D m_Coords; // vertex normal CVector3D m_Norm; - // vertex UVs - std::vector m_UVs; // vertex blend data SVertexBlend m_Blend; }; @@ -173,6 +173,8 @@ public: // accessor: get number of UV sets size_t GetNumUVsPerVertex() const { return m_NumUVsPerVertex; } + const std::vector& GetUVCoordinates() const { return m_UVCoordinates; } + // accessor: get face data size_t GetNumFaces() const { return m_NumFaces; } SModelFace* GetFaces() const { return m_pFaces; } @@ -256,6 +258,7 @@ public: // vertex data size_t m_NumVertices; SModelVertex* m_pVertices; + std::vector m_UVCoordinates; size_t m_NumUVsPerVertex; // number of UV pairs per vertex // face data size_t m_NumFaces; diff --git a/source/renderer/MikktspaceWrap.cpp b/source/renderer/MikktspaceWrap.cpp index df6a106862..5a09378c46 100644 --- a/source/renderer/MikktspaceWrap.cpp +++ b/source/renderer/MikktspaceWrap.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2019 Wildfire Games. +/* Copyright (C) 2021 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -81,11 +81,12 @@ void MikkTSpace::GetTexCoord(const SMikkTSpaceContext* pContext, { const MikkTSpace* userData = GetUserDataFromContext(pContext); const SModelFace& face = userData->m_Model->GetFaces()[iFace]; - const SModelVertex& v = userData->m_Model->GetVertices()[face.m_Verts[iVert]]; + const size_t numberOfUVPerVertex = userData->m_Model->GetNumUVsPerVertex(); // The tangents are calculated according to the 'default' UV set - fvTexcOut[0] = v.m_UVs[0]; - fvTexcOut[1] = 1.0 - v.m_UVs[1]; + const CVector2D& uv = userData->m_Model->GetUVCoordinates()[face.m_Verts[iVert] * numberOfUVPerVertex]; + fvTexcOut[0] = uv.X; + fvTexcOut[1] = 1.0 - uv.Y; } @@ -121,11 +122,12 @@ void MikkTSpace::SetTSpace(const SMikkTSpaceContext* pContext, const float* fvTa } } - size_t numUVsPerVertex = userData->m_Model->GetNumUVsPerVertex(); - for (size_t UVset = 0; UVset < numUVsPerVertex; ++UVset) + const size_t numberOfUVPerVertex = userData->m_Model->GetNumUVsPerVertex(); + for (size_t UVset = 0; UVset < numberOfUVPerVertex; ++UVset) { - userData->m_NewVertices.push_back(vertex.m_UVs[UVset * 2]); - userData->m_NewVertices.push_back(1.f - vertex.m_UVs[UVset * 2 + 1]); + const CVector2D& uv = userData->m_Model->GetUVCoordinates()[face.m_Verts[iVert] * numberOfUVPerVertex + UVset]; + userData->m_NewVertices.push_back(uv.X); + userData->m_NewVertices.push_back(1.f - uv.Y); } } diff --git a/source/renderer/ModelRenderer.cpp b/source/renderer/ModelRenderer.cpp index 7365f178d7..4d6fb701d9 100644 --- a/source/renderer/ModelRenderer.cpp +++ b/source/renderer/ModelRenderer.cpp @@ -141,13 +141,14 @@ void ModelRenderer::BuildUV( const VertexArrayIterator& UV, int UVset) { - size_t numVertices = mdef->GetNumVertices(); - SModelVertex* vertices = mdef->GetVertices(); + const size_t numVertices = mdef->GetNumVertices(); + const size_t numberOfUVPerVertex = mdef->GetNumUVsPerVertex(); for (size_t j = 0; j < numVertices; ++j) { - UV[j][0] = vertices[j].m_UVs[UVset * 2]; - UV[j][1] = 1.0 - vertices[j].m_UVs[UVset * 2 + 1]; + const CVector2D& uv = mdef->GetUVCoordinates()[j * numberOfUVPerVertex + UVset]; + UV[j][0] = uv.X; + UV[j][1] = 1.0 - uv.Y; } }