2022-08-13 01:26:00 +00:00
|
|
|
#include "MetroidPrime/CActor.hpp"
|
2022-08-14 18:38:41 +00:00
|
|
|
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "MetaRender/CCubeRenderer.hpp"
|
2022-08-13 01:26:00 +00:00
|
|
|
#include "MetroidPrime/CActorLights.hpp"
|
2022-09-13 04:26:54 +00:00
|
|
|
#include "MetroidPrime/CActorModelParticles.hpp"
|
2022-08-13 01:26:00 +00:00
|
|
|
#include "MetroidPrime/CActorParameters.hpp"
|
2022-08-14 18:38:41 +00:00
|
|
|
#include "MetroidPrime/CAnimData.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "MetroidPrime/CGameArea.hpp"
|
2022-08-13 01:26:00 +00:00
|
|
|
#include "MetroidPrime/CModelData.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "MetroidPrime/CSimpleShadow.hpp"
|
|
|
|
#include "MetroidPrime/CStateManager.hpp"
|
|
|
|
#include "MetroidPrime/CWorld.hpp"
|
2022-08-14 18:38:41 +00:00
|
|
|
#include "MetroidPrime/Cameras/CCameraManager.hpp"
|
|
|
|
#include "MetroidPrime/Cameras/CGameCamera.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "MetroidPrime/Player/CPlayerState.hpp"
|
2022-08-13 01:26:00 +00:00
|
|
|
|
|
|
|
#include "Kyoto/Audio/CAudioSys.hpp"
|
2022-08-15 04:51:06 +00:00
|
|
|
#include "Kyoto/Audio/CSfxManager.hpp"
|
2022-09-13 04:26:54 +00:00
|
|
|
#include "Kyoto/CTimeProvider.hpp"
|
2022-08-16 02:14:28 +00:00
|
|
|
#include "Kyoto/Graphics/CGraphics.hpp"
|
|
|
|
#include "Kyoto/Math/CFrustumPlanes.hpp"
|
2022-09-13 04:26:54 +00:00
|
|
|
#include "Kyoto/Math/CMath.hpp"
|
|
|
|
|
|
|
|
#include "rstl/math.hpp"
|
2022-08-13 01:26:00 +00:00
|
|
|
|
2022-09-18 06:05:46 +00:00
|
|
|
static CMaterialList MakeActorMaterialList(const CMaterialList& in,
|
|
|
|
const CActorParameters& params) {
|
2022-08-13 01:26:00 +00:00
|
|
|
CMaterialList ret = in;
|
|
|
|
if (params.GetVisorParameters().GetBool1()) {
|
|
|
|
ret.Add(kMT_Unknown46);
|
|
|
|
}
|
|
|
|
if (params.GetVisorParameters().GetScanPassthrough()) {
|
|
|
|
ret.Add(kMT_ScanPassthrough);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2022-09-18 06:05:46 +00:00
|
|
|
CActor::CActor(TUniqueId uid, bool active, const rstl::string& name, const CEntityInfo& info,
|
|
|
|
const CTransform4f& xf, const CModelData& mData, const CMaterialList& list,
|
|
|
|
const CActorParameters& params, TUniqueId nextDrawNode)
|
2022-08-13 01:26:00 +00:00
|
|
|
: CEntity(uid, info, active, name)
|
|
|
|
, x34_transform(xf)
|
2022-08-16 02:14:28 +00:00
|
|
|
, x64_modelData(mData.IsNull() ? nullptr : new CModelData(mData))
|
2022-08-13 01:26:00 +00:00
|
|
|
, x68_material(MakeActorMaterialList(list, params))
|
2022-09-18 06:05:46 +00:00
|
|
|
, x70_materialFilter(
|
|
|
|
CMaterialFilter::MakeIncludeExclude(CMaterialList(SolidMaterial), CMaterialList()))
|
2022-08-13 01:26:00 +00:00
|
|
|
, x88_sfxId(InvalidSfxId)
|
2022-08-16 02:14:28 +00:00
|
|
|
, x90_actorLights(mData.IsNull() ? nullptr : params.GetLighting().MakeActorLights().release())
|
2022-09-30 00:24:12 +00:00
|
|
|
, x9c_renderBounds(CAABox::MakeMaxInvertedBox())
|
2022-08-13 01:26:00 +00:00
|
|
|
, xb4_drawFlags(CModelFlags::Normal())
|
|
|
|
, xbc_time(0.f)
|
|
|
|
, xc0_pitchBend(8192)
|
|
|
|
, xc4_fluidId(kInvalidUniqueId)
|
|
|
|
, xc6_nextDrawNode(nextDrawNode)
|
|
|
|
, xc8_drawnToken(-1)
|
|
|
|
, xcc_addedToken(-1)
|
|
|
|
, xd0_damageMag(params.GetThermalMag())
|
2022-08-14 18:42:30 +00:00
|
|
|
, xd4_maxVol(CAudioSys::kMaxVolume)
|
2022-09-30 00:24:12 +00:00
|
|
|
, xd8_nonLoopingSfxHandles(CSfxHandle())
|
2022-08-13 01:26:00 +00:00
|
|
|
, xe4_24_nextNonLoopingSfxHandle(0)
|
|
|
|
, xe4_27_notInSortedLists(true)
|
|
|
|
, xe4_28_transformDirty(true)
|
|
|
|
, xe4_29_actorLightsDirty(true)
|
|
|
|
, xe4_30_outOfFrustum(false)
|
|
|
|
, xe4_31_calculateLighting(true)
|
|
|
|
, xe5_24_shadowEnabled(false)
|
|
|
|
, xe5_25_shadowDirty(false)
|
|
|
|
, xe5_26_muted(false)
|
|
|
|
, xe5_27_useInSortedLists(true)
|
|
|
|
, xe5_28_callTouch(true)
|
|
|
|
, xe5_29_globalTimeProvider(params.GetUseGlobalRenderTime())
|
|
|
|
, xe5_30_renderUnsorted(params.ForceRenderUnsorted())
|
|
|
|
, xe5_31_pointGeneratorParticles(false)
|
|
|
|
, xe6_24_fluidCounter(0)
|
|
|
|
, xe6_27_thermalVisorFlags(params.IsHotInThermal() ? kTF_Hot : kTF_Cold)
|
|
|
|
, xe6_29_renderParticleDBInside(true)
|
|
|
|
, xe6_30_enablePitchBend(false)
|
|
|
|
, xe6_31_targetableVisorFlags(params.GetVisorParameters().GetMask())
|
|
|
|
, xe7_27_enableRender(true)
|
|
|
|
, xe7_28_worldLightingDirty(false)
|
|
|
|
, xe7_29_drawEnabled(active)
|
|
|
|
, xe7_30_doTargetDistanceTest(true)
|
|
|
|
, xe7_31_targetable(true) {
|
2022-08-16 02:14:28 +00:00
|
|
|
if (!x64_modelData.null()) {
|
2022-08-13 01:26:00 +00:00
|
|
|
if (params.GetXRay().first != 0) {
|
|
|
|
x64_modelData->SetXRayModel(params.GetXRay());
|
|
|
|
}
|
|
|
|
if (params.GetInfra().first != 0) {
|
|
|
|
x64_modelData->SetInfraModel(params.GetInfra());
|
|
|
|
}
|
|
|
|
const CLightParameters& lighting = params.GetLighting();
|
|
|
|
if (!lighting.ShouldMakeLights() || lighting.GetMaxAreaLights() == 0) {
|
|
|
|
x64_modelData->SetAmbientColor(lighting.GetAmbientColor());
|
|
|
|
}
|
|
|
|
x64_modelData->SetSortThermal(!params.NoSortThermal());
|
|
|
|
}
|
|
|
|
const CAssetId scanId = params.GetScannable().GetScannableObject0();
|
|
|
|
if (scanId != kInvalidAssetId) {
|
2022-09-18 06:05:46 +00:00
|
|
|
x98_scanObjectInfo =
|
|
|
|
new TCachedToken< CScannableObjectInfo >(gpSimplePool->GetObj(SObjectTag('SCAN', scanId)));
|
2022-08-13 01:26:00 +00:00
|
|
|
x98_scanObjectInfo->Lock();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CActor::~CActor() { RemoveEmitter(); }
|
|
|
|
|
2022-10-08 04:53:28 +00:00
|
|
|
CAdvancementDeltas CActor::UpdateAnimation(float dt, CStateManager& mgr, bool advTree) {
|
|
|
|
CAdvancementDeltas result = ModelData()->AdvanceAnimation(dt, mgr, GetAreaId(), advTree);
|
2022-08-15 05:50:25 +00:00
|
|
|
ModelData()->AdvanceParticles(GetTransform(), dt, mgr);
|
2022-08-13 01:26:00 +00:00
|
|
|
UpdateSfxEmitters();
|
2022-08-14 18:38:41 +00:00
|
|
|
if (HasAnimation()) {
|
2022-10-09 05:37:23 +00:00
|
|
|
ushort maxVol = xd4_maxVol;
|
2022-09-05 04:01:13 +00:00
|
|
|
int aid = x4_areaId.Value();
|
2022-08-14 18:38:41 +00:00
|
|
|
|
2022-08-16 02:14:28 +00:00
|
|
|
const CGameCamera* camera = mgr.GetCameraManager()->GetCurrentCamera(mgr);
|
2022-08-14 18:38:41 +00:00
|
|
|
const CVector3f origin = GetTranslation();
|
|
|
|
const CVector3f toCamera = camera->GetTranslation() - origin;
|
|
|
|
|
2022-08-16 02:14:28 +00:00
|
|
|
const CInt32POINode* intNode;
|
|
|
|
const CSoundPOINode* soundNode;
|
|
|
|
const CParticlePOINode* particleNode;
|
|
|
|
|
2022-09-05 04:01:13 +00:00
|
|
|
int soundNodeCount = 0;
|
2022-08-15 04:51:06 +00:00
|
|
|
if (HasAnimation()) {
|
|
|
|
soundNode = GetAnimationData()->GetSoundPOIList(soundNodeCount);
|
|
|
|
} else {
|
|
|
|
soundNode = nullptr;
|
|
|
|
}
|
2022-08-14 18:38:41 +00:00
|
|
|
if (soundNodeCount > 0 && soundNode != nullptr) {
|
2022-09-05 04:01:13 +00:00
|
|
|
for (int i = 0; i < soundNodeCount; ++soundNode, ++i) {
|
|
|
|
int charIdx = soundNode->GetCharacterIndex();
|
2022-08-15 04:51:06 +00:00
|
|
|
if (soundNode->GetPoiType() != kPT_Sound || GetMuted())
|
2022-08-14 18:38:41 +00:00
|
|
|
continue;
|
2022-08-15 04:51:06 +00:00
|
|
|
if (charIdx != -1 && GetAnimationData()->GetCharacterIndex() != charIdx)
|
2022-08-14 18:38:41 +00:00
|
|
|
continue;
|
2022-09-18 06:05:46 +00:00
|
|
|
ProcessSoundEvent(soundNode->GetSoundId(), soundNode->GetWeight(), soundNode->GetFlags(),
|
|
|
|
soundNode->GetFallOff(), soundNode->GetMaxDistance(), 20, maxVol,
|
|
|
|
toCamera, origin, aid, mgr, true);
|
2022-08-14 18:38:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 04:01:13 +00:00
|
|
|
int intNodeCount = 0;
|
2022-08-15 04:51:06 +00:00
|
|
|
if (HasAnimation()) {
|
|
|
|
intNode = GetAnimationData()->GetInt32POIList(intNodeCount);
|
|
|
|
} else {
|
|
|
|
intNode = nullptr;
|
|
|
|
}
|
2022-08-14 18:38:41 +00:00
|
|
|
if (intNodeCount > 0 && intNode != nullptr) {
|
2022-09-05 04:01:13 +00:00
|
|
|
for (int i = 0; i < intNodeCount; ++intNode, ++i) {
|
|
|
|
int charIdx = intNode->GetCharacterIndex();
|
2022-08-15 04:51:06 +00:00
|
|
|
if (intNode->GetPoiType() == kPT_SoundInt32 && !GetMuted() &&
|
|
|
|
(charIdx == -1 || GetAnimationData()->GetCharacterIndex() == charIdx)) {
|
2022-09-18 06:05:46 +00:00
|
|
|
ProcessSoundEvent(intNode->GetValue(), intNode->GetWeight(), intNode->GetFlags(), 0.1f,
|
|
|
|
150.f, 20, maxVol, toCamera, origin, aid, mgr, true);
|
2022-08-15 04:51:06 +00:00
|
|
|
} else if (intNode->GetPoiType() == kPT_UserEvent) {
|
2022-08-14 18:38:41 +00:00
|
|
|
DoUserAnimEvent(mgr, *intNode, static_cast< EUserEventType >(intNode->GetValue()), dt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-05 04:01:13 +00:00
|
|
|
int particleNodeCount = 0;
|
2022-08-15 04:51:06 +00:00
|
|
|
if (HasAnimation()) {
|
|
|
|
particleNode = GetAnimationData()->GetParticlePOIList(particleNodeCount);
|
|
|
|
} else {
|
|
|
|
particleNode = nullptr;
|
|
|
|
}
|
2022-08-14 18:38:41 +00:00
|
|
|
if (particleNodeCount > 0 && particleNode != nullptr) {
|
2022-09-05 04:01:13 +00:00
|
|
|
for (int i = 0; i < particleNodeCount; ++particleNode, ++i) {
|
|
|
|
int charIdx = particleNode->GetCharacterIndex();
|
2022-08-15 04:51:06 +00:00
|
|
|
if (charIdx != -1 && GetAnimationData()->GetCharacterIndex() != charIdx)
|
2022-08-14 18:38:41 +00:00
|
|
|
continue;
|
2022-08-15 04:51:06 +00:00
|
|
|
AnimationData()->SetParticleEffectState(particleNode->GetString(), true, mgr);
|
2022-08-14 18:38:41 +00:00
|
|
|
}
|
|
|
|
}
|
2022-08-13 01:26:00 +00:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2022-08-15 04:51:06 +00:00
|
|
|
|
|
|
|
void CActor::RemoveEmitter() {
|
2022-08-16 02:14:28 +00:00
|
|
|
if (CSfxHandle handle = x8c_loopingSfxHandle) {
|
2022-08-15 04:51:06 +00:00
|
|
|
CSfxManager::RemoveEmitter(handle);
|
|
|
|
x88_sfxId = -1;
|
2022-09-30 00:24:12 +00:00
|
|
|
x8c_loopingSfxHandle = CSfxHandle();
|
2022-08-15 04:51:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-18 06:05:46 +00:00
|
|
|
void CActor::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type,
|
|
|
|
float dt) {
|
2022-08-15 04:51:06 +00:00
|
|
|
if (type == kUE_LoopedSoundStop) {
|
|
|
|
RemoveEmitter();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-09 05:37:23 +00:00
|
|
|
float CActor::GetAverageAnimVelocity(int anim) {
|
2022-09-18 06:05:46 +00:00
|
|
|
return HasAnimation() ? GetAnimationData()->GetAverageVelocity(anim) : 0.f;
|
|
|
|
}
|
2022-08-15 04:51:06 +00:00
|
|
|
|
|
|
|
void CActor::CalculateRenderBounds() {
|
|
|
|
if (HasModelData()) {
|
2022-08-16 02:14:28 +00:00
|
|
|
SetRenderBounds(GetModelData()->GetBounds(GetTransform()));
|
2022-08-15 04:51:06 +00:00
|
|
|
} else {
|
|
|
|
const CVector3f origin = GetTranslation();
|
2022-08-16 02:14:28 +00:00
|
|
|
SetRenderBounds(CAABox(origin, origin));
|
2022-08-15 04:51:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-18 06:05:46 +00:00
|
|
|
void CActor::SetModelData(const CModelData& modelData) {
|
|
|
|
x64_modelData = modelData.IsNull() ? nullptr : new CModelData(modelData);
|
|
|
|
}
|
2022-08-15 04:51:06 +00:00
|
|
|
|
2022-08-16 02:14:28 +00:00
|
|
|
// TODO nonmatching
|
|
|
|
void CActor::PreRender(CStateManager& mgr, const CFrustumPlanes& planes) {
|
|
|
|
if (HasModelData()) {
|
|
|
|
SetPreRenderClipped(!planes.BoxInFrustumPlanes(x9c_renderBounds));
|
|
|
|
if (!GetPreRenderClipped()) {
|
|
|
|
bool lightsDirty = false;
|
|
|
|
if (GetPreRenderHasMoved()) {
|
|
|
|
SetPreRenderHasMoved(false);
|
|
|
|
SetShadowDirty(true);
|
|
|
|
lightsDirty = true;
|
|
|
|
} else if (xe7_28_worldLightingDirty) {
|
|
|
|
lightsDirty = true;
|
|
|
|
} else if (HasActorLights() && GetActorLights()->GetNeedsRelight()) {
|
|
|
|
lightsDirty = true;
|
|
|
|
}
|
|
|
|
|
2022-09-13 04:26:54 +00:00
|
|
|
// TODO why doesn't GetDrawShadow() work?
|
|
|
|
if (GetShadowDirty() && xe5_24_shadowEnabled && HasShadow()) {
|
2022-08-16 02:14:28 +00:00
|
|
|
Shadow()->Calculate(GetModelData()->GetBounds(), GetTransform(), mgr);
|
|
|
|
SetShadowDirty(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetCalculateLighting()) {
|
|
|
|
CAABox bounds = GetModelData()->GetBounds(GetTransform());
|
|
|
|
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::kPV_Thermal) {
|
|
|
|
ActorLights()->BuildConstantAmbientLighting();
|
|
|
|
} else {
|
2022-09-13 04:26:54 +00:00
|
|
|
if (lightsDirty == true) {
|
|
|
|
if (x4_areaId != kInvalidAreaId) {
|
|
|
|
TAreaId aid = x4_areaId;
|
|
|
|
if (mgr.GetWorld()->IsAreaValid(aid)) {
|
|
|
|
const CGameArea* area = mgr.GetWorld()->GetArea(aid);
|
|
|
|
if (ActorLights()->BuildAreaLightList(mgr, *area, bounds)) {
|
|
|
|
xe7_28_worldLightingDirty = false;
|
|
|
|
}
|
|
|
|
}
|
2022-08-16 02:14:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ActorLights()->BuildDynamicLightList(mgr, bounds);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (GetModelData()->HasAnimation()) {
|
|
|
|
AnimationData()->PreRender();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (GetPreRenderHasMoved()) {
|
|
|
|
SetPreRenderHasMoved(false);
|
|
|
|
SetShadowDirty(true);
|
|
|
|
}
|
2022-09-13 04:26:54 +00:00
|
|
|
// TODO why doesn't GetDrawShadow() work?
|
|
|
|
if (GetShadowDirty() && xe5_24_shadowEnabled && HasShadow()) {
|
2022-09-18 06:05:46 +00:00
|
|
|
if (planes.BoxInFrustumPlanes(
|
|
|
|
GetShadow()->GetMaxShadowBox(GetModelData()->GetBounds(GetTransform()))) == true) {
|
2022-08-16 02:14:28 +00:00
|
|
|
Shadow()->Calculate(GetModelData()->GetBounds(), GetTransform(), mgr);
|
|
|
|
SetShadowDirty(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CActor::AddToRenderer(const CFrustumPlanes& planes, const CStateManager& mgr) const {
|
|
|
|
if (HasModelData()) {
|
|
|
|
if (GetRenderParticleDatabaseInside()) {
|
|
|
|
GetModelData()->RenderParticles(planes);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!GetPreRenderClipped()) {
|
|
|
|
if (CanRenderUnsorted(mgr)) {
|
|
|
|
Render(mgr);
|
|
|
|
} else {
|
|
|
|
EnsureRendered(mgr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::kPV_XRay &&
|
2022-09-18 06:05:46 +00:00
|
|
|
mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::kPV_Thermal && GetDrawShadow() &&
|
|
|
|
GetShadow()->Valid() && planes.BoxInFrustumPlanes(GetShadow()->GetBounds()) == true) {
|
|
|
|
gpRender->AddDrawable(GetShadow(), GetShadow()->GetTransform().GetTranslation(),
|
|
|
|
GetShadow()->GetBounds(), 1, IRenderer::kDS_SortedCallback);
|
2022-08-16 02:14:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-09-18 06:05:46 +00:00
|
|
|
void CActor::EnsureRendered(const CStateManager& mgr, const CVector3f& pos,
|
|
|
|
const CAABox& bounds) const {
|
2022-08-16 02:14:28 +00:00
|
|
|
if (GetModelData()) {
|
|
|
|
const CModelData::EWhichModel which = CModelData::GetRenderingModel(mgr);
|
|
|
|
GetModelData()->RenderUnsortedParts(which, GetTransform(), GetActorLights(), GetModelFlags());
|
|
|
|
}
|
|
|
|
mgr.AddDrawableActor(*this, pos, bounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CActor::EnsureRendered(const CStateManager& mgr) const {
|
|
|
|
const CAABox bounds = GetSortingBounds(mgr);
|
|
|
|
const CVector3f viewForward = CGraphics::GetViewMatrix().GetForward();
|
|
|
|
const CVector3f pos = bounds.ClosestPointAlongVector(viewForward);
|
|
|
|
EnsureRendered(mgr, pos, bounds);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CActor::DrawTouchBounds() const {}
|
|
|
|
|
|
|
|
bool CActor::CanRenderUnsorted(const CStateManager& mgr) const {
|
2022-09-13 04:26:54 +00:00
|
|
|
bool result = HasAnimation();
|
2022-09-18 06:05:46 +00:00
|
|
|
if (result && GetAnimationData()->GetParticleDB().AreAnySystemsDrawnWithModel() &&
|
|
|
|
GetRenderParticleDatabaseInside()) {
|
2022-09-13 04:26:54 +00:00
|
|
|
result = false;
|
|
|
|
} else {
|
|
|
|
result = xe5_30_renderUnsorted || IsModelOpaque(mgr);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void CActor::Render(const CStateManager& mgr) const {
|
|
|
|
if (GetModelData() && !NullModel()) {
|
|
|
|
bool renderPrePostParticles = GetRenderParticleDatabaseInside() && HasAnimation();
|
|
|
|
if (renderPrePostParticles) {
|
2022-10-04 00:00:46 +00:00
|
|
|
GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnFirst();
|
2022-09-13 04:26:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (xe7_27_enableRender) {
|
|
|
|
if (xe5_31_pointGeneratorParticles) {
|
|
|
|
mgr.SetupParticleHook(*this);
|
|
|
|
}
|
|
|
|
if (xe5_29_globalTimeProvider) {
|
|
|
|
RenderInternal(mgr);
|
|
|
|
} else {
|
2022-10-09 05:37:23 +00:00
|
|
|
const float timeSince = CGraphics::GetSecondsMod900() - xbc_time;
|
2022-10-04 00:00:46 +00:00
|
|
|
CTimeProvider tp(CMath::FastFmod(timeSince, 900.f));
|
2022-09-13 04:26:54 +00:00
|
|
|
RenderInternal(mgr);
|
|
|
|
}
|
|
|
|
if (xe5_31_pointGeneratorParticles) {
|
|
|
|
CSkinnedModel::ClearPointGeneratorFunc();
|
|
|
|
mgr.GetActorModelParticles()->Render(mgr, *this);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (renderPrePostParticles) {
|
2022-10-04 00:00:46 +00:00
|
|
|
GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnLast();
|
2022-09-13 04:26:54 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
DrawTouchBounds();
|
2022-08-16 02:14:28 +00:00
|
|
|
}
|
2022-09-13 04:26:54 +00:00
|
|
|
|
|
|
|
void CActor::RenderInternal(const CStateManager& mgr) const {
|
|
|
|
CModelData::EWhichModel which = CModelData::GetRenderingModel(mgr);
|
|
|
|
if (which == CModelData::kWM_ThermalHot) {
|
|
|
|
if (GetModelData()->GetSortThermal()) {
|
2022-10-09 05:37:23 +00:00
|
|
|
uchar addMag;
|
|
|
|
uchar mulMag = 255;
|
2022-09-13 04:26:54 +00:00
|
|
|
if (xd0_damageMag <= 1.f) {
|
|
|
|
mulMag = CCast::ToUint8(xd0_damageMag * 255.f);
|
|
|
|
addMag = 0.f;
|
|
|
|
} else if (xd0_damageMag < 2.f) {
|
|
|
|
addMag = CCast::ToUint8((xd0_damageMag - 1.f) * 255.f);
|
|
|
|
} else {
|
|
|
|
addMag = 255;
|
|
|
|
}
|
|
|
|
|
2022-10-09 05:37:23 +00:00
|
|
|
const uchar rgb = mulMag * xb4_drawFlags.GetColor().GetAlphauchar();
|
|
|
|
CColor mulColor(rgb, rgb, rgb, xb4_drawFlags.GetColor().GetAlphauchar());
|
|
|
|
CColor addColor(addMag, addMag, addMag, xb4_drawFlags.GetColor().GetAlphauchar() / 4);
|
2022-09-13 04:26:54 +00:00
|
|
|
GetModelData()->RenderThermal(x34_transform, mulColor, addColor, xb4_drawFlags);
|
|
|
|
return;
|
|
|
|
} else if (mgr.GetThermalColdScale2() > 0.0001f && xb4_drawFlags.GetTrans() == 0) {
|
2022-10-09 05:37:23 +00:00
|
|
|
const float scale = rstl::min_val< float >(
|
2022-09-18 06:05:46 +00:00
|
|
|
(mgr.GetThermalColdScale2() + mgr.GetThermalColdScale1()) * mgr.GetThermalColdScale2(),
|
|
|
|
mgr.GetThermalColdScale2());
|
2022-10-09 05:37:23 +00:00
|
|
|
const float rgbf = CMath::Clamp(0.f, scale * 255.f, 255.f);
|
|
|
|
const uchar rgb = CCast::ToUint8(rgbf);
|
2022-09-13 04:26:54 +00:00
|
|
|
CColor color(rgb, rgb, rgb, 255);
|
|
|
|
CModelFlags flags(xb4_drawFlags, CModelFlags::kT_Two, color);
|
|
|
|
GetModelData()->Render(which, x34_transform, x90_actorLights.get(), flags);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
GetModelData()->Render(which, x34_transform, x90_actorLights.get(), xb4_drawFlags);
|
2022-09-18 06:05:46 +00:00
|
|
|
};
|