Tons of DrawWorld-related implementations

This commit is contained in:
Jack Andersen 2017-03-03 18:31:08 -10:00
parent 5c884fec0c
commit cac0e328f7
32 changed files with 743 additions and 61 deletions

View File

@ -36,6 +36,12 @@ struct ITweakGui : ITweak
virtual float GetXrayBlurScaleLinear() const=0;
virtual float GetXrayBlurScaleQuadratic() const=0;
virtual float GetWorldTransManagerCharsPerSfx() const=0;
virtual atUint32 GetXRayFogMode() const=0;
virtual float GetXRayFogNearZ() const=0;
virtual float GetXRayFogFarZ() const=0;
virtual const zeus::CColor& GetXRayFogColor() const=0;
virtual float GetThermalVisorLevel() const=0;
virtual const zeus::CColor& GetThermalVisorColor() const=0;
};
}

View File

@ -151,12 +151,12 @@ struct CTweakGui : ITweakGui
Value<bool> x274_;
bool x275_ = true;
Value<float> x278_wtMgrCharsPerSfx;
Value<atUint32> x27c_;
Value<float> x280_;
Value<float> x284_;
DNAColor x288_;
Value<float> x28c_;
DNAColor x290_;
Value<atUint32> x27c_xrayFogMode;
Value<float> x280_xrayFogNearZ;
Value<float> x284_xrayFogFarZ;
DNAColor x288_xrayFogColor;
Value<float> x28c_thermalVisorLevel;
DNAColor x290_thermalVisorColor;
DNAColor x294_;
DNAColor x298_;
DNAColor x29c_;
@ -204,6 +204,12 @@ struct CTweakGui : ITweakGui
float GetXrayBlurScaleLinear() const { return x204_xrayBlurScaleLinear; }
float GetXrayBlurScaleQuadratic() const { return x208_xrayBlurScaleQuadratic; }
float GetWorldTransManagerCharsPerSfx() const { return x278_wtMgrCharsPerSfx; }
atUint32 GetXRayFogMode() const { return x27c_xrayFogMode; }
float GetXRayFogNearZ() const { return x280_xrayFogNearZ; }
float GetXRayFogFarZ() const { return x284_xrayFogFarZ; }
const zeus::CColor& GetXRayFogColor() const { return x288_xrayFogColor; }
float GetThermalVisorLevel() const { return x28c_thermalVisorLevel; }
const zeus::CColor& GetThermalVisorColor() const { return x290_thermalVisorColor; }
float GetScanSpeed(int idx) const
{
@ -224,14 +230,14 @@ struct CTweakGui : ITweakGui
x210_ = zeus::degToRad(x210_);
x228_ = x220_ + x224_;
if (x27c_ == 1)
x27c_ = 2;
else if (x27c_ == 2)
x27c_ = 4;
else if (x27c_ == 3)
x27c_ = 5;
if (x27c_xrayFogMode == 1)
x27c_xrayFogMode = 2;
else if (x27c_xrayFogMode == 2)
x27c_xrayFogMode = 4;
else if (x27c_xrayFogMode == 3)
x27c_xrayFogMode = 5;
else
x27c_ = 0;
x27c_xrayFogMode = 0;
x84_ *= 2.0f;
}

View File

@ -30,6 +30,7 @@
#include "Camera/CBallCamera.hpp"
#include "Collision/CMaterialFilter.hpp"
#include "World/CScriptDock.hpp"
#include "Particle/CDecalManager.hpp"
#include <cmath>
@ -63,6 +64,8 @@ CStateManager::CStateManager(const std::weak_ptr<CRelayTracker>& relayTracker,
x884_actorModelParticles = &x86c_stateManagerContainer->xf168_actorModelParticles;
x88c_rumbleManager = &x86c_stateManagerContainer->xf250_rumbleManager;
g_Renderer->SetDrawableCallback(&CStateManager::RendererDrawCallback, this);
x90c_loaderFuncs[int(EScriptObjectType::Actor)] = ScriptLoader::LoadActor;
x90c_loaderFuncs[int(EScriptObjectType::Waypoint)] = ScriptLoader::LoadWaypoint;
x90c_loaderFuncs[int(EScriptObjectType::Door)] = ScriptLoader::LoadDoor;
@ -255,22 +258,44 @@ void CStateManager::UpdateThermalVisor()
}
}
void CStateManager::RendererDrawCallback(const void* drawable, const void* ctx, int type)
{
CStateManager& mgr = reinterpret_cast<CStateManager&>(ctx);
switch (type)
{
case 0:
{
CActor& actor = reinterpret_cast<CActor&>(drawable);
if (actor.xc8_drawnToken == mgr.x8dc_objectDrawToken)
break;
if (actor.xc6_nextDrawNode != kInvalidUniqueId)
mgr.RecursiveDrawTree(actor.xc6_nextDrawNode);
actor.Render(mgr);
actor.xc8_drawnToken = mgr.x8dc_objectDrawToken;
break;
}
case 1:
reinterpret_cast<CSimpleShadow&>(drawable).Render(mgr.x8f0_shadowTex.GetObj());
break;
case 2:
reinterpret_cast<CDecal&>(drawable).Render();
break;
default: break;
}
}
bool CStateManager::RenderLast(TUniqueId) { return false; }
void CStateManager::AddDrawableActorPlane(const CActor& actor, const zeus::CPlane& plane,
const zeus::CAABox& aabb) const
{
#if 0
actor.SetAddedToken(x8dc_ + 1);
#endif
const_cast<CActor&>(actor).SetAddedToken(x8dc_objectDrawToken + 1);
g_Renderer->AddPlaneObject(static_cast<const void*>(&actor), aabb, plane, 0);
}
void CStateManager::AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const
{
#if 0
actor.SetAddedToken(x8dc_ + 1);
#endif
const_cast<CActor&>(actor).SetAddedToken(x8dc_objectDrawToken + 1);
g_Renderer->AddDrawable(static_cast<const void*>(&actor), vec, aabb, 0,
IRenderer::EDrawableSorting::SortedCallback);
}
@ -344,7 +369,10 @@ std::string CStateManager::HashInstanceName(CInputStream& in)
void CStateManager::SetActorAreaId(CActor& actor, TAreaId) {}
void CStateManager::TouchSky() const {}
void CStateManager::TouchSky() const
{
x850_world->TouchSky();
}
void CStateManager::TouchPlayerActor()
{
@ -442,10 +470,191 @@ void CStateManager::DrawWorld() const
CTimeProvider timeProvider(xf14_);
zeus::CFrustum frustum = SetupViewForDraw(g_Viewport);
GetVisAreaId();
/* Area camera is in (not necessarily player) */
TAreaId visAreaId = GetVisAreaId();
x850_world->TouchSky();
int areaCount = 0;
CGameArea* areaArr[10];
for (CGameArea* area = x850_world->x4c_chainHeads[3];
area != CWorld::AliveAreasEnd() && areaCount != 10;
area = area->x130_next)
{
CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded;
if (area->IsPostConstructed())
occState = area->GetOcclusionState();
if (occState == CGameArea::EOcclusionState::Occluded)
areaArr[areaCount++] = area;
}
std::sort(std::begin(areaArr), std::begin(areaArr) + areaCount,
[visAreaId](CGameArea* a, CGameArea* b) -> bool
{
if (a->x4_selfIdx == b->x4_selfIdx)
return false;
if (visAreaId == a->x4_selfIdx)
return false;
if (visAreaId == b->x4_selfIdx)
return true;
return CGraphics::g_ViewPoint.dot(a->GetAABB().center()) >
CGraphics::g_ViewPoint.dot(b->GetAABB().center());
});
int pvsCount = 0;
CPVSVisSet pvsArr[10];
for (CGameArea** area = areaArr;
area != areaArr + areaCount;
++area)
{
CGameArea* areaPtr = *area;
CPVSVisSet& pvsSet = pvsArr[pvsCount++];
pvsSet.Reset(EPVSVisSetState::OutOfBounds);
GetVisSetForArea(areaPtr->x4_selfIdx, visAreaId, pvsSet);
}
int mask;
int targetMask;
CPlayerState::EPlayerVisor visor = x8b8_playerState->GetActiveVisor(*this);
bool thermal = visor == CPlayerState::EPlayerVisor::Thermal;
if (thermal)
{
const_cast<CStateManager&>(*this).xf34_particleFlags = 1;
mask = 52;
targetMask = 0;
}
else
{
const_cast<CStateManager&>(*this).xf34_particleFlags = 2;
mask = 1 << (visor == CPlayerState::EPlayerVisor::XRay ? 3 : 1);
targetMask = 0;
}
g_Renderer->SetThermal(thermal, g_tweakGui->GetThermalVisorLevel(), g_tweakGui->GetThermalVisorColor());
g_Renderer->SetThermalColdScale(xf28_thermColdScale2 + xf24_thermColdScale1);
for (int i=areaCount-1 ; i>=0 ; --i)
{
CGameArea& area = *areaArr[i];
SetupFogForArea(area);
g_Renderer->EnablePVS(&pvsArr[i], area.x4_selfIdx);
g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel);
g_Renderer->DrawUnsortedGeometry(area.x4_selfIdx, mask, targetMask);
}
if (!SetupFogForDraw())
g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::CColor::skBlack);
x850_world->DrawSky(zeus::CTransform::Translate(CGraphics::g_ViewPoint));
if (areaCount)
SetupFogForArea(*areaArr[areaCount-1]);
for (TUniqueId id : x86c_stateManagerContainer->xf370_)
{
if (const CActor* ent = static_cast<const CActor*>(GetObjectById(id)))
{
if (!thermal || ent->xe6_27_ & 0x2)
{
ent->Render(*this);
}
}
}
bool morphingPlayerVisible = false;
int thermalActorCount = 0;
CActor* thermalActorArr[1024];
for (int i=0 ; i<areaCount ; ++i)
{
CGameArea& area = *areaArr[i];
CPVSVisSet& pvs = pvsArr[i];
bool isVisArea = area.x4_selfIdx == visAreaId;
SetupFogForArea(area);
g_Renderer->SetWorldLightFadeLevel(area.GetPostConstructed()->x1128_worldLightingLevel);
for (CEntity* ent : *area.GetPostConstructed()->x10c0_areaObjs)
{
if (TCastToPtr<CActor> actor = ent)
{
if (!actor->xe7_29_)
continue;
TUniqueId actorId = actor->GetUniqueId();
if (!thermal && area.LookupPVSUniqueID(actorId) == actorId)
if (pvs.GetVisible(area.LookupPVSID(actorId)) == EPVSVisSetState::EndOfTree)
continue;
if (x84c_player.get() == actor.GetPtr())
{
if (thermal)
continue;
switch (x84c_player->GetMorphballTransitionState())
{
case CPlayer::EPlayerMorphBallState::Unmorphed:
case CPlayer::EPlayerMorphBallState::Morphed:
x84c_player->AddToRenderer(frustum, *this);
continue;
default:
morphingPlayerVisible = true;
continue;
}
}
if (!thermal || actor->xe6_27_ & 0x2)
actor->AddToRenderer(frustum, *this);
if (thermal && actor->xe6_27_ & 0x4)
thermalActorArr[thermalActorCount++] = actor.GetPtr();
}
}
if (isVisArea && !thermal)
{
CDecalManager::AddToRenderer(frustum, *this);
x884_actorModelParticles->AddStragglersToRenderer(*this);
}
++const_cast<CStateManager&>(*this).x8dc_objectDrawToken;
// TODO: Finish
x84c_player->GetMorphBall();
}
}
void CStateManager::SetupFogForArea(const CGameArea& area) const {}
void CStateManager::SetupFogForArea(const CGameArea& area) const
{
if (SetupFogForDraw())
return;
if (x8b8_playerState->GetActiveVisor(*this) == CPlayerState::EPlayerVisor::XRay)
{
float fogDist = area.GetXRayFogDistance();
float farz = g_tweakGui->GetXRayFogNearZ() * (1.f - fogDist) +
g_tweakGui->GetXRayFogFarZ() * fogDist;
g_Renderer->SetWorldFog(ERglFogMode(g_tweakGui->GetXRayFogMode()),
g_tweakGui->GetXRayFogNearZ(),
farz, g_tweakGui->GetXRayFogColor());
}
else
{
area.GetAreaFog()->SetCurrent();
}
}
bool CStateManager::SetupFogForDraw() const
{
switch (x8b8_playerState->GetActiveVisor(*this))
{
case CPlayerState::EPlayerVisor::Thermal:
g_Renderer->SetWorldFog(ERglFogMode::None, 0.f, 1.f, zeus::CColor::skBlack);
return true;
case CPlayerState::EPlayerVisor::XRay:
default:
return false;
case CPlayerState::EPlayerVisor::Combat:
case CPlayerState::EPlayerVisor::Scan:
auto& fog = x870_cameraManager->Fog();
if (fog.IsFogDisabled())
return false;
fog.SetCurrent();
return true;
}
}
void CStateManager::PreRender()
{
@ -549,7 +758,20 @@ bool CStateManager::GetVisSetForArea(TAreaId a, TAreaId b, CPVSVisSet& setOut) c
return false;
}
void CStateManager::RecursiveDrawTree(TUniqueId) const {}
void CStateManager::RecursiveDrawTree(TUniqueId node) const
{
if (TCastToConstPtr<CActor> actor = GetObjectById(node))
{
if (x8dc_objectDrawToken != actor->xc8_drawnToken)
{
if (actor->xc6_nextDrawNode != kInvalidUniqueId)
RecursiveDrawTree(actor->xc6_nextDrawNode);
if (x8dc_objectDrawToken == actor->xcc_addedToken)
actor->Render(*this);
const_cast<CActor*>(actor.GetPtr())->xc8_drawnToken = x8dc_objectDrawToken;
}
}
}
void CStateManager::SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg)
{

View File

@ -133,6 +133,7 @@ class CStateManager
//u32 x8d0_extFrameIdx = 0;
//u32 x8d4_updateFrameIdx = 0;
//u32 x8d8_drawFrameIdx = 0;
u32 x8dc_objectDrawToken = 0;
std::vector<CLight> x8e0_dynamicLights;
@ -192,7 +193,7 @@ class CStateManager
float xf24_thermColdScale1 = 0.f;
float xf28_thermColdScale2 = 0.f;
zeus::CVector2f xf2c_viewportScale = {1.f, 1.f};
u32 xf34_ = 2;
u32 xf34_particleFlags = 2;
TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId;
std::list<u32> xf3c_;
u32 xf50_ = 0;
@ -228,6 +229,7 @@ class CStateManager
};
void UpdateThermalVisor();
static void RendererDrawCallback(const void*, const void*, int);
public:
/* TODO: Public for CFirstPersonCamera */
@ -268,6 +270,7 @@ public:
zeus::CFrustum SetupViewForDraw(const SViewport& vp) const;
void DrawWorld() const;
void SetupFogForArea(const CGameArea& area) const;
bool SetupFogForDraw() const;
void PreRender();
bool GetVisSetForArea(TAreaId, TAreaId, CPVSVisSet& setOut) const;
void RecursiveDrawTree(TUniqueId) const;
@ -394,6 +397,7 @@ public:
TUniqueId GetLastRelayId() const { return xf76_lastRelay; }
bool GetIsGeneratingObject() const { return xf94_26_generatingObject; }
void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; }
u32 GetParticleFlags() const { return xf34_particleFlags; }
};
}

View File

@ -102,7 +102,7 @@ public:
CFirstPersonCamera* GetFirstPersonCamera() { return x7c_fpCamera; }
CBallCamera* GetBallCamera() { return x80_ballCamera; }
CBallCamera* BallCamera(CStateManager&) const;
CGameArea::CAreaFog Fog() { return x3c_fog; }
CGameArea::CAreaFog& Fog() { return x3c_fog; }
float sub80009148() const;

View File

@ -231,7 +231,7 @@ void CBooRenderer::RenderBucketItems(CAreaListItem* item)
if (xa8_drawableCallback)
{
xa8_drawableCallback(drawable->GetData(), xac_callbackContext,
int(drawable->GetType()) - 2);
int(drawable->GetType()) - 2);
}
break;
}
@ -512,9 +512,9 @@ void CBooRenderer::AddDrawable(const void* obj, const zeus::CVector3f& pos, cons
Buckets::Insert(pos, aabb, EDrawableType(mode + 2), obj, xb0_viewPlane, 0);
}
void CBooRenderer::SetDrawableCallback(TDrawableCallback&& cb, const void* ctx)
void CBooRenderer::SetDrawableCallback(TDrawableCallback cb, const void* ctx)
{
xa8_drawableCallback = std::move(cb);
xa8_drawableCallback = cb;
xac_callbackContext = ctx;
}
@ -727,4 +727,9 @@ void CBooRenderer::PrepareDynamicLights(const std::vector<CLight>& lights)
}
}
void CBooRenderer::SetWorldLightFadeLevel(float level)
{
x2fc_tevReg1Color = zeus::CColor(level, level, level, 1.f);
}
}

View File

@ -111,6 +111,7 @@ class CBooRenderer : public IRenderer
float x2f0_thermalVisorLevel;
zeus::CColor x2f4_thermColor;
float x2f8_thermColdScale = 0.f;
zeus::CColor x2fc_tevReg1Color = {1.f, 0.f, 1.f, 1.f};
CThermalColdFilter m_thermColdFilter;
std::experimental::optional<CThermalHotFilter> m_thermHotFilter;
@ -157,7 +158,7 @@ public:
void AddParticleGen(const CParticleGen&);
void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int);
void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting);
void SetDrawableCallback(TDrawableCallback&&, const void*);
void SetDrawableCallback(TDrawableCallback, const void*);
void SetWorldViewpoint(const zeus::CTransform&);
void SetPerspective(float, float, float, float, float);
void SetPerspective(float, float, float, float);
@ -203,6 +204,7 @@ public:
void DoThermalBlendHot();
u32 GetStaticWorldDataSize();
void PrepareDynamicLights(const std::vector<CLight>& lights);
void SetWorldLightFadeLevel(float level);
boo::ITexture* GetThermoPalette() {return x288_thermoPalette;}

View File

@ -11,7 +11,8 @@ enum class EDrawableType : u16
WorldSurface,
Particle,
UnsortedCallback,
SortedCallback
SortedCallback,
Decal
};
class CDrawable

View File

@ -5,5 +5,10 @@ namespace urde
CSimpleShadow::CSimpleShadow(float, float, float, float)
{
}
void CSimpleShadow::Render(const CTexture* tex)
{
}
}

View File

@ -3,11 +3,14 @@
namespace urde
{
class CTexture;
class CSimpleShadow
{
public:
CSimpleShadow() = default;
CSimpleShadow(float, float, float, float);
void Render(const CTexture* tex);
};
}

View File

@ -25,7 +25,7 @@ struct CAreaRenderOctTree;
class IRenderer
{
public:
using TDrawableCallback = std::function<void(const void*, const void*, int)>;
typedef void(*TDrawableCallback)(const void*, const void*, int);
using TReflectionCallback = std::function<void(void*, const zeus::CVector3f&)>;
enum class EDrawableSorting
@ -54,7 +54,7 @@ public:
virtual void AddParticleGen(const CParticleGen&)=0;
virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0;
virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0;
virtual void SetDrawableCallback(TDrawableCallback&&, const void*)=0;
virtual void SetDrawableCallback(TDrawableCallback, const void*)=0;
virtual void SetWorldViewpoint(const zeus::CTransform&)=0;
virtual void SetPerspective(float, float, float, float, float)=0;
virtual void SetPerspective(float, float, float, float)=0;
@ -100,6 +100,7 @@ public:
virtual void DoThermalBlendHot()=0;
virtual u32 GetStaticWorldDataSize()=0;
virtual void PrepareDynamicLights(const std::vector<CLight>& lights)=0;
virtual void SetWorldLightFadeLevel(float level)=0;
};
}

View File

@ -72,4 +72,9 @@ void CDecal::SetMoveRedToAlphaBuffer(bool move)
{
sMoveRedToAphaBuffer = move;
}
void CDecal::Render() const
{
}
}

View File

@ -11,6 +11,7 @@ namespace urde
{
class CDecal
{
friend class CDecalManager;
public:
struct CQuadDecal
{
@ -58,6 +59,7 @@ public:
bool IsDone() const;
void RenderQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&) const;
void RenderMdl() const;
void Render() const;
void ProcessQuad(CQuadDecal&, const CDecalDescription::SQuadDescr&, s32) const;
void Update(float);
void CheckTime(s32, s32);

View File

@ -1,6 +1,9 @@
#include "CDecalManager.hpp"
#include "CDecalDescription.hpp"
#include "CDecal.hpp"
#include "CStateManager.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "GameGlobalObjects.hpp"
namespace urde
{
@ -32,4 +35,19 @@ void CDecalManager::Shutdown()
}
void CDecalManager::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr)
{
for (s32 idx : m_ActiveIndexList)
{
CDecalManager::SDecal& decal = m_DecalPool[idx];
if (decal.x75_flags & 0x2 || mgr.GetParticleFlags())
{
const zeus::CVector3f& point = decal.x0_decal->xc_transform.origin;
zeus::CAABox aabb(point, point);
g_Renderer->AddDrawable(&*decal.x0_decal, point, aabb, 2,
IRenderer::EDrawableSorting::SortedCallback);
}
}
}
}

View File

@ -6,17 +6,20 @@
#include "optional.hpp"
#include "CToken.hpp"
#include "CDecal.hpp"
#include "zeus/CFrustum.hpp"
namespace urde
{
class CStateManager;
class CDecalManager
{
struct SDecal
{
TAreaId m_areaId;
std::experimental::optional<CDecal> x60_decal;
SDecal() = default;
SDecal(std::experimental::optional<CDecal>&&, TAreaId);
std::experimental::optional<CDecal> x0_decal;
TAreaId x70_areaId;
u8 x74_index;
u8 x75_flags : 2;
};
static bool m_PoolInitialized;
@ -29,6 +32,7 @@ class CDecalManager
public:
static void Initialize();
static void Shutdown();
static void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr);
};
}

View File

@ -24,7 +24,7 @@ CActor::CActor(TUniqueId uid, bool active, const std::string& name, const CEntit
: CEntity(uid, info, active, name)
, x68_material(MakeActorMaterialList(list, params))
, x70_materialFilter(CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {0ull}))
, xc6_(otherUid)
, xc6_nextDrawNode(otherUid)
{
if (mData.x10_animData || mData.x1c_normalModel)
x64_modelData = std::make_unique<CModelData>(std::move(mData));
@ -74,8 +74,8 @@ void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMana
continue;
const CActor* act = TCastToConstPtr<CActor>(mgr.GetObjectById(mgr.GetIdForScript(conn.x8_objId)));
if (act && xc6_ == kInvalidUniqueId)
xc6_ = act->GetUniqueId();
if (act && xc6_nextDrawNode == kInvalidUniqueId)
xc6_nextDrawNode = act->GetUniqueId();
}
}
break;

View File

@ -26,6 +26,7 @@ class CSimpleShadow;
class CActor : public CEntity
{
friend class CStateManager;
protected:
zeus::CTransform x34_transform;
std::unique_ptr<CModelData> x64_modelData;
@ -44,9 +45,9 @@ protected:
float xbc_time = 0.f;
s32 xc0_ = 0;
TUniqueId xc4_fluidId = kInvalidUniqueId;
TUniqueId xc6_ = kInvalidUniqueId;
s32 xc8_ = -1;
s32 xcc_addedToken = -1;
TUniqueId xc6_nextDrawNode = kInvalidUniqueId;
u32 xc8_drawnToken = -1;
u32 xcc_addedToken = -1;
float xd0_;
u8 xd4_ = 0x7F;
u32 xd8_ = 2;

View File

@ -0,0 +1,154 @@
#include "CActorModelParticles.hpp"
#include "CStateManager.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "CDependencyGroup.hpp"
#include "Particle/CElementGen.hpp"
#include "Particle/CParticleElectric.hpp"
#include "Particle/CParticleSwoosh.hpp"
#include "World/CWorld.hpp"
#include "Graphics/CBooRenderer.hpp"
namespace urde
{
CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& parent)
: x0_id(ent.GetUniqueId()), x4_areaId(ent.GetAreaIdAlways()),
xdc_ashy(parent.x48_ashy), x128_parent(parent)
{
x8_.resize(8);
}
static const char* ParticleDGRPs[] =
{
"Effect_OnFire_DGRP",
"Effect_Ash_DGRP",
"Effect_IceBreak_DGRP",
"Effect_FirePop_DGRP",
"Effect_IcePop_DGRP",
"Effect_Electric_DGRP",
};
std::pair<std::vector<CToken>, bool>
CActorModelParticles::GetParticleDGRPTokens(const char* name)
{
std::pair<std::vector<CToken>, bool> ret = {};
TToken<CDependencyGroup> dgrp = g_SimplePool->GetObj(name);
const auto& vector = dgrp->GetObjectTagVector();
ret.first.reserve(vector.size());
for (const SObjectTag& tag : vector)
ret.first.push_back(g_SimplePool->GetObj(tag));
return ret;
}
void CActorModelParticles::LoadParticleDGRPs()
{
for (int i=0 ; i<6 ; ++i)
x50_dgrps.push_back(GetParticleDGRPTokens(ParticleDGRPs[i]));
}
std::unique_ptr<CElementGen> CActorModelParticles::MakeOnFireGen() const
{
return std::make_unique<CElementGen>(x18_onFire,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
}
std::unique_ptr<CElementGen> CActorModelParticles::MakeAshGen() const
{
return std::make_unique<CElementGen>(x20_ash,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
}
std::unique_ptr<CElementGen> CActorModelParticles::MakeIceGen() const
{
return std::make_unique<CElementGen>(x28_iceBreak,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
}
std::unique_ptr<CElementGen> CActorModelParticles::MakeFirePopGen() const
{
return std::make_unique<CElementGen>(x30_firePop,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
}
std::unique_ptr<CElementGen> CActorModelParticles::MakeIcePopGen() const
{
return std::make_unique<CElementGen>(x38_icePop,
CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One);
}
std::unique_ptr<CParticleElectric> CActorModelParticles::MakeElectricGen() const
{
return std::make_unique<CParticleElectric>(x40_electric);
}
CActorModelParticles::CActorModelParticles()
{
x18_onFire = g_SimplePool->GetObj("Effect_OnFire");
x20_ash = g_SimplePool->GetObj("Effect_Ash");
x28_iceBreak = g_SimplePool->GetObj("Effect_IceBreak");
x30_firePop = g_SimplePool->GetObj("Effect_FirePop");
x38_icePop = g_SimplePool->GetObj("Effect_IcePop");
x40_electric = g_SimplePool->GetObj("Effect_Electric");
x48_ashy = g_SimplePool->GetObj("TXTR_Ashy");
LoadParticleDGRPs();
}
void CActorModelParticles::AddStragglersToRenderer(const CStateManager& mgr)
{
bool isNotOne = mgr.GetParticleFlags() != 1;
bool isNotZero = mgr.GetParticleFlags() != 0;
for (CItem& item : x0_items)
{
if (item.x4_areaId != kInvalidAreaId)
{
const CGameArea* area = mgr.GetWorld()->GetAreaAlways(item.x4_areaId);
if (!area->IsPostConstructed())
continue;
CGameArea::EOcclusionState occState = area->GetPostConstructed()->x10dc_occlusionState;
if (occState == CGameArea::EOcclusionState::NotOccluded)
continue;
}
if (mgr.GetObjectById(item.x0_id) &&
((isNotOne && item.x12c_24_) || (isNotZero && item.x12c_25_)))
{
item.x12c_24_ = false;
item.x12c_25_ = false;
continue;
}
if (isNotOne)
{
for (int i=0 ; i<8 ; ++i)
{
std::unique_ptr<CElementGen>& gen = item.x8_[i].first;
if (gen)
g_Renderer->AddParticleGen(*gen);
}
if (mgr.GetParticleFlags() && item.x78_)
g_Renderer->AddParticleGen(*item.x78_);
if (item.xb8_)
g_Renderer->AddParticleGen(*item.xb8_);
if (item.xc0_)
g_Renderer->AddParticleGen(*item.xc0_);
}
if (isNotZero)
{
for (std::unique_ptr<CElementGen>& gen : item.x8c_)
g_Renderer->AddParticleGen(*gen);
if (item.xe4_)
g_Renderer->AddParticleGen(*item.xe4_);
}
if (isNotOne)
{
item.x12c_24_ = false;
item.x12c_25_ = false;
}
}
}
}

View File

@ -1,11 +1,90 @@
#ifndef __URDE_CACTORMODELPARTICLES_HPP__
#define __URDE_CACTORMODELPARTICLES_HPP__
#include <list>
#include "Audio/CSfxManager.hpp"
#include "CToken.hpp"
#include "zeus/CTransform.hpp"
namespace urde
{
class CStateManager;
class CEntity;
class CElementGen;
class CTexture;
class CElectricDescription;
class CGenDescription;
class CParticleElectric;
class CActorModelParticles
{
class CItem
{
friend class CActorModelParticles;
TUniqueId x0_id;
TAreaId x4_areaId;
rstl::reserved_vector<std::pair<std::unique_ptr<CElementGen>, u32>, 8> x8_;
float x6c_ = 0.f;
CSfxHandle x74_sfx;
bool x70_ = false;
std::unique_ptr<CElementGen> x78_;
u32 x80_ = 0;
u32 x84_ = -1;
u32 x88_ = 99;
rstl::reserved_vector<std::unique_ptr<CElementGen>, 4> x8c_;
u32 xb0_ = -1;
u32 xb4_ = 99;
std::unique_ptr<CElementGen> xb8_;
std::unique_ptr<CElementGen> xc0_;
u32 xc8_ = 0;
u32 xcc_ = 99;
zeus::CColor xd0_;
std::unique_ptr<u32> xd4_;
TToken<CTexture> xdc_ashy;
std::unique_ptr<CElementGen> xe4_;
float xec_ = 1.f;
float xf0_ = 1.f;
float xf4_ = 1.f;
zeus::CTransform xf8_;
CActorModelParticles& x128_parent;
union
{
struct
{
bool x12c_24_ : 1;
bool x12c_25_ : 1;
};
u16 _dummy = 0;
};
float x130_ = 10.f;
u8 x134_bits = 0;
public:
CItem(const CEntity& ent, CActorModelParticles& parent);
};
std::list<CItem> x0_items;
TToken<CGenDescription> x18_onFire;
TToken<CGenDescription> x20_ash;
TToken<CGenDescription> x28_iceBreak;
TToken<CGenDescription> x30_firePop;
TToken<CGenDescription> x38_icePop;
TToken<CElectricDescription> x40_electric;
TToken<CTexture> x48_ashy;
rstl::reserved_vector<std::pair<std::vector<CToken>, bool>, 6> x50_dgrps;
std::pair<std::vector<CToken>, bool> GetParticleDGRPTokens(const char* name);
void LoadParticleDGRPs();
std::unique_ptr<CElementGen> MakeOnFireGen() const;
std::unique_ptr<CElementGen> MakeAshGen() const;
std::unique_ptr<CElementGen> MakeIceGen() const;
std::unique_ptr<CElementGen> MakeFirePopGen() const;
std::unique_ptr<CElementGen> MakeIcePopGen() const;
std::unique_ptr<CParticleElectric> MakeElectricGen() const;
public:
CActorModelParticles();
void AddStragglersToRenderer(const CStateManager& mgr);
};
}

View File

@ -61,6 +61,7 @@ public:
return x4_areaId;
return kInvalidAreaId;
}
TAreaId GetAreaIdAlways() const { return x4_areaId; }
TUniqueId GetUniqueId() const {return x8_uid;}
TEditorId GetEditorId() const {return xc_editorId;}
void SendScriptMsgs(EScriptObjectState state, CStateManager& stateMgr, EScriptObjectMessage msg);

View File

@ -474,6 +474,14 @@ void CGameArea::SetThermalSpeedAndTarget(float speed, float target)
x12c_postConstructed->x1124_thermalTarget = target;
}
float CGameArea::GetXRayFogDistance() const
{
const CScriptAreaAttributes* attrs = x12c_postConstructed->x10d8_areaAttributes;
if (attrs)
return attrs->GetXRayFogDistance();
return 1.f;
}
bool CGameArea::DoesAreaNeedEnvFx() const
{
return false;
@ -1030,6 +1038,16 @@ CGameArea::MREAHeader CGameArea::VerifyHeader() const
return header;
}
TUniqueId CGameArea::LookupPVSUniqueID(TUniqueId id) const
{
return x12c_postConstructed->xa8_pvsEntityMap[id & 0x3ff].x4_uid;
}
s16 CGameArea::LookupPVSID(TUniqueId id) const
{
return x12c_postConstructed->xa8_pvsEntityMap[id & 0x3ff].x0_id;
}
void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes)
{
x12c_postConstructed->x10d8_areaAttributes = areaAttributes;

View File

@ -280,6 +280,7 @@ public:
ResId GetAreaAssetId() const { return x84_mrea; }
const CAreaFog* GetAreaFog() const { return GetPostConstructed()->x10c4_areaFog.get(); }
CAreaFog* AreaFog() { return const_cast<CAreaFog*>(GetAreaFog()); }
float GetXRayFogDistance() const;
bool DoesAreaNeedEnvFx() const;
bool DoesAreaNeedSkyNow() const;
bool OtherAreaOcclusionChanged();
@ -312,6 +313,8 @@ public:
void ClearTokenList();
u32 GetPreConstructedSize() const;
MREAHeader VerifyHeader() const;
TUniqueId LookupPVSUniqueID(TUniqueId id) const;
s16 LookupPVSID(TUniqueId id) const;
const zeus::CTransform& GetTransform() const {return xc_transform;}
const zeus::CTransform& GetInverseTransform() const {return x3c_invTransform;}
@ -329,6 +332,8 @@ public:
bool GetActive() const { return xf0_25_active; }
void SetActive(bool active) { xf0_25_active = active; }
CObjectList& GetAreaObjects() const { return *GetPostConstructed()->x10c0_areaObjs.get(); }
CGameArea* GetNext() const { return x130_next; }
};
}

View File

@ -8,6 +8,7 @@ set(WORLD_SOURCES
CEnergyDrainSource.hpp CEnergyDrainSource.cpp
CPlayerCameraBob.hpp CPlayerCameraBob.cpp
CMorphBall.hpp CMorphBall.cpp
CMorphBallTrail.hpp CMorphBallTrail.cpp
CActor.hpp CActor.cpp
CAi.hpp CAi.cpp
CAiFuncMap.hpp CAiFuncMap.cpp

View File

@ -0,0 +1,69 @@
#include "CMorphBallTrail.hpp"
#include "CStateManager.hpp"
#include "World/CWorld.hpp"
namespace urde
{
static union
{
struct
{
bool x_24_ : 1;
bool x_25_ : 1;
bool x_26_ : 1;
bool x_27_ : 1;
};
u16 _dummy = 0;
} s_flags;
CMorphBallTrail::CMorphBallTrail(int w, int h, const TToken<CTexture>& fadeTex)
: xb0_w(w), xb4_h(h), xa8_ballFade(fadeTex)
{
m_gfxToken = CGraphics::CommitResources([this, w, h](boo::IGraphicsDataFactory::Context& ctx)
{
m_renderTex = ctx.newRenderTexture(w, h, true, false);
return true;
});
}
void CMorphBallTrail::GatherAreas(CStateManager& mgr)
{
x18_areas.clear();
for (CGameArea* area = mgr.WorldNC()->GetChainHead(EChain::Alive);
area != CWorld::GetAliveAreasEnd();
area = area->GetNext())
{
CGameArea::EOcclusionState occState = CGameArea::EOcclusionState::NotOccluded;
if (area->IsPostConstructed())
occState = area->GetPostConstructed()->x10dc_occlusionState;
if (occState == CGameArea::EOcclusionState::Occluded)
x18_areas.push_back(area);
}
}
void CMorphBallTrail::RenderToTex(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player)
{
xb8_ = aabb;
x0_.clear();
x18_areas.clear();
x30_.clear();
s_flags.x_26_ = true;
if (!s_flags.x_27_)
{
xd0_ = false;
return;
}
GatherAreas(mgr);
// TODO: finish
}
void CMorphBallTrail::Render(CStateManager& mgr)
{
}
}

View File

@ -0,0 +1,36 @@
#ifndef __URDE_CMORPHBALLTRAIL_HPP__
#define __URDE_CMORPHBALLTRAIL_HPP__
#include "CToken.hpp"
#include "Graphics/CTexture.hpp"
#include "zeus/CAABox.hpp"
namespace urde
{
class CStateManager;
class CPlayer;
class CGameArea;
class CMorphBallTrail
{
std::list<u32> x0_;
std::list<CGameArea*> x18_areas;
std::vector<u32> x30_;
//CTexture x40_;
boo::GraphicsDataToken m_gfxToken;
boo::ITextureR* m_renderTex;
TToken<CTexture> xa8_ballFade;
int xb0_w;
int xb4_h;
zeus::CAABox xb8_;
bool xd0_ = false;
void GatherAreas(CStateManager& mgr);
public:
CMorphBallTrail(int w, int h, const TToken<CTexture>& fadeTex);
void RenderToTex(const zeus::CAABox& aabb, CStateManager& mgr, CPlayer& player);
void Render(CStateManager& mgr);
};
}
#endif // __URDE_CMORPHBALLTRAIL_HPP__

View File

@ -109,7 +109,7 @@ void CPlayer::PreRender(CStateManager& mgr, const zeus::CFrustum&) {}
void CPlayer::CalculateRenderBounds() {}
void CPlayer::AddToRenderer(const zeus::CFrustum&, CStateManager&) {}
void CPlayer::AddToRenderer(const zeus::CFrustum&, const CStateManager&) {}
void CPlayer::ComputeFreeLook(const CFinalInput& input) {}

View File

@ -319,7 +319,7 @@ public:
void RenderReflectedPlayer(CStateManager& mgr) const;
void PreRender(CStateManager& mgr, const zeus::CFrustum&);
void CalculateRenderBounds();
void AddToRenderer(const zeus::CFrustum&, CStateManager&);
void AddToRenderer(const zeus::CFrustum&, const CStateManager&);
void ComputeFreeLook(const CFinalInput& input);
void UpdateFreeLook(float dt);
float GetMaximumPlayerPositiveVerticalVelocity(CStateManager&) const;

View File

@ -50,11 +50,4 @@ void CScriptAreaAttributes::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
}
}
bool CScriptAreaAttributes::GetNeedsSky() const { return x34_24_showSkybox; }
bool CScriptAreaAttributes::GetNeedsEnvFx() const { return x38_envFx != EEnvFxType::None; }
float CScriptAreaAttributes::GetThermalHeat() const { return x40_thermalHeat; }
float CScriptAreaAttributes::GetWorldLightingLevel() const { return x48_worldLightingLevel; }
}

View File

@ -25,11 +25,13 @@ public:
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
bool GetNeedsSky() const;
bool GetNeedsEnvFx() const;
float GetEnvFxDensity() const;
float GetThermalHeat() const;
float GetWorldLightingLevel() const;
bool GetNeedsSky() const { return x34_24_showSkybox; }
bool GetNeedsEnvFx() const { return x38_envFx != EEnvFxType::None; }
float GetEnvFxDensity() const { return x3c_envFxDensity; }
float GetThermalHeat() const { return x40_thermalHeat; }
float GetXRayFogDistance() const { return x44_xrayFogDistance; }
float GetWorldLightingLevel() const { return x48_worldLightingLevel; }
};
}

View File

@ -7,6 +7,7 @@
#include "Audio/CAudioGroupSet.hpp"
#include "Editor/ProjectResourceFactoryBase.hpp"
#include "CGameState.hpp"
#include "Graphics/CBooRenderer.hpp"
namespace urde
{
@ -237,7 +238,7 @@ void CWorld::MoveToChain(CGameArea* area, EChain chain)
void CWorld::MoveAreaToChain3(TAreaId aid)
{
MoveToChain(x18_areas[aid].get(), EChain::Three);
MoveToChain(x18_areas[aid].get(), EChain::Alive);
}
void CWorld::LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data) {}
@ -416,13 +417,13 @@ bool CWorld::ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr)
}
else
{
if (area->x138_curChain != EChain::Three)
if (area->x138_curChain != EChain::Alive)
{
if (area->x138_curChain != EChain::Four)
{
x70_24_ = true;
}
MoveToChain(area, EChain::Three);
MoveToChain(area, EChain::Alive);
}
return false;
}
@ -464,7 +465,7 @@ void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther)
if (area->x138_curChain != EChain::Four)
x70_24_ = true;
area->Validate(mgr);
MoveToChain(area, EChain::Three);
MoveToChain(area, EChain::Alive);
area->SetOcclusionState(CGameArea::EOcclusionState::Occluded);
CGameArea* otherLoadArea = nullptr;
@ -581,4 +582,38 @@ void CWorld::PreRender()
head->PreRender();
}
}
void CWorld::TouchSky()
{
#if 0
if (xa4_skyboxB.IsLoaded())
xa4_skyboxB->Touch();
if (xb4_skyboxC.IsLoaded())
xb4_skyboxC->Touch();
#endif
}
void CWorld::DrawSky(const zeus::CTransform& xf) const
{
const CModel* model;
if (xa4_skyboxB)
model = xa4_skyboxB.GetObj();
else if (xb4_skyboxC)
model = xb4_skyboxC.GetObj();
else
return;
if (!x70_27_)
return;
CGraphics::DisableAllLights();
CGraphics::SetModelMatrix(xf);
g_Renderer->SetAmbientColor(zeus::CColor::skWhite);
CGraphics::SetDepthRange(0.999f, 1.f);
CModelFlags flags(0, 0, 1, zeus::CColor::skWhite);
model->Draw(flags);
CGraphics::SetDepthRange(0.125f, 1.f);
}
}

View File

@ -145,6 +145,7 @@ private:
std::string x84_defAudioTrack;
TLockedToken<CModel> x94_skybox;
TLockedToken<CModel> xa4_skyboxB;
TLockedToken<CModel> xb4_skyboxC;
void LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data);
void LoadSoundGroups();
@ -154,6 +155,7 @@ public:
void MoveToChain(CGameArea* area, EChain chain);
void MoveAreaToChain3(TAreaId aid);
bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId);
CGameArea* GetChainHead(EChain chain) { return x4c_chainHeads[int(chain)]; }
bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr);
void TravelToArea(TAreaId aid, CStateManager& mgr, bool);
void SetPauseState(bool paused);
@ -186,6 +188,8 @@ public:
static CGameArea* AliveAreasEnd() { return skGlobalNonConstEnd; }
void PreRender();
void TouchSky();
void DrawSky(const zeus::CTransform& xf) const;
};
struct CWorldLayers

View File

@ -58,7 +58,7 @@ enum class EChain
Zero,
One,
Two,
Three,
Alive,
Four
};