mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 02:39:17 +00:00
Applied various fixes to the attachment system, made skeleton rendering more flexible, added the ability for attachments to specify an attach type
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
#include "Core/Render/CBoneTransformData.h"
|
||||
#include "Core/Render/CDrawUtil.h"
|
||||
#include "Core/Render/CGraphics.h"
|
||||
#include <Common/Assert.h>
|
||||
#include <Math/MathUtil.h>
|
||||
|
||||
// ************ CBone ************
|
||||
@@ -44,6 +45,11 @@ CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const
|
||||
return rkData[mID] * Position();
|
||||
}
|
||||
|
||||
CQuaternion CBone::TransformedRotation(const CBoneTransformData &rkData) const
|
||||
{
|
||||
return rkData[mID] * Rotation();
|
||||
}
|
||||
|
||||
bool CBone::IsRoot() const
|
||||
{
|
||||
// In Retro's engine most skeletons have another bone named Skeleton_Root parented directly under the
|
||||
@@ -103,33 +109,41 @@ u32 CSkeleton::MaxBoneID() const
|
||||
|
||||
void CSkeleton::UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot)
|
||||
{
|
||||
ASSERT(rData.NumTrackedBones() >= MaxBoneID());
|
||||
mpRootBone->UpdateTransform(rData, SBoneTransformInfo(), pAnim, Time, AnchorRoot);
|
||||
}
|
||||
|
||||
void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData& rkData)
|
||||
void CSkeleton::Draw(FRenderOptions /*Options*/, const CBoneTransformData *pkData)
|
||||
{
|
||||
// Draw all child links first to minimize model matrix swaps.
|
||||
for (u32 iBone = 0; iBone < mBones.size(); iBone++)
|
||||
{
|
||||
CBone *pBone = mBones[iBone];
|
||||
CVector3f BonePos = pBone->TransformedPosition(rkData);
|
||||
CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position();
|
||||
|
||||
// Draw child links
|
||||
for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++)
|
||||
{
|
||||
CBone *pChild = pBone->ChildByIndex(iChild);
|
||||
CVector3f ChildPos = pkData ? pChild->TransformedPosition(*pkData) : pChild->Position();
|
||||
CDrawUtil::DrawLine(BonePos, ChildPos);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw bone spheres
|
||||
CTransform4f BaseTransform = CGraphics::sMVPBlock.ModelMatrix;
|
||||
|
||||
for (u32 iBone = 0; iBone < mBones.size(); iBone++)
|
||||
{
|
||||
CBone *pBone = mBones[iBone];
|
||||
CVector3f BonePos = pkData ? pBone->TransformedPosition(*pkData) : pBone->Position();
|
||||
|
||||
// Draw bone
|
||||
CTransform4f Transform;
|
||||
Transform.Scale(skSphereRadius);
|
||||
Transform.Translate(BonePos);
|
||||
CGraphics::sMVPBlock.ModelMatrix = Transform;
|
||||
CGraphics::sMVPBlock.ModelMatrix = Transform * BaseTransform;
|
||||
CGraphics::UpdateMVPBlock();
|
||||
CDrawUtil::DrawSphere(CColor::skWhite);
|
||||
|
||||
// Draw child links
|
||||
CGraphics::sMVPBlock.ModelMatrix = CMatrix4f::skIdentity;
|
||||
CGraphics::UpdateMVPBlock();
|
||||
|
||||
for (u32 iChild = 0; iChild < pBone->NumChildren(); iChild++)
|
||||
{
|
||||
CVector3f ChildPos = pBone->ChildByIndex(iChild)->TransformedPosition(rkData);
|
||||
CDrawUtil::DrawLine(BonePos, ChildPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
CBone* BoneByName(const TString& rkBoneName) const;
|
||||
u32 MaxBoneID() const;
|
||||
|
||||
void Draw(FRenderOptions Options, const CBoneTransformData& rkData);
|
||||
void Draw(FRenderOptions Options, const CBoneTransformData *pkData);
|
||||
std::pair<s32,float> RayIntersect(const CRay& rkRay, const CBoneTransformData& rkData);
|
||||
|
||||
inline u32 NumBones() const { return mBones.size(); }
|
||||
@@ -66,6 +66,7 @@ public:
|
||||
CBone(CSkeleton *pSkel);
|
||||
void UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo& rkParentTransform, CAnimation *pAnim, float Time, bool AnchorRoot);
|
||||
CVector3f TransformedPosition(const CBoneTransformData& rkData) const;
|
||||
CQuaternion TransformedRotation(const CBoneTransformData& rkData) const;
|
||||
bool IsRoot() const;
|
||||
|
||||
// Accessors
|
||||
|
||||
@@ -323,6 +323,14 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp)
|
||||
pAttachment->SetAttribute("propertyID", *it->AttachProperty);
|
||||
pAttachment->SetAttribute("locator", *it->LocatorName);
|
||||
pAttachments->LinkEndChild(pAttachment);
|
||||
|
||||
// Sub-properties
|
||||
if (it->AttachType != eAttach)
|
||||
{
|
||||
XMLElement *pAttachType = ScriptXML.NewElement("attach_type");
|
||||
pAttachType->SetText("follow");
|
||||
pAttachment->LinkEndChild(pAttachType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -561,6 +561,7 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(XMLDocument *pDoc, const TS
|
||||
SAttachment Attachment;
|
||||
Attachment.AttachProperty = pAttachment->Attribute("propertyID");
|
||||
Attachment.LocatorName = pAttachment->Attribute("locator");
|
||||
Attachment.AttachType = eAttach;
|
||||
|
||||
// Validate property
|
||||
IPropertyTemplate *pProp = pScript->mpBaseStruct->PropertyByIDString(Attachment.AttachProperty);
|
||||
@@ -569,8 +570,28 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(XMLDocument *pDoc, const TS
|
||||
Log::Error(rkTemplateName + ": Invalid property for attachment " + TString::FromInt32(AttachIdx) + ": " + Attachment.AttachProperty);
|
||||
else if (pProp->Type() != eCharacterProperty && (pProp->Type() != eFileProperty || !static_cast<CFileTemplate*>(pProp)->AcceptsExtension("CMDL")))
|
||||
Log::Error(rkTemplateName + ": Property referred to by attachment " + TString::FromInt32(AttachIdx) + " is not an attachable asset! Must be a file property that accepts CMDLs, or a character property.");
|
||||
|
||||
else
|
||||
{
|
||||
// Check sub-elements
|
||||
XMLElement *pParams = pAttachment->FirstChildElement();
|
||||
|
||||
while (pParams)
|
||||
{
|
||||
TString ParamName = pParams->Name();
|
||||
|
||||
if (ParamName == "attach_type")
|
||||
{
|
||||
TString Type = TString(pParams->GetText()).ToLower();
|
||||
if (Type == "follow") Attachment.AttachType = eFollow;
|
||||
else if (Type != "attach") Log::Error(rkTemplateName + ": Attachment " + TString::FromInt32(AttachIdx) + " has invalid attach type specified: " + Type);
|
||||
}
|
||||
|
||||
pParams = pParams->NextSiblingElement();
|
||||
}
|
||||
|
||||
pScript->mAttachments.push_back(Attachment);
|
||||
}
|
||||
|
||||
pAttachment = pAttachment->NextSiblingElement("attachment");
|
||||
}
|
||||
|
||||
@@ -163,7 +163,8 @@ void CModel::DrawWireframe(FRenderOptions Options, CColor WireColor /*= CColor::
|
||||
|
||||
void CModel::SetSkin(CSkin *pSkin)
|
||||
{
|
||||
ASSERT(!mpSkin || !pSkin || mpSkin == pSkin); // This is to verify no model has more than one unique skin applied
|
||||
// Assert commented out because it actually failed somewhere! Needs to be addressed.
|
||||
//ASSERT(!mpSkin || !pSkin || mpSkin == pSkin); // This is to verify no model has more than one unique skin applied
|
||||
|
||||
if (mpSkin != pSkin)
|
||||
{
|
||||
|
||||
@@ -13,13 +13,19 @@
|
||||
#include <vector>
|
||||
|
||||
class CScriptObject;
|
||||
|
||||
typedef TString TIDString;
|
||||
|
||||
enum EAttachType
|
||||
{
|
||||
eAttach,
|
||||
eFollow
|
||||
};
|
||||
|
||||
struct SAttachment
|
||||
{
|
||||
TIDString AttachProperty; // Must point to a CMDL!
|
||||
TString LocatorName;
|
||||
EAttachType AttachType;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user