mirror of
https://github.com/AxioDL/PrimeWorldEditor.git
synced 2025-12-21 02:39:17 +00:00
Added support for attaching assets from properties to locator bones in the World Editor
This commit is contained in:
@@ -7,8 +7,8 @@
|
||||
|
||||
CAnimationParameters::CAnimationParameters()
|
||||
: mGame(ePrime)
|
||||
, mNodeIndex(0)
|
||||
, mUnknown1(0)
|
||||
, mCharIndex(0)
|
||||
, mAnimIndex(0)
|
||||
, mUnknown2(0)
|
||||
, mUnknown3(0)
|
||||
{
|
||||
@@ -16,8 +16,8 @@ CAnimationParameters::CAnimationParameters()
|
||||
|
||||
CAnimationParameters::CAnimationParameters(EGame Game)
|
||||
: mGame(Game)
|
||||
, mNodeIndex(0)
|
||||
, mUnknown1(0)
|
||||
, mCharIndex(0)
|
||||
, mAnimIndex(0)
|
||||
, mUnknown2(0)
|
||||
, mUnknown3(0)
|
||||
{
|
||||
@@ -25,22 +25,22 @@ CAnimationParameters::CAnimationParameters(EGame Game)
|
||||
|
||||
CAnimationParameters::CAnimationParameters(IInputStream& rSCLY, EGame Game)
|
||||
: mGame(Game)
|
||||
, mNodeIndex(0)
|
||||
, mUnknown1(0)
|
||||
, mCharIndex(0)
|
||||
, mAnimIndex(0)
|
||||
, mUnknown2(0)
|
||||
, mUnknown3(0)
|
||||
{
|
||||
if (Game <= eEchoes)
|
||||
{
|
||||
mCharacter = CResourceInfo(rSCLY.ReadLong(), "ANCS");
|
||||
mNodeIndex = rSCLY.ReadLong();
|
||||
mUnknown1 = rSCLY.ReadLong();
|
||||
mCharIndex = rSCLY.ReadLong();
|
||||
mAnimIndex = rSCLY.ReadLong();
|
||||
}
|
||||
|
||||
else if (Game <= eCorruption)
|
||||
{
|
||||
mCharacter = CResourceInfo(rSCLY.ReadLongLong(), "CHAR");
|
||||
mUnknown1 = rSCLY.ReadLong();
|
||||
mAnimIndex = rSCLY.ReadLong();
|
||||
}
|
||||
|
||||
else if (Game == eReturns)
|
||||
@@ -50,7 +50,7 @@ CAnimationParameters::CAnimationParameters(IInputStream& rSCLY, EGame Game)
|
||||
// 0x80 - CharacterAnimationSet is empty.
|
||||
if (Flags & 0x80)
|
||||
{
|
||||
mUnknown1 = -1;
|
||||
mAnimIndex = -1;
|
||||
mUnknown2 = 0;
|
||||
mUnknown3 = 0;
|
||||
return;
|
||||
@@ -60,9 +60,9 @@ CAnimationParameters::CAnimationParameters(IInputStream& rSCLY, EGame Game)
|
||||
|
||||
// 0x20 - Default Anim is present
|
||||
if (Flags & 0x20)
|
||||
mUnknown1 = rSCLY.ReadLong();
|
||||
mAnimIndex = rSCLY.ReadLong();
|
||||
else
|
||||
mUnknown1 = -1;
|
||||
mAnimIndex = -1;
|
||||
|
||||
// 0x40 - Two-value struct is present
|
||||
if (Flags & 0x40)
|
||||
@@ -85,8 +85,8 @@ void CAnimationParameters::Write(IOutputStream& rSCLY)
|
||||
if (mCharacter.IsValid())
|
||||
{
|
||||
rSCLY.WriteLong(mCharacter.ID().ToLong());
|
||||
rSCLY.WriteLong(mNodeIndex);
|
||||
rSCLY.WriteLong(mUnknown1);
|
||||
rSCLY.WriteLong(mCharIndex);
|
||||
rSCLY.WriteLong(mAnimIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -101,7 +101,7 @@ void CAnimationParameters::Write(IOutputStream& rSCLY)
|
||||
if (mCharacter.IsValid())
|
||||
{
|
||||
rSCLY.WriteLongLong(mCharacter.ID().ToLongLong());
|
||||
rSCLY.WriteLong(mUnknown1);
|
||||
rSCLY.WriteLong(mAnimIndex);
|
||||
}
|
||||
|
||||
else
|
||||
@@ -119,14 +119,14 @@ void CAnimationParameters::Write(IOutputStream& rSCLY)
|
||||
else
|
||||
{
|
||||
u8 Flag = 0;
|
||||
if (mUnknown1 != -1) Flag |= 0x20;
|
||||
if (mAnimIndex != -1) Flag |= 0x20;
|
||||
if (mUnknown2 != 0 || mUnknown3 != 0) Flag |= 0x40;
|
||||
|
||||
rSCLY.WriteByte(Flag);
|
||||
rSCLY.WriteLongLong(mCharacter.ID().ToLongLong());
|
||||
|
||||
if (Flag & 0x20)
|
||||
rSCLY.WriteLong(mUnknown1);
|
||||
rSCLY.WriteLong(mAnimIndex);
|
||||
|
||||
if (Flag & 0x40)
|
||||
{
|
||||
@@ -144,7 +144,7 @@ CModel* CAnimationParameters::GetCurrentModel(s32 NodeIndex /*= -1*/)
|
||||
CAnimSet *pSet = (CAnimSet*) mCharacter.Load();
|
||||
if (!pSet) return nullptr;
|
||||
if (pSet->Type() != eAnimSet) return nullptr;
|
||||
if (NodeIndex == -1) NodeIndex = mNodeIndex;
|
||||
if (NodeIndex == -1) NodeIndex = mCharIndex;
|
||||
|
||||
if (pSet->NumNodes() <= (u32) NodeIndex) return nullptr;
|
||||
return pSet->NodeModel(NodeIndex);
|
||||
@@ -157,7 +157,7 @@ TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
||||
CAnimSet *pSet = (CAnimSet*) mCharacter.Load();
|
||||
if (!pSet) return "";
|
||||
if (pSet->Type() != eAnimSet) return "";
|
||||
if (NodeIndex == -1) NodeIndex = mNodeIndex;
|
||||
if (NodeIndex == -1) NodeIndex = mCharIndex;
|
||||
|
||||
if (pSet->NumNodes() <= (u32) NodeIndex) return "";
|
||||
return pSet->NodeName((u32) NodeIndex);
|
||||
@@ -166,9 +166,11 @@ TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
||||
// ************ ACCESSORS ************
|
||||
u32 CAnimationParameters::Unknown(u32 Index)
|
||||
{
|
||||
// mAnimIndex isn't unknown, but I'm too lazy to move it because there's a lot
|
||||
// of UI stuff that depends on these functions atm for accessing and editing parameters.
|
||||
switch (Index)
|
||||
{
|
||||
case 0: return mUnknown1;
|
||||
case 0: return mAnimIndex;
|
||||
case 1: return mUnknown2;
|
||||
case 2: return mUnknown3;
|
||||
default: return 0;
|
||||
@@ -180,7 +182,7 @@ void CAnimationParameters::SetResource(CResourceInfo Res)
|
||||
if (Res.Type() == "ANCS" || Res.Type() == "CHAR")
|
||||
{
|
||||
mCharacter = Res;
|
||||
mNodeIndex = 0;
|
||||
mCharIndex = 0;
|
||||
}
|
||||
else
|
||||
Log::Error("Resource with invalid type passed to CAnimationParameters: " + Res.ToString());
|
||||
@@ -190,7 +192,7 @@ void CAnimationParameters::SetUnknown(u32 Index, u32 Value)
|
||||
{
|
||||
switch (Index)
|
||||
{
|
||||
case 0: mUnknown1 = Value;
|
||||
case 0: mAnimIndex = Value;
|
||||
case 1: mUnknown2 = Value;
|
||||
case 2: mUnknown3 = Value;
|
||||
}
|
||||
|
||||
@@ -12,8 +12,8 @@ class CAnimationParameters
|
||||
EGame mGame;
|
||||
CResourceInfo mCharacter;
|
||||
|
||||
u32 mNodeIndex;
|
||||
u32 mUnknown1;
|
||||
u32 mCharIndex;
|
||||
u32 mAnimIndex;
|
||||
u32 mUnknown2;
|
||||
u32 mUnknown3;
|
||||
|
||||
@@ -29,8 +29,10 @@ public:
|
||||
// Accessors
|
||||
inline EGame Version() const { return mGame; }
|
||||
inline CAnimSet* AnimSet() const { return (CAnimSet*) mCharacter.Load(); }
|
||||
inline u32 CharacterIndex() { return mNodeIndex; }
|
||||
inline void SetNodeIndex(u32 Index) { mNodeIndex = Index; }
|
||||
inline u32 CharacterIndex() const { return mCharIndex; }
|
||||
inline u32 AnimIndex() const { return mAnimIndex; }
|
||||
inline void SetCharIndex(u32 Index) { mCharIndex = Index; }
|
||||
inline void SetAnimIndex(u32 Index) { mAnimIndex = Index; }
|
||||
|
||||
u32 Unknown(u32 Index);
|
||||
void SetResource(CResourceInfo Res);
|
||||
@@ -41,8 +43,8 @@ public:
|
||||
{
|
||||
return ( (mGame == rkOther.mGame) &&
|
||||
(mCharacter == rkOther.mCharacter) &&
|
||||
(mNodeIndex == rkOther.mNodeIndex) &&
|
||||
(mUnknown1 == rkOther.mUnknown1) &&
|
||||
(mCharIndex == rkOther.mCharIndex) &&
|
||||
(mAnimIndex == rkOther.mAnimIndex) &&
|
||||
(mUnknown2 == rkOther.mUnknown2) &&
|
||||
(mUnknown3 == rkOther.mUnknown3) );
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ void CBone::UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo&
|
||||
{
|
||||
// Get transform data
|
||||
SBoneTransformInfo TransformInfo;
|
||||
TransformInfo.Position = mPosition;
|
||||
TransformInfo.Position = mLocalPosition;
|
||||
|
||||
if (pAnim)
|
||||
pAnim->EvaluateTransform(Time, mID, &TransformInfo.Position, &TransformInfo.Rotation, &TransformInfo.Scale);
|
||||
@@ -41,7 +41,7 @@ void CBone::UpdateTransform(CBoneTransformData& rData, const SBoneTransformInfo&
|
||||
|
||||
CVector3f CBone::TransformedPosition(const CBoneTransformData& rkData) const
|
||||
{
|
||||
return rkData[mID] * AbsolutePosition();
|
||||
return rkData[mID] * Position();
|
||||
}
|
||||
|
||||
bool CBone::IsRoot() const
|
||||
@@ -77,6 +77,17 @@ CBone* CSkeleton::BoneByID(u32 BoneID) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CBone* CSkeleton::BoneByName(const TString& rkBoneName) const
|
||||
{
|
||||
for (u32 iBone = 0; iBone < mBones.size(); iBone++)
|
||||
{
|
||||
if (mBones[iBone]->Name() == rkBoneName)
|
||||
return mBones[iBone];
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
u32 CSkeleton::MaxBoneID() const
|
||||
{
|
||||
u32 ID = 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
~CSkeleton();
|
||||
void UpdateTransform(CBoneTransformData& rData, CAnimation *pAnim, float Time, bool AnchorRoot);
|
||||
CBone* BoneByID(u32 BoneID) const;
|
||||
CBone* BoneByName(const TString& rkBoneName) const;
|
||||
u32 MaxBoneID() const;
|
||||
|
||||
void Draw(FRenderOptions Options, const CBoneTransformData& rkData);
|
||||
@@ -55,7 +56,9 @@ class CBone
|
||||
std::vector<CBone*> mChildren;
|
||||
u32 mID;
|
||||
CVector3f mPosition;
|
||||
CVector3f mLocalPosition;
|
||||
CQuaternion mRotation;
|
||||
CQuaternion mLocalRotation;
|
||||
TString mName;
|
||||
CTransform4f mInvBind;
|
||||
|
||||
@@ -72,8 +75,9 @@ public:
|
||||
inline CBone* ChildByIndex(u32 Index) const { return mChildren[Index]; }
|
||||
inline u32 ID() const { return mID; }
|
||||
inline CVector3f Position() const { return mPosition; }
|
||||
inline CVector3f AbsolutePosition() const { return mPosition + (mpParent ? mpParent->AbsolutePosition() : CVector3f::skZero); }
|
||||
inline CVector3f LocalPosition() const { return mLocalPosition; }
|
||||
inline CQuaternion Rotation() const { return mRotation; }
|
||||
inline CQuaternion LocalRotation() const { return mLocalRotation; }
|
||||
inline TString Name() const { return mName; }
|
||||
};
|
||||
|
||||
|
||||
@@ -311,6 +311,21 @@ void CTemplateWriter::SaveScriptTemplate(CScriptTemplate *pTemp)
|
||||
pAssets->LinkEndChild(pAsset);
|
||||
}
|
||||
|
||||
// Attachments
|
||||
if (!pTemp->mAttachments.empty())
|
||||
{
|
||||
XMLElement *pAttachments = ScriptXML.NewElement("attachments");
|
||||
pEditor->LinkEndChild(pAttachments);
|
||||
|
||||
for (auto it = pTemp->mAttachments.begin(); it != pTemp->mAttachments.end(); it++)
|
||||
{
|
||||
XMLElement *pAttachment = ScriptXML.NewElement("attachment");
|
||||
pAttachment->SetAttribute("propertyID", *it->AttachProperty);
|
||||
pAttachment->SetAttribute("locator", *it->LocatorName);
|
||||
pAttachments->LinkEndChild(pAttachment);
|
||||
}
|
||||
}
|
||||
|
||||
// Preview Scale
|
||||
if (pTemp->mPreviewScale != 1.f)
|
||||
{
|
||||
|
||||
@@ -10,7 +10,9 @@ void CSkeletonLoader::SetLocalBoneCoords(CBone *pBone)
|
||||
SetLocalBoneCoords(pBone->ChildByIndex(iChild));
|
||||
|
||||
if (pBone->mpParent)
|
||||
pBone->mPosition -= pBone->mpParent->mPosition;
|
||||
pBone->mLocalPosition = pBone->mPosition - pBone->mpParent->mPosition;
|
||||
else
|
||||
pBone->mLocalPosition = pBone->mPosition;
|
||||
}
|
||||
|
||||
void CSkeletonLoader::CalculateBoneInverseBindMatrices()
|
||||
@@ -18,7 +20,7 @@ void CSkeletonLoader::CalculateBoneInverseBindMatrices()
|
||||
for (u32 iBone = 0; iBone < mpSkeleton->mBones.size(); iBone++)
|
||||
{
|
||||
CBone *pBone = mpSkeleton->mBones[iBone];
|
||||
pBone->mInvBind = CTransform4f::TranslationMatrix(-pBone->AbsolutePosition());
|
||||
pBone->mInvBind = CTransform4f::TranslationMatrix(-pBone->Position());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,8 +52,8 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF)
|
||||
BoneInfo[iBone].ParentID = rCINF.ReadLong();
|
||||
pBone->mPosition = CVector3f(rCINF);
|
||||
|
||||
// Version test. No version number. The next value is the linked bone count in MP1 and the first
|
||||
// skin metric value in MP2. The max bone count is 100 so the linked bone count will not be higher
|
||||
// Version test. No version number. The next value is the linked bone count in MP1 and the
|
||||
// rotation value in MP2. The max bone count is 100 so the linked bone count will not be higher
|
||||
// than that. Additionally, every bone links to its parent at least and every skeleton (as far as I
|
||||
// know) has at least two bones so the linked bone count will never be 0.
|
||||
if (Game == eUnknownVersion)
|
||||
@@ -62,7 +64,7 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF)
|
||||
if (Game == eEchoes)
|
||||
{
|
||||
pBone->mRotation = CQuaternion(rCINF);
|
||||
rCINF.Seek(0x10, SEEK_CUR); // Think this is another quaternion, not sure what for.
|
||||
pBone->mLocalRotation = CQuaternion(rCINF);
|
||||
}
|
||||
|
||||
u32 NumLinkedBones = rCINF.ReadLong();
|
||||
|
||||
@@ -548,6 +548,34 @@ CScriptTemplate* CTemplateLoader::LoadScriptTemplate(XMLDocument *pDoc, const TS
|
||||
}
|
||||
}
|
||||
|
||||
// Attachments
|
||||
XMLElement *pAttachments = pEditor->FirstChildElement("attachments");
|
||||
|
||||
if (pAttachments)
|
||||
{
|
||||
XMLElement *pAttachment = pAttachments->FirstChildElement("attachment");
|
||||
u32 AttachIdx = 0;
|
||||
|
||||
while (pAttachment)
|
||||
{
|
||||
SAttachment Attachment;
|
||||
Attachment.AttachProperty = pAttachment->Attribute("propertyID");
|
||||
Attachment.LocatorName = pAttachment->Attribute("locator");
|
||||
|
||||
// Validate property
|
||||
IPropertyTemplate *pProp = pScript->mpBaseStruct->PropertyByIDString(Attachment.AttachProperty);
|
||||
|
||||
if (!pProp)
|
||||
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
|
||||
pScript->mAttachments.push_back(Attachment);
|
||||
|
||||
pAttachment = pAttachment->NextSiblingElement("attachment");
|
||||
}
|
||||
}
|
||||
|
||||
// Preview Scale
|
||||
XMLElement *pPreviewScale = pEditor->FirstChildElement("preview_scale");
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "CBasicModel.h"
|
||||
#include "SSurface.h"
|
||||
#include "Core/Resource/CMaterialSet.h"
|
||||
#include "Core/Resource/CSkeleton.h"
|
||||
#include "Core/Resource/CSkin.h"
|
||||
#include "Core/OpenGL/CIndexBuffer.h"
|
||||
#include "Core/OpenGL/GLCommon.h"
|
||||
@@ -40,7 +41,7 @@ public:
|
||||
bool HasTransparency(u32 MatSet);
|
||||
bool IsSurfaceTransparent(u32 Surface, u32 MatSet);
|
||||
|
||||
bool IsSkinned() const { return (mpSkin != nullptr); }
|
||||
inline bool IsSkinned() const { return (mpSkin != nullptr); }
|
||||
|
||||
private:
|
||||
CIndexBuffer* InternalGetIBO(u32 Surface, EGXPrimitiveType Primitive);
|
||||
|
||||
@@ -9,8 +9,6 @@ CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLa
|
||||
, mpLayer(pLayer)
|
||||
, mVersion(0)
|
||||
, mInstanceID(InstanceID)
|
||||
, mpDisplayModel(nullptr)
|
||||
, mpCollision(nullptr)
|
||||
, mHasInGameModel(false)
|
||||
, mIsCheckingNearVisibleActivation(false)
|
||||
{
|
||||
@@ -37,21 +35,14 @@ CScriptObject::~CScriptObject()
|
||||
mpScale = mpTemplate->FindScale(mpProperties);
|
||||
mpActive = mpTemplate->FindActive(mpProperties);
|
||||
mpLightParameters = mpTemplate->FindLightParameters(mpProperties);
|
||||
mHasInGameModel = mpTemplate->HasInGameModel(mpProperties);
|
||||
EvaluateDisplayModel();
|
||||
EvaluateBillboard();
|
||||
EvaluateDisplayAsset();
|
||||
EvaluateCollisionModel();
|
||||
EvaluateVolume();
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateDisplayModel()
|
||||
void CScriptObject::EvaluateDisplayAsset()
|
||||
{
|
||||
mpDisplayModel = mpTemplate->FindDisplayModel(mpProperties);
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateBillboard()
|
||||
{
|
||||
mpBillboard = mpTemplate->FindBillboardTexture(mpProperties);
|
||||
mpDisplayAsset = mpTemplate->FindDisplayAsset(mpProperties, mActiveCharIndex, mActiveAnimIndex, mHasInGameModel);
|
||||
}
|
||||
|
||||
void CScriptObject::EvaluateCollisionModel()
|
||||
|
||||
@@ -38,9 +38,10 @@ class CScriptObject
|
||||
TVector3Property *mpScale;
|
||||
TBoolProperty *mpActive;
|
||||
CPropertyStruct *mpLightParameters;
|
||||
TResPtr<CModel> mpDisplayModel;
|
||||
TResPtr<CTexture> mpBillboard;
|
||||
TResPtr<CResource> mpDisplayAsset;
|
||||
TResPtr<CCollisionMeshGroup> mpCollision;
|
||||
u32 mActiveCharIndex;
|
||||
u32 mActiveAnimIndex;
|
||||
bool mHasInGameModel;
|
||||
|
||||
EVolumeShape mVolumeShape;
|
||||
@@ -54,8 +55,7 @@ public:
|
||||
~CScriptObject();
|
||||
|
||||
void EvaluateProperties();
|
||||
void EvaluateDisplayModel();
|
||||
void EvaluateBillboard();
|
||||
void EvaluateDisplayAsset();
|
||||
void EvaluateCollisionModel();
|
||||
void EvaluateVolume();
|
||||
bool IsEditorProperty(IProperty *pProp);
|
||||
@@ -89,8 +89,9 @@ public:
|
||||
bool IsActive() const { return mpActive ? mpActive->Get() : false; }
|
||||
bool HasInGameModel() const { return mHasInGameModel; }
|
||||
CPropertyStruct* LightParameters() const { return mpLightParameters; }
|
||||
CModel* DisplayModel() const { return mpDisplayModel; }
|
||||
CTexture* Billboard() const { return mpBillboard; }
|
||||
CResource* DisplayAsset() const { return mpDisplayAsset; }
|
||||
u32 ActiveCharIndex() const { return mActiveCharIndex; }
|
||||
u32 ActiveAnimIndex() const { return mActiveAnimIndex; }
|
||||
CCollisionMeshGroup* Collision() const { return mpCollision; }
|
||||
EVolumeShape VolumeShape() const { return mVolumeShape; }
|
||||
float VolumeScale() const { return mVolumeScale; }
|
||||
|
||||
@@ -152,12 +152,14 @@ CPropertyStruct* CScriptTemplate::FindLightParameters(CPropertyStruct *pProperti
|
||||
return TFetchProperty<CPropertyStruct*, eStructProperty>(pProperties, mLightParametersIDString);
|
||||
}
|
||||
|
||||
// todo: merge these four functions, they have near-identical code
|
||||
CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties)
|
||||
CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32& rOutCharIndex, u32& rOutAnimIndex, bool& rOutIsInGame)
|
||||
{
|
||||
rOutCharIndex = -1;
|
||||
rOutAnimIndex = -1;
|
||||
rOutIsInGame = false;
|
||||
|
||||
for (auto it = mAssets.begin(); it != mAssets.end(); it++)
|
||||
{
|
||||
if ((it->AssetType != SEditorAsset::eModel) && (it->AssetType != SEditorAsset::eAnimParams)) continue;
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
// File
|
||||
@@ -172,58 +174,34 @@ CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties)
|
||||
{
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
if (it->AssetType == SEditorAsset::eAnimParams && pProp->Type() == eCharacterProperty)
|
||||
{
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get().Load();
|
||||
TCharacterProperty *pChar = static_cast<TCharacterProperty*>(pProp);
|
||||
pRes = pChar->Get().AnimSet();
|
||||
|
||||
if (pRes)
|
||||
{
|
||||
rOutCharIndex = (it->ForceNodeIndex >= 0 ? it->ForceNodeIndex : pChar->Get().CharacterIndex());
|
||||
rOutAnimIndex = pChar->Get().AnimIndex();
|
||||
}
|
||||
}
|
||||
|
||||
else if (pProp->Type() == eCharacterProperty)
|
||||
{
|
||||
TCharacterProperty *pParams = static_cast<TCharacterProperty*>(pProp);
|
||||
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
|
||||
}
|
||||
}
|
||||
|
||||
// Verify resource exists + is correct type
|
||||
if (pRes && (pRes->Type() == eModel))
|
||||
return static_cast<CModel*>(pRes);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CTexture* CScriptTemplate::FindBillboardTexture(CPropertyStruct *pProperties)
|
||||
{
|
||||
for (auto it = mAssets.begin(); it != mAssets.end(); it++)
|
||||
{
|
||||
if (it->AssetType != SEditorAsset::eBillboard) continue;
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
// File
|
||||
if (it->AssetSource == SEditorAsset::eFile)
|
||||
{
|
||||
TString path = "../resources/" + it->AssetLocation;
|
||||
pRes = gResCache.GetResource(path);
|
||||
}
|
||||
|
||||
// Property
|
||||
else
|
||||
{
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
else
|
||||
{
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get().Load();
|
||||
}
|
||||
}
|
||||
|
||||
// Verify resource exists + is correct type
|
||||
if (pRes && (pRes->Type() == eTexture))
|
||||
return static_cast<CTexture*>(pRes);
|
||||
// If we have a valid resource, return
|
||||
if (pRes)
|
||||
{
|
||||
rOutIsInGame = (pRes->Type() != eTexture && it->AssetSource == SEditorAsset::eProperty);
|
||||
return pRes;
|
||||
}
|
||||
}
|
||||
|
||||
// None are valid - no display asset
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -261,35 +239,6 @@ CCollisionMeshGroup* CScriptTemplate::FindCollision(CPropertyStruct *pProperties
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool CScriptTemplate::HasInGameModel(CPropertyStruct *pProperties)
|
||||
{
|
||||
for (auto it = mAssets.begin(); it != mAssets.end(); it++)
|
||||
{
|
||||
if ((it->AssetType != SEditorAsset::eModel) && (it->AssetType != SEditorAsset::eAnimParams)) continue;
|
||||
if (it->AssetSource == SEditorAsset::eFile) continue;
|
||||
CResource *pRes = nullptr;
|
||||
|
||||
IProperty *pProp = pProperties->PropertyByIDString(it->AssetLocation);
|
||||
|
||||
if (pProp->Type() == eFileProperty)
|
||||
{
|
||||
TFileProperty *pFile = static_cast<TFileProperty*>(pProp);
|
||||
pRes = pFile->Get().Load();
|
||||
}
|
||||
|
||||
else if (pProp->Type() == eCharacterProperty)
|
||||
{
|
||||
TCharacterProperty *pParams = static_cast<TCharacterProperty*>(pProp);
|
||||
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
|
||||
}
|
||||
|
||||
// Verify resource exists + is correct type
|
||||
if (pRes && (pRes->Type() == eModel))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// ************ OBJECT TRACKING ************
|
||||
u32 CScriptTemplate::NumObjects() const
|
||||
|
||||
@@ -16,6 +16,12 @@ class CScriptObject;
|
||||
|
||||
typedef TString TIDString;
|
||||
|
||||
struct SAttachment
|
||||
{
|
||||
TIDString AttachProperty; // Must point to a CMDL!
|
||||
TString LocatorName;
|
||||
};
|
||||
|
||||
/*
|
||||
* CScriptTemplate is a class that encases the data contained in one of the XML templates.
|
||||
* It essentially sets the layout of any given script object.
|
||||
@@ -68,6 +74,7 @@ private:
|
||||
TIDString mActiveIDString;
|
||||
TIDString mLightParametersIDString;
|
||||
std::vector<SEditorAsset> mAssets;
|
||||
std::vector<SAttachment> mAttachments;
|
||||
|
||||
ERotationType mRotationType;
|
||||
EScaleType mScaleType;
|
||||
@@ -99,10 +106,8 @@ public:
|
||||
TVector3Property* FindScale(CPropertyStruct *pProperties);
|
||||
TBoolProperty* FindActive(CPropertyStruct *pProperties);
|
||||
CPropertyStruct* FindLightParameters(CPropertyStruct *pProperties);
|
||||
CModel* FindDisplayModel(CPropertyStruct *pProperties);
|
||||
CTexture* FindBillboardTexture(CPropertyStruct *pProperties);
|
||||
CResource* FindDisplayAsset(CPropertyStruct *pProperties, u32& rOutCharIndex, u32& rOutAnimIndex, bool& rOutIsInGame);
|
||||
CCollisionMeshGroup* FindCollision(CPropertyStruct *pProperties);
|
||||
bool HasInGameModel(CPropertyStruct *pProperties);
|
||||
|
||||
// Accessors
|
||||
inline CMasterTemplate* MasterTemplate() const { return mpMaster; }
|
||||
@@ -114,6 +119,8 @@ public:
|
||||
inline bool IsVisible() const { return mVisible; }
|
||||
inline TString SourceFile() const { return mSourceFile; }
|
||||
inline CStructTemplate* BaseStruct() const { return mpBaseStruct; }
|
||||
inline u32 NumAttachments() const { return mAttachments.size(); }
|
||||
const SAttachment& Attachment(u32 Index) const { return mAttachments[Index]; }
|
||||
|
||||
inline bool HasName() const { return !mNameIDString.IsEmpty(); }
|
||||
inline bool HasPosition() const { return !mPositionIDString.IsEmpty(); }
|
||||
|
||||
Reference in New Issue
Block a user