160 lines
4.8 KiB
C++
160 lines
4.8 KiB
C++
#include "CScriptAttachNode.h"
|
|
#include "CScriptNode.h"
|
|
#include "Core/Render/CRenderer.h"
|
|
#include "Core/Resource/Script/Property/IProperty.h"
|
|
#include <Common/Macros.h>
|
|
|
|
CScriptAttachNode::CScriptAttachNode(CScene *pScene, const SAttachment& rkAttachment, CScriptNode *pParent)
|
|
: CSceneNode(pScene, -1, pParent)
|
|
, mpScriptNode(pParent)
|
|
, mAttachType(rkAttachment.AttachType)
|
|
, mLocatorName(rkAttachment.LocatorName)
|
|
{
|
|
CStructProperty* pBaseStruct = pParent->Template()->Properties();
|
|
|
|
mpAttachAssetProp = pBaseStruct->ChildByIDString(rkAttachment.AttachProperty);
|
|
mAttachAssetRef = CAssetRef(pParent->Instance()->PropertyData(), mpAttachAssetProp);
|
|
mAttachAnimSetRef = CAnimationSetRef(pParent->Instance()->PropertyData(), mpAttachAssetProp);
|
|
if (mpAttachAssetProp) AttachPropertyModified();
|
|
|
|
ParentDisplayAssetChanged(mpScriptNode->DisplayAsset());
|
|
}
|
|
|
|
void CScriptAttachNode::AttachPropertyModified()
|
|
{
|
|
if (mpAttachAssetProp)
|
|
{
|
|
if (mAttachAssetRef.IsValid())
|
|
mpAttachAsset = gpResourceStore->LoadResource<CModel>(mAttachAssetRef.Get());
|
|
else if (mAttachAnimSetRef.IsValid())
|
|
mpAttachAsset = mAttachAnimSetRef.Get().AnimSet();
|
|
|
|
CModel* pModel = Model();
|
|
|
|
if (pModel && pModel->Type() == EResourceType::Model)
|
|
mLocalAABox = pModel->AABox();
|
|
else
|
|
mLocalAABox = CAABox::skInfinite;
|
|
|
|
MarkTransformChanged();
|
|
}
|
|
}
|
|
|
|
void CScriptAttachNode::ParentDisplayAssetChanged(CResource* pNewDisplayAsset)
|
|
{
|
|
if (pNewDisplayAsset->Type() == EResourceType::AnimSet)
|
|
{
|
|
CSkeleton* pSkel = mpScriptNode->ActiveSkeleton();
|
|
mpLocator = pSkel->BoneByName(mLocatorName);
|
|
}
|
|
|
|
else
|
|
{
|
|
mpLocator = nullptr;
|
|
}
|
|
|
|
MarkTransformChanged();
|
|
}
|
|
|
|
CModel* CScriptAttachNode::Model() const
|
|
{
|
|
if (mpAttachAsset)
|
|
{
|
|
if (mpAttachAsset->Type() == EResourceType::Model)
|
|
return static_cast<CModel*>(mpAttachAsset.RawPointer());
|
|
|
|
else if (mpAttachAsset->Type() == EResourceType::AnimSet)
|
|
return mAttachAnimSetRef.Get().GetCurrentModel();
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void CScriptAttachNode::AddToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo)
|
|
{
|
|
CModel *pModel = Model();
|
|
if (!pModel) return;
|
|
|
|
if (rkViewInfo.ViewFrustum.BoxInFrustum(AABox()))
|
|
{
|
|
AddModelToRenderer(pRenderer, pModel, 0);
|
|
|
|
if (mpParent->IsSelected() && !rkViewInfo.GameMode)
|
|
pRenderer->AddMesh(this, -1, AABox(), false, ERenderCommand::DrawSelection);
|
|
}
|
|
}
|
|
|
|
void CScriptAttachNode::Draw(FRenderOptions Options, int /*ComponentIndex*/, ERenderCommand Command, const SViewInfo& rkViewInfo)
|
|
{
|
|
LoadModelMatrix();
|
|
mpParent->LoadLights(rkViewInfo);
|
|
|
|
CGraphics::SetupAmbientColor();
|
|
CGraphics::UpdateVertexBlock();
|
|
|
|
CGraphics::sPixelBlock.TintColor = mpParent->TintColor(rkViewInfo);
|
|
CGraphics::sPixelBlock.SetAllTevColors(CColor::skWhite);
|
|
CGraphics::UpdatePixelBlock();
|
|
DrawModelParts(Model(), Options, 0, Command);
|
|
}
|
|
|
|
void CScriptAttachNode::DrawSelection()
|
|
{
|
|
LoadModelMatrix();
|
|
glBlendFunc(GL_ONE, GL_ZERO);
|
|
Model()->DrawWireframe(ERenderOption::None, mpParent->WireframeColor());
|
|
}
|
|
|
|
void CScriptAttachNode::RayAABoxIntersectTest(CRayCollisionTester& rTester, const SViewInfo& /*rkViewInfo*/)
|
|
{
|
|
CModel *pModel = Model();
|
|
if (!pModel) return;
|
|
|
|
const CRay& rkRay = rTester.Ray();
|
|
std::pair<bool,float> BoxResult = AABox().IntersectsRay(rkRay);
|
|
|
|
if (BoxResult.first)
|
|
rTester.AddNodeModel(this, pModel);
|
|
}
|
|
|
|
SRayIntersection CScriptAttachNode::RayNodeIntersectTest(const CRay& rkRay, uint32 AssetID, const SViewInfo& rkViewInfo)
|
|
{
|
|
FRenderOptions Options = rkViewInfo.pRenderer->RenderOptions();
|
|
|
|
SRayIntersection Out;
|
|
Out.pNode = mpParent;
|
|
Out.ComponentIndex = AssetID;
|
|
|
|
CRay TransformedRay = rkRay.Transformed(Transform().Inverse());
|
|
std::pair<bool,float> Result = Model()->GetSurface(AssetID)->IntersectsRay(TransformedRay, Options.HasFlag(ERenderOption::EnableBackfaceCull));
|
|
|
|
if (Result.first)
|
|
{
|
|
Out.Hit = true;
|
|
CVector3f HitPoint = TransformedRay.PointOnRay(Result.second);
|
|
CVector3f WorldHitPoint = Transform() * HitPoint;
|
|
Out.Distance = rkRay.Origin().Distance(WorldHitPoint);
|
|
}
|
|
|
|
else Out.Hit = false;
|
|
|
|
return Out;
|
|
}
|
|
|
|
// ************ PROTECTED ************
|
|
void CScriptAttachNode::CalculateTransform(CTransform4f& rOut) const
|
|
{
|
|
// Apply our local transform
|
|
rOut.Scale(LocalScale());
|
|
rOut.Rotate(LocalRotation());
|
|
rOut.Translate(LocalPosition());
|
|
|
|
// Apply bone transform
|
|
if (mpLocator)
|
|
rOut = mpScriptNode->BoneTransform(mpLocator->ID(), mAttachType, false) * rOut;
|
|
|
|
// Apply parent transform
|
|
if (mpParent)
|
|
rOut = mpParent->Transform() * rOut;
|
|
}
|