CScriptNode: Tidy up code

- Collapse loops to ranged for where applicable, etc.
This commit is contained in:
Lioncash 2020-06-19 20:42:28 -04:00
parent 0a66503026
commit 9f8ecc855b

View File

@ -22,9 +22,9 @@ CScriptNode::CScriptNode(CScene *pScene, uint32 NodeID, CSceneNode *pParent, CSc
mpCollisionNode = new CCollisionNode(pScene, -1, this); mpCollisionNode = new CCollisionNode(pScene, -1, this);
mpCollisionNode->SetInheritance(true, true, false); mpCollisionNode->SetInheritance(true, true, false);
if (mpInstance) if (mpInstance != nullptr)
{ {
CScriptTemplate *pTemp = Template(); const CScriptTemplate* pTemp = Template();
// Determine transform // Determine transform
mHasValidPosition = pTemp->PositionProperty() != nullptr; mHasValidPosition = pTemp->PositionProperty() != nullptr;
@ -57,15 +57,13 @@ CScriptNode::CScriptNode(CScene *pScene, uint32 NodeID, CSceneNode *pParent, CSc
for (size_t iAttach = 0; iAttach < pTemp->NumAttachments(); iAttach++) for (size_t iAttach = 0; iAttach < pTemp->NumAttachments(); iAttach++)
{ {
const SAttachment& rkAttach = pTemp->Attachment(iAttach); const SAttachment& rkAttach = pTemp->Attachment(iAttach);
CScriptAttachNode *pAttach = new CScriptAttachNode(pScene, rkAttach, this); mAttachments.push_back(new CScriptAttachNode(pScene, rkAttach, this));
mAttachments.push_back(pAttach);
} }
// Fetch LightParameters // Fetch LightParameters
mpLightParameters = std::make_unique<CLightParameters>(mpInstance->LightParameters(), mpInstance->GameTemplate()->Game()); mpLightParameters = std::make_unique<CLightParameters>(mpInstance->LightParameters(), mpInstance->GameTemplate()->Game());
SetLightLayerIndex(mpLightParameters->LightLayerIndex()); SetLightLayerIndex(mpLightParameters->LightLayerIndex());
} }
else else
{ {
// Shouldn't ever happen // Shouldn't ever happen
@ -82,18 +80,18 @@ ENodeType CScriptNode::NodeType()
void CScriptNode::PostLoad() void CScriptNode::PostLoad()
{ {
CModel *pModel = ActiveModel(); CModel* pModel = ActiveModel();
if (pModel) if (pModel == nullptr)
{ return;
pModel->BufferGL();
pModel->GenerateMaterialShaders(); pModel->BufferGL();
} pModel->GenerateMaterialShaders();
} }
void CScriptNode::OnTransformed() void CScriptNode::OnTransformed()
{ {
if (mpInstance) if (mpInstance != nullptr)
{ {
if (LocalPosition() != mpInstance->Position()) if (LocalPosition() != mpInstance->Position())
mpInstance->SetPosition(LocalPosition()); mpInstance->SetPosition(LocalPosition());
@ -105,16 +103,18 @@ void CScriptNode::OnTransformed()
mpInstance->SetScale(LocalScale()); mpInstance->SetScale(LocalScale());
} }
if (mpExtra) if (mpExtra != nullptr)
mpExtra->OnTransformed(); mpExtra->OnTransformed();
} }
void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo) void CScriptNode::AddToRenderer(CRenderer* pRenderer, const SViewInfo& rkViewInfo)
{ {
if (!mpInstance) return; if (mpInstance == nullptr)
return;
// Add script extra to renderer first // Add script extra to renderer first
if (mpExtra) mpExtra->AddToRenderer(pRenderer, rkViewInfo); if (mpExtra != nullptr)
mpExtra->AddToRenderer(pRenderer, rkViewInfo);
// If we're in game mode, then override other visibility settings. // If we're in game mode, then override other visibility settings.
if (rkViewInfo.GameMode) if (rkViewInfo.GameMode)
@ -127,27 +127,25 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInf
} }
// Check whether the script extra wants us to render before we render. // Check whether the script extra wants us to render before we render.
bool ShouldDraw = (!mpExtra || mpExtra->ShouldDrawNormalAssets()); const bool ShouldDraw = mpExtra == nullptr || mpExtra->ShouldDrawNormalAssets();
if (ShouldDraw) if (ShouldDraw)
{ {
// Otherwise, we proceed as normal // Otherwise, we proceed as normal
if ((rkViewInfo.ShowFlags & EShowFlag::ObjectCollision) && (!rkViewInfo.GameMode)) if ((rkViewInfo.ShowFlags & EShowFlag::ObjectCollision) != 0 && !rkViewInfo.GameMode)
mpCollisionNode->AddToRenderer(pRenderer, rkViewInfo); mpCollisionNode->AddToRenderer(pRenderer, rkViewInfo);
if (rkViewInfo.ShowFlags & EShowFlag::ObjectGeometry || rkViewInfo.GameMode) if ((rkViewInfo.ShowFlags & EShowFlag::ObjectGeometry) != 0 || rkViewInfo.GameMode)
{ {
for (uint32 iAttach = 0; iAttach < mAttachments.size(); iAttach++) for (auto& attachment : mAttachments)
mAttachments[iAttach]->AddToRenderer(pRenderer, rkViewInfo); attachment->AddToRenderer(pRenderer, rkViewInfo);
if (rkViewInfo.ViewFrustum.BoxInFrustum(AABox())) if (rkViewInfo.ViewFrustum.BoxInFrustum(AABox()))
{ {
CModel *pModel = ActiveModel(); if (CModel* pModel = ActiveModel())
if (!pModel)
pRenderer->AddMesh(this, -1, AABox(), false, ERenderCommand::DrawMesh);
else
AddModelToRenderer(pRenderer, pModel, 0); AddModelToRenderer(pRenderer, pModel, 0);
else
pRenderer->AddMesh(this, -1, AABox(), false, ERenderCommand::DrawMesh);
} }
} }
} }
@ -159,14 +157,15 @@ void CScriptNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInf
if (ShouldDraw) if (ShouldDraw)
pRenderer->AddMesh(this, -1, AABox(), false, ERenderCommand::DrawSelection); pRenderer->AddMesh(this, -1, AABox(), false, ERenderCommand::DrawSelection);
if (mHasVolumePreview && (!mpExtra || mpExtra->ShouldDrawVolume())) if (mHasVolumePreview && (mpExtra == nullptr || mpExtra->ShouldDrawVolume()))
mpVolumePreviewNode->AddToRenderer(pRenderer, rkViewInfo); mpVolumePreviewNode->AddToRenderer(pRenderer, rkViewInfo);
} }
} }
void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCommand Command, const SViewInfo& rkViewInfo) void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCommand Command, const SViewInfo& rkViewInfo)
{ {
if (!mpInstance) return; if (mpInstance == nullptr)
return;
// Draw model // Draw model
if (UsesModel()) if (UsesModel())
@ -181,7 +180,6 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
CGraphics::sPixelBlock.LightmapMultiplier = 1.f; CGraphics::sPixelBlock.LightmapMultiplier = 1.f;
CGraphics::UpdateLightBlock(); CGraphics::UpdateLightBlock();
} }
else else
{ {
// DKCR doesn't support world lighting yet, so light nodes that don't have ingame models with default lighting // DKCR doesn't support world lighting yet, so light nodes that don't have ingame models with default lighting
@ -191,21 +189,21 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor; CGraphics::sVertexBlock.COLOR0_Amb = CGraphics::skDefaultAmbientColor;
CGraphics::sVertexBlock.COLOR0_Mat = CColor::TransparentWhite(); CGraphics::sVertexBlock.COLOR0_Mat = CColor::TransparentWhite();
} }
else else
{
LoadLights(rkViewInfo); LoadLights(rkViewInfo);
}
} }
LoadModelMatrix(); LoadModelMatrix();
// Draw model if possible! // Draw model if possible!
CModel *pModel = ActiveModel(); if (CModel* pModel = ActiveModel())
if (pModel)
{ {
if (pModel->IsSkinned()) CGraphics::LoadIdentityBoneTransforms(); if (pModel->IsSkinned())
CGraphics::LoadIdentityBoneTransforms();
if (mpExtra) if (mpExtra != nullptr)
CGraphics::sPixelBlock.SetAllTevColors(mpExtra->TevColor()); CGraphics::sPixelBlock.SetAllTevColors(mpExtra->TevColor());
else else
CGraphics::sPixelBlock.SetAllTevColors(CColor::White()); CGraphics::sPixelBlock.SetAllTevColors(CColor::White());
@ -214,9 +212,7 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
CGraphics::UpdatePixelBlock(); CGraphics::UpdatePixelBlock();
DrawModelParts(pModel, Options, 0, Command); DrawModelParts(pModel, Options, 0, Command);
} }
else // If no model or billboard, default to drawing a purple box
// If no model or billboard, default to drawing a purple box
else
{ {
glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO); glBlendFuncSeparate(GL_ONE, GL_ZERO, GL_ZERO, GL_ZERO);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
@ -225,7 +221,6 @@ void CScriptNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCo
CDrawUtil::DrawShadedCube(CColor::TransparentPurple() * TintColor(rkViewInfo)); CDrawUtil::DrawShadedCube(CColor::TransparentPurple() * TintColor(rkViewInfo));
} }
} }
// Draw billboard // Draw billboard
else if (mpDisplayAsset->Type() == EResourceType::Texture) else if (mpDisplayAsset->Type() == EResourceType::Texture)
{ {
@ -241,8 +236,10 @@ void CScriptNode::DrawSelection()
// Draw wireframe for models // Draw wireframe for models
if (UsesModel()) if (UsesModel())
{ {
CModel *pModel = ActiveModel(); CModel* pModel = ActiveModel();
if (!pModel) pModel = CDrawUtil::GetCubeModel(); if (pModel == nullptr)
pModel = CDrawUtil::GetCubeModel();
pModel->DrawWireframe(ERenderOption::None, WireframeColor()); pModel->DrawWireframe(ERenderOption::None, WireframeColor());
} }
@ -262,7 +259,7 @@ void CScriptNode::DrawSelection()
DrawRotationArrow(); DrawRotationArrow();
} }
if (mpInstance) if (mpInstance != nullptr)
{ {
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity; CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
CGraphics::UpdateMVPBlock(); CGraphics::UpdateMVPBlock();
@ -270,17 +267,17 @@ void CScriptNode::DrawSelection()
for (size_t iIn = 0; iIn < mpInstance->NumLinks(ELinkType::Incoming); iIn++) for (size_t iIn = 0; iIn < mpInstance->NumLinks(ELinkType::Incoming); iIn++)
{ {
// Don't draw in links if the other object is selected. // Don't draw in links if the other object is selected.
const CLink *pLink = mpInstance->Link(ELinkType::Incoming, iIn); const CLink* pLink = mpInstance->Link(ELinkType::Incoming, iIn);
const CScriptNode *pLinkNode = mpScene->NodeForInstanceID(pLink->SenderID()); const CScriptNode* pLinkNode = mpScene->NodeForInstanceID(pLink->SenderID());
if (pLinkNode && !pLinkNode->IsSelected()) if (pLinkNode != nullptr && !pLinkNode->IsSelected())
CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::TransparentRed()); CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::TransparentRed());
} }
for (size_t iOut = 0; iOut < mpInstance->NumLinks(ELinkType::Outgoing); iOut++) for (size_t iOut = 0; iOut < mpInstance->NumLinks(ELinkType::Outgoing); iOut++)
{ {
const CLink *pLink = mpInstance->Link(ELinkType::Outgoing, iOut); const CLink* pLink = mpInstance->Link(ELinkType::Outgoing, iOut);
const CScriptNode *pLinkNode = mpScene->NodeForInstanceID(pLink->ReceiverID()); const CScriptNode* pLinkNode = mpScene->NodeForInstanceID(pLink->ReceiverID());
if (pLinkNode) if (pLinkNode != nullptr)
CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::TransparentGreen()); CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::TransparentGreen());
} }
} }
@ -288,11 +285,11 @@ void CScriptNode::DrawSelection()
void CScriptNode::RayAABoxIntersectTest(CRayCollisionTester& rTester, const SViewInfo& rkViewInfo) void CScriptNode::RayAABoxIntersectTest(CRayCollisionTester& rTester, const SViewInfo& rkViewInfo)
{ {
if (!mpInstance) if (mpInstance == nullptr)
return; return;
// Let script extra do ray check first // Let script extra do ray check first
if (mpExtra) if (mpExtra != nullptr)
{ {
mpExtra->RayAABoxIntersectTest(rTester, rkViewInfo); mpExtra->RayAABoxIntersectTest(rTester, rkViewInfo);
@ -316,39 +313,41 @@ void CScriptNode::RayAABoxIntersectTest(CRayCollisionTester& rTester, const SVie
if (UsesModel()) if (UsesModel())
{ {
std::pair<bool,float> BoxResult = AABox().IntersectsRay(rkRay); const auto [intersects, distance] = AABox().IntersectsRay(rkRay);
if (BoxResult.first) if (intersects)
{ {
CModel *pModel = ActiveModel(); if (CModel* pModel = ActiveModel())
if (pModel) rTester.AddNodeModel(this, pModel); rTester.AddNodeModel(this, pModel);
else rTester.AddNode(this, 0, BoxResult.second); else
rTester.AddNode(this, 0, distance);
} }
} }
else else
{ {
// Because the billboard rotates a lot, expand the AABox on the X/Y axes to cover any possible orientation // Because the billboard rotates a lot, expand the AABox on the X/Y axes to cover any possible orientation
CVector2f BillScale = BillboardScale(); const CVector2f BillScale = BillboardScale();
float ScaleXY = (BillScale.X > BillScale.Y ? BillScale.X : BillScale.Y); const float ScaleXY = (BillScale.X > BillScale.Y ? BillScale.X : BillScale.Y);
CAABox BillBox = CAABox(mPosition + CVector3f(-ScaleXY, -ScaleXY, -BillScale.Y), const CAABox BillBox = CAABox(mPosition + CVector3f(-ScaleXY, -ScaleXY, -BillScale.Y),
mPosition + CVector3f( ScaleXY, ScaleXY, BillScale.Y)); mPosition + CVector3f(ScaleXY, ScaleXY, BillScale.Y));
std::pair<bool,float> BoxResult = BillBox.IntersectsRay(rkRay); const auto [intersects, distance] = BillBox.IntersectsRay(rkRay);
if (BoxResult.first) rTester.AddNode(this, 0, BoxResult.second); if (intersects)
rTester.AddNode(this, 0, distance);
} }
// Run ray check on child nodes as well // Run ray check on child nodes as well
mpCollisionNode->RayAABoxIntersectTest(rTester, rkViewInfo); mpCollisionNode->RayAABoxIntersectTest(rTester, rkViewInfo);
for (uint32 iAttach = 0; iAttach < mAttachments.size(); iAttach++) for (auto& attachment : mAttachments)
mAttachments[iAttach]->RayAABoxIntersectTest(rTester, rkViewInfo); attachment->RayAABoxIntersectTest(rTester, rkViewInfo);
} }
SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 AssetID, const SViewInfo& rkViewInfo) SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 AssetID, const SViewInfo& rkViewInfo)
{ {
FRenderOptions Options = rkViewInfo.pRenderer->RenderOptions(); const FRenderOptions Options = rkViewInfo.pRenderer->RenderOptions();
SRayIntersection Out; SRayIntersection Out;
Out.pNode = this; Out.pNode = this;
@ -357,19 +356,19 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 Ass
// Model test // Model test
if (UsesModel()) if (UsesModel())
{ {
CModel *pModel = ActiveModel(); CModel* pModel = ActiveModel();
if (!pModel) if (!pModel)
pModel = CDrawUtil::GetCubeModel(); pModel = CDrawUtil::GetCubeModel();
CRay TransformedRay = rkRay.Transformed(Transform().Inverse()); const CRay TransformedRay = rkRay.Transformed(Transform().Inverse());
std::pair<bool,float> Result = pModel->GetSurface(AssetID)->IntersectsRay(TransformedRay, ((Options & ERenderOption::EnableBackfaceCull) == 0)); const auto [intersects, distance] = pModel->GetSurface(AssetID)->IntersectsRay(TransformedRay, ((Options & ERenderOption::EnableBackfaceCull) == 0));
if (Result.first) if (intersects)
{ {
Out.Hit = true; Out.Hit = true;
CVector3f HitPoint = TransformedRay.PointOnRay(Result.second); const CVector3f HitPoint = TransformedRay.PointOnRay(distance);
CVector3f WorldHitPoint = Transform() * HitPoint; const CVector3f WorldHitPoint = Transform() * HitPoint;
Out.Distance = Math::Distance(rkRay.Origin(), WorldHitPoint); Out.Distance = Math::Distance(rkRay.Origin(), WorldHitPoint);
} }
else else
@ -377,28 +376,27 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 Ass
Out.Hit = false; Out.Hit = false;
} }
} }
// Billboard test // Billboard test
// todo: come up with a better way to share this code between CScriptNode and CLightNode // todo: come up with a better way to share this code between CScriptNode and CLightNode
else else
{ {
// Step 1: check whether the ray intersects with the plane the billboard is on // Step 1: check whether the ray intersects with the plane the billboard is on
CPlane BillboardPlane(-rkViewInfo.pCamera->Direction(), mPosition); const CPlane BillboardPlane(-rkViewInfo.pCamera->Direction(), mPosition);
std::pair<bool,float> PlaneTest = Math::RayPlaneIntersection(rkRay, BillboardPlane); const auto [intersects, distance] = Math::RayPlaneIntersection(rkRay, BillboardPlane);
if (PlaneTest.first) if (intersects)
{ {
// Step 2: transform the hit point into the plane's local space // Step 2: transform the hit point into the plane's local space
CVector3f PlaneHitPoint = rkRay.PointOnRay(PlaneTest.second); const CVector3f PlaneHitPoint = rkRay.PointOnRay(distance);
CVector3f RelHitPoint = PlaneHitPoint - mPosition; const CVector3f RelHitPoint = PlaneHitPoint - mPosition;
CVector3f PlaneForward = -rkViewInfo.pCamera->Direction(); const CVector3f PlaneForward = -rkViewInfo.pCamera->Direction();
CVector3f PlaneRight = -rkViewInfo.pCamera->RightVector(); const CVector3f PlaneRight = -rkViewInfo.pCamera->RightVector();
CVector3f PlaneUp = rkViewInfo.pCamera->UpVector(); const CVector3f PlaneUp = rkViewInfo.pCamera->UpVector();
CQuaternion PlaneRot = CQuaternion::FromAxes(PlaneRight, PlaneForward, PlaneUp); const CQuaternion PlaneRot = CQuaternion::FromAxes(PlaneRight, PlaneForward, PlaneUp);
CVector3f RotatedHitPoint = PlaneRot.Inverse() * RelHitPoint; const CVector3f RotatedHitPoint = PlaneRot.Inverse() * RelHitPoint;
CVector2f LocalHitPoint = RotatedHitPoint.XZ() / BillboardScale(); const CVector2f LocalHitPoint = RotatedHitPoint.XZ() / BillboardScale();
// Step 3: check whether the transformed hit point is in the -1 to 1 range // Step 3: check whether the transformed hit point is in the -1 to 1 range
if ((LocalHitPoint.X >= -1.f) && (LocalHitPoint.X <= 1.f) && (LocalHitPoint.Y >= -1.f) && (LocalHitPoint.Y <= 1.f)) if ((LocalHitPoint.X >= -1.f) && (LocalHitPoint.X <= 1.f) && (LocalHitPoint.Y >= -1.f) && (LocalHitPoint.Y <= 1.f))
@ -406,7 +404,7 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 Ass
// Step 4: look up the hit texel and check whether it's transparent or opaque // Step 4: look up the hit texel and check whether it's transparent or opaque
CVector2f TexCoord = (LocalHitPoint + CVector2f(1.f)) * 0.5f; CVector2f TexCoord = (LocalHitPoint + CVector2f(1.f)) * 0.5f;
TexCoord.X = -TexCoord.X + 1.f; TexCoord.X = -TexCoord.X + 1.f;
float TexelAlpha = ActiveBillboard()->ReadTexelAlpha(TexCoord); const float TexelAlpha = ActiveBillboard()->ReadTexelAlpha(TexCoord);
if (TexelAlpha < 0.25f) if (TexelAlpha < 0.25f)
{ {
@ -416,7 +414,7 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 Ass
{ {
// It's opaque... we have a hit! // It's opaque... we have a hit!
Out.Hit = true; Out.Hit = true;
Out.Distance = PlaneTest.second; Out.Distance = distance;
} }
} }
else else
@ -435,30 +433,36 @@ SRayIntersection CScriptNode::RayNodeIntersectTest(const CRay& rkRay, uint32 Ass
bool CScriptNode::AllowsRotate() const bool CScriptNode::AllowsRotate() const
{ {
return (Template()->RotationType() == CScriptTemplate::ERotationType::RotationEnabled); return Template()->RotationType() == CScriptTemplate::ERotationType::RotationEnabled;
} }
bool CScriptNode::AllowsScale() const bool CScriptNode::AllowsScale() const
{ {
return (Template()->ScaleType() != CScriptTemplate::EScaleType::ScaleDisabled); return Template()->ScaleType() != CScriptTemplate::EScaleType::ScaleDisabled;
} }
bool CScriptNode::IsVisible() const bool CScriptNode::IsVisible() const
{ {
// Reimplementation of CSceneNode::IsVisible() to allow for layer and template visiblity to be taken into account // Reimplementation of CSceneNode::IsVisible() to allow for layer and template visiblity to be taken into account
return (mVisible && mpInstance->Layer()->IsVisible() && Template()->IsVisible()); return mVisible && mpInstance->Layer()->IsVisible() && Template()->IsVisible();
} }
CColor CScriptNode::TintColor(const SViewInfo &ViewInfo) const CColor CScriptNode::TintColor(const SViewInfo& ViewInfo) const
{ {
CColor BaseColor = CSceneNode::TintColor(ViewInfo); CColor BaseColor = CSceneNode::TintColor(ViewInfo);
if (mpExtra) mpExtra->ModifyTintColor(BaseColor);
if (mpExtra != nullptr)
mpExtra->ModifyTintColor(BaseColor);
return BaseColor; return BaseColor;
} }
void CScriptNode::LinksModified() void CScriptNode::LinksModified()
{ {
if (mpExtra) mpExtra->LinksModified(); if (mpExtra == nullptr)
return;
mpExtra->LinksModified();
} }
CStructRef CScriptNode::GetProperties() const CStructRef CScriptNode::GetProperties() const
@ -469,25 +473,23 @@ CStructRef CScriptNode::GetProperties() const
void CScriptNode::PropertyModified(IProperty* pProp) void CScriptNode::PropertyModified(IProperty* pProp)
{ {
// Update volume // Update volume
EPropertyType Type = pProp->Type(); const EPropertyType Type = pProp->Type();
if ( Type == EPropertyType::Bool || Type == EPropertyType::Byte || Type == EPropertyType::Short || if (Type == EPropertyType::Bool || Type == EPropertyType::Byte || Type == EPropertyType::Short ||
Type == EPropertyType::Int || Type == EPropertyType::Choice || Type == EPropertyType::Enum ) Type == EPropertyType::Int || Type == EPropertyType::Choice || Type == EPropertyType::Enum)
{ {
mpInstance->EvaluateVolume(); mpInstance->EvaluateVolume();
UpdatePreviewVolume(); UpdatePreviewVolume();
} }
// Update resources // Update resources
else if (Type == EPropertyType::AnimationSet) else if (Type == EPropertyType::AnimationSet)
{ {
mpInstance->EvaluateDisplayAsset(); mpInstance->EvaluateDisplayAsset();
SetDisplayAsset(mpInstance->DisplayAsset()); SetDisplayAsset(mpInstance->DisplayAsset());
} }
else if (Type == EPropertyType::Asset) else if (Type == EPropertyType::Asset)
{ {
CAssetProperty* pAssetProperty = TPropCast<CAssetProperty>(pProp); const auto* pAssetProperty = TPropCast<CAssetProperty>(pProp);
const CResTypeFilter& rkFilter = pAssetProperty->GetTypeFilter(); const CResTypeFilter& rkFilter = pAssetProperty->GetTypeFilter();
if (rkFilter.Accepts(EResourceType::Model) || rkFilter.Accepts(EResourceType::Texture) || if (rkFilter.Accepts(EResourceType::Model) || rkFilter.Accepts(EResourceType::Texture) ||
@ -504,17 +506,14 @@ void CScriptNode::PropertyModified(IProperty* pProp)
} }
// Update other editor properties // Update other editor properties
CScriptTemplate *pTemplate = Template(); const CScriptTemplate* pTemplate = Template();
if (pProp == pTemplate->NameProperty()) if (pProp == pTemplate->NameProperty())
SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName()); SetName("[" + mpInstance->Template()->Name() + "] " + mpInstance->InstanceName());
else if (pProp == pTemplate->PositionProperty() || pProp->Parent() == pTemplate->PositionProperty()) else if (pProp == pTemplate->PositionProperty() || pProp->Parent() == pTemplate->PositionProperty())
mPosition = mpInstance->Position(); mPosition = mpInstance->Position();
else if (pProp == pTemplate->RotationProperty() || pProp->Parent() == pTemplate->RotationProperty()) else if (pProp == pTemplate->RotationProperty() || pProp->Parent() == pTemplate->RotationProperty())
mRotation = CQuaternion::FromEuler(mpInstance->Rotation()); mRotation = CQuaternion::FromEuler(mpInstance->Rotation());
else if (pProp == pTemplate->ScaleProperty() || pProp->Parent() == pTemplate->ScaleProperty()) else if (pProp == pTemplate->ScaleProperty() || pProp->Parent() == pTemplate->ScaleProperty())
mScale = mpInstance->Scale(); mScale = mpInstance->Scale();
@ -522,26 +521,25 @@ void CScriptNode::PropertyModified(IProperty* pProp)
SetLightLayerIndex(mpLightParameters->LightLayerIndex()); SetLightLayerIndex(mpLightParameters->LightLayerIndex());
// Notify attachments // Notify attachments
for (uint32 AttachIdx = 0; AttachIdx < mAttachments.size(); AttachIdx++) for (auto* pAttachNode : mAttachments)
{ {
CScriptAttachNode* pAttachNode = mAttachments[AttachIdx];
if (pAttachNode->AttachProperty() == pProp) if (pAttachNode->AttachProperty() == pProp)
pAttachNode->AttachPropertyModified(); pAttachNode->AttachPropertyModified();
} }
// Notify script extra // Notify script extra
if (mpExtra) mpExtra->PropertyModified(pProp); if (mpExtra != nullptr)
mpExtra->PropertyModified(pProp);
// Update game mode visibility // Update game mode visibility
if (pProp && pProp == pTemplate->ActiveProperty()) if (pProp != nullptr && pProp == pTemplate->ActiveProperty())
TestGameModeVisibility(); TestGameModeVisibility();
} }
void CScriptNode::UpdatePreviewVolume() void CScriptNode::UpdatePreviewVolume()
{ {
EVolumeShape Shape = mpInstance->VolumeShape(); const EVolumeShape Shape = mpInstance->VolumeShape();
TResPtr<CModel> pVolumeModel = nullptr; TResPtr<CModel> pVolumeModel;
switch (Shape) switch (Shape)
{ {
@ -557,10 +555,12 @@ void CScriptNode::UpdatePreviewVolume()
case EVolumeShape::CylinderShape: case EVolumeShape::CylinderShape:
pVolumeModel = gpEditorStore->LoadResource("VolumeCylinder.CMDL"); pVolumeModel = gpEditorStore->LoadResource("VolumeCylinder.CMDL");
break; break;
default: break;
default:
break;
} }
mHasVolumePreview = (pVolumeModel != nullptr); mHasVolumePreview = pVolumeModel != nullptr;
if (mHasVolumePreview) if (mHasVolumePreview)
{ {
@ -574,7 +574,7 @@ void CScriptNode::GeneratePosition()
if (!mHasValidPosition) if (!mHasValidPosition)
{ {
// Default to center of the active area; this is to prevent recursion issues // Default to center of the active area; this is to prevent recursion issues
CTransform4f AreaTransform = mpScene->ActiveArea()->Transform(); const CTransform4f AreaTransform = mpScene->ActiveArea()->Transform();
mPosition = CVector3f(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]); mPosition = CVector3f(AreaTransform[0][3], AreaTransform[1][3], AreaTransform[2][3]);
mHasValidPosition = true; mHasValidPosition = true;
MarkTransformChanged(); MarkTransformChanged();
@ -587,7 +587,7 @@ void CScriptNode::GeneratePosition()
if (NumLinks == 1) if (NumLinks == 1)
{ {
const uint32 LinkedID = (mpInstance->NumLinks(ELinkType::Incoming) > 0 ? mpInstance->Link(ELinkType::Incoming, 0)->SenderID() : mpInstance->Link(ELinkType::Outgoing, 0)->ReceiverID()); const uint32 LinkedID = (mpInstance->NumLinks(ELinkType::Incoming) > 0 ? mpInstance->Link(ELinkType::Incoming, 0)->SenderID() : mpInstance->Link(ELinkType::Outgoing, 0)->ReceiverID());
CScriptNode *pNode = mpScene->NodeForInstanceID(LinkedID); CScriptNode* pNode = mpScene->NodeForInstanceID(LinkedID);
pNode->GeneratePosition(); pNode->GeneratePosition();
mPosition = pNode->AbsolutePosition(); mPosition = pNode->AbsolutePosition();
mPosition.Z += (pNode->AABox().Size().Z / 2.f); mPosition.Z += (pNode->AABox().Size().Z / 2.f);
@ -601,9 +601,9 @@ void CScriptNode::GeneratePosition()
for (size_t iIn = 0; iIn < mpInstance->NumLinks(ELinkType::Incoming); iIn++) for (size_t iIn = 0; iIn < mpInstance->NumLinks(ELinkType::Incoming); iIn++)
{ {
CScriptNode *pNode = mpScene->NodeForInstanceID(mpInstance->Link(ELinkType::Incoming, iIn)->SenderID()); CScriptNode* pNode = mpScene->NodeForInstanceID(mpInstance->Link(ELinkType::Incoming, iIn)->SenderID());
if (pNode) if (pNode != nullptr)
{ {
pNode->GeneratePosition(); pNode->GeneratePosition();
NewPos += pNode->AABox().Center(); NewPos += pNode->AABox().Center();
@ -612,9 +612,9 @@ void CScriptNode::GeneratePosition()
for (size_t iOut = 0; iOut < mpInstance->NumLinks(ELinkType::Outgoing); iOut++) for (size_t iOut = 0; iOut < mpInstance->NumLinks(ELinkType::Outgoing); iOut++)
{ {
CScriptNode *pNode = mpScene->NodeForInstanceID(mpInstance->Link(ELinkType::Outgoing, iOut)->ReceiverID()); CScriptNode* pNode = mpScene->NodeForInstanceID(mpInstance->Link(ELinkType::Outgoing, iOut)->ReceiverID());
if (pNode) if (pNode != nullptr)
{ {
pNode->GeneratePosition(); pNode->GeneratePosition();
NewPos += pNode->AABox().Center(); NewPos += pNode->AABox().Center();
@ -633,10 +633,13 @@ void CScriptNode::TestGameModeVisibility()
{ {
// Don't render if we don't have an ingame model, or if this is the Prime series and the instance is not active. // Don't render if we don't have an ingame model, or if this is the Prime series and the instance is not active.
if ((Template()->Game() < EGame::DKCReturns && !mpInstance->IsActive()) || !mpInstance->HasInGameModel()) if ((Template()->Game() < EGame::DKCReturns && !mpInstance->IsActive()) || !mpInstance->HasInGameModel())
{
mGameModeVisibility = EGameModeVisibility::NotVisible; mGameModeVisibility = EGameModeVisibility::NotVisible;
// If this is Returns, only render if the instance is active OR if it has a near visible activation. }
else else // If this is Returns, only render if the instance is active OR if it has a near visible activation.
{
mGameModeVisibility = (mpInstance->IsActive() || mpInstance->HasNearVisibleActivation()) ? EGameModeVisibility::Visible : EGameModeVisibility::NotVisible; mGameModeVisibility = (mpInstance->IsActive() || mpInstance->HasNearVisibleActivation()) ? EGameModeVisibility::Visible : EGameModeVisibility::NotVisible;
}
} }
CColor CScriptNode::WireframeColor() const CColor CScriptNode::WireframeColor() const
@ -661,7 +664,7 @@ CScriptExtra* CScriptNode::Extra() const
CModel* CScriptNode::ActiveModel() const CModel* CScriptNode::ActiveModel() const
{ {
if (mpDisplayAsset) if (mpDisplayAsset != nullptr)
{ {
if (mpDisplayAsset->Type() == EResourceType::Model) if (mpDisplayAsset->Type() == EResourceType::Model)
return static_cast<CModel*>(mpDisplayAsset.RawPointer()); return static_cast<CModel*>(mpDisplayAsset.RawPointer());
@ -674,7 +677,7 @@ CModel* CScriptNode::ActiveModel() const
CAnimSet* CScriptNode::ActiveAnimSet() const CAnimSet* CScriptNode::ActiveAnimSet() const
{ {
if (mpDisplayAsset && (mpDisplayAsset->Type() == EResourceType::AnimSet || mpDisplayAsset->Type() == EResourceType::Character)) if (mpDisplayAsset != nullptr && (mpDisplayAsset->Type() == EResourceType::AnimSet || mpDisplayAsset->Type() == EResourceType::Character))
return static_cast<CAnimSet*>(mpDisplayAsset.RawPointer()); return static_cast<CAnimSet*>(mpDisplayAsset.RawPointer());
return nullptr; return nullptr;
@ -682,9 +685,7 @@ CAnimSet* CScriptNode::ActiveAnimSet() const
CSkeleton* CScriptNode::ActiveSkeleton() const CSkeleton* CScriptNode::ActiveSkeleton() const
{ {
CAnimSet *pSet = ActiveAnimSet(); if (const CAnimSet* pSet = ActiveAnimSet())
if (pSet)
return pSet->Character(mCharIndex)->pSkeleton; return pSet->Character(mCharIndex)->pSkeleton;
return nullptr; return nullptr;
@ -692,21 +693,23 @@ CSkeleton* CScriptNode::ActiveSkeleton() const
CAnimation* CScriptNode::ActiveAnimation() const CAnimation* CScriptNode::ActiveAnimation() const
{ {
CAnimSet *pSet = ActiveAnimSet(); if (const CAnimSet* pSet = ActiveAnimSet())
return pSet ? pSet->FindAnimationAsset(mAnimIndex) : nullptr; return pSet->FindAnimationAsset(mAnimIndex);
return nullptr;
} }
CTexture* CScriptNode::ActiveBillboard() const CTexture* CScriptNode::ActiveBillboard() const
{ {
if (mpDisplayAsset && mpDisplayAsset->Type() == EResourceType::Texture) if (mpDisplayAsset != nullptr && mpDisplayAsset->Type() == EResourceType::Texture)
return static_cast<CTexture*>(mpDisplayAsset.RawPointer()); return static_cast<CTexture*>(mpDisplayAsset.RawPointer());
else
return nullptr; return nullptr;
} }
bool CScriptNode::UsesModel() const bool CScriptNode::UsesModel() const
{ {
return (mpDisplayAsset == nullptr || ActiveModel() != nullptr); return mpDisplayAsset == nullptr || ActiveModel() != nullptr;
} }
bool CScriptNode::HasPreviewVolume() const bool CScriptNode::HasPreviewVolume() const
@ -718,28 +721,28 @@ CAABox CScriptNode::PreviewVolumeAABox() const
{ {
if (!mHasVolumePreview) if (!mHasVolumePreview)
return CAABox::Zero(); return CAABox::Zero();
else
return mpVolumePreviewNode->AABox(); return mpVolumePreviewNode->AABox();
} }
CVector2f CScriptNode::BillboardScale() const CVector2f CScriptNode::BillboardScale() const
{ {
CVector2f Out = (Template()->ScaleType() == CScriptTemplate::EScaleType::ScaleEnabled ? AbsoluteScale().XZ() : CVector2f(1.f)); const CVector2f Out = (Template()->ScaleType() == CScriptTemplate::EScaleType::ScaleEnabled ? AbsoluteScale().XZ() : CVector2f(1.f));
return Out * 0.5f * Template()->PreviewScale(); return Out * 0.5f * Template()->PreviewScale();
} }
CTransform4f CScriptNode::BoneTransform(uint32 BoneID, EAttachType AttachType, bool Absolute) const CTransform4f CScriptNode::BoneTransform(uint32 BoneID, EAttachType AttachType, bool Absolute) const
{ {
CTransform4f Out; CTransform4f Out;
CSkeleton *pSkel = ActiveSkeleton();
if (pSkel) if (const CSkeleton* pSkel = ActiveSkeleton())
{ {
CBone *pBone = pSkel->BoneByID(BoneID); const CBone* pBone = pSkel->BoneByID(BoneID);
ASSERT(pBone); ASSERT(pBone);
if (AttachType == EAttachType::Attach) if (AttachType == EAttachType::Attach)
Out.Rotate(pBone->Rotation()); Out.Rotate(pBone->Rotation());
Out.Translate(pBone->Position()); Out.Translate(pBone->Position());
} }
@ -754,28 +757,28 @@ void CScriptNode::SetDisplayAsset(CResource *pRes)
{ {
mpDisplayAsset = pRes; mpDisplayAsset = pRes;
bool IsAnimSet = (pRes && (pRes->Type() == EResourceType::AnimSet || pRes->Type() == EResourceType::Character)); const bool IsAnimSet = pRes != nullptr && (pRes->Type() == EResourceType::AnimSet || pRes->Type() == EResourceType::Character);
mCharIndex = (IsAnimSet ? mpInstance->ActiveCharIndex() : -1); mCharIndex = IsAnimSet ? mpInstance->ActiveCharIndex() : UINT32_MAX;
mAnimIndex = (IsAnimSet ? mpInstance->ActiveAnimIndex() : -1); mAnimIndex = IsAnimSet ? mpInstance->ActiveAnimIndex() : UINT32_MAX;
CModel *pModel = ActiveModel(); const CModel* pModel = ActiveModel();
mLocalAABox = (pModel ? pModel->AABox() : CAABox::One()); mLocalAABox = pModel != nullptr ? pModel->AABox() : CAABox::One();
MarkTransformChanged(); MarkTransformChanged();
for (uint32 iAttach = 0; iAttach < mAttachments.size(); iAttach++) for (auto& attachment : mAttachments)
mAttachments[iAttach]->ParentDisplayAssetChanged(pRes); attachment->ParentDisplayAssetChanged(pRes);
if (mpExtra) if (mpExtra != nullptr)
mpExtra->DisplayAssetChanged(pRes); mpExtra->DisplayAssetChanged(pRes);
} }
void CScriptNode::CalculateTransform(CTransform4f& rOut) const void CScriptNode::CalculateTransform(CTransform4f& rOut) const
{ {
CScriptTemplate *pTemp = Template(); const CScriptTemplate* pTemp = Template();
if (pTemp->ScaleType() != CScriptTemplate::EScaleType::ScaleDisabled) if (pTemp->ScaleType() != CScriptTemplate::EScaleType::ScaleDisabled)
{ {
CVector3f Scale = (HasPreviewVolume() ? CVector3f::One() : AbsoluteScale()); const CVector3f Scale = (HasPreviewVolume() ? CVector3f::One() : AbsoluteScale());
rOut.Scale(Scale * pTemp->PreviewScale()); rOut.Scale(Scale * pTemp->PreviewScale());
} }