From 728cb25488519f3609c1f3229ef609644c518dd1 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 26 Jul 2016 12:05:59 -1000 Subject: [PATCH] Static geometry list in CBooRenderer --- DataSpec/DNACommon/CMDL.cpp | 221 +++++++++++++++++++++ DataSpec/DNACommon/CMDL.hpp | 12 +- Runtime/Graphics/CBooRenderer.cpp | 72 ++++++- Runtime/Graphics/CBooRenderer.hpp | 36 +++- Runtime/Graphics/CMakeLists.txt | 2 +- Runtime/Graphics/CMetroidModelInstance.cpp | 18 ++ Runtime/Graphics/CMetroidModelInstance.hpp | 15 ++ Runtime/Graphics/CModel.hpp | 8 + Runtime/Graphics/IRenderer.hpp | 12 +- hecl | 2 +- 10 files changed, 371 insertions(+), 27 deletions(-) create mode 100644 Runtime/Graphics/CMetroidModelInstance.cpp diff --git a/DataSpec/DNACommon/CMDL.cpp b/DataSpec/DNACommon/CMDL.cpp index 189b61292..f54dd0a4b 100644 --- a/DataSpec/DNACommon/CMDL.cpp +++ b/DataSpec/DNACommon/CMDL.cpp @@ -1623,5 +1623,226 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in template bool WriteHMDLCMDL (const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh); +void SurfaceHeader_1::read(athena::io::IStreamReader& reader) +{ + /* centroid */ + centroid = reader.readVec3fBig(); + /* matIdx */ + matIdx = reader.readUint32Big(); + /* qDiv */ + qDiv = reader.readUint16Big(); + /* dlSize */ + dlSize = reader.readUint16Big(); + /* idxStart */ + idxStart = reader.readUint32Big(); + /* idxCount */ + idxCount = reader.readUint32Big(); + /* aabbSz */ + aabbSz = reader.readUint32Big(); + /* reflectionNormal */ + reflectionNormal = reader.readVec3fBig(); + /* aabb */ + size_t remAABB = aabbSz; + if (remAABB >= 24) + { + aabb[0] = reader.readVec3fBig(); + aabb[1] = reader.readVec3fBig(); + remAABB -= 24; + } + reader.seek(remAABB, athena::Current); + /* align */ + reader.seekAlign32(); +} + +void SurfaceHeader_1::write(athena::io::IStreamWriter& writer) const +{ + /* centroid */ + writer.writeVec3fBig(centroid); + /* matIdx */ + writer.writeUint32Big(matIdx); + /* qDiv */ + writer.writeUint16Big(qDiv); + /* dlSize */ + writer.writeUint16Big(dlSize); + /* idxStart */ + writer.writeUint32Big(idxStart); + /* idxCount */ + writer.writeUint32Big(idxCount); + /* aabbSz */ + writer.writeUint32Big(aabbSz ? 24 : 0); + /* reflectionNormal */ + writer.writeVec3fBig(reflectionNormal); + /* aabb */ + if (aabbSz) + { + writer.writeVec3fBig(aabb[0]); + writer.writeVec3fBig(aabb[1]); + } + /* align */ + writer.seekAlign32(); +} + +size_t SurfaceHeader_1::binarySize(size_t __isz) const +{ + __isz += (aabbSz ? 24 : 0); + __isz += 44; + __isz = (__isz + 31) & ~31; + return __isz; +} + +void SurfaceHeader_2::read(athena::io::IStreamReader& reader) +{ + /* centroid */ + centroid = reader.readVec3fBig(); + /* matIdx */ + matIdx = reader.readUint32Big(); + /* qDiv */ + qDiv = reader.readUint16Big(); + /* dlSize */ + dlSize = reader.readUint16Big(); + /* idxStart */ + idxStart = reader.readUint32Big(); + /* idxCount */ + idxCount = reader.readUint32Big(); + /* aabbSz */ + aabbSz = reader.readUint32Big(); + /* reflectionNormal */ + reflectionNormal = reader.readVec3fBig(); + /* skinMtxBankIdx */ + skinMtxBankIdx = reader.readInt16Big(); + /* surfaceGroup */ + surfaceGroup = reader.readUint16Big(); + /* aabb */ + size_t remAABB = aabbSz; + if (remAABB >= 24) + { + aabb[0] = reader.readVec3fBig(); + aabb[1] = reader.readVec3fBig(); + remAABB -= 24; + } + reader.seek(remAABB, athena::Current); + /* align */ + reader.seekAlign32(); +} + +void SurfaceHeader_2::write(athena::io::IStreamWriter& writer) const +{ + /* centroid */ + writer.writeVec3fBig(centroid); + /* matIdx */ + writer.writeUint32Big(matIdx); + /* qDiv */ + writer.writeUint16Big(qDiv); + /* dlSize */ + writer.writeUint16Big(dlSize); + /* idxStart */ + writer.writeUint32Big(idxStart); + /* idxCount */ + writer.writeUint32Big(idxCount); + /* aabbSz */ + writer.writeUint32Big(aabbSz ? 24 : 0); + /* reflectionNormal */ + writer.writeVec3fBig(reflectionNormal); + /* skinMtxBankIdx */ + writer.writeInt16Big(skinMtxBankIdx); + /* surfaceGroup */ + writer.writeUint16Big(surfaceGroup); + /* aabb */ + if (aabbSz) + { + writer.writeVec3fBig(aabb[0]); + writer.writeVec3fBig(aabb[1]); + } + /* align */ + writer.seekAlign32(); +} + +size_t SurfaceHeader_2::binarySize(size_t __isz) const +{ + __isz += (aabbSz ? 24 : 0); + __isz += 48; + __isz = (__isz + 31) & ~31; + return __isz; +} + +void SurfaceHeader_3::read(athena::io::IStreamReader& reader) +{ + /* centroid */ + centroid = reader.readVec3fBig(); + /* matIdx */ + matIdx = reader.readUint32Big(); + /* qDiv */ + qDiv = reader.readUint16Big(); + /* dlSize */ + dlSize = reader.readUint16Big(); + /* idxStart */ + idxStart = reader.readUint32Big(); + /* idxCount */ + idxCount = reader.readUint32Big(); + /* aabbSz */ + aabbSz = reader.readUint32Big(); + /* reflectionNormal */ + reflectionNormal = reader.readVec3fBig(); + /* skinMtxBankIdx */ + skinMtxBankIdx = reader.readInt16Big(); + /* surfaceGroup */ + surfaceGroup = reader.readUint16Big(); + /* aabb */ + size_t remAABB = aabbSz; + if (remAABB >= 24) + { + aabb[0] = reader.readVec3fBig(); + aabb[1] = reader.readVec3fBig(); + remAABB -= 24; + } + reader.seek(remAABB, athena::Current); + /* unk3 */ + unk3 = reader.readUByte(); + /* align */ + reader.seekAlign32(); +} + +void SurfaceHeader_3::write(athena::io::IStreamWriter& writer) const +{ + /* centroid */ + writer.writeVec3fBig(centroid); + /* matIdx */ + writer.writeUint32Big(matIdx); + /* qDiv */ + writer.writeUint16Big(qDiv); + /* dlSize */ + writer.writeUint16Big(dlSize); + /* idxStart */ + writer.writeUint32Big(idxStart); + /* idxCount */ + writer.writeUint32Big(idxCount); + /* aabbSz */ + writer.writeUint32Big(aabbSz ? 24 : 0); + /* reflectionNormal */ + writer.writeVec3fBig(reflectionNormal); + /* skinMtxBankIdx */ + writer.writeInt16Big(skinMtxBankIdx); + /* surfaceGroup */ + writer.writeUint16Big(surfaceGroup); + /* aabb */ + if (aabbSz) + { + writer.writeVec3fBig(aabb[0]); + writer.writeVec3fBig(aabb[1]); + } + /* unk3 */ + writer.writeUByte(unk3); + /* align */ + writer.seekAlign32(); +} + +size_t SurfaceHeader_3::binarySize(size_t __isz) const +{ + __isz += (aabbSz ? 24 : 0); + __isz += 49; + __isz = (__isz + 31) & ~31; + return __isz; +} + } } diff --git a/DataSpec/DNACommon/CMDL.hpp b/DataSpec/DNACommon/CMDL.hpp index 9ea2c68cb..832aaca75 100644 --- a/DataSpec/DNACommon/CMDL.hpp +++ b/DataSpec/DNACommon/CMDL.hpp @@ -40,7 +40,7 @@ struct Header : BigDNA struct SurfaceHeader_1 : BigDNA { - DECL_DNA + DECL_EXPLICIT_DNA Value centroid; Value matIdx = 0; Value qDiv = 0x8000; @@ -49,7 +49,7 @@ struct SurfaceHeader_1 : BigDNA Value idxCount = 0; /* Actually used by game to stash next CCubeSurface pointer */ Value aabbSz = 0; Value reflectionNormal; - Seek seek2; + Value aabb[2]; Align<32> align; static constexpr bool UseMatrixSkinning() {return false;} @@ -58,7 +58,7 @@ struct SurfaceHeader_1 : BigDNA struct SurfaceHeader_2 : BigDNA { - DECL_DNA + DECL_EXPLICIT_DNA Value centroid; Value matIdx = 0; Value qDiv = 0x8000; @@ -69,7 +69,7 @@ struct SurfaceHeader_2 : BigDNA Value reflectionNormal; Value skinMtxBankIdx; Value surfaceGroup; - Seek seek2; + Value aabb[2]; Align<32> align; static constexpr bool UseMatrixSkinning() {return false;} @@ -78,7 +78,7 @@ struct SurfaceHeader_2 : BigDNA struct SurfaceHeader_3 : BigDNA { - DECL_DNA + DECL_EXPLICIT_DNA Value centroid; Value matIdx = 0; Value qDiv = 0x8000; @@ -89,7 +89,7 @@ struct SurfaceHeader_3 : BigDNA Value reflectionNormal; Value skinMtxBankIdx; Value surfaceGroup; - Seek seek2; + Value aabb[2]; Value unk3; Align<32> align; diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index 5c1708cd8..44f2b635f 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -6,6 +6,7 @@ #include "CTexture.hpp" #include "CModel.hpp" #include "Particle/CParticleGen.hpp" +#include "CMetroidModelInstance.hpp" #define MIRROR_RAMP_RES 32 #define FOGVOL_RAMP_RES 256 @@ -138,6 +139,13 @@ void Buckets::Init() sMinMaxDistance[1] = skWorstMinMaxDistance[1]; } +CBooRenderer::CAreaListItem::CAreaListItem +(const std::vector* geom, const CAreaOctTree* octTree, + std::vector&& models, int unk) +: x0_geometry(geom), x4_octTree(octTree), x10_models(std::move(models)), x18_unk(unk) {} + +CBooRenderer::CAreaListItem::~CAreaListItem() {} + void CBooRenderer::RenderBucketItems(const std::vector& lights) { for (u16 idx : Buckets::sBucketIndex) @@ -256,12 +264,49 @@ CBooRenderer::CBooRenderer(IObjectStore& store, IFactory& resFac) Buckets::Init(); } -void CBooRenderer::AddStaticGeometry(const std::vector&, const CAreaOctTree*, int) +void CBooRenderer::AddWorldSurfaces(CBooModel& model) { + CBooSurface* surf = model.x3c_firstSortedSurface; + while (surf) + { + const CBooModel::MaterialSet::Material& mat = model.GetMaterialByIndex(surf->selfIdx); + zeus::CAABox aabb = surf->GetBounds(); + zeus::CVector3f pt = aabb.closestPointAlongVector(xb0_.vec); + Buckets::Insert(pt, aabb, EDrawableType::Surface, surf, xb0_, + mat.heclIr.m_blendDst != boo::BlendFactor::Zero); + surf = surf->m_next; + } } -void CBooRenderer::RemoveStaticGeometry(const std::vector&) +std::list::iterator +CBooRenderer::FindStaticGeometry(const std::vector* geometry) { + return std::find_if(x1c_areaListItems.begin(), x1c_areaListItems.end(), + [&](CAreaListItem& item) -> bool {return item.x0_geometry == geometry;}); +} + +void CBooRenderer::AddStaticGeometry(const std::vector* geometry, + const CAreaOctTree* octTree, int unk) +{ + auto search = FindStaticGeometry(geometry); + if (search == x1c_areaListItems.end()) + { + std::vector models; + if (geometry->size()) + { + models.reserve(geometry->size()); + for (const CMetroidModelInstance& inst : *geometry) + models.push_back(inst.m_instance.get()); + } + x1c_areaListItems.emplace_back(geometry, octTree, std::move(models), unk); + } +} + +void CBooRenderer::RemoveStaticGeometry(const std::vector* geometry) +{ + auto search = FindStaticGeometry(geometry); + if (search != x1c_areaListItems.end()) + x1c_areaListItems.erase(search); } void CBooRenderer::DrawUnsortedGeometry(const std::vector&, int, unsigned int, unsigned int) @@ -270,6 +315,7 @@ void CBooRenderer::DrawUnsortedGeometry(const std::vector&, int, unsigne void CBooRenderer::DrawSortedGeometry(const std::vector&, int, unsigned int, unsigned int) { + //SetupRendererStates(); } void CBooRenderer::DrawStaticGeometry(const std::vector&, int, unsigned int, unsigned int) @@ -280,20 +326,33 @@ void CBooRenderer::PostRenderFogs() { } -void CBooRenderer::AddParticleGen(const CElementGen&) +void CBooRenderer::AddParticleGen(const CParticleGen& gen) { + std::pair bounds = gen.GetBounds(); + if (bounds.second) + { + zeus::CVector3f pt = bounds.first.closestPointAlongVector(xb0_.vec); + Buckets::Insert(pt, bounds.first, EDrawableType::Particle, &gen, xb0_, 0); + } } void CBooRenderer::AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int) { + } -void CBooRenderer::AddDrawable(const void*, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting) +void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, const zeus::CAABox& aabb, int mode, EDrawableSorting sorting) { + if (sorting == EDrawableSorting::UnsortedCallback) + xa8_renderCallback(obj, xac_callbackContext, mode); + else + Buckets::Insert(pos, aabb, EDrawableType(mode + 2), obj, xb0_, 0); } -void CBooRenderer::SetDrawableCallback(TDrawableCallback, const void*) +void CBooRenderer::SetDrawableCallback(TDrawableCallback&& cb, const void* ctx) { + xa8_renderCallback = std::move(cb); + xac_callbackContext = ctx; } void CBooRenderer::SetWorldViewpoint(const zeus::CTransform&) @@ -316,8 +375,9 @@ void CBooRenderer::SetViewportOrtho(bool, float, float) { } -void CBooRenderer::SetClippingPlanes(const zeus::CFrustum&) +void CBooRenderer::SetClippingPlanes(const zeus::CFrustum& frustum) { + x44_frustumPlanes = frustum; } void CBooRenderer::SetViewport(int, int, int, int) diff --git a/Runtime/Graphics/CBooRenderer.hpp b/Runtime/Graphics/CBooRenderer.hpp index 932134a68..04dbb64d2 100644 --- a/Runtime/Graphics/CBooRenderer.hpp +++ b/Runtime/Graphics/CBooRenderer.hpp @@ -14,6 +14,8 @@ class IObjectStore; class CMemorySys; class IFactory; class CTexture; +class CParticleGen; +class CBooModel; class Buckets { @@ -40,19 +42,34 @@ public: class CBooRenderer : public IRenderer { + struct CAreaListItem + { + const std::vector* x0_geometry; + const CAreaOctTree* x4_octTree; + //std::vector> x8_textures; + std::vector x10_models; + int x18_unk; + int x20_unk1 = 0; + int x24_unk2 = 0; + int x28_unk3 = 0; + + CAreaListItem(const std::vector* geom, const CAreaOctTree* octTree, + std::vector&& models, int unk); + ~CAreaListItem(); + }; + IFactory& x8_factory; IObjectStore& xc_store; boo::GraphicsDataToken m_gfxToken; // CFont x10_fnt; u32 x18_ = 0; - std::list x1c_; + std::list x1c_areaListItems; zeus::CFrustum x44_frustumPlanes; TDrawableCallback xa8_renderCallback; const void* xac_callbackContext; - zeus::CVector3f xb0_ = {0.f, 1.f, 0.f}; - float xbc_ = 0; + zeus::CPlane xb0_ = {0.f, 1.f, 0.f, 0.f}; //boo::ITextureS* xe4_blackTex = nullptr; bool xee_24_ : 1; @@ -100,22 +117,25 @@ class CBooRenderer : public IRenderer public: CBooRenderer(IObjectStore& store, IFactory& resFac); - void AddStaticGeometry(const std::vector&, const CAreaOctTree*, int); - void RemoveStaticGeometry(const std::vector&); + void AddWorldSurfaces(CBooModel& model); + + std::list::iterator FindStaticGeometry(const std::vector*); + void AddStaticGeometry(const std::vector*, const CAreaOctTree*, int); + void RemoveStaticGeometry(const std::vector*); void DrawUnsortedGeometry(const std::vector&, int, unsigned int, unsigned int); void DrawSortedGeometry(const std::vector&, int, unsigned int, unsigned int); void DrawStaticGeometry(const std::vector&, int, unsigned int, unsigned int); void PostRenderFogs(); - void AddParticleGen(const CElementGen&); + void AddParticleGen(const CParticleGen&); void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int); void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting); - void SetDrawableCallback(TDrawableCallback, const void*); + void SetDrawableCallback(TDrawableCallback&&, const void*); void SetWorldViewpoint(const zeus::CTransform&); void SetPerspectiveFovScalar(float); void SetPerspective(float, float, float, float, float); void SetPerspective(float, float, float, float); void SetViewportOrtho(bool, float, float); - void SetClippingPlanes(const zeus::CFrustum&); + void SetClippingPlanes(const zeus::CFrustum& frustum); void SetViewport(int, int, int, int); void SetDepthReadWrite(bool, bool); void SetBlendMode_AdditiveAlpha(); diff --git a/Runtime/Graphics/CMakeLists.txt b/Runtime/Graphics/CMakeLists.txt index 3ee8437aa..532a3c36a 100644 --- a/Runtime/Graphics/CMakeLists.txt +++ b/Runtime/Graphics/CMakeLists.txt @@ -11,7 +11,7 @@ set(GRAPHICS_SOURCES CDrawable.hpp CDrawable.cpp CDrawablePlaneObject.hpp CDrawablePlaneObject.cpp CLineRenderer.hpp CLineRenderer.cpp - CMetroidModelInstance.hpp + CMetroidModelInstance.hpp CMetroidModelInstance.cpp CLight.hpp CLight.cpp CTexture.hpp CTextureBoo.cpp CModel.hpp CModelBoo.cpp diff --git a/Runtime/Graphics/CMetroidModelInstance.cpp b/Runtime/Graphics/CMetroidModelInstance.cpp new file mode 100644 index 000000000..2d1d037b7 --- /dev/null +++ b/Runtime/Graphics/CMetroidModelInstance.cpp @@ -0,0 +1,18 @@ +#include "CMetroidModelInstance.hpp" +#include "CModel.hpp" + +namespace urde +{ + +CMetroidModelInstance::CMetroidModelInstance +(const void* modelHeader, std::unique_ptr&& inst) +: x0_visorFlags(hecl::SBig(*static_cast(modelHeader))), m_instance(std::move(inst)) +{ + athena::io::MemoryReader r(static_cast(modelHeader) + 4, INT32_MAX); + x4_xf.read34RowMajor(r); + x34_aabb.readBoundingBoxBig(r); +} + +CMetroidModelInstance::~CMetroidModelInstance() {} + +} diff --git a/Runtime/Graphics/CMetroidModelInstance.hpp b/Runtime/Graphics/CMetroidModelInstance.hpp index a992fe043..21bcf2767 100644 --- a/Runtime/Graphics/CMetroidModelInstance.hpp +++ b/Runtime/Graphics/CMetroidModelInstance.hpp @@ -1,11 +1,26 @@ #ifndef __URDE_CMETROIDMODELINSTANCE_HPP__ #define __URDE_CMETROIDMODELINSTANCE_HPP__ +#include +#include "RetroTypes.hpp" +#include "zeus/CTransform.hpp" +#include "zeus/CAABox.hpp" + namespace urde { +class CBooModel; class CMetroidModelInstance { + friend class CBooRenderer; + + int x0_visorFlags; + zeus::CTransform x4_xf; + zeus::CAABox x34_aabb; + std::unique_ptr m_instance; +public: + CMetroidModelInstance(const void* modelHeader, std::unique_ptr&& inst); + ~CMetroidModelInstance(); }; } diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index c6054aa8b..b1f39f24f 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -45,6 +45,14 @@ struct CBooSurface size_t selfIdx; class CBooModel* m_parent = nullptr; CBooSurface* m_next = nullptr; + + zeus::CAABox GetBounds() const + { + if (!m_data.aabbSz) + return zeus::CAABox(m_data.centroid, m_data.centroid); + else + return zeus::CAABox(m_data.aabb[0], m_data.aabb[1]); + } }; class CBooModel diff --git a/Runtime/Graphics/IRenderer.hpp b/Runtime/Graphics/IRenderer.hpp index aa579faaa..8d088181d 100644 --- a/Runtime/Graphics/IRenderer.hpp +++ b/Runtime/Graphics/IRenderer.hpp @@ -14,7 +14,7 @@ namespace urde class CMetroidModelInstance; class CLight; class CAreaOctTree; -class CElementGen; +class CParticleGen; class CModel; class CSkinnedModel; @@ -26,6 +26,8 @@ public: enum class EDrawableSorting { + SortedBuckets, + UnsortedCallback }; enum class EDebugOption { @@ -38,16 +40,16 @@ public: }; virtual ~IRenderer() = default; - virtual void AddStaticGeometry(const std::vector&, const CAreaOctTree*, int)=0; - virtual void RemoveStaticGeometry(const std::vector&)=0; + virtual void AddStaticGeometry(const std::vector*, const CAreaOctTree*, int)=0; + virtual void RemoveStaticGeometry(const std::vector*)=0; virtual void DrawUnsortedGeometry(const std::vector&, int, unsigned int, unsigned int)=0; virtual void DrawSortedGeometry(const std::vector&, int, unsigned int, unsigned int)=0; virtual void DrawStaticGeometry(const std::vector&, int, unsigned int, unsigned int)=0; virtual void PostRenderFogs()=0; - virtual void AddParticleGen(const CElementGen&)=0; + virtual void AddParticleGen(const CParticleGen&)=0; virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0; virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0; - virtual void SetDrawableCallback(TDrawableCallback, const void*)=0; + virtual void SetDrawableCallback(TDrawableCallback&&, const void*)=0; virtual void SetWorldViewpoint(const zeus::CTransform&)=0; virtual void SetPerspectiveFovScalar(float)=0; virtual void SetPerspective(float, float, float, float, float)=0; diff --git a/hecl b/hecl index 3f867ce40..412af8a3e 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 3f867ce409fa74e6ec33135bf2d294d4fd1d198f +Subproject commit 412af8a3e14d301927bfce72aecebd44cbbb3a0d