mirror of https://github.com/AxioDL/metaforce.git
Work on CMapWorld rendering
This commit is contained in:
parent
56e386088a
commit
337ffd1c16
|
@ -45,6 +45,8 @@ struct ITweakAutoMapper : public ITweak
|
|||
virtual float GetCamPanUnitsPerFrame() const=0;
|
||||
virtual float GetCamVerticalOffset() const=0;
|
||||
virtual const zeus::CColor& GetMiniMapSamusModColor() const=0;
|
||||
virtual const zeus::CColor& GetDoorColor(int idx) const=0;
|
||||
virtual const zeus::CColor& GetOpenDoorColor() const=0;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -120,6 +120,8 @@ struct CTweakAutoMapper : public ITweakAutoMapper
|
|||
float GetCamPanUnitsPerFrame() const { return xe0_camPanUnitsPerFrame; }
|
||||
float GetCamVerticalOffset() const { return xec_camVerticalOffset; }
|
||||
const zeus::CColor& GetMiniMapSamusModColor() const { return xf0_miniMapSamusModColor; }
|
||||
const zeus::CColor& GetDoorColor(int idx) const { return x104_doorColors[idx]; }
|
||||
const zeus::CColor& GetOpenDoorColor() const { return x11c_openDoorColor; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,10 +29,14 @@ void CMapArea::PostConstruct()
|
|||
x38_moStart = x44_buf.get();
|
||||
x3c_vertexStart = x38_moStart + (x28_mappableObjCount * 0x50);
|
||||
x40_surfaceStart = x40_surfaceStart + (x2c_vertexCount * 12);
|
||||
for (u32 i = 0, j=0 ; i<x28_mappableObjCount ; ++i, j += 0x50)
|
||||
(reinterpret_cast<CMappableObject*>(x38_moStart + j))->PostConstruct(x44_buf.get());
|
||||
|
||||
#if __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
|
||||
m_mappableObjects.reserve(x28_mappableObjCount);
|
||||
for (u32 i = 0, j=0 ; i<x28_mappableObjCount ; ++i, j += 0x50)
|
||||
{
|
||||
m_mappableObjects.emplace_back(x38_moStart + j);
|
||||
m_mappableObjects.back().PostConstruct(x44_buf.get());
|
||||
}
|
||||
|
||||
u8* tmp = x3c_vertexStart;
|
||||
for (u32 i = 0 ; i<(x2c_vertexCount*3) ; ++i)
|
||||
{
|
||||
|
@ -40,11 +44,29 @@ void CMapArea::PostConstruct()
|
|||
*fl = hecl::SBig(*fl);
|
||||
tmp += 4;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
std::vector<u32> index;
|
||||
m_surfaces.reserve(x30_surfaceCount);
|
||||
for (u32 i = 0, j = 0 ; i<x30_surfaceCount ; ++i, j += 32)
|
||||
(reinterpret_cast<CMapAreaSurface*>(x40_surfaceStart + j))->PostConstruct(x44_buf.get());
|
||||
{
|
||||
m_surfaces.emplace_back(x40_surfaceStart + j);
|
||||
m_surfaces.back().PostConstruct(x44_buf.get(), index);
|
||||
}
|
||||
|
||||
m_gfxToken = CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, x3c_vertexStart, 12, x2c_vertexCount);
|
||||
m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size());
|
||||
for (u32 i = 0 ; i<x30_surfaceCount ; ++i)
|
||||
m_surfaces[i].m_surfacePrims.emplace(ctx, m_vbo, m_ibo);
|
||||
for (u32 i = 0 ; i<x28_mappableObjCount ; ++i)
|
||||
{
|
||||
CMappableObject& mapObj = m_mappableObjects[i];
|
||||
if (CMappableObject::IsDoorType(mapObj.GetType()))
|
||||
mapObj.m_doorSurface.emplace(ctx);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const
|
||||
|
@ -138,8 +160,151 @@ const zeus::CVector3f& CMapArea::GetAreaPostTranslate(const IWorld& world, TArea
|
|||
return zeus::CVector3f::skZero;
|
||||
}
|
||||
|
||||
void CMapArea::CMapAreaSurface::PostConstruct(const void *)
|
||||
CMapArea::CMapAreaSurface::CMapAreaSurface(const void* surfBuf)
|
||||
{
|
||||
athena::io::MemoryReader r(surfBuf, 32);
|
||||
x0_normal = r.readVec3fBig();
|
||||
xc_centroid = r.readVec3fBig();
|
||||
x18_surfOffset = reinterpret_cast<const u8*>(uintptr_t(r.readUint32Big()));
|
||||
x1c_outlineOffset = reinterpret_cast<const u8*>(uintptr_t(r.readUint32Big()));
|
||||
}
|
||||
|
||||
void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector<u32>& index)
|
||||
{
|
||||
x18_surfOffset = buf + reinterpret_cast<uintptr_t>(x18_surfOffset);
|
||||
x1c_outlineOffset = buf + reinterpret_cast<uintptr_t>(x1c_outlineOffset);
|
||||
|
||||
m_primStart = index.size();
|
||||
{
|
||||
athena::io::MemoryReader r(x18_surfOffset, INT_MAX);
|
||||
u32 primCount = r.readUint32Big();
|
||||
for (u32 i=0 ; i<primCount ; ++i)
|
||||
{
|
||||
GX::Primitive prim = GX::Primitive(r.readUint32Big());
|
||||
u32 count = r.readUint32Big();
|
||||
switch (prim)
|
||||
{
|
||||
case GX::Primitive::TRIANGLES:
|
||||
{
|
||||
for (u32 v=0 ; v<count ; v+=3)
|
||||
{
|
||||
if (index.size())
|
||||
{
|
||||
index.push_back(index.back());
|
||||
index.push_back(r.readUByte());
|
||||
index.push_back(index.back());
|
||||
}
|
||||
else
|
||||
{
|
||||
index.push_back(r.readUByte());
|
||||
}
|
||||
index.push_back(r.readUByte());
|
||||
index.push_back(r.readUByte());
|
||||
index.push_back(index.back());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GX::Primitive::TRIANGLESTRIP:
|
||||
{
|
||||
if (index.size())
|
||||
{
|
||||
index.push_back(index.back());
|
||||
index.push_back(r.readUByte());
|
||||
index.push_back(index.back());
|
||||
}
|
||||
else
|
||||
{
|
||||
index.push_back(r.readUByte());
|
||||
}
|
||||
for (u32 v=1 ; v<count ; ++v)
|
||||
index.push_back(r.readUByte());
|
||||
if (count & 1)
|
||||
index.push_back(index.back());
|
||||
break;
|
||||
}
|
||||
case GX::Primitive::TRIANGLEFAN:
|
||||
{
|
||||
u8 firstVert = r.readUByte();
|
||||
if (index.size())
|
||||
{
|
||||
index.push_back(index.back());
|
||||
index.push_back(r.readUByte());
|
||||
}
|
||||
else
|
||||
{
|
||||
index.push_back(r.readUByte());
|
||||
index.push_back(index.back());
|
||||
}
|
||||
for (u32 v=1 ; v<count ; ++v)
|
||||
{
|
||||
index.push_back(firstVert);
|
||||
index.push_back(r.readUByte());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
r.seekAlign4();
|
||||
}
|
||||
}
|
||||
m_primCount = index.size() - m_primStart;
|
||||
}
|
||||
|
||||
void CMapArea::CMapAreaSurface::Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor,
|
||||
const zeus::CColor& lineColor, float lineWidth) const
|
||||
{
|
||||
if (surfColor.a)
|
||||
const_cast<CMapSurfaceShader&>(*m_surfacePrims).draw(surfColor, m_primStart, m_primCount);
|
||||
|
||||
if (lineColor.a)
|
||||
{
|
||||
bool draw2 = lineWidth > 1.f;
|
||||
int totalPrims = draw2 + 1;
|
||||
athena::io::MemoryReader r(x1c_outlineOffset, INT_MAX);
|
||||
u32 outlineCount = r.readUint32Big();
|
||||
totalPrims *= outlineCount;
|
||||
|
||||
std::vector<CLineRenderer>& linePrims = const_cast<std::vector<CLineRenderer>&>(m_linePrims);
|
||||
if (linePrims.size() < totalPrims)
|
||||
{
|
||||
linePrims.reserve(totalPrims);
|
||||
for (u32 j=0 ; j<=draw2 ; ++j)
|
||||
{
|
||||
r.seek(4, athena::SeekOrigin::Begin);
|
||||
for (u32 i=0 ; i<outlineCount ; ++i)
|
||||
{
|
||||
u32 count = r.readUint32Big();
|
||||
r.seek(count);
|
||||
r.seekAlign4();
|
||||
linePrims.emplace_back(CLineRenderer::EPrimitiveMode::LineStrip, count, nullptr, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zeus::CColor color = lineColor;
|
||||
if (draw2)
|
||||
color.a *= 0.5f;
|
||||
float width = lineWidth;
|
||||
|
||||
auto primIt = linePrims.begin();
|
||||
for (u32 j=0 ; j<=draw2 ; ++j)
|
||||
{
|
||||
r.seek(4, athena::SeekOrigin::Begin);
|
||||
for (u32 i=0 ; i<outlineCount ; ++i)
|
||||
{
|
||||
CLineRenderer& prim = *primIt++;
|
||||
prim.Reset();
|
||||
u32 count = r.readUint32Big();
|
||||
for (u32 v=0 ; v<count ; ++v)
|
||||
{
|
||||
u8 idx = r.readUByte();
|
||||
prim.AddVertex(verts[idx], color, width);
|
||||
}
|
||||
prim.Render();
|
||||
}
|
||||
width -= 1.f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in, const CVParamTransfer&,
|
||||
|
|
|
@ -5,6 +5,10 @@
|
|||
#include "CResFactory.hpp"
|
||||
#include "zeus/CAABox.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||
#include "Graphics/CLineRenderer.hpp"
|
||||
#include "Graphics/Shaders/CMapSurfaceShader.hpp"
|
||||
#include "CMappableObject.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -14,11 +18,23 @@ class CMapArea
|
|||
public:
|
||||
class CMapAreaSurface
|
||||
{
|
||||
friend class CMapArea;
|
||||
zeus::CVector3f x0_normal;
|
||||
zeus::CVector3f xc_centroid;
|
||||
const u8* x18_surfOffset;
|
||||
const u8* x1c_outlineOffset;
|
||||
u32 m_primStart;
|
||||
u32 m_primCount;
|
||||
std::experimental::optional<CMapSurfaceShader> m_surfacePrims;
|
||||
std::vector<CLineRenderer> m_linePrims;
|
||||
public:
|
||||
void PostConstruct(const void*);
|
||||
void Draw(const zeus::CVector3f*, const zeus::CColor&, const zeus::CColor&, float) const;
|
||||
const zeus::CVector3f& GetNormal() const;
|
||||
const zeus::CVector3f& GetCenterPosition() const;
|
||||
CMapAreaSurface(const void* surfBuf);
|
||||
CMapAreaSurface(CMapAreaSurface&&) = default;
|
||||
void PostConstruct(const u8* buf, std::vector<u32>& index);
|
||||
void Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor,
|
||||
const zeus::CColor& lineColor, float lineWidth) const;
|
||||
const zeus::CVector3f& GetNormal() const { return x0_normal; }
|
||||
const zeus::CVector3f& GetCenterPosition() const { return xc_centroid; }
|
||||
};
|
||||
enum class EVisMode
|
||||
{
|
||||
|
@ -39,20 +55,25 @@ private:
|
|||
u32 x30_surfaceCount;
|
||||
u32 x34_size;
|
||||
u8* x38_moStart;
|
||||
std::vector<CMappableObject> m_mappableObjects;
|
||||
u8* x3c_vertexStart;
|
||||
u8* x40_surfaceStart;
|
||||
std::vector<CMapAreaSurface> m_surfaces;
|
||||
std::unique_ptr<u8[]> x44_buf;
|
||||
boo::GraphicsDataToken m_gfxToken;
|
||||
boo::IGraphicsBufferS* m_vbo;
|
||||
boo::IGraphicsBufferS* m_ibo;
|
||||
|
||||
public:
|
||||
CMapArea(CInputStream&, u32);
|
||||
CMapArea(CInputStream& in, u32 size);
|
||||
void PostConstruct();
|
||||
bool GetIsVisibleToAutoMapper(bool, bool) const;
|
||||
bool GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const;
|
||||
zeus::CVector3f GetAreaCenterPoint() const { return x10_box.center(); }
|
||||
const zeus::CAABox& GetBoundingBox() const { return x10_box; }
|
||||
const zeus::CVector3f& GetVertices() const;
|
||||
void GetMappableObject(s32) const;
|
||||
void GetSurface(s32) const;
|
||||
u32 GetNumMappableObjects() const;
|
||||
u32 GetNumSurfaces() const;
|
||||
const CMappableObject& GetMappableObject(int idx) const { return m_mappableObjects[idx]; }
|
||||
const CMapAreaSurface& GetSurface(int idx) const { return m_surfaces[idx]; }
|
||||
u32 GetNumMappableObjects() const { return m_mappableObjects.size(); }
|
||||
u32 GetNumSurfaces() const { return m_surfaces.size(); }
|
||||
zeus::CTransform GetAreaPostTransform(const IWorld& world, TAreaId aid) const;
|
||||
static const zeus::CVector3f& GetAreaPostTranslate(const IWorld& world, TAreaId aid);
|
||||
};
|
||||
|
|
|
@ -1,31 +1,102 @@
|
|||
#include "CMapWorld.hpp"
|
||||
#include "CMapWorldInfo.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "World/CWorld.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CMapWorld::CMapAreaData::CMapAreaData(ResId areaRes, EMapAreaList list, CMapAreaData* next)
|
||||
: x0_area(g_SimplePool->GetObj(SObjectTag{FOURCC('MAPA'), areaRes})), x10_list(list), x14_next(next)
|
||||
{}
|
||||
|
||||
CMapWorld::CMapWorld(CInputStream& in)
|
||||
{
|
||||
x10_listHeads.resize(3);
|
||||
in.readUint32Big();
|
||||
in.readUint32Big();
|
||||
u32 areaCount = in.readUint32Big();
|
||||
x0_areas.reserve(areaCount);
|
||||
x20_traversed.resize(areaCount);
|
||||
for (u32 i=0 ; i<areaCount ; ++i)
|
||||
{
|
||||
ResId mapaId = in.readUint32Big();
|
||||
x0_areas.emplace_back(mapaId, EMapAreaList::Unloaded, x0_areas.empty() ? nullptr : &x0_areas.back());
|
||||
}
|
||||
x10_listHeads[2] = &x0_areas.back();
|
||||
}
|
||||
|
||||
void CMapWorld::IsMapAreaInBFSInfoVector(const CMapWorld::CMapAreaData*, const std::vector<CMapWorld::CMapAreaBFSInfo>&) const
|
||||
bool CMapWorld::IsMapAreaInBFSInfoVector(const CMapWorld::CMapAreaData* area,
|
||||
const std::vector<CMapWorld::CMapAreaBFSInfo>& vec) const
|
||||
{
|
||||
|
||||
for (const CMapWorld::CMapAreaBFSInfo& bfs : vec)
|
||||
{
|
||||
if (&x0_areas[bfs.GetAreaIndex()] == area)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CMapWorld::SetWhichMapAreasLoaded(const IWorld&, int start, int count)
|
||||
void CMapWorld::SetWhichMapAreasLoaded(const IWorld& wld, int start, int count)
|
||||
{
|
||||
ClearTraversedFlags();
|
||||
|
||||
std::vector<CMapAreaBFSInfo> bfsInfos;
|
||||
bfsInfos.reserve(x0_areas.size());
|
||||
DoBFS(wld, start, count, 9999.f, 9999.f, false, bfsInfos);
|
||||
|
||||
for (int i=0 ; i<2 ; ++i)
|
||||
{
|
||||
for (CMapAreaData* data = x10_listHeads[i] ; data ; data = data->NextMapAreaData())
|
||||
{
|
||||
if (!IsMapAreaInBFSInfoVector(data, bfsInfos))
|
||||
{
|
||||
data->Unlock();
|
||||
MoveMapAreaToList(data, EMapAreaList::Unloaded);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (CMapAreaBFSInfo& bfs : bfsInfos)
|
||||
{
|
||||
CMapAreaData& data = x0_areas[bfs.GetAreaIndex()];
|
||||
data.Lock();
|
||||
if (data.GetContainingList() == EMapAreaList::Unloaded)
|
||||
MoveMapAreaToList(&data, EMapAreaList::Loading);
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapWorld::IsMapAreasStreaming() const
|
||||
{
|
||||
return false;
|
||||
bool ret = false;
|
||||
for (CMapAreaData* data = x10_listHeads[1] ; data ; data = data->NextMapAreaData())
|
||||
{
|
||||
if (data->IsLoaded())
|
||||
const_cast<CMapWorld*>(this)->MoveMapAreaToList(data, EMapAreaList::Loaded);
|
||||
else
|
||||
ret = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CMapWorld::MoveMapAreaToList(CMapWorld::CMapAreaData*, CMapWorld::EMapAreaList)
|
||||
void CMapWorld::MoveMapAreaToList(CMapWorld::CMapAreaData* data, CMapWorld::EMapAreaList list)
|
||||
{
|
||||
|
||||
CMapAreaData* last = nullptr;
|
||||
for (CMapAreaData* head = x10_listHeads[int(data->GetContainingList())] ;;
|
||||
last = head, head = head->NextMapAreaData())
|
||||
{
|
||||
if (head != data)
|
||||
continue;
|
||||
if (!last)
|
||||
x10_listHeads[int(data->GetContainingList())] = head->NextMapAreaData();
|
||||
else
|
||||
last->SetNextMapArea(head->NextMapAreaData());
|
||||
break;
|
||||
}
|
||||
data->SetNextMapArea(x10_listHeads[int(list)]);
|
||||
data->SetContainingList(list);
|
||||
x10_listHeads[int(list)] = data;
|
||||
}
|
||||
|
||||
s32 CMapWorld::GetCurrentMapAreaDepth(const IWorld& wld, TAreaId aid) const
|
||||
|
@ -39,9 +110,9 @@ s32 CMapWorld::GetCurrentMapAreaDepth(const IWorld& wld, TAreaId aid) const
|
|||
return info.back().GetDepth();
|
||||
}
|
||||
|
||||
std::vector<TAreaId> CMapWorld::GetVisibleAreas(const IWorld& wld, const CMapWorldInfo& mwInfo) const
|
||||
std::vector<int> CMapWorld::GetVisibleAreas(const IWorld& wld, const CMapWorldInfo& mwInfo) const
|
||||
{
|
||||
std::vector<TAreaId> ret;
|
||||
std::vector<int> ret;
|
||||
ret.reserve(x0_areas.size());
|
||||
for (int i=0 ; i<x0_areas.size() ; ++i)
|
||||
{
|
||||
|
@ -56,29 +127,439 @@ std::vector<TAreaId> CMapWorld::GetVisibleAreas(const IWorld& wld, const CMapWor
|
|||
return ret;
|
||||
}
|
||||
|
||||
void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms&, int, int, float, float, bool) const
|
||||
void CMapWorld::Draw(const CMapWorld::CMapWorldDrawParms& parms, int curArea, int otherArea,
|
||||
float depth1, float depth2, bool inMapScreen) const
|
||||
{
|
||||
if (depth1 == 0.f && depth2 == 0.f)
|
||||
return;
|
||||
|
||||
ClearTraversedFlags();
|
||||
int areaDepth = std::ceil(std::max(depth1, depth2));
|
||||
|
||||
std::vector<CMapAreaBFSInfo> bfsInfos;
|
||||
bfsInfos.reserve(x0_areas.size());
|
||||
if (curArea != otherArea)
|
||||
{
|
||||
const_cast<CMapWorld*>(this)->x20_traversed[otherArea] = true;
|
||||
DoBFS(parms.GetWorld(), curArea, areaDepth, depth1, depth2, true, bfsInfos);
|
||||
|
||||
float lowD1 = std::ceil(depth1 - 1.f);
|
||||
float tmp;
|
||||
if (depth1 == std::floor(depth1))
|
||||
tmp = 0.f;
|
||||
else
|
||||
tmp = 1.f - std::fmod(depth1, 1.f);
|
||||
float newD1 = lowD1 + tmp;
|
||||
|
||||
float lowD2 = std::ceil(depth2 - 1.f);
|
||||
if (depth2 == std::floor(depth2))
|
||||
tmp = 0.f;
|
||||
else
|
||||
tmp = 1.f - std::fmod(depth2, 1.f);
|
||||
float newD2 = lowD2 + tmp;
|
||||
|
||||
int otherDepth = std::ceil(std::max(newD1, newD2));
|
||||
if (parms.GetWorld().IGetAreaAlways(otherArea)->IIsActive())
|
||||
{
|
||||
const_cast<CMapWorld*>(this)->x20_traversed[otherArea] = false;
|
||||
DoBFS(parms.GetWorld(), otherArea, otherDepth, newD1, newD2, true, bfsInfos);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DoBFS(parms.GetWorld(), curArea, areaDepth, depth1, depth2, true, bfsInfos);
|
||||
}
|
||||
|
||||
DrawAreas(parms, curArea, bfsInfos, inMapScreen);
|
||||
}
|
||||
|
||||
void CMapWorld::DoBFS(const IWorld& wld, int startArea, int areaCount, float surfDepth, float outlineDepth,
|
||||
bool checkLoad, std::vector<CMapAreaBFSInfo>& bfsInfos) const
|
||||
{
|
||||
if (areaCount <= 0 || !IsMapAreaValid(wld, startArea, checkLoad))
|
||||
return;
|
||||
|
||||
int size = bfsInfos.size();
|
||||
bfsInfos.emplace_back(startArea, 1, surfDepth, outlineDepth);
|
||||
const_cast<CMapWorld*>(this)->x20_traversed[startArea] = true;
|
||||
|
||||
for (; size != bfsInfos.size() ; ++size)
|
||||
{
|
||||
CMapAreaBFSInfo& testInfo = bfsInfos[size];
|
||||
if (testInfo.GetDepth() == areaCount)
|
||||
continue;
|
||||
|
||||
surfDepth = testInfo.GetSurfaceDrawDepth() - 1.f;
|
||||
outlineDepth = testInfo.GetOutlineDrawDepth() - 1.f;
|
||||
|
||||
const IGameArea* area = wld.IGetAreaAlways(testInfo.GetAreaIndex());
|
||||
for (int i=0 ; i<area->IGetNumAttachedAreas() ; ++i)
|
||||
{
|
||||
TAreaId attId = area->IGetAttachedAreaId(i);
|
||||
if (IsMapAreaValid(wld, attId, checkLoad) && !x20_traversed[attId])
|
||||
{
|
||||
bfsInfos.emplace_back(attId, testInfo.GetDepth() + 1, surfDepth, outlineDepth);
|
||||
const_cast<CMapWorld*>(this)->x20_traversed[attId] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CMapWorld::IsMapAreaValid(const IWorld& wld, int areaIdx, bool checkLoad) const
|
||||
{
|
||||
if (!wld.IGetAreaAlways(areaIdx)->IIsActive())
|
||||
return false;
|
||||
const CMapArea* mapa = GetMapArea(areaIdx);
|
||||
if (checkLoad)
|
||||
return mapa != nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms&, int,
|
||||
const std::vector<CMapWorld::CMapAreaBFSInfo>&, bool) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CMapWorld::DoBFS(const IWorld&, TAreaId, int, float, float, bool, std::vector<CMapAreaBFSInfo>&) const
|
||||
struct Support
|
||||
{
|
||||
int x0_;
|
||||
int x4_[3];
|
||||
};
|
||||
|
||||
struct Circle2
|
||||
{
|
||||
zeus::CVector2f x0_point;
|
||||
float x8_radiusSq;
|
||||
};
|
||||
|
||||
struct Circle
|
||||
{
|
||||
zeus::CVector2f x0_point;
|
||||
float x8_radius;
|
||||
Circle(const Circle2& circ2)
|
||||
: x0_point(circ2.x0_point), x8_radius(std::sqrt(circ2.x8_radiusSq)) {}
|
||||
};
|
||||
|
||||
static Circle2 ExactCircle1(const zeus::CVector2f* a)
|
||||
{
|
||||
return {*a, 0.f};
|
||||
}
|
||||
|
||||
bool CMapWorld::IsMapAreaValid(const IWorld &, int, bool) const
|
||||
static Circle2 ExactCircle2(const zeus::CVector2f* a, const zeus::CVector2f* b)
|
||||
{
|
||||
return false;
|
||||
Circle2 ret = {};
|
||||
ret.x0_point = 0.5f * (*a + *b);
|
||||
ret.x8_radiusSq = (*b - *a).magSquared() * 0.25f;
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CMapWorld::DrawAreas(const CMapWorld::CMapWorldDrawParms&, int, const std::vector<CMapWorld::CMapAreaBFSInfo>&, bool) const
|
||||
static Circle2 ExactCircle3(const zeus::CVector2f* a, const zeus::CVector2f* b, const zeus::CVector2f* c)
|
||||
{
|
||||
|
||||
Circle2 ret = {};
|
||||
zeus::CVector2f d1 = *b - *a;
|
||||
zeus::CVector2f d2 = *c - *a;
|
||||
float cross = d1.cross(d2);
|
||||
zeus::CVector2f magVec(d1.magSquared() * 0.5f, d2.magSquared() * 0.5f);
|
||||
if (std::fabs(cross) > 0.01f)
|
||||
{
|
||||
zeus::CVector2f tmp((d2.y * magVec.x - d1.y * magVec.y) / cross,
|
||||
(d1.x * magVec.y - d2.x * magVec.x) / cross);
|
||||
ret.x0_point = *a + tmp;
|
||||
ret.x8_radiusSq = tmp.magSquared();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret.x8_radiusSq = FLT_MAX;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo&, const IWorld&) const
|
||||
static bool PointInsideCircle(const zeus::CVector2f& point, const Circle2& circ, float& intersect)
|
||||
{
|
||||
intersect = (point - circ.x0_point).magSquared() - circ.x8_radiusSq;
|
||||
return intersect <= 0.f;
|
||||
}
|
||||
|
||||
static Circle2 UpdateSupport1(int idx, zeus::CVector2f** list, Support& support)
|
||||
{
|
||||
Circle2 ret = ExactCircle2(list[support.x4_[0]], list[idx]);
|
||||
support.x0_ = 2;
|
||||
support.x4_[1] = idx;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Circle2 UpdateSupport2(int idx, zeus::CVector2f** list, Support& support)
|
||||
{
|
||||
Circle2 circs[3] = {};
|
||||
float intersect;
|
||||
int circIdx = -1;
|
||||
float minRad = FLT_MAX;
|
||||
|
||||
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
|
||||
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect))
|
||||
{
|
||||
minRad = circs[0].x8_radiusSq;
|
||||
circIdx = 0;
|
||||
}
|
||||
|
||||
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
|
||||
if (circs[1].x8_radiusSq < minRad && PointInsideCircle(*list[support.x4_[1]], circs[1], intersect))
|
||||
{
|
||||
minRad = circs[1].x8_radiusSq;
|
||||
circIdx = 1;
|
||||
}
|
||||
|
||||
Circle2 ret = {};
|
||||
if (circIdx != -1)
|
||||
{
|
||||
ret = circs[circIdx];
|
||||
support.x4_[1 - circIdx] = idx;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
|
||||
support.x0_ = 3;
|
||||
support.x4_[2] = idx;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Circle2 UpdateSupport3(int idx, zeus::CVector2f** list, Support& support)
|
||||
{
|
||||
Circle2 circs[6] = {};
|
||||
float intersect;
|
||||
int circIdxA = -1;
|
||||
int circIdxB = -1;
|
||||
float minRadA = FLT_MAX;
|
||||
float minRadB = FLT_MAX;
|
||||
|
||||
circs[0] = ExactCircle2(list[support.x4_[0]], list[idx]);
|
||||
if (PointInsideCircle(*list[support.x4_[1]], circs[0], intersect))
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[2]], circs[0], intersect))
|
||||
{
|
||||
minRadA = circs[0].x8_radiusSq;
|
||||
circIdxA = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 0;
|
||||
}
|
||||
|
||||
circs[1] = ExactCircle2(list[support.x4_[1]], list[idx]);
|
||||
if (circs[1].x8_radiusSq < minRadA)
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[0]], circs[1], intersect))
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[2]], circs[1], intersect))
|
||||
{
|
||||
minRadA = circs[1].x8_radiusSq;
|
||||
circIdxA = 1;
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 1;
|
||||
}
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 1;
|
||||
}
|
||||
}
|
||||
|
||||
circs[2] = ExactCircle2(list[support.x4_[2]], list[idx]);
|
||||
if (circs[2].x8_radiusSq < minRadA)
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[0]], circs[2], intersect))
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[1]], circs[2], intersect))
|
||||
{
|
||||
minRadA = circs[2].x8_radiusSq;
|
||||
circIdxA = 2;
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 2;
|
||||
}
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 2;
|
||||
}
|
||||
}
|
||||
|
||||
circs[3] = ExactCircle3(list[support.x4_[0]], list[support.x4_[1]], list[idx]);
|
||||
if (circs[3].x8_radiusSq < minRadA)
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[2]], circs[3], intersect))
|
||||
{
|
||||
minRadA = circs[3].x8_radiusSq;
|
||||
circIdxA = 3;
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 3;
|
||||
}
|
||||
}
|
||||
|
||||
circs[4] = ExactCircle3(list[support.x4_[0]], list[support.x4_[2]], list[idx]);
|
||||
if (circs[4].x8_radiusSq < minRadA)
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[1]], circs[4], intersect))
|
||||
{
|
||||
minRadA = circs[4].x8_radiusSq;
|
||||
circIdxA = 4;
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
minRadB = intersect;
|
||||
circIdxB = 4;
|
||||
}
|
||||
}
|
||||
|
||||
circs[5] = ExactCircle3(list[support.x4_[1]], list[support.x4_[2]], list[idx]);
|
||||
if (circs[5].x8_radiusSq < minRadA)
|
||||
{
|
||||
if (PointInsideCircle(*list[support.x4_[0]], circs[5], intersect))
|
||||
{
|
||||
circIdxA = 5;
|
||||
}
|
||||
else if (intersect < minRadB)
|
||||
{
|
||||
circIdxB = 5;
|
||||
}
|
||||
}
|
||||
|
||||
if (circIdxA == -1)
|
||||
circIdxA = circIdxB;
|
||||
|
||||
switch (circIdxA)
|
||||
{
|
||||
case 0:
|
||||
support.x0_ = 2;
|
||||
support.x4_[1] = idx;
|
||||
break;
|
||||
case 1:
|
||||
support.x0_ = 2;
|
||||
support.x4_[0] = idx;
|
||||
break;
|
||||
case 2:
|
||||
support.x0_ = 2;
|
||||
support.x4_[0] = support.x4_[2];
|
||||
support.x4_[1] = idx;
|
||||
break;
|
||||
case 3:
|
||||
support.x4_[2] = idx;
|
||||
break;
|
||||
case 4:
|
||||
support.x4_[1] = idx;
|
||||
break;
|
||||
case 5:
|
||||
support.x4_[0] = idx;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return circs[circIdxA];
|
||||
}
|
||||
|
||||
typedef Circle2(*FSupport)(int idx, zeus::CVector2f** list, Support& support);
|
||||
static const FSupport SupportFuncs[] =
|
||||
{
|
||||
nullptr,
|
||||
UpdateSupport1,
|
||||
UpdateSupport2,
|
||||
UpdateSupport3
|
||||
};
|
||||
|
||||
static Circle MinCircle(const std::vector<zeus::CVector2f>& coords)
|
||||
{
|
||||
Circle2 ret = {};
|
||||
if (coords.size() >= 1)
|
||||
{
|
||||
std::unique_ptr<zeus::CVector2f*[]> randArr(new zeus::CVector2f*[coords.size()]);
|
||||
for (int i=0 ; i<coords.size() ; ++i)
|
||||
randArr[i] = const_cast<zeus::CVector2f*>(&coords[i]);
|
||||
for (int i=coords.size()-1 ; i>=0 ; --i)
|
||||
{
|
||||
int shuf = rand() % (i+1);
|
||||
if (shuf != i)
|
||||
std::swap(randArr[i], randArr[shuf]);
|
||||
}
|
||||
ret = ExactCircle1(randArr[0]);
|
||||
|
||||
Support support = {};
|
||||
support.x0_ = 1;
|
||||
for (int i=1 ; i<coords.size() ;)
|
||||
{
|
||||
bool broke = false;
|
||||
for (int j=0 ; j<support.x0_ ; ++j)
|
||||
{
|
||||
if ((*randArr[i] - *randArr[support.x4_[j]]).magSquared() < 0.01f)
|
||||
{
|
||||
broke = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
float intersect;
|
||||
if (!broke && !PointInsideCircle(*randArr[i], ret, intersect))
|
||||
{
|
||||
Circle2 circ = SupportFuncs[support.x0_](i, randArr.get(), support);
|
||||
if (circ.x8_radiusSq > ret.x8_radiusSq)
|
||||
{
|
||||
i = 0;
|
||||
ret = circ;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CMapWorld::RecalculateWorldSphere(const CMapWorldInfo& mwInfo, const IWorld& wld) const
|
||||
{
|
||||
std::vector<zeus::CVector2f> coords;
|
||||
coords.reserve(x0_areas.size() * 8);
|
||||
float zMin = FLT_MAX;
|
||||
float zMax = FLT_MIN;
|
||||
for (int i=0 ; i<x0_areas.size() ; ++i)
|
||||
{
|
||||
if (IsMapAreaValid(wld, i, true))
|
||||
{
|
||||
const CMapArea* mapa = GetMapArea(i);
|
||||
if (mapa->GetIsVisibleToAutoMapper(mwInfo.IsWorldVisible(i), mwInfo.IsAreaVisible(i)))
|
||||
{
|
||||
zeus::CAABox aabb = mapa->GetBoundingBox().getTransformedAABox(mapa->GetAreaPostTransform(wld, i));
|
||||
for (int j=0 ; j<8 ; ++j)
|
||||
{
|
||||
zeus::CVector3f point = aabb.getPoint(j);
|
||||
coords.emplace_back(point.x, point.y);
|
||||
zMin = std::min(point.z, zMin);
|
||||
zMax = std::max(point.z, zMax);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Circle circle = MinCircle(coords);
|
||||
const_cast<CMapWorld*>(this)->x3c_ = circle.x8_radius;
|
||||
const_cast<CMapWorld*>(this)->x30_ = zeus::CVector3f(circle.x0_point.x, circle.x0_point.y, (zMin + zMax) * 0.5f);
|
||||
const_cast<CMapWorld*>(this)->x40_ = (zMax - zMin) * 0.5f;
|
||||
}
|
||||
|
||||
zeus::CVector3f CMapWorld::ConstrainToWorldVolume(const zeus::CVector3f&, const zeus::CVector3f&) const
|
||||
|
@ -88,7 +569,9 @@ zeus::CVector3f CMapWorld::ConstrainToWorldVolume(const zeus::CVector3f&, const
|
|||
|
||||
void CMapWorld::ClearTraversedFlags() const
|
||||
{
|
||||
|
||||
std::vector<bool>& flags = const_cast<CMapWorld*>(this)->x20_traversed;
|
||||
for (int i=0 ; i<flags.size() ; ++i)
|
||||
flags[i] = false;
|
||||
}
|
||||
|
||||
CFactoryFnReturn FMapWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
|
||||
|
|
|
@ -19,54 +19,70 @@ public:
|
|||
/* skDrawProfileItemNames; */
|
||||
enum class EMapAreaList
|
||||
{
|
||||
Loaded,
|
||||
Loading,
|
||||
Unloaded
|
||||
};
|
||||
|
||||
class CMapAreaBFSInfo
|
||||
{
|
||||
s32 x0_areaIdx;
|
||||
s32 x4_depth;
|
||||
float x8_;
|
||||
float xc_;
|
||||
int x0_areaIdx;
|
||||
int x4_depth;
|
||||
float x8_surfDrawDepth;
|
||||
float xc_outlineDrawDepth;
|
||||
public:
|
||||
CMapAreaBFSInfo(s32 areaIdx, s32 depth, float a, float b)
|
||||
: x0_areaIdx(areaIdx), x4_depth(depth), x8_(a), xc_(b) {}
|
||||
s32 GetAreaIndex() const { return x0_areaIdx; }
|
||||
s32 GetDepth() const { return x4_depth; }
|
||||
float GetOutlineDrawDepth() const;
|
||||
float GetSurfaceDrawDepth() const;
|
||||
CMapAreaBFSInfo(int areaIdx, int depth, float a, float b)
|
||||
: x0_areaIdx(areaIdx), x4_depth(depth), x8_surfDrawDepth(a), xc_outlineDrawDepth(b) {}
|
||||
int GetAreaIndex() const { return x0_areaIdx; }
|
||||
int GetDepth() const { return x4_depth; }
|
||||
float GetOutlineDrawDepth() const { return x8_surfDrawDepth; }
|
||||
float GetSurfaceDrawDepth() const { return xc_outlineDrawDepth; }
|
||||
};
|
||||
|
||||
class CMapObjectSortInfo
|
||||
{
|
||||
float x0_zDist;
|
||||
int x4_areaIdx;
|
||||
int x8_typeAndIdx;
|
||||
zeus::CColor xc_surfColor;
|
||||
zeus::CColor x10_outlineColor;
|
||||
public:
|
||||
enum class EObjectCode
|
||||
{
|
||||
One = 1 << 16,
|
||||
Door = 2 << 16,
|
||||
Three = 3 << 16,
|
||||
Four = 4 << 16
|
||||
};
|
||||
private:
|
||||
public:
|
||||
CMapObjectSortInfo(float, int, EObjectCode, int, const zeus::CColor&, const zeus::CColor& );
|
||||
const zeus::CColor& GetOutlineColor() const;
|
||||
const zeus::CColor& GetSurfaceColor() const;
|
||||
u32 GetLocalObjectIndex();
|
||||
EObjectCode GetObjectCode() const;
|
||||
u32 GetAreaIndex() const;
|
||||
float GetZDistance() const;
|
||||
|
||||
CMapObjectSortInfo(float zDist, int areaIdx, EObjectCode type, int idx,
|
||||
const zeus::CColor& surfColor, const zeus::CColor& outlineColor)
|
||||
: x0_zDist(zDist), x4_areaIdx(areaIdx), x8_typeAndIdx(int(type) | idx),
|
||||
xc_surfColor(surfColor), x10_outlineColor(outlineColor) {}
|
||||
const zeus::CColor& GetOutlineColor() const { return x10_outlineColor; }
|
||||
const zeus::CColor& GetSurfaceColor() const { return xc_surfColor; }
|
||||
u32 GetLocalObjectIndex() const { return x8_typeAndIdx & 0xffff; }
|
||||
EObjectCode GetObjectCode() const { return EObjectCode(x8_typeAndIdx & 0xffff0000); }
|
||||
u32 GetAreaIndex() const { return x4_areaIdx; }
|
||||
float GetZDistance() const { return x0_zDist; }
|
||||
};
|
||||
|
||||
class CMapAreaData
|
||||
{
|
||||
TCachedToken<CMapArea> x0_area;
|
||||
EMapAreaList x10_list;
|
||||
CMapAreaData* x14_next;
|
||||
public:
|
||||
CMapAreaData(u32, EMapAreaList, CMapAreaData*);
|
||||
void Lock();
|
||||
void Unlock();
|
||||
bool IsLoaded() const;
|
||||
CMapAreaData(ResId areaRes, EMapAreaList list, CMapAreaData* next);
|
||||
void Lock() { x0_area.Lock(); }
|
||||
void Unlock() { x0_area.Unlock(); }
|
||||
bool IsLoaded() const { return x0_area.IsLoaded(); }
|
||||
const CMapArea* GetMapArea() const { return x0_area.IsLoaded() ? x0_area.GetObj() : nullptr; }
|
||||
void GetNextMapAreaData() const;
|
||||
void GetContainingList() const;
|
||||
void NextMapAreaData();
|
||||
void SetContainingList(EMapAreaList);
|
||||
void SetNextMapArea(CMapAreaData*);
|
||||
const CMapAreaData* GetNextMapAreaData() const { return x14_next; }
|
||||
EMapAreaList GetContainingList() const { return x10_list; }
|
||||
CMapAreaData* NextMapAreaData() { return x14_next; }
|
||||
void SetContainingList(EMapAreaList list) { x10_list = list; }
|
||||
void SetNextMapArea(CMapAreaData* next) { x14_next = next; }
|
||||
};
|
||||
|
||||
class CMapWorldDrawParms
|
||||
|
@ -126,18 +142,23 @@ public:
|
|||
|
||||
private:
|
||||
std::vector<CMapAreaData> x0_areas;
|
||||
rstl::reserved_vector<CMapAreaData*, 3> x10_listHeads;
|
||||
std::vector<bool> x20_traversed;
|
||||
zeus::CVector3f x30_;
|
||||
float x3c_ = 0.f;
|
||||
float x40_ = 0.f;
|
||||
public:
|
||||
CMapWorld(CInputStream&);
|
||||
u32 GetNumAreas() const { return x0_areas.size(); }
|
||||
const CMapArea* GetMapArea(TAreaId aid) const { return x0_areas[aid].GetMapArea(); }
|
||||
void IsMapAreaInBFSInfoVector(const CMapAreaData*, const std::vector<CMapAreaBFSInfo>&) const;
|
||||
const CMapArea* GetMapArea(int aid) const { return x0_areas[aid].GetMapArea(); }
|
||||
bool IsMapAreaInBFSInfoVector(const CMapAreaData*, const std::vector<CMapAreaBFSInfo>&) const;
|
||||
void SetWhichMapAreasLoaded(const IWorld&, int start, int count);
|
||||
bool IsMapAreasStreaming() const;
|
||||
void MoveMapAreaToList(CMapAreaData*, EMapAreaList);
|
||||
s32 GetCurrentMapAreaDepth(const IWorld&, TAreaId) const;
|
||||
std::vector<TAreaId> GetVisibleAreas(const IWorld&, const CMapWorldInfo&) const;
|
||||
s32 GetCurrentMapAreaDepth(const IWorld&, int areaIdx) const;
|
||||
std::vector<int> GetVisibleAreas(const IWorld&, const CMapWorldInfo&) const;
|
||||
void Draw(const CMapWorldDrawParms&, int, int, float, float, bool) const;
|
||||
void DoBFS(const IWorld&, TAreaId, int, float, float, bool, std::vector<CMapAreaBFSInfo>&) const;
|
||||
void DoBFS(const IWorld&, int, int, float, float, bool, std::vector<CMapAreaBFSInfo>&) const;
|
||||
bool IsMapAreaValid(const IWorld&, int, bool) const;
|
||||
void DrawAreas(const CMapWorldDrawParms&, int, const std::vector<CMapAreaBFSInfo>&, bool) const;
|
||||
void RecalculateWorldSphere(const CMapWorldInfo&, const IWorld&) const;
|
||||
|
|
|
@ -1,10 +1,34 @@
|
|||
#include "CMappableObject.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CMapWorldInfo.hpp"
|
||||
#include "CSimplePool.hpp"
|
||||
#include "CToken.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
const zeus::CVector3f CMappableObject::skDoorVerts[8] = {};
|
||||
|
||||
static const u32 DoorIndices[] =
|
||||
{
|
||||
6, 4, 2, 0,
|
||||
3, 1, 7, 5,
|
||||
1, 0, 5, 4,
|
||||
7, 6, 3, 2,
|
||||
3, 2, 1, 0,
|
||||
5, 4, 7, 6
|
||||
};
|
||||
|
||||
CMappableObject::CMappableObject(const void* buf)
|
||||
{
|
||||
athena::io::MemoryReader r(buf, 64);
|
||||
x0_type = EMappableObjectType(r.readUint32Big());
|
||||
x4_ = r.readUint32Big();
|
||||
x8_objId = r.readUint32Big();
|
||||
xc_ = r.readUint32Big();
|
||||
x10_transform.read34RowMajor(r);
|
||||
}
|
||||
|
||||
zeus::CTransform CMappableObject::AdjustTransformForType()
|
||||
{
|
||||
const float doorCenterX = g_tweakAutoMapper->GetDoorCenter().x;
|
||||
|
@ -14,7 +38,7 @@ zeus::CTransform CMappableObject::AdjustTransformForType()
|
|||
zeus::CTransform orientation;
|
||||
orientation.origin = {-1.4f*doorCenterX, 0.0f, 0.0f};
|
||||
orientation.rotateLocalZ(zeus::degToRad(90.0f));
|
||||
return (x10_transform * orientation) * zeus::CTransform::Scale(zeus::CVector3f{1.5f});
|
||||
return (x10_transform * orientation) * zeus::CTransform::Scale(zeus::CVector3f{1.5f});
|
||||
}
|
||||
else if (x0_type == EMappableObjectType::BigDoor2)
|
||||
{
|
||||
|
@ -40,14 +64,14 @@ zeus::CTransform CMappableObject::AdjustTransformForType()
|
|||
return x10_transform * orientation;
|
||||
}
|
||||
else if ((u32(x0_type) - u32(EMappableObjectType::IceDoorFloor2)) <= u32(EMappableObjectType::ShieldDoor)
|
||||
|| x0_type == EMappableObjectType::Fifteen)
|
||||
|| x0_type == EMappableObjectType::PlasmaDoorFloor2)
|
||||
{
|
||||
zeus::CTransform orientation;
|
||||
orientation.origin = {-0.49f * doorCenterX, 0.f, -1.f * doorCenterZ};
|
||||
orientation.rotateLocalY(zeus::degToRad(90.f));
|
||||
return x10_transform * orientation;
|
||||
}
|
||||
else if (x0_type >= EMappableObjectType::BlueDoor || x0_type <= EMappableObjectType::Fifteen)
|
||||
else if (x0_type >= EMappableObjectType::BlueDoor || x0_type <= EMappableObjectType::PlasmaDoorFloor2)
|
||||
{
|
||||
zeus::CMatrix4f tmp = x10_transform.toMatrix4f().transposed();
|
||||
return zeus::CTransform::Translate(tmp.m[1][0], tmp.m[2][1], tmp[3][2]);
|
||||
|
@ -55,35 +79,189 @@ zeus::CTransform CMappableObject::AdjustTransformForType()
|
|||
return x10_transform;
|
||||
}
|
||||
|
||||
void CMappableObject::PostConstruct(const void *)
|
||||
std::pair<zeus::CColor, zeus::CColor>
|
||||
CMappableObject::GetDoorColors(int curAreaId, const CMapWorldInfo& mwInfo, float alpha) const
|
||||
{
|
||||
#if __BYTE_ORDER__!= __ORDER_BIG_ENDIAN__
|
||||
x0_type = EMappableObjectType(hecl::SBig(u32(x0_type)));
|
||||
x4_ = hecl::SBig(x4_);
|
||||
x8_.id = hecl::SBig(x8_.id);
|
||||
xc_ = hecl::SBig(xc_);
|
||||
for (u32 i = 0 ; i<3 ; i++)
|
||||
zeus::CColor color = {1.f, 0.f, 1.f, 1.f};
|
||||
if (x8_objId.AreaNum() == curAreaId)
|
||||
{
|
||||
for (u32 j = 0 ; j<4 ; j++)
|
||||
if (mwInfo.IsDoorVisited(x8_objId) && x0_type == EMappableObjectType::ShieldDoor)
|
||||
{
|
||||
u32* tmp = reinterpret_cast<u32*>(&x10_transform.basis.m[i][j]);
|
||||
*tmp = hecl::SBig(*tmp);
|
||||
color = g_tweakAutoMapper->GetDoorColor(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
int colorIdx = 0;
|
||||
switch (x0_type)
|
||||
{
|
||||
case EMappableObjectType::ShieldDoor:
|
||||
colorIdx = 1;
|
||||
break;
|
||||
case EMappableObjectType::IceDoor:
|
||||
case EMappableObjectType::IceDoorCeiling:
|
||||
case EMappableObjectType::IceDoorFloor:
|
||||
case EMappableObjectType::IceDoorFloor2:
|
||||
colorIdx = 2;
|
||||
break;
|
||||
case EMappableObjectType::WaveDoor:
|
||||
case EMappableObjectType::WaveDoorCeiling:
|
||||
case EMappableObjectType::WaveDoorFloor:
|
||||
case EMappableObjectType::WaveDoorFloor2:
|
||||
colorIdx = 3;
|
||||
break;
|
||||
case EMappableObjectType::PlasmaDoor:
|
||||
case EMappableObjectType::PlasmaDoorCeiling:
|
||||
case EMappableObjectType::PlasmaDoorFloor:
|
||||
case EMappableObjectType::PlasmaDoorFloor2:
|
||||
colorIdx = 4;
|
||||
default: break;
|
||||
}
|
||||
color = g_tweakAutoMapper->GetDoorColor(colorIdx);
|
||||
}
|
||||
}
|
||||
else if (mwInfo.IsDoorVisited(x8_objId))
|
||||
{
|
||||
color = g_tweakAutoMapper->GetOpenDoorColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
color = zeus::CColor::skClear;
|
||||
}
|
||||
|
||||
#endif
|
||||
x10_transform.origin.x = x10_transform.basis.m[0][3];
|
||||
x10_transform.origin.y = x10_transform.basis.m[1][3];
|
||||
x10_transform.origin.z = x10_transform.basis.m[2][3];
|
||||
x10_transform.basis.transpose();
|
||||
color.a *= alpha;
|
||||
return {color, zeus::CColor(std::min(1.4f * color.r, 1.f),
|
||||
std::min(1.4f * color.g, 1.f),
|
||||
std::min(1.4f * color.b, 1.f),
|
||||
std::min(1.4f * color.a, 1.f))};
|
||||
}
|
||||
|
||||
void CMappableObject::PostConstruct(const void *)
|
||||
{
|
||||
x10_transform = AdjustTransformForType();
|
||||
}
|
||||
|
||||
zeus::CVector3f CMappableObject::BuildSurfaceCenterPoint(s32) const
|
||||
void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo,
|
||||
float alpha, bool needsVtxLoad) const
|
||||
{
|
||||
if (IsDoorType(x0_type))
|
||||
{
|
||||
std::pair<zeus::CColor, zeus::CColor> colors = GetDoorColors(curArea, mwInfo, alpha);
|
||||
for (int s=0 ; s<6 ; ++s)
|
||||
{
|
||||
DoorSurface& ds = const_cast<DoorSurface&>(*m_doorSurface);
|
||||
ds.m_surface.draw(colors.first, s * 4, 4);
|
||||
CLineRenderer& line = ds.m_outline;
|
||||
const u32* baseIdx = &DoorIndices[s * 4];
|
||||
line.Reset();
|
||||
line.AddVertex(skDoorVerts[baseIdx[0]], colors.second, 1.f);
|
||||
line.AddVertex(skDoorVerts[baseIdx[1]], colors.second, 1.f);
|
||||
line.AddVertex(skDoorVerts[baseIdx[2]], colors.second, 1.f);
|
||||
line.AddVertex(skDoorVerts[baseIdx[3]], colors.second, 1.f);
|
||||
line.Render();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ResId iconRes;
|
||||
zeus::CColor iconColor = zeus::CColor::skWhite;
|
||||
switch (x0_type)
|
||||
{
|
||||
case EMappableObjectType::DownArrowYellow:
|
||||
iconRes = g_tweakPlayerRes->x10_minesBreakFirstTopIcon;
|
||||
iconColor = zeus::CColor{1.f, 1.f, 0.588f, 1.f};
|
||||
break;
|
||||
case EMappableObjectType::UpArrowYellow:
|
||||
iconRes = g_tweakPlayerRes->x14_minesBreakFirstBottomIcon;
|
||||
iconColor = zeus::CColor{1.f, 1.f, 0.588f, 1.f};
|
||||
break;
|
||||
case EMappableObjectType::DownArrowGreen:
|
||||
iconRes = g_tweakPlayerRes->x10_minesBreakFirstTopIcon;
|
||||
iconColor = zeus::CColor{0.392f, 1.f, 0.588f, 1.f};
|
||||
break;
|
||||
case EMappableObjectType::UpArrowGreen:
|
||||
iconRes = g_tweakPlayerRes->x14_minesBreakFirstBottomIcon;
|
||||
iconColor = zeus::CColor{0.392f, 1.f, 0.588f, 1.f};
|
||||
break;
|
||||
case EMappableObjectType::DownArrowRed:
|
||||
iconRes = g_tweakPlayerRes->x10_minesBreakFirstTopIcon;
|
||||
iconColor = zeus::CColor{1.f, 0.392f, 0.588f, 1.f};
|
||||
break;
|
||||
case EMappableObjectType::UpArrowRed:
|
||||
iconRes = g_tweakPlayerRes->x14_minesBreakFirstBottomIcon;
|
||||
iconColor = zeus::CColor{1.f, 0.392f, 0.588f, 1.f};
|
||||
break;
|
||||
case EMappableObjectType::SaveStation:
|
||||
iconRes = g_tweakPlayerRes->x4_saveStationIcon;
|
||||
break;
|
||||
case EMappableObjectType::MissileStation:
|
||||
iconRes = g_tweakPlayerRes->x8_missileStationIcon;
|
||||
break;
|
||||
default:
|
||||
iconRes = g_tweakPlayerRes->xc_elevatorIcon;
|
||||
break;
|
||||
}
|
||||
|
||||
iconColor.a *= alpha;
|
||||
|
||||
TLockedToken<CTexture> tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), iconRes});
|
||||
if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj())
|
||||
const_cast<CMappableObject*>(this)->m_texQuadFilter.emplace(CCameraFilterPass::EFilterType::Blend, tex);
|
||||
|
||||
CTexturedQuadFilter::Vert verts[4] =
|
||||
{
|
||||
{{-2.6f, 0.f, 2.6f}, {0.f, 1.f}},
|
||||
{{-2.6f, 0.f, -2.6f}, {0.f, 0.f}},
|
||||
{{2.6f, 0.f, 2.6f}, {1.f, 1.f}},
|
||||
{{2.6f, 0.f, -2.6f}, {1.f, 0.f}}
|
||||
};
|
||||
const_cast<CMappableObject*>(this)->m_texQuadFilter->drawVerts(iconColor, verts);
|
||||
}
|
||||
}
|
||||
|
||||
void CMappableObject::DrawDoorSurface(int curArea, const CMapWorldInfo& mwInfo,
|
||||
float alpha, int surfIdx, bool needsVtxLoad) const
|
||||
{
|
||||
std::pair<zeus::CColor, zeus::CColor> colors = GetDoorColors(curArea, mwInfo, alpha);
|
||||
DoorSurface& ds = const_cast<DoorSurface&>(*m_doorSurface);
|
||||
ds.m_surface.draw(colors.first, surfIdx * 4, 4);
|
||||
CLineRenderer& line = ds.m_outline;
|
||||
const u32* baseIdx = &DoorIndices[surfIdx * 4];
|
||||
line.Reset();
|
||||
line.AddVertex(skDoorVerts[baseIdx[0]], colors.second, 1.f);
|
||||
line.AddVertex(skDoorVerts[baseIdx[1]], colors.second, 1.f);
|
||||
line.AddVertex(skDoorVerts[baseIdx[2]], colors.second, 1.f);
|
||||
line.AddVertex(skDoorVerts[baseIdx[3]], colors.second, 1.f);
|
||||
line.Render();
|
||||
}
|
||||
|
||||
zeus::CVector3f CMappableObject::BuildSurfaceCenterPoint(int surfIdx) const
|
||||
{
|
||||
const zeus::CVector3f& doorCenter = g_tweakAutoMapper->GetDoorCenter();
|
||||
|
||||
switch (surfIdx)
|
||||
{
|
||||
case 0:
|
||||
return x10_transform * zeus::CVector3f::skZero;
|
||||
case 1:
|
||||
return x10_transform * zeus::CVector3f{0.f, 0.f, 2.f * doorCenter.x};
|
||||
case 2:
|
||||
return x10_transform * zeus::CVector3f{0.f, -doorCenter.y, 0.f};
|
||||
case 3:
|
||||
return x10_transform * zeus::CVector3f{0.f, doorCenter.y, 0.f};
|
||||
case 4:
|
||||
return x10_transform * zeus::CVector3f{-doorCenter.x, 0.f, 0.f};
|
||||
case 5:
|
||||
return x10_transform * zeus::CVector3f{doorCenter.x, 0.f, 0.f};
|
||||
default: break;
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
boo::GraphicsDataToken CMappableObject::g_gfxToken = {};
|
||||
boo::IGraphicsBufferS* CMappableObject::g_doorVbo;
|
||||
boo::IGraphicsBufferS* CMappableObject::g_doorIbo;
|
||||
|
||||
void CMappableObject::ReadAutoMapperTweaks(const ITweakAutoMapper& tweaks)
|
||||
{
|
||||
const zeus::CVector3f& center = tweaks.GetDoorCenter();
|
||||
|
@ -97,5 +275,17 @@ void CMappableObject::ReadAutoMapperTweaks(const ITweakAutoMapper& tweaks)
|
|||
doorVerts[5].assign(.2f * -center.z, -center.y, 2.f * center.x);
|
||||
doorVerts[6].assign(.2f * -center.z, center.y, 0.f);
|
||||
doorVerts[7].assign(.2f * -center.z, center.y, 2.f * center.x);
|
||||
|
||||
g_gfxToken = CGraphics::CommitResources([](boo::IGraphicsDataFactory::Context& ctx)
|
||||
{
|
||||
g_doorVbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, skDoorVerts, 16, 8);
|
||||
g_doorIbo = ctx.newStaticBuffer(boo::BufferUse::Index, DoorIndices, 4, 24);
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
void CMappableObject::Shutdown()
|
||||
{
|
||||
g_gfxToken.doDestroy();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,12 +5,22 @@
|
|||
#include "zeus/CAABox.hpp"
|
||||
#include "zeus/CTransform.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "Graphics/Shaders/CMapSurfaceShader.hpp"
|
||||
#include "Graphics/Shaders/CTexturedQuadFilter.hpp"
|
||||
#include "Graphics/CLineRenderer.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
class CStateManager;
|
||||
class CMapWorldInfo;
|
||||
|
||||
class CMappableObject
|
||||
{
|
||||
friend class CMapArea;
|
||||
static boo::GraphicsDataToken g_gfxToken;
|
||||
static boo::IGraphicsBufferS* g_doorVbo;
|
||||
static boo::IGraphicsBufferS* g_doorIbo;
|
||||
|
||||
public:
|
||||
enum class EMappableObjectType
|
||||
{
|
||||
|
@ -29,7 +39,7 @@ public:
|
|||
PlasmaDoorFloor = 12,
|
||||
IceDoorFloor2 = 13,
|
||||
WaveDoorFloor2 = 14,
|
||||
Fifteen = 15,
|
||||
PlasmaDoorFloor2 = 15,
|
||||
DownArrowYellow = 27, /* Maintenance Tunnel */
|
||||
UpArrowYellow = 28, /* Phazon Processing Center */
|
||||
DownArrowGreen = 29, /* Elevator A */
|
||||
|
@ -46,25 +56,44 @@ private:
|
|||
|
||||
EMappableObjectType x0_type;
|
||||
u32 x4_;
|
||||
TEditorId x8_;
|
||||
TEditorId x8_objId;
|
||||
u32 xc_;
|
||||
zeus::CTransform x10_transform;
|
||||
|
||||
struct DoorSurface
|
||||
{
|
||||
CMapSurfaceShader m_surface;
|
||||
CLineRenderer m_outline;
|
||||
DoorSurface(boo::IGraphicsDataFactory::Context& ctx)
|
||||
: m_surface(ctx, g_doorVbo, g_doorIbo),
|
||||
m_outline(ctx, CLineRenderer::EPrimitiveMode::LineStrip, 5, nullptr, false)
|
||||
{}
|
||||
};
|
||||
std::experimental::optional<DoorSurface> m_doorSurface;
|
||||
std::experimental::optional<CTexturedQuadFilter> m_texQuadFilter;
|
||||
|
||||
zeus::CTransform AdjustTransformForType();
|
||||
std::pair<zeus::CColor, zeus::CColor> GetDoorColors(int idx, const CMapWorldInfo& mwInfo, float alpha) const;
|
||||
public:
|
||||
CMappableObject(const void* buf);
|
||||
CMappableObject(CMappableObject&&) = default;
|
||||
void PostConstruct(const void*);
|
||||
const zeus::CTransform& GetTransform() const;
|
||||
EMappableObjectType GetType() const;
|
||||
void Draw(int, const CStateManager&, float, bool) const;
|
||||
void DrawDoorSurface(int, const CStateManager&, float, int, bool) const;
|
||||
zeus::CVector3f BuildSurfaceCenterPoint(s32) const;
|
||||
bool IsDoorConnectedToArea(s32, const CStateManager&) const;
|
||||
const zeus::CTransform& GetTransform() const { return x10_transform; }
|
||||
EMappableObjectType GetType() const { return x0_type; }
|
||||
void Draw(int, const CMapWorldInfo&, float, bool) const;
|
||||
void DrawDoorSurface(int curArea, const CMapWorldInfo& mwInfo, float alpha,
|
||||
int surfIdx, bool needsVtxLoad) const;
|
||||
zeus::CVector3f BuildSurfaceCenterPoint(int surfIdx) const;
|
||||
bool IsDoorConnectedToArea(int idx, const CStateManager&) const;
|
||||
bool IsDoorConnectedToVisitedArea(const CStateManager&) const;
|
||||
bool GetIsVisibleToAutoMapper(bool) const;
|
||||
bool GetIsSeen() const;
|
||||
|
||||
void ReadAutoMapperTweaks(const ITweakAutoMapper&);
|
||||
static void ReadAutoMapperTweaks(const ITweakAutoMapper&);
|
||||
static bool GetTweakIsMapVisibilityCheat();
|
||||
static bool IsDoorType(EMappableObjectType);
|
||||
static bool IsDoorType(EMappableObjectType type) { return type >= EMappableObjectType::BlueDoor &&
|
||||
type <= EMappableObjectType::PlasmaDoorFloor2; }
|
||||
static void Shutdown();
|
||||
};
|
||||
}
|
||||
#endif // __URDE_CMAPPABLEOBJECT_HPP__
|
||||
|
|
|
@ -33,6 +33,38 @@ struct SDrawUniform
|
|||
zeus::CColor moduColor;
|
||||
};
|
||||
|
||||
CLineRenderer::CLineRenderer(boo::IGraphicsDataFactory::Context& ctx,
|
||||
EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive)
|
||||
: m_mode(mode), m_maxVerts(maxVerts)
|
||||
{
|
||||
if (maxVerts < 2)
|
||||
{
|
||||
LineRendererLog.report(logvisor::Fatal, _S("maxVerts < 2, maxVerts = %i"), maxVerts);
|
||||
return;
|
||||
}
|
||||
m_textured = texture != nullptr;
|
||||
|
||||
u32 maxTriVerts;
|
||||
switch (mode)
|
||||
{
|
||||
case EPrimitiveMode::Lines:
|
||||
maxTriVerts = maxVerts * 3;
|
||||
break;
|
||||
case EPrimitiveMode::LineStrip:
|
||||
maxTriVerts = maxVerts * 2;
|
||||
break;
|
||||
case EPrimitiveMode::LineLoop:
|
||||
maxTriVerts = maxVerts * 2 + 2;
|
||||
break;
|
||||
}
|
||||
|
||||
m_vertBuf = ctx.newDynamicBuffer(boo::BufferUse::Vertex,
|
||||
texture ? sizeof(SDrawVertTex) : sizeof(SDrawVertNoTex),
|
||||
maxTriVerts);
|
||||
m_uniformBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(SDrawUniform), 1);
|
||||
CLineRendererShaders::BuildShaderDataBinding(ctx, *this, texture, additive);
|
||||
}
|
||||
|
||||
CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive)
|
||||
: m_mode(mode), m_maxVerts(maxVerts)
|
||||
{
|
||||
|
|
|
@ -44,7 +44,10 @@ public:
|
|||
boo::IGraphicsBufferD* m_uniformBuf;
|
||||
boo::IShaderDataBinding* m_shaderBind = nullptr;
|
||||
|
||||
CLineRenderer(boo::IGraphicsDataFactory::Context& ctx,
|
||||
EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive);
|
||||
CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive);
|
||||
CLineRenderer(CLineRenderer&&) = default;
|
||||
|
||||
void Reset();
|
||||
void AddVertex(const zeus::CVector3f& position, const zeus::CColor& color, float width,
|
||||
|
|
|
@ -13,7 +13,8 @@ if(WIN32)
|
|||
Shaders/CFogVolumePlaneShaderHLSL.cpp
|
||||
Shaders/CFogVolumeFilterHLSL.cpp
|
||||
Shaders/CEnergyBarShaderHLSL.cpp
|
||||
Shaders/CRadarPaintShaderHLSL.cpp)
|
||||
Shaders/CRadarPaintShaderHLSL.cpp
|
||||
Shaders/CMapSurfaceShaderHLSL.cpp)
|
||||
elseif(BOO_HAS_METAL)
|
||||
set(PLAT_SRCS
|
||||
Shaders/CLineRendererShadersMetal.cpp
|
||||
|
@ -29,7 +30,8 @@ elseif(BOO_HAS_METAL)
|
|||
Shaders/CFogVolumePlaneShaderMetal.cpp
|
||||
Shaders/CFogVolumeFilterMetal.cpp
|
||||
Shaders/CEnergyBarShaderMetal.cpp
|
||||
Shaders/CRadarPaintShaderMetal.cpp)
|
||||
Shaders/CRadarPaintShaderMetal.cpp
|
||||
Shaders/CMapSurfaceShaderMetal.cpp)
|
||||
endif()
|
||||
|
||||
set(GRAPHICS_SOURCES
|
||||
|
@ -39,7 +41,7 @@ set(GRAPHICS_SOURCES
|
|||
CDrawable.hpp CDrawable.cpp
|
||||
CDrawablePlaneObject.hpp CDrawablePlaneObject.cpp
|
||||
CLineRenderer.hpp CLineRenderer.cpp
|
||||
CMetroidModelInstance.hpp CMetroidModelInstance.cpp
|
||||
CMetroidModelInstance.hpp
|
||||
CLight.hpp CLight.cpp
|
||||
CTexture.hpp CTextureBoo.cpp
|
||||
CModel.hpp CModelBoo.cpp
|
||||
|
@ -67,6 +69,7 @@ set(GRAPHICS_SOURCES
|
|||
Shaders/CFogVolumeFilter.hpp Shaders/CFogVolumeFilter.cpp Shaders/CFogVolumeFilterGLSL.cpp
|
||||
Shaders/CEnergyBarShader.hpp Shaders/CEnergyBarShader.cpp Shaders/CEnergyBarShaderGLSL.cpp
|
||||
Shaders/CRadarPaintShader.hpp Shaders/CRadarPaintShader.cpp Shaders/CRadarPaintShaderGLSL.cpp
|
||||
Shaders/CMapSurfaceShader.hpp Shaders/CMapSurfaceShader.cpp Shaders/CMapSurfaceShaderGLSL.cpp
|
||||
${PLAT_SRCS})
|
||||
|
||||
runtime_add_list(Graphics GRAPHICS_SOURCES)
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
#include "CMetroidModelInstance.hpp"
|
||||
#include "CModel.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
#if 0
|
||||
CMetroidModelInstance::CMetroidModelInstance(CBooModel* inst)
|
||||
: x0_visorFlags(0), m_instance(inst)
|
||||
{
|
||||
x34_aabb = inst->x20_aabb;
|
||||
}
|
||||
|
||||
CMetroidModelInstance::CMetroidModelInstance
|
||||
(const void* modelHeader, CBooModel* inst)
|
||||
: x0_visorFlags(hecl::SBig(*static_cast<const u32*>(modelHeader))), m_instance(inst)
|
||||
{
|
||||
athena::io::MemoryReader r(static_cast<const u8*>(modelHeader) + 4, INT32_MAX);
|
||||
x4_xf.read34RowMajor(r);
|
||||
x34_aabb.readBoundingBoxBig(r);
|
||||
}
|
||||
|
||||
CMetroidModelInstance::~CMetroidModelInstance() {}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -22,9 +22,8 @@ class CMetroidModelInstance
|
|||
std::vector<CBooSurface> m_surfaces;
|
||||
std::unique_ptr<CBooModel> m_instance;
|
||||
public:
|
||||
//CMetroidModelInstance(CBooModel* inst);
|
||||
//CMetroidModelInstance(const void* modelHeader, CBooModel* inst);
|
||||
//~CMetroidModelInstance();
|
||||
CMetroidModelInstance() = default;
|
||||
CMetroidModelInstance(CMetroidModelInstance&&) = default;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -132,7 +132,7 @@ CLineRendererShaders::IDataBindingFactory* CLineRendererShaders::Initialize(boo:
|
|||
m_texAlpha = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None,
|
||||
true, true, false, boo::CullMode::None);
|
||||
false, true, false, boo::CullMode::None);
|
||||
m_texAdditive = ctx.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, TexNames, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None,
|
||||
|
@ -140,7 +140,7 @@ CLineRendererShaders::IDataBindingFactory* CLineRendererShaders::Initialize(boo:
|
|||
m_noTexAlpha = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, 1, nullptr, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None,
|
||||
true, true, false, boo::CullMode::None);
|
||||
false, true, false, boo::CullMode::None);
|
||||
m_noTexAdditive = ctx.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, 1, nullptr, 1, UniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||
boo::Primitive::TriStrips, boo::ZTest::None,
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
#include "CMapSurfaceShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CMapSurfaceShader::CMapSurfaceShader(boo::IGraphicsDataFactory::Context& ctx,
|
||||
boo::IGraphicsBufferS* vbo,
|
||||
boo::IGraphicsBufferS* ibo)
|
||||
: m_vbo(vbo), m_ibo(ibo)
|
||||
{
|
||||
m_uniBuf = ctx.newDynamicBuffer(boo::BufferUse::Uniform, sizeof(Uniform), 1);
|
||||
m_dataBind = TShader<CMapSurfaceShader>::BuildShaderDataBinding(ctx, *this);
|
||||
}
|
||||
|
||||
void CMapSurfaceShader::draw(const zeus::CColor& color, u32 start, u32 count)
|
||||
{
|
||||
m_uniform.mtx = CGraphics::GetPerspectiveProjectionMatrix(true) * CGraphics::g_GXModelView.toMatrix4f();
|
||||
m_uniform.color = color;
|
||||
m_uniBuf->load(&m_uniform, sizeof(m_uniform));
|
||||
CGraphics::SetShaderDataBinding(m_dataBind);
|
||||
CGraphics::DrawArrayIndexed(start, count);
|
||||
}
|
||||
|
||||
URDE_SPECIALIZE_SHADER(CMapSurfaceShader)
|
||||
|
||||
void CMapSurfaceShader::Shutdown() {}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
#ifndef __URDE_CMAPSURFACESHADER_HPP__
|
||||
#define __URDE_CMAPSURFACESHADER_HPP__
|
||||
|
||||
#include "TShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
class CMapSurfaceShader
|
||||
{
|
||||
friend struct CMapSurfaceShaderGLDataBindingFactory;
|
||||
friend struct CMapSurfaceShaderVulkanDataBindingFactory;
|
||||
friend struct CMapSurfaceShaderMetalDataBindingFactory;
|
||||
friend struct CMapSurfaceShaderD3DDataBindingFactory;
|
||||
|
||||
struct Uniform
|
||||
{
|
||||
zeus::CMatrix4f mtx;
|
||||
zeus::CColor color;
|
||||
};
|
||||
|
||||
Uniform m_uniform;
|
||||
boo::IGraphicsBufferD* m_uniBuf;
|
||||
boo::IGraphicsBufferS* m_vbo;
|
||||
boo::IGraphicsBufferS* m_ibo;
|
||||
boo::IShaderDataBinding* m_dataBind;
|
||||
|
||||
public:
|
||||
CMapSurfaceShader(boo::IGraphicsDataFactory::Context& ctx, boo::IGraphicsBufferS* vbo,
|
||||
boo::IGraphicsBufferS* ibo);
|
||||
void draw(const zeus::CColor& color, u32 start, u32 count);
|
||||
|
||||
using _CLS = CMapSurfaceShader;
|
||||
#include "TShaderDecl.hpp"
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CMAPSURFACESHADER_HPP__
|
|
@ -0,0 +1,115 @@
|
|||
#include "CMapSurfaceShader.hpp"
|
||||
#include "TShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"layout(location=0) in vec4 posIn;\n"
|
||||
"\n"
|
||||
"UBINDING0 uniform MapSurfaceUniform\n"
|
||||
"{\n"
|
||||
" mat4 xf;\n"
|
||||
" vec4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) out VertToFrag vtf;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" vtf.color = color;\n"
|
||||
" gl_Position = xf * vec4(posIn.xyz, 1.0);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS =
|
||||
"#version 330\n"
|
||||
BOO_GLSL_BINDING_HEAD
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" vec4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"SBINDING(0) in VertToFrag vtf;\n"
|
||||
"layout(location=0) out vec4 colorOut;\n"
|
||||
"void main()\n"
|
||||
"{\n"
|
||||
" colorOut = vtf.color;\n"
|
||||
"}\n";
|
||||
|
||||
URDE_DECL_SPECIALIZE_SHADER(CMapSurfaceShader)
|
||||
|
||||
static boo::IVertexFormat* s_VtxFmt = nullptr;
|
||||
static boo::IShaderPipeline* s_Pipeline = nullptr;
|
||||
|
||||
struct CMapSurfaceShaderGLDataBindingFactory : TShader<CMapSurfaceShader>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CMapSurfaceShader& filter)
|
||||
{
|
||||
boo::GLDataFactory::Context& cctx = static_cast<boo::GLDataFactory::Context&>(ctx);
|
||||
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{filter.m_vbo, filter.m_ibo, boo::VertexSemantic::Position4}
|
||||
};
|
||||
boo::IVertexFormat* vtxFmt = ctx.newVertexFormat(1, VtxVmt);
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
|
||||
boo::PipelineStage stages[] = {boo::PipelineStage::Vertex};
|
||||
filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline,
|
||||
vtxFmt, filter.m_vbo, nullptr, filter.m_ibo,
|
||||
1, bufs, stages, nullptr, nullptr, 0, nullptr, nullptr, nullptr);
|
||||
return filter.m_dataBind;
|
||||
}
|
||||
};
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
struct CMapSurfaceShaderVulkanDataBindingFactory : TShader<CMapSurfaceShader>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CMapSurfaceShader& filter)
|
||||
{
|
||||
boo::VulkanDataFactory::Context& cctx = static_cast<boo::VulkanDataFactory::Context&>(ctx);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
|
||||
filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, s_VtxFmt,
|
||||
filter.m_vbo, nullptr, filter.m_ibo, 1, bufs,
|
||||
nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr);
|
||||
return filter.m_dataBind;
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
TShader<CMapSurfaceShader>::IDataBindingFactory*
|
||||
CMapSurfaceShader::Initialize(boo::GLDataFactory::Context& ctx)
|
||||
{
|
||||
const char* uniNames[] = {"MapSurfaceUniform"};
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, 0, nullptr, 1, uniNames,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||
boo::Primitive::TriStrips, boo::ZTest::LEqual, false, true,
|
||||
false, boo::CullMode::Backface);
|
||||
return new CMapSurfaceShaderGLDataBindingFactory;
|
||||
}
|
||||
|
||||
#if BOO_HAS_VULKAN
|
||||
TShader<CMapSurfaceShader>::IDataBindingFactory*
|
||||
CMapSurfaceShader::Initialize(boo::VulkanDataFactory::Context& ctx)
|
||||
{
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4}
|
||||
};
|
||||
s_VtxFmt = ctx.newVertexFormat(1, VtxVmt);
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, boo::BlendFactor::SrcAlpha,
|
||||
boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
|
||||
boo::ZTest::LEqual, false, true, false, boo::CullMode::Backface);
|
||||
return new CMapSurfaceShaderVulkanDataBindingFactory;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
#include "CMapSurfaceShader.hpp"
|
||||
#include "TShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS =
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn : POSITION;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"cbuffer MapSurfaceUniform : register(b0)\n"
|
||||
"{\n"
|
||||
" float4x4 xf;\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"VertToFrag main(in VertData v)\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" vtf.color = color;\n"
|
||||
" vtf.position = mul(xf * float4(v.posIn.xyz, 1.0));\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS =
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position : SV_Position;\n"
|
||||
" float4 color : COLOR;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"float4 main(in VertToFrag vtf) : SV_Target0\n"
|
||||
"{\n"
|
||||
" return vtf.color;\n"
|
||||
"}\n";
|
||||
|
||||
URDE_DECL_SPECIALIZE_SHADER(CMapSurfaceShader)
|
||||
|
||||
static boo::IVertexFormat* s_VtxFmt = nullptr;
|
||||
static boo::IShaderPipeline* s_Pipeline = nullptr;
|
||||
|
||||
struct CMapSurfaceShaderD3DDataBindingFactory : TShader<CMapSurfaceShader>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CMapSurfaceShader& filter)
|
||||
{
|
||||
boo::ID3DDataFactory::Context& cctx = static_cast<boo::ID3DDataFactory::Context&>(ctx);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
|
||||
filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, s_VtxFmt,
|
||||
filter.m_vbo, nullptr, filter.m_ibo, 1, bufs,
|
||||
nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr);
|
||||
return filter.m_dataBind;
|
||||
}
|
||||
};
|
||||
|
||||
TShader<CMapSurfaceShader>::IDataBindingFactory*
|
||||
CMapSurfaceShader::Initialize(boo::ID3DDataFactory::Context& ctx)
|
||||
{
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4}
|
||||
};
|
||||
s_VtxFmt = ctx.newVertexFormat(1, VtxVmt);
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, nullptr, nullptr, nullptr, s_VtxFmt,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
|
||||
boo::ZTest::LEqual, false, true, false, boo::CullMode::Backface);
|
||||
return new CMapSurfaceShaderD3DDataBindingFactory;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,83 @@
|
|||
#include "CMapSurfaceShader.hpp"
|
||||
#include "TShader.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
static const char* VS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertData\n"
|
||||
"{\n"
|
||||
" float4 posIn [[ attribute(0) ]];\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct MapSurfaceUniform\n"
|
||||
"{\n"
|
||||
" float4x4 xf;\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"vertex VertToFrag vmain(VertData v [[ stage_in ]], constant MapSurfaceUniform& msu [[ buffer(2) ]])\n"
|
||||
"{\n"
|
||||
" VertToFrag vtf;\n"
|
||||
" vtf.color = msu.color;\n"
|
||||
" vtf.position = msu.xf * float4(v.posIn.xyz, 1.0);\n"
|
||||
" return vtf;\n"
|
||||
"}\n";
|
||||
|
||||
static const char* FS =
|
||||
"#include <metal_stdlib>\n"
|
||||
"using namespace metal;\n"
|
||||
"struct VertToFrag\n"
|
||||
"{\n"
|
||||
" float4 position [[ position ]];\n"
|
||||
" float4 color;\n"
|
||||
"};\n"
|
||||
"\n"
|
||||
"fragment float4 fmain(VertToFrag vtf [[ stage_in ]])\n"
|
||||
"{\n"
|
||||
" return vtf.color;\n"
|
||||
"}\n";
|
||||
|
||||
URDE_DECL_SPECIALIZE_SHADER(CMapSurfaceShader)
|
||||
|
||||
static boo::IVertexFormat* s_VtxFmt = nullptr;
|
||||
static boo::IShaderPipeline* s_Pipeline = nullptr;
|
||||
|
||||
struct CMapSurfaceShaderMetalDataBindingFactory : TShader<CMapSurfaceShader>::IDataBindingFactory
|
||||
{
|
||||
boo::IShaderDataBinding* BuildShaderDataBinding(boo::IGraphicsDataFactory::Context& ctx,
|
||||
CMapSurfaceShader& filter)
|
||||
{
|
||||
boo::MetalDataFactory::Context& cctx = static_cast<boo::MetalDataFactory::Context&>(ctx);
|
||||
|
||||
boo::IGraphicsBuffer* bufs[] = {filter.m_uniBuf};
|
||||
filter.m_dataBind = cctx.newShaderDataBinding(s_Pipeline, s_VtxFmt,
|
||||
filter.m_vbo, nullptr, filter.m_ibo, 1, bufs,
|
||||
nullptr, nullptr, nullptr, 0, nullptr, nullptr, nullptr);
|
||||
return filter.m_dataBind;
|
||||
}
|
||||
};
|
||||
|
||||
TShader<CMapSurfaceShader>::IDataBindingFactory*
|
||||
CMapSurfaceShader::Initialize(boo::MetalDataFactory::Context& ctx)
|
||||
{
|
||||
const boo::VertexElementDescriptor VtxVmt[] =
|
||||
{
|
||||
{nullptr, nullptr, boo::VertexSemantic::Position4}
|
||||
};
|
||||
s_VtxFmt = ctx.newVertexFormat(1, VtxVmt);
|
||||
s_Pipeline = ctx.newShaderPipeline(VS, FS, s_VtxFmt, CGraphics::g_ViewportSamples,
|
||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha, boo::Primitive::TriStrips,
|
||||
boo::ZTest::LEqual, false, true, false, boo::CullMode::Backface);
|
||||
return new CMapSurfaceShaderMetalDataBindingFactory;
|
||||
}
|
||||
|
||||
}
|
|
@ -86,6 +86,7 @@ void CTweaks::RegisterTweaks()
|
|||
tag = factory.GetResourceIdByName("AutoMapper");
|
||||
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
|
||||
g_tweakAutoMapper = new DataSpec::DNAMP1::CTweakAutoMapper(*strm);
|
||||
CMappableObject::ReadAutoMapperTweaks(*g_tweakAutoMapper);
|
||||
|
||||
/* Gui */
|
||||
tag = factory.GetResourceIdByName("Gui");
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include "Graphics/Shaders/CTextSupportShader.hpp"
|
||||
#include "Graphics/Shaders/CEnergyBarShader.hpp"
|
||||
#include "Graphics/Shaders/CRadarPaintShader.hpp"
|
||||
#include "Graphics/Shaders/CMapSurfaceShader.hpp"
|
||||
#include "Character/CCharLayoutInfo.hpp"
|
||||
#include "Audio/CStreamAudioManager.hpp"
|
||||
#include "CGBASupport.hpp"
|
||||
|
@ -27,6 +28,7 @@ URDE_DECL_SPECIALIZE_SHADER(CFogVolumePlaneShader)
|
|||
URDE_DECL_SPECIALIZE_SHADER(CFogVolumeFilter)
|
||||
URDE_DECL_SPECIALIZE_SHADER(CEnergyBarShader)
|
||||
URDE_DECL_SPECIALIZE_SHADER(CRadarPaintShader)
|
||||
URDE_DECL_SPECIALIZE_SHADER(CMapSurfaceShader)
|
||||
URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CColoredQuadFilter)
|
||||
URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilter)
|
||||
URDE_DECL_SPECIALIZE_MULTI_BLEND_SHADER(CTexturedQuadFilterAlpha)
|
||||
|
@ -219,6 +221,7 @@ CMain::BooSetter::BooSetter(boo::IGraphicsDataFactory* factory,
|
|||
TShader<CFogVolumeFilter>::Initialize();
|
||||
TShader<CEnergyBarShader>::Initialize();
|
||||
TShader<CRadarPaintShader>::Initialize();
|
||||
TShader<CMapSurfaceShader>::Initialize();
|
||||
TMultiBlendShader<CColoredQuadFilter>::Initialize();
|
||||
TMultiBlendShader<CTexturedQuadFilter>::Initialize();
|
||||
TMultiBlendShader<CTexturedQuadFilterAlpha>::Initialize();
|
||||
|
@ -334,6 +337,7 @@ void CMain::ShutdownSubsystems()
|
|||
CAnimData::FreeCache();
|
||||
CMemoryCardSys::Shutdown();
|
||||
CModelShaders::Shutdown();
|
||||
CMappableObject::Shutdown();
|
||||
}
|
||||
|
||||
void CMain::Shutdown()
|
||||
|
@ -349,6 +353,7 @@ void CMain::Shutdown()
|
|||
TShader<CFogVolumeFilter>::Shutdown();
|
||||
TShader<CEnergyBarShader>::Shutdown();
|
||||
TShader<CRadarPaintShader>::Shutdown();
|
||||
TShader<CMapSurfaceShader>::Shutdown();
|
||||
TMultiBlendShader<CColoredQuadFilter>::Shutdown();
|
||||
TMultiBlendShader<CTexturedQuadFilter>::Shutdown();
|
||||
TMultiBlendShader<CTexturedQuadFilterAlpha>::Shutdown();
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
virtual ResId IGetSaveWorldAssetId() const=0;
|
||||
virtual const CMapWorld* IGetMapWorld() const=0;
|
||||
virtual CMapWorld* IMapWorld()=0;
|
||||
virtual const IGameArea* IGetAreaAlways(TAreaId id) const=0;
|
||||
virtual const IGameArea* IGetAreaAlways(TAreaId id) const=0;
|
||||
virtual TAreaId IGetCurrentAreaId() const=0;
|
||||
virtual TAreaId IGetAreaId(ResId id) const=0;
|
||||
virtual bool ICheckWorldComplete()=0;
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit eca3f3fdfad2f2558a98b0e193a63011cb76d02d
|
||||
Subproject commit 2066835a7c597ec5fb022713edbb5a598941dce7
|
Loading…
Reference in New Issue