From 56e386088adaaebc04210ba0b65c6a7575072d17 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Tue, 18 Apr 2017 13:41:01 -1000 Subject: [PATCH] Additional work on CAutoMapper; CGameArea model setup --- DataSpec/DNACommon/MAPA.cpp | 21 +++- DataSpec/DNACommon/MAPA.hpp | 16 ++- .../DNACommon/Tweaks/ITweakAutoMapper.hpp | 1 + DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp | 3 +- Runtime/AutoMapper/CAutoMapper.cpp | 107 +++++++++++++++++- Runtime/AutoMapper/CAutoMapper.hpp | 5 +- Runtime/AutoMapper/CMapArea.cpp | 24 ++-- Runtime/AutoMapper/CMapArea.hpp | 10 +- Runtime/AutoMapper/CMapWorldInfo.cpp | 8 +- Runtime/AutoMapper/CMapWorldInfo.hpp | 2 +- Runtime/CStateManager.cpp | 2 +- Runtime/Graphics/CBooRenderer.cpp | 2 +- Runtime/Graphics/CMetroidModelInstance.cpp | 2 + Runtime/Graphics/CMetroidModelInstance.hpp | 11 +- Runtime/Graphics/CModel.hpp | 6 +- Runtime/Graphics/CModelBoo.cpp | 12 +- .../Graphics/Shaders/CTexturedQuadFilter.cpp | 30 +++-- .../Graphics/Shaders/CTexturedQuadFilter.hpp | 19 ++-- .../Shaders/CTexturedQuadFilterGLSL.cpp | 6 +- Runtime/World/CGameArea.cpp | 69 ++++++++++- Runtime/World/CGameArea.hpp | 7 +- hecl | 2 +- specter | 2 +- 23 files changed, 300 insertions(+), 67 deletions(-) diff --git a/DataSpec/DNACommon/MAPA.cpp b/DataSpec/DNACommon/MAPA.cpp index a861c2a13..ef13732e3 100644 --- a/DataSpec/DNACommon/MAPA.cpp +++ b/DataSpec/DNACommon/MAPA.cpp @@ -91,6 +91,14 @@ size_t MAPA::binarySize(size_t __isz) const return __isz + 8; } +static const char* RetroMapVisModes[] = +{ + "ALWAYS", + "MAPSTATIONORVISIT", + "VISIT", + "NEVER" +}; + template bool ReadMAPAToBlender(hecl::BlenderConnection& conn, const MAPA& mapa, @@ -112,6 +120,11 @@ bool ReadMAPAToBlender(hecl::BlenderConnection& conn, "bpy.types.Object.retro_mappable_type = bpy.props.IntProperty(name='Retro: MAPA object type', default=-1)\n" "bpy.types.Object.retro_mappable_unk = bpy.props.IntProperty(name='Retro: MAPA object unk')\n" "bpy.types.Object.retro_mappable_sclyid = bpy.props.StringProperty(name='Retro: MAPA object SCLY ID')\n" + "bpy.types.Scene.retro_map_vis_mode = bpy.props.EnumProperty(items=[('ALWAYS', 'Always', 'Always Visible', 0)," + "('MAPSTATIONORVISIT', 'Map Station or Visit', 'Visible after Map Station or Visit', 1)," + "('VISIT', 'Visit', 'Visible after Visit', 2)," + "('NEVER', 'Never', 'Never Visible', 3)]," + "name='Retro: Map Visibility Mode')\n" "\n" "for ar in bpy.context.screen.areas:\n" " for sp in ar.spaces:\n" @@ -142,8 +155,10 @@ bool ReadMAPAToBlender(hecl::BlenderConnection& conn, " edge.seam = True\n" "\n"; - os.format("bpy.context.scene.name = 'MAPA_%s'\n", - entry.id.toString().c_str()); + os.format("bpy.context.scene.name = 'MAPA_%s'\n" + "bpy.context.scene.retro_map_vis_mode = '%s'\n", + entry.id.toString().c_str(), + RetroMapVisModes[mapa.header->visMode()]); /* Add empties representing MappableObjects */ int moIdx = 0; @@ -362,7 +377,7 @@ bool Cook(const hecl::BlenderConnection::DataStream::MapArea& mapaIn, const hecl mapa.header = std::make_unique(); typename MAPAType::Header& header = static_cast(*mapa.header); header.unknown1 = 0; - header.unknown2 = 1; + header.mapVisMode = mapaIn.visType.val; header.boundingBox[0] = aabb.min; header.boundingBox[1] = aabb.max; header.moCount = mapaIn.pois.size(); diff --git a/DataSpec/DNACommon/MAPA.hpp b/DataSpec/DNACommon/MAPA.hpp index 4e86847ed..bcc61ffa8 100644 --- a/DataSpec/DNACommon/MAPA.hpp +++ b/DataSpec/DNACommon/MAPA.hpp @@ -17,6 +17,7 @@ struct MAPA : BigDNA struct IMAPAHeader : BigDNA { Delete _d; + virtual atUint32 visMode() const=0; virtual atUint32 mappableObjectCount() const=0; virtual atUint32 vertexCount() const=0; virtual atUint32 surfaceCount() const=0; @@ -26,21 +27,22 @@ struct MAPA : BigDNA { DECL_DNA Value unknown1 = 0; - Value unknown2 = 0; + Value mapVisMode = 0; Value boundingBox[2] = {}; Value moCount = 0; Value vtxCount = 0; Value surfCount = 0; - virtual atUint32 mappableObjectCount() const { return moCount;} - virtual atUint32 vertexCount() const { return vtxCount; } - virtual atUint32 surfaceCount() const { return surfCount; } + atUint32 visMode() const { return mapVisMode; } + atUint32 mappableObjectCount() const { return moCount;} + atUint32 vertexCount() const { return vtxCount; } + atUint32 surfaceCount() const { return surfCount; } }; struct HeaderMP2 : IMAPAHeader { DECL_DNA Value unknown1 = 0; - Value unknown2 = 0; + Value mapVisMode = 0; Value boundingBox[2] = {}; Value unknown3 = 0; Value unknown4 = 0; @@ -48,6 +50,7 @@ struct MAPA : BigDNA Value moCount = 0; Value vtxCount = 0; Value surfCount = 0; + atUint32 visMode() const { return mapVisMode; } atUint32 mappableObjectCount() const { return moCount;} atUint32 vertexCount() const { return vtxCount; } atUint32 surfaceCount() const { return surfCount; } @@ -57,7 +60,7 @@ struct MAPA : BigDNA { DECL_DNA Value unknown1 = 0; - Value unknown2 = 0; + Value mapVisMode = 0; Value boundingBox[2] = {}; Value unknown3 = 0; Value unknown4 = 0; @@ -69,6 +72,7 @@ struct MAPA : BigDNA Value internalNameLength = 0; Value unknown7 = 0; String internalName; + atUint32 visMode() const { return mapVisMode; } atUint32 mappableObjectCount() const { return moCount;} atUint32 vertexCount() const { return vtxCount; } atUint32 surfaceCount() const { return surfCount; } diff --git a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp index e3a58e810..d765105c0 100644 --- a/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp +++ b/DataSpec/DNACommon/Tweaks/ITweakAutoMapper.hpp @@ -44,6 +44,7 @@ struct ITweakAutoMapper : public ITweak virtual float GetSwitchToFromUniverseTime() const=0; virtual float GetCamPanUnitsPerFrame() const=0; virtual float GetCamVerticalOffset() const=0; + virtual const zeus::CColor& GetMiniMapSamusModColor() const=0; }; } diff --git a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp index 0b315925d..5d0d22b5d 100644 --- a/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp +++ b/DataSpec/DNAMP1/Tweaks/CTweakAutoMapper.hpp @@ -71,7 +71,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper Value xe4_; Value xe8_; Value xec_camVerticalOffset; - DNAColor xf0_; + DNAColor xf0_miniMapSamusModColor; DNAColor xf4_; DNAColor xf8_; DNAColor xfc_; @@ -119,6 +119,7 @@ struct CTweakAutoMapper : public ITweakAutoMapper float GetSwitchToFromUniverseTime() const { return xdc_switchToFromUniverseTime; } float GetCamPanUnitsPerFrame() const { return xe0_camPanUnitsPerFrame; } float GetCamVerticalOffset() const { return xec_camVerticalOffset; } + const zeus::CColor& GetMiniMapSamusModColor() const { return xf0_miniMapSamusModColor; } }; } } diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index 06ba8a7da..acc67bc0e 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -11,6 +11,7 @@ #include "Input/ControlMapper.hpp" #include "GuiSys/CGuiFrame.hpp" #include "GuiSys/CGuiTextPane.hpp" +#include "GuiSys/CGuiWidgetDrawParms.hpp" namespace urde { @@ -1566,9 +1567,111 @@ void CAutoMapper::Draw(const CStateManager& mgr, const zeus::CTransform& xf, flo if (!IsInMapperState(EAutoMapperState::MapScreenUniverse)) { - /* TODO: Finish */ + zeus::CTransform mapXf = planeXf * preXf; + if (x24_world == mgr.GetWorld()) + { + float func = zeus::clamp(0.f, 0.5f * (1.f + std::sin(5.f * CGraphics::GetSecondsMod900() - (M_PIF / 2.f))), 1.f); + float scale = std::min(0.6f * g_tweakAutoMapper->GetMaxCamDist() / g_tweakAutoMapper->GetMinCamDist(), objectScale); + zeus::CEulerAngles eulers(mgr.GetCameraManager()->GetCurrentCameraTransform(mgr)); + float angle = eulers.z - std::floor(eulers.z / (2.f * M_PIF)) * 2.f * M_PIF; + if (angle < 0.f) + angle += 2.f * M_PIF; + zeus::CTransform playerXf(zeus::CMatrix3f::RotateZ(angle), + CMapArea::GetAreaPostTranslate(*x24_world, mgr.GetNextAreaId()) + mgr.GetPlayer().GetTranslation()); + CGraphics::SetModelMatrix(mapXf * playerXf * zeus::CTransform::Scale(scale * (0.25f * func + 0.75f))); + float alpha; + if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) + alpha = 1.f; + else + alpha = xa8_renderStates[0].x34_alphaSurfaceVisited; + alpha *= mapAlpha; + zeus::CColor modColor = g_tweakAutoMapper->GetMiniMapSamusModColor(); + modColor.a *= alpha; + CModelFlags flags(5, 0, 3 | 8 | 1, modColor); + x30_miniMapSamus->Draw(flags); + } + if (IsInMapperState(EAutoMapperState::MapScreen)) + { + ResId wldMlvl = x24_world->IGetWorldAssetId(); + const CMapWorld* mw = x24_world->IGetMapWorld(); + std::vector& hintBeaconFilters = const_cast(*this).m_hintBeaconFilters; + if (hintBeaconFilters.size() < x1f8_hintLocations.size()) + { + hintBeaconFilters.reserve(x1f8_hintLocations.size()); + for (int i=hintBeaconFilters.size() ; iGetMapArea(loc.xc_areaId); + if (!mapa) + continue; + zeus::CTransform camRot(camXf.buildMatrix3f(), zeus::CVector3f::skZero); + CGraphics::SetModelMatrix(mapXf * + zeus::CTransform::Translate(mapa->GetAreaPostTransform(*x24_world, loc.xc_areaId).origin) * + zeus::CTransform::Translate(mapa->GetAreaCenterPoint()) * + zeus::CTransform::Scale(objectScale) * camRot); + float beaconAlpha = 0.f; + if (loc.x0_showBeacon == 1) + beaconAlpha = loc.x4_beaconAlpha; + if (beaconAlpha > 0.f) + { + CTexturedQuadFilter::Vert verts[4] = + { + {{-4.f, -8.f, 8.f}, {0.f, 1.f}}, + {{-4.f, -8.f, 0.f}, {0.f, 0.f}}, + {{4.f, -8.f, 8.f}, {1.f, 1.f}}, + {{4.f, -8.f, 0.f}, {1.f, 0.f}} + }; + float alpha = beaconAlpha; + if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) + {} + else + alpha *= xa8_renderStates[0].x34_alphaSurfaceVisited; + alpha *= mapAlpha; + zeus::CColor color = zeus::CColor::skWhite; + color.a = alpha; + filter.drawVerts(color, verts); + } + } + } } + // No zread, no zwrite + // Ambient color white + // Disable all lights + if (m_frmeInitialized) + { + float frmeAlpha = 0.f; + if (x1bc_state != EAutoMapperState::MiniMap && x1c0_nextState != EAutoMapperState::MiniMap) + { + frmeAlpha = 1.f; + } + else + { + if (x1c0_nextState != EAutoMapperState::MiniMap) + { + if (x1c4_interpDur > 0.f) + frmeAlpha = x1c8_interpTime / x1c4_interpDur; + } + else + { + if (x1c4_interpDur > 0.f) + frmeAlpha = x1c8_interpTime / x1c4_interpDur; + frmeAlpha = 1.f - frmeAlpha; + } + } + CGraphics::SetDepthRange(0.f, 0.f); + CGuiWidgetDrawParms parms(frmeAlpha, zeus::CVector3f::skZero); + x28_frmeMapScreen->Draw(parms); + CGraphics::SetDepthRange(0.f, 1.f / 512.f); + } } void CAutoMapper::TransformRenderStatesWorldToUniverse() @@ -1666,7 +1769,7 @@ ResId CAutoMapper::GetAreaHintDescriptionString(ResId mreaId) { if (hintLoc.xc_areaId != loc.x8_areaId) continue; - if (hintLoc.x4_ > 0.f) + if (hintLoc.x4_beaconAlpha > 0.f) return loc.xc_stringId; } } diff --git a/Runtime/AutoMapper/CAutoMapper.hpp b/Runtime/AutoMapper/CAutoMapper.hpp index d4a0959fe..3a768aa86 100644 --- a/Runtime/AutoMapper/CAutoMapper.hpp +++ b/Runtime/AutoMapper/CAutoMapper.hpp @@ -125,8 +125,8 @@ public: struct SAutoMapperHintLocation { - u32 x0_; - float x4_; + u32 x0_showBeacon; + float x4_beaconAlpha; ResId x8_worldId; TAreaId xc_areaId; }; @@ -172,6 +172,7 @@ private: bool m_frmeInitialized = false; TLockedToken x30_miniMapSamus; TLockedToken x3c_hintBeacon; + std::vector m_hintBeaconFilters; rstl::reserved_vector, 5> x48_mapIcons; ResId x74_areaHintDescId = -1; TLockedToken x78_areaHintDesc; diff --git a/Runtime/AutoMapper/CMapArea.cpp b/Runtime/AutoMapper/CMapArea.cpp index 017267086..4596f369a 100644 --- a/Runtime/AutoMapper/CMapArea.cpp +++ b/Runtime/AutoMapper/CMapArea.cpp @@ -12,7 +12,7 @@ CMapArea::CMapArea(CInputStream& in, u32 size) : x0_magic(in.readUint32()), x4_version(in.readUint32Big()), x8_(in.readUint32Big()), - xc_(in.readUint32Big()), + xc_visibilityMode(EVisMode(in.readUint32Big())), x10_box(zeus::CAABox::ReadBoundingBoxBig(in)), x28_mappableObjCount(in.readUint32Big()), x2c_vertexCount(in.readUint32Big()), @@ -36,8 +36,8 @@ void CMapArea::PostConstruct() u8* tmp = x3c_vertexStart; for (u32 i = 0 ; i<(x2c_vertexCount*3) ; ++i) { - u32* fl = reinterpret_cast(tmp); - *fl = SBIG(*fl); + float* fl = reinterpret_cast(tmp); + *fl = hecl::SBig(*fl); tmp += 4; } #endif @@ -49,15 +49,15 @@ void CMapArea::PostConstruct() bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const { - switch (xc_) + switch (xc_visibilityMode) { - case 0: + case EVisMode::Always: return true; - case 1: + case EVisMode::MapStationOrVisit: return worldVis || areaVis; - case 2: + case EVisMode::Visit: return areaVis; - case 3: + case EVisMode::Never: return false; default: return true; @@ -130,6 +130,14 @@ zeus::CTransform CMapArea::GetAreaPostTransform(const IWorld& world, TAreaId aid } } +const zeus::CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TAreaId aid) +{ + if (world.IGetWorldAssetId() == g_ResFactory->TranslateOriginalToNew(0xB1AC4D65)) // Phazon Mines + return MinesPostTransforms[MinesPostTransformIndices[aid]]; + else + return zeus::CVector3f::skZero; +} + void CMapArea::CMapAreaSurface::PostConstruct(const void *) { } diff --git a/Runtime/AutoMapper/CMapArea.hpp b/Runtime/AutoMapper/CMapArea.hpp index 3fac9d00b..bc4752c25 100644 --- a/Runtime/AutoMapper/CMapArea.hpp +++ b/Runtime/AutoMapper/CMapArea.hpp @@ -20,12 +20,19 @@ public: const zeus::CVector3f& GetNormal() const; const zeus::CVector3f& GetCenterPosition() const; }; + enum class EVisMode + { + Always, + MapStationOrVisit, + Visit, + Never + }; private: u32 x0_magic; u32 x4_version; u32 x8_; - u32 xc_; + EVisMode xc_visibilityMode; zeus::CAABox x10_box; u32 x28_mappableObjCount; u32 x2c_vertexCount; @@ -47,6 +54,7 @@ public: u32 GetNumMappableObjects() const; u32 GetNumSurfaces() const; zeus::CTransform GetAreaPostTransform(const IWorld& world, TAreaId aid) const; + static const zeus::CVector3f& GetAreaPostTranslate(const IWorld& world, TAreaId aid); }; CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in, const CVParamTransfer&, diff --git a/Runtime/AutoMapper/CMapWorldInfo.cpp b/Runtime/AutoMapper/CMapWorldInfo.cpp index b9282e916..c7f7cb181 100644 --- a/Runtime/AutoMapper/CMapWorldInfo.cpp +++ b/Runtime/AutoMapper/CMapWorldInfo.cpp @@ -26,7 +26,7 @@ CMapWorldInfo::CMapWorldInfo(CBitStreamReader& reader, const CSaveWorld& savw, R for (TEditorId doorId : savw.GetDoors()) SetDoorVisited(doorId, reader.ReadEncoded(1)); - x38_worldVisited = reader.ReadEncoded(1); + x38_mapStationUsed = reader.ReadEncoded(1); } void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, ResId mlvlId) const @@ -52,7 +52,7 @@ void CMapWorldInfo::PutTo(CBitStreamWriter& writer, const CSaveWorld& savw, ResI for (TEditorId doorId : savw.GetDoors()) writer.WriteEncoded(IsDoorVisited(doorId), 1); - writer.WriteEncoded(x38_worldVisited, 1); + writer.WriteEncoded(x38_mapStationUsed, 1); } void CMapWorldInfo::SetDoorVisited(TEditorId eid, bool visited) @@ -113,7 +113,7 @@ void CMapWorldInfo::SetIsMapped(TAreaId aid, bool mapped) bool CMapWorldInfo::IsWorldVisible(TAreaId aid) const { - return x38_worldVisited || IsMapped(aid); + return x38_mapStationUsed || IsMapped(aid); } bool CMapWorldInfo::IsAreaVisible(TAreaId aid) const @@ -131,7 +131,7 @@ bool CMapWorldInfo::IsAnythingSet() const for (int i=0 ; i x18_mappedAreas; std::map x28_visitedDoors; - bool x38_worldVisited = false; + bool x38_mapStationUsed = false; public: CMapWorldInfo()=default; CMapWorldInfo(CBitStreamReader&, const CSaveWorld& saveWorld, ResId mlvlId); diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index 79521cb88..def551422 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -681,7 +681,7 @@ void CStateManager::DrawWorld() const if (thermal) { const_cast(*this).xf34_particleFlags = 1; - mask = 52; + mask = 0x34; targetMask = 0; } else diff --git a/Runtime/Graphics/CBooRenderer.cpp b/Runtime/Graphics/CBooRenderer.cpp index a0981c3b2..67aa4704a 100644 --- a/Runtime/Graphics/CBooRenderer.cpp +++ b/Runtime/Graphics/CBooRenderer.cpp @@ -686,7 +686,7 @@ void CBooRenderer::AddStaticGeometry(const std::vector* g int instIdx = 0; for (const CMetroidModelInstance& inst : *geometry) { - models.push_back(inst.m_instance); + models.push_back(inst.m_instance.get()); models.back()->x44_areaInstanceIdx = instIdx++; } } diff --git a/Runtime/Graphics/CMetroidModelInstance.cpp b/Runtime/Graphics/CMetroidModelInstance.cpp index 90325e47b..fafeca12a 100644 --- a/Runtime/Graphics/CMetroidModelInstance.cpp +++ b/Runtime/Graphics/CMetroidModelInstance.cpp @@ -4,6 +4,7 @@ namespace urde { +#if 0 CMetroidModelInstance::CMetroidModelInstance(CBooModel* inst) : x0_visorFlags(0), m_instance(inst) { @@ -20,5 +21,6 @@ CMetroidModelInstance::CMetroidModelInstance } CMetroidModelInstance::~CMetroidModelInstance() {} +#endif } diff --git a/Runtime/Graphics/CMetroidModelInstance.hpp b/Runtime/Graphics/CMetroidModelInstance.hpp index b16a28a2b..46d3220d1 100644 --- a/Runtime/Graphics/CMetroidModelInstance.hpp +++ b/Runtime/Graphics/CMetroidModelInstance.hpp @@ -9,19 +9,22 @@ namespace urde { class CBooModel; +class CBooSurface; class CMetroidModelInstance { friend class CBooRenderer; + friend class CGameArea; int x0_visorFlags; zeus::CTransform x4_xf; zeus::CAABox x34_aabb; - CBooModel* m_instance; + std::vector m_surfaces; + std::unique_ptr m_instance; public: - CMetroidModelInstance(CBooModel* inst); - CMetroidModelInstance(const void* modelHeader, CBooModel* inst); - ~CMetroidModelInstance(); + //CMetroidModelInstance(CBooModel* inst); + //CMetroidModelInstance(const void* modelHeader, CBooModel* inst); + //~CMetroidModelInstance(); }; } diff --git a/Runtime/Graphics/CModel.hpp b/Runtime/Graphics/CModel.hpp index de4a5ed08..56a73ce69 100644 --- a/Runtime/Graphics/CModel.hpp +++ b/Runtime/Graphics/CModel.hpp @@ -99,7 +99,7 @@ private: CBooSurface* x3c_firstSortedSurface = nullptr; bool x40_24_texturesLoaded : 1; bool x40_25_modelVisible : 1; - u8 x41_mask = 0; + u8 x41_mask; u32 x44_areaInstanceIdx = -1; struct UVAnimationBuffer @@ -137,7 +137,8 @@ public: ~CBooModel(); CBooModel(TToken& token, std::vector* surfaces, SShader& shader, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, - size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, int numInsts); + size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, u8 renderMask, + int numInsts); static void MakeTexturesFromMats(const MaterialSet& matSet, std::vector>& toksOut, @@ -191,6 +192,7 @@ class CModel //u32 x4_dataLen; TToken m_selfToken; /* DO NOT LOCK! */ zeus::CAABox m_aabb; + u32 m_flags; std::vector x8_surfaces; std::vector x18_matSets; std::unique_ptr x28_modelInst; diff --git a/Runtime/Graphics/CModelBoo.cpp b/Runtime/Graphics/CModelBoo.cpp index c89a8b4f1..0956acbcf 100644 --- a/Runtime/Graphics/CModelBoo.cpp +++ b/Runtime/Graphics/CModelBoo.cpp @@ -135,11 +135,12 @@ CBooModel::~CBooModel() CBooModel::CBooModel(TToken& token, std::vector* surfaces, SShader& shader, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, - size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, int instCount) + size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb, u8 renderMask, + int instCount) : m_model(token), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_matSetIdx(shader.m_matSetIdx), m_pipelines(&shader.m_shaders), m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount), m_skinBankCount(skinBankCount), x1c_textures(shader.x0_textures), x20_aabb(aabb), - x40_24_texturesLoaded(false), x40_25_modelVisible(0) + x40_24_texturesLoaded(false), x40_25_modelVisible(0), x41_mask(renderMask) { if (!g_FirstModel) g_FirstModel = this; @@ -888,7 +889,8 @@ std::unique_ptr CModel::MakeNewInstance(int shaderIdx, int subInsts) if (shaderIdx >= x18_matSets.size()) shaderIdx = 0; return std::make_unique(m_selfToken, &x8_surfaces, x18_matSets[shaderIdx], - m_vtxFmt, m_vbo, m_ibo, m_weightVecCount, m_skinBankCount, m_aabb, subInsts); + m_vtxFmt, m_vbo, m_ibo, m_weightVecCount, m_skinBankCount, + m_aabb, (m_flags & 0x2) != 0, subInsts); } CModel::CModel(std::unique_ptr&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef) @@ -898,7 +900,7 @@ CModel::CModel(std::unique_ptr&& in, u32 /* dataLen */, IObjectStore* stor std::unique_ptr data = std::move(in); u32 version = hecl::SBig(*reinterpret_cast(data.get() + 0x4)); - u32 flags = hecl::SBig(*reinterpret_cast(data.get() + 0x8)); + m_flags = hecl::SBig(*reinterpret_cast(data.get() + 0x8)); if (version != 0x10002) Log.report(logvisor::Fatal, "invalid CMDL for loading with boo"); @@ -988,7 +990,7 @@ void CBooModel::SShader::UnlockTextures() void CBooModel::VerifyCurrentShader(int shaderIdx) { - if (shaderIdx != m_matSetIdx) + if (shaderIdx != m_matSetIdx && m_model) RemapMaterialData(m_model->x18_matSets[shaderIdx]); } diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp index 9a033f11d..09a8ba798 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.cpp @@ -32,10 +32,10 @@ void CTexturedQuadFilter::draw(const zeus::CColor& color, float uvScale, const z { Vert verts[4] = { - {{0.f, 0.f}, {0.f, 0.f}}, - {{0.f, 1.f}, {0.f, 1.f}}, - {{1.f, 0.f}, {1.f, 0.f}}, - {{1.f, 1.f}, {1.f, 1.f}}, + {{0.f, 0.f, 0.f}, {0.f, 0.f}}, + {{0.f, 1.f, 0.f}, {0.f, uvScale}}, + {{1.f, 0.f, 0.f}, {uvScale, 0.f}}, + {{1.f, 1.f, 0.f}, {uvScale, uvScale}}, }; m_vbo->load(verts, sizeof(verts)); @@ -44,7 +44,6 @@ void CTexturedQuadFilter::draw(const zeus::CColor& color, float uvScale, const z m_uniform.m_matrix[3][0] = rect.position.x * 2.f - 1.f; m_uniform.m_matrix[3][1] = rect.position.y * 2.f - 1.f; m_uniform.m_color = color; - m_uniform.m_uvScale = uvScale; m_uniBuf->load(&m_uniform, sizeof(m_uniform)); CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind); @@ -60,15 +59,26 @@ void CTexturedQuadFilter::drawCropped(const zeus::CColor& color, float uvScale) Vert verts[4] = { - {{-1.0, -1.0}, {xBias, yBias}}, - {{-1.0, 1.0}, {xBias, yBias + yFac}}, - {{ 1.0, -1.0}, {xBias + xFac, yBias}}, - {{ 1.0, 1.0}, {xBias + xFac, yBias + yFac}}, + {{-1.0, -1.0, 0.f}, {xBias * uvScale, yBias * uvScale}}, + {{-1.0, 1.0, 0.f}, {xBias * uvScale, (yBias + yFac) * uvScale}}, + {{ 1.0, -1.0, 0.f}, {(xBias + xFac) * uvScale, yBias * uvScale}}, + {{ 1.0, 1.0, 0.f}, {(xBias + xFac) * uvScale, (yBias + yFac) * uvScale}}, }; m_vbo->load(verts, sizeof(verts)); m_uniform.m_color = color; - m_uniform.m_uvScale = uvScale; + m_uniBuf->load(&m_uniform, sizeof(m_uniform)); + + CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind); + CGraphics::g_BooMainCommandQueue->draw(0, 4); +} + +void CTexturedQuadFilter::drawVerts(const zeus::CColor& color, const Vert verts[4]) +{ + m_vbo->load(verts, sizeof(Vert) * 4); + + m_uniform.m_matrix = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f(); + m_uniform.m_color = color; m_uniBuf->load(&m_uniform, sizeof(m_uniform)); CGraphics::g_BooMainCommandQueue->setShaderDataBinding(m_dataBind); diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp b/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp index ac613bc2c..4ecfab111 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilter.hpp @@ -19,17 +19,10 @@ class CTexturedQuadFilter friend struct CTexturedQuadFilterD3DDataBindingFactory; protected: - struct Vert - { - zeus::CVector2f m_pos; - zeus::CVector2f m_uv; - }; - struct Uniform { zeus::CMatrix4f m_matrix; zeus::CColor m_color; - float m_uvScale; }; TLockedToken m_tex; boo::ITexture* m_booTex; @@ -40,12 +33,24 @@ protected: Uniform m_uniform; CTexturedQuadFilter(boo::ITexture* tex); + public: + struct Vert + { + zeus::CVector3f m_pos; + zeus::CVector2f m_uv; + }; + static const zeus::CRectangle DefaultRect; CTexturedQuadFilter(CCameraFilterPass::EFilterType type, TLockedToken tex); CTexturedQuadFilter(CCameraFilterPass::EFilterType type, boo::ITexture* tex); + CTexturedQuadFilter(const CTexturedQuadFilter&) = delete; + CTexturedQuadFilter& operator=(const CTexturedQuadFilter&) = delete; + CTexturedQuadFilter(CTexturedQuadFilter&&) = default; + CTexturedQuadFilter& operator=(CTexturedQuadFilter&&) = default; void draw(const zeus::CColor& color, float uvScale, const zeus::CRectangle& rect=DefaultRect); void drawCropped(const zeus::CColor& color, float uvScale); + void drawVerts(const zeus::CColor& color, const Vert verts[4]); const TLockedToken& GetTex() const { return m_tex; } using _CLS = CTexturedQuadFilter; diff --git a/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp b/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp index 6f371ca58..ee649954a 100644 --- a/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp +++ b/Runtime/Graphics/Shaders/CTexturedQuadFilterGLSL.cpp @@ -15,7 +15,6 @@ BOO_GLSL_BINDING_HEAD "{\n" " mat4 mtx;\n" " vec4 color;\n" -" float uvScale;\n" "};\n" "\n" "struct VertToFrag\n" @@ -28,7 +27,7 @@ BOO_GLSL_BINDING_HEAD "void main()\n" "{\n" " vtf.color = color;\n" -" vtf.uv = uvIn.xy * uvScale;\n" +" vtf.uv = uvIn.xy;\n" " gl_Position = mtx * vec4(posIn.xyz, 1.0);\n" " gl_Position = FLIPFROMGL(gl_Position);\n" "}\n"; @@ -43,7 +42,6 @@ BOO_GLSL_BINDING_HEAD "{\n" " mat4 mtx;\n" " vec4 color;\n" -" float uvScale;\n" "};\n" "\n" "struct VertToFrag\n" @@ -56,7 +54,7 @@ BOO_GLSL_BINDING_HEAD "void main()\n" "{\n" " vtf.color = color;\n" -" vtf.uv = -uvIn.xy * uvScale;\n" +" vtf.uv = -uvIn.xy;\n" " gl_Position = mtx * vec4(posIn.xyz, 1.0);\n" " gl_Position = FLIPFROMGL(gl_Position);\n" "}\n"; diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index c18efed7d..9da745d26 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -5,6 +5,7 @@ #include "CStateManager.hpp" #include "World/CScriptAreaAttributes.hpp" #include "CGameState.hpp" +#include "DataSpec/DNAMP1/MREA.hpp" namespace urde { @@ -566,7 +567,7 @@ void CGameArea::AddStaticGeometry() { x12c_postConstructed->x10e0_ = 0; x12c_postConstructed->x10dc_occlusionState = EOcclusionState::Visible; - if (!x12c_postConstructed->x1108_25_) + if (!x12c_postConstructed->x1108_25_modelsConstructed) FillInStaticGeometry(); g_Renderer->AddStaticGeometry(&x12c_postConstructed->x4c_insts, x12c_postConstructed->xc_octTree ? @@ -825,6 +826,7 @@ void CGameArea::PostConstructArea() u32 sec = 3; /* Models */ + x12c_postConstructed->x4c_insts.reserve(header.modelCount); for (u32 i=0 ; i((secIt+4)->first)); @@ -947,6 +949,71 @@ void CGameArea::FillInStaticGeometry() { x12c_postConstructed->x4c_insts.clear(); + /* Materials */ + auto secIt = m_resolvedBufs.begin() + 2; + { + athena::io::MemoryReader r(secIt->first, secIt->second); + x12c_postConstructed->m_materialSet.m_matSet.read(r); + ++secIt; + } + + x12c_postConstructed->m_gfxToken = CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) -> bool + { + /* Models */ + for (u32 i=0 ; ix4c_insts.capacity() ; ++i) + { + x12c_postConstructed->x4c_insts.emplace_back(); + CMetroidModelInstance& inst = x12c_postConstructed->x4c_insts.back(); + + { + DataSpec::DNAMP1::MREA::MeshHeader header; + athena::io::MemoryReader r(secIt->first, secIt->second); + header.read(r); + inst.x0_visorFlags = header.visorFlags.flags; + inst.x4_xf = header.xfMtx; + inst.x34_aabb = zeus::CAABox(header.aabb[0], header.aabb[1]); + ++secIt; + } + + hecl::HMDLMeta hmdlMeta; + { + athena::io::MemoryReader r(secIt->first, secIt->second); + hmdlMeta.read(r); + } + ++secIt; + + boo::IGraphicsBufferS* vbo; + boo::IGraphicsBufferS* ibo; + boo::IVertexFormat* vtxFmt; + vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, secIt->first, hmdlMeta.vertStride, hmdlMeta.vertCount); + ++secIt; + ibo = ctx.newStaticBuffer(boo::BufferUse::Index, secIt->first, 4, hmdlMeta.indexCount); + ++secIt; + vtxFmt = hecl::Runtime::HMDLData::NewVertexFormat(ctx, hmdlMeta, vbo, ibo); + + u32 surfCount = hecl::SBig(*reinterpret_cast(secIt->first)); + inst.m_surfaces.reserve(surfCount); + ++secIt; + for (u32 i=0 ; ifirst, secIt->second); + surf.m_data.read(r); + ++secIt; + } + + TToken nullModel; + inst.m_instance = std::make_unique + (nullModel, &inst.m_surfaces, x12c_postConstructed->m_materialSet, vtxFmt, vbo, ibo, + hmdlMeta.weightCount, hmdlMeta.bankCount, inst.x34_aabb, inst.x0_visorFlags, 1); + } + + return true; + }); + + x12c_postConstructed->x1108_25_modelsConstructed = true; } void CGameArea::VerifyTokenList(CStateManager& stateMgr) diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 808a0cae4..949b15744 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -14,6 +14,7 @@ #include "CWorldLight.hpp" #include "Graphics/CPVSAreaSet.hpp" #include "Graphics/CGraphics.hpp" +#include "Graphics/CModel.hpp" #include "CPathFindArea.hpp" #include "Editor/ProjectResourceFactoryBase.hpp" @@ -195,6 +196,8 @@ public: u32 x8_collisionSize = 0; std::experimental::optional xc_octTree; std::vector x4c_insts; + CBooModel::SShader m_materialSet = {0}; + boo::GraphicsDataToken m_gfxToken; //std::unique_ptr x5c_; std::vector x60_lightsA; std::vector x70_gfxLightsA; @@ -230,14 +233,14 @@ public: struct { bool x1108_24_ : 1; - bool x1108_25_ : 1; + bool x1108_25_modelsConstructed : 1; bool x1108_26_ : 1; bool x1108_27_ : 1; bool x1108_28_ : 1; bool x1108_29_ : 1; bool x1108_30_ : 1; }; - u8 _dummy = 0; + u32 _dummy = 0; }; std::vector> x110c_layerPtrs; float x111c_thermalCurrent = 0.f; diff --git a/hecl b/hecl index 8fb54452d..eca3f3fdf 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit 8fb54452d2b5edecb3b98f0fb0e07ed4c860cd02 +Subproject commit eca3f3fdfad2f2558a98b0e193a63011cb76d02d diff --git a/specter b/specter index fcec6f102..07daf4082 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit fcec6f102176a49bede4693e6d5dbabf7c4dce00 +Subproject commit 07daf408244c41188e90bbf3e7a78be37a1d0dce