#include "CMapArea.hpp" #include "GameGlobalObjects.hpp" #include "CMappableObject.hpp" #include "CToken.hpp" #include "World/CWorld.hpp" #include "World/CGameArea.hpp" #include "CResFactory.hpp" namespace urde { CMapArea::CMapArea(CInputStream& in, u32 size) : x0_magic(in.readUint32()), x4_version(in.readUint32Big()), x8_(in.readUint32Big()), xc_visibilityMode(EVisMode(in.readUint32Big())), x10_box(zeus::CAABox::ReadBoundingBoxBig(in)), x28_mappableObjCount(in.readUint32Big()), x2c_vertexCount(in.readUint32Big()), x30_surfaceCount(in.readUint32Big()), x34_size(size - 52) { x44_buf.reset(new u8[x34_size]); in.readUBytesToBuf(x44_buf.get(), x34_size); PostConstruct(); } void CMapArea::PostConstruct() { x38_moStart = x44_buf.get(); x3c_vertexStart = x38_moStart + (x28_mappableObjCount * 0x50); x40_surfaceStart = x3c_vertexStart + (x2c_vertexCount * 12); m_mappableObjects.reserve(x28_mappableObjCount); for (u32 i = 0, j=0 ; i(tmp); m_verts.emplace_back(hecl::SBig(fl[0]), hecl::SBig(fl[1]), hecl::SBig(fl[2])); tmp += 12; } std::vector index; m_surfaces.reserve(x30_surfaceCount); for (u32 i = 0, j = 0 ; i& linePrims = instance.m_linePrims; linePrims.reserve(outlineCount * 2); for (u32 j=0 ; j<2 ; ++j) { r.seek(4, athena::SeekOrigin::Begin); for (u32 i=0 ; iTranslateOriginalToNew(0xB1AC4D65)) // Phazon Mines { const zeus::CTransform& areaXf = world.IGetAreaAlways(aid)->IGetTM(); const zeus::CVector3f& postVec = MinesPostTransforms[MinesPostTransformIndices[aid]]; return zeus::CTransform::Translate(postVec) * areaXf; } else { return world.IGetAreaAlways(aid)->IGetTM(); } } 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; } CMapArea::CMapAreaSurface::CMapAreaSurface(const void* surfBuf) { athena::io::MemoryReader r(surfBuf, 32); x0_normal = r.readVec3fBig(); xc_centroid = r.readVec3fBig(); x18_surfOffset = reinterpret_cast(uintptr_t(r.readUint32Big())); x1c_outlineOffset = reinterpret_cast(uintptr_t(r.readUint32Big())); } void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector& index) { x18_surfOffset = buf + reinterpret_cast(x18_surfOffset); x1c_outlineOffset = buf + reinterpret_cast(x1c_outlineOffset); m_primStart = index.size(); bool start = true; { athena::io::MemoryReader r(x18_surfOffset, INT_MAX); u32 primCount = r.readUint32Big(); for (u32 i=0 ; i= m_instances.size()) return; Instance& instance = const_cast(m_instances[instIdx]); if (surfColor.a) instance.m_surfacePrims.draw(surfColor, m_primStart, m_primCount); if (lineColor.a) { bool draw2 = lineWidth > 1.f; athena::io::MemoryReader r(x1c_outlineOffset, INT_MAX); u32 outlineCount = r.readUint32Big(); std::vector& linePrims = instance.m_linePrims; zeus::CColor color = lineColor; if (draw2) color.a *= 0.5f; float width = lineWidth; auto primIt = linePrims.begin(); for (u32 j=0 ; j<=u32(draw2) ; ++j) { r.seek(4, athena::SeekOrigin::Begin); for (u32 i=0 ; iResourceSize(objTag); return TToken::GetIObjObjectFor(std::make_unique(in, size)); } }