Added support for CHAR, SAND, and SCAN dependencies in MP3
This commit is contained in:
parent
11ccd23baf
commit
88c11555c0
|
@ -228,8 +228,8 @@ HEADERS += \
|
||||||
Resource/CResTypeInfo.h \
|
Resource/CResTypeInfo.h \
|
||||||
Resource/Cooker/CResourceCooker.h \
|
Resource/Cooker/CResourceCooker.h \
|
||||||
Resource/CAudioMacro.h \
|
Resource/CAudioMacro.h \
|
||||||
Resource/Animation/CCharacter.h \
|
CompressionUtil.h \
|
||||||
CompressionUtil.h
|
Resource/Animation/CSourceAnimData.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "Core/Resource/CFont.h"
|
#include "Core/Resource/CFont.h"
|
||||||
#include "Core/Resource/CScan.h"
|
#include "Core/Resource/CScan.h"
|
||||||
#include "Core/Resource/CWorld.h"
|
#include "Core/Resource/CWorld.h"
|
||||||
|
#include "Core/Resource/Animation/CAnimSet.h"
|
||||||
#include "Core/Resource/Script/CScriptLayer.h"
|
#include "Core/Resource/Script/CScriptLayer.h"
|
||||||
#include <Math/MathUtil.h>
|
#include <Math/MathUtil.h>
|
||||||
|
|
||||||
|
@ -398,19 +399,44 @@ void GenerateAssetNames(CGameProject *pProj)
|
||||||
if (pkChar->pSkeleton) ApplyGeneratedName(pkChar->pSkeleton->Entry(), SetDir, CharName);
|
if (pkChar->pSkeleton) ApplyGeneratedName(pkChar->pSkeleton->Entry(), SetDir, CharName);
|
||||||
if (pkChar->pSkin) ApplyGeneratedName(pkChar->pSkin->Entry(), SetDir, CharName);
|
if (pkChar->pSkin) ApplyGeneratedName(pkChar->pSkin->Entry(), SetDir, CharName);
|
||||||
|
|
||||||
if (pkChar->IceModel.IsValid() || pkChar->IceSkin.IsValid())
|
if (pProj->Game() >= eCorruptionProto && pProj->Game() <= eCorruption && pkChar->ID == 0)
|
||||||
{
|
{
|
||||||
TWideString IceName = TWideString::Format(L"%s_frozen", *CharName);
|
CResourceEntry *pAnimDataEntry = gpResourceStore->FindEntry( pkChar->AnimDataID );
|
||||||
|
|
||||||
if (pkChar->IceModel.IsValid())
|
if (pAnimDataEntry)
|
||||||
{
|
{
|
||||||
CResourceEntry *pIceModelEntry = pStore->FindEntry(pkChar->IceModel);
|
TWideString AnimDataName = TString::Format(L"%s_animdata", *CharName);
|
||||||
ApplyGeneratedName(pIceModelEntry, SetDir, IceName);
|
ApplyGeneratedName(pAnimDataEntry, SetDir, AnimDataName);
|
||||||
}
|
}
|
||||||
if (pkChar->IceSkin.IsValid())
|
}
|
||||||
|
|
||||||
|
for (u32 iOverlay = 0; iOverlay < pkChar->OverlayModels.size(); iOverlay++)
|
||||||
|
{
|
||||||
|
const SOverlayModel& rkOverlay = pkChar->OverlayModels[iOverlay];
|
||||||
|
|
||||||
|
if (rkOverlay.ModelID.IsValid() || rkOverlay.SkinID.IsValid())
|
||||||
{
|
{
|
||||||
CResourceEntry *pIceSkinEntry = pStore->FindEntry(pkChar->IceSkin);
|
TWideString TypeName = (
|
||||||
ApplyGeneratedName(pIceSkinEntry, SetDir, IceName);
|
rkOverlay.Type == eOT_Frozen ? L"frozen" :
|
||||||
|
rkOverlay.Type == eOT_Acid ? L"acid" :
|
||||||
|
rkOverlay.Type == eOT_Hypermode ? L"hypermode" :
|
||||||
|
rkOverlay.Type == eOT_XRay ? L"xray" :
|
||||||
|
L""
|
||||||
|
);
|
||||||
|
ASSERT(TypeName != L"");
|
||||||
|
|
||||||
|
TWideString OverlayName = TWideString::Format(L"%s_%s", *CharName, *TypeName);
|
||||||
|
|
||||||
|
if (rkOverlay.ModelID.IsValid())
|
||||||
|
{
|
||||||
|
CResourceEntry *pModelEntry = pStore->FindEntry(rkOverlay.ModelID);
|
||||||
|
ApplyGeneratedName(pModelEntry, SetDir, OverlayName);
|
||||||
|
}
|
||||||
|
if (rkOverlay.SkinID.IsValid())
|
||||||
|
{
|
||||||
|
CResourceEntry *pSkinEntry = pStore->FindEntry(rkOverlay.SkinID);
|
||||||
|
ApplyGeneratedName(pSkinEntry, SetDir, OverlayName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "CDependencyTree.h"
|
#include "CDependencyTree.h"
|
||||||
#include "Core/GameProject/CGameProject.h"
|
#include "Core/GameProject/CGameProject.h"
|
||||||
|
#include "Core/Resource/Animation/CAnimSet.h"
|
||||||
#include "Core/Resource/Script/CMasterTemplate.h"
|
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||||
#include "Core/Resource/Script/CScriptLayer.h"
|
#include "Core/Resource/Script/CScriptLayer.h"
|
||||||
#include "Core/Resource/Script/CScriptObject.h"
|
#include "Core/Resource/Script/CScriptObject.h"
|
||||||
|
@ -199,34 +200,35 @@ void CSetCharacterDependency::Serialize(IArchive& rArc)
|
||||||
<< SERIAL_ABSTRACT_CONTAINER("Children", mChildren, "Child", &gDependencyNodeFactory);
|
<< SERIAL_ABSTRACT_CONTAINER("Children", mChildren, "Child", &gDependencyNodeFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
CSetCharacterDependency* CSetCharacterDependency::BuildTree(const CAnimSet *pkOwnerSet, u32 CharIndex)
|
CSetCharacterDependency* CSetCharacterDependency::BuildTree(const SSetCharacter& rkChar)
|
||||||
{
|
{
|
||||||
CSetCharacterDependency *pTree = new CSetCharacterDependency(CharIndex);
|
CSetCharacterDependency *pTree = new CSetCharacterDependency(rkChar.ID);
|
||||||
const SSetCharacter *pkChar = pkOwnerSet->Character(CharIndex);
|
pTree->AddDependency(rkChar.pModel);
|
||||||
|
pTree->AddDependency(rkChar.pSkeleton);
|
||||||
|
pTree->AddDependency(rkChar.pSkin);
|
||||||
|
pTree->AddDependency(rkChar.AnimDataID);
|
||||||
|
|
||||||
if (pkChar)
|
const std::vector<CAssetID> *pkParticleVectors[5] = {
|
||||||
|
&rkChar.GenericParticles, &rkChar.ElectricParticles,
|
||||||
|
&rkChar.SwooshParticles, &rkChar.SpawnParticles,
|
||||||
|
&rkChar.EffectParticles
|
||||||
|
};
|
||||||
|
|
||||||
|
for (u32 iVec = 0; iVec < 5; iVec++)
|
||||||
{
|
{
|
||||||
pTree->AddDependency(pkChar->pModel);
|
for (u32 iPart = 0; iPart < pkParticleVectors[iVec]->size(); iPart++)
|
||||||
pTree->AddDependency(pkChar->pSkeleton);
|
pTree->AddDependency(pkParticleVectors[iVec]->at(iPart));
|
||||||
pTree->AddDependency(pkChar->pSkin);
|
|
||||||
|
|
||||||
const std::vector<CAssetID> *pkParticleVectors[5] = {
|
|
||||||
&pkChar->GenericParticles, &pkChar->ElectricParticles,
|
|
||||||
&pkChar->SwooshParticles, &pkChar->SpawnParticles,
|
|
||||||
&pkChar->EffectParticles
|
|
||||||
};
|
|
||||||
|
|
||||||
for (u32 iVec = 0; iVec < 5; iVec++)
|
|
||||||
{
|
|
||||||
for (u32 iPart = 0; iPart < pkParticleVectors[iVec]->size(); iPart++)
|
|
||||||
pTree->AddDependency(pkParticleVectors[iVec]->at(iPart));
|
|
||||||
}
|
|
||||||
|
|
||||||
pTree->AddDependency(pkChar->IceModel);
|
|
||||||
pTree->AddDependency(pkChar->IceSkin);
|
|
||||||
pTree->AddDependency(pkChar->SpatialPrimitives);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (u32 iOverlay = 0; iOverlay < rkChar.OverlayModels.size(); iOverlay++)
|
||||||
|
{
|
||||||
|
const SOverlayModel& rkOverlay = rkChar.OverlayModels[iOverlay];
|
||||||
|
pTree->AddDependency(rkOverlay.ModelID);
|
||||||
|
pTree->AddDependency(rkOverlay.SkinID);
|
||||||
|
}
|
||||||
|
|
||||||
|
pTree->AddDependency(rkChar.SpatialPrimitives);
|
||||||
|
|
||||||
return pTree;
|
return pTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -160,7 +160,7 @@ public:
|
||||||
inline u32 CharSetIndex() const { return mCharSetIndex; }
|
inline u32 CharSetIndex() const { return mCharSetIndex; }
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static CSetCharacterDependency* BuildTree(const CAnimSet *pkOwnerSet, u32 CharIndex);
|
static CSetCharacterDependency* BuildTree(const SSetCharacter& rkChar);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Node representing a character animation. Indicates which character indices use this animation.
|
// Node representing a character animation. Indicates which character indices use this animation.
|
||||||
|
|
|
@ -154,12 +154,9 @@ void CCharacterUsageMap::ParseDependencyNode(IDependencyNode *pNode)
|
||||||
CResourceDependency *pDep = static_cast<CResourceDependency*>(pNode);
|
CResourceDependency *pDep = static_cast<CResourceDependency*>(pNode);
|
||||||
CResourceEntry *pEntry = mpStore->FindEntry(pDep->ID());
|
CResourceEntry *pEntry = mpStore->FindEntry(pDep->ID());
|
||||||
|
|
||||||
if (pEntry)
|
if (pEntry && pEntry->ResourceType() == eScan)
|
||||||
{
|
{
|
||||||
EResType ResType = pEntry->ResourceType();
|
ParseDependencyNode(pEntry->Dependencies());
|
||||||
|
|
||||||
if (ResType == eScan)
|
|
||||||
ParseDependencyNode(pEntry->Dependencies());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -144,8 +144,8 @@ void CRenderer::RenderBuckets(const SViewInfo& rkViewInfo)
|
||||||
|
|
||||||
void CRenderer::RenderBloom()
|
void CRenderer::RenderBloom()
|
||||||
{
|
{
|
||||||
// Check to ensure bloom is enabled
|
// Check to ensure bloom is enabled. Also don't render bloom in unlit mode.
|
||||||
if (mBloomMode == eNoBloom) return;
|
if (mBloomMode == eNoBloom || CGraphics::sLightMode != CGraphics::eWorldLighting) return;
|
||||||
|
|
||||||
// Setup
|
// Setup
|
||||||
static const float skHOffset[6] = { -0.008595f, -0.005470f, -0.002345f,
|
static const float skHOffset[6] = { -0.008595f, -0.005470f, -0.002345f,
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "CAnimEventData.h"
|
#include "CAnimEventData.h"
|
||||||
#include "CSkeleton.h"
|
#include "CSkeleton.h"
|
||||||
#include "CSkin.h"
|
#include "CSkin.h"
|
||||||
|
#include "CSourceAnimData.h"
|
||||||
#include "IMetaAnimation.h"
|
#include "IMetaAnimation.h"
|
||||||
#include "IMetaTransition.h"
|
#include "IMetaTransition.h"
|
||||||
#include "Core/Resource/CDependencyGroup.h"
|
#include "Core/Resource/CDependencyGroup.h"
|
||||||
|
@ -43,20 +44,38 @@ struct SHalfTransition
|
||||||
IMetaTransition *pMetaTrans;
|
IMetaTransition *pMetaTrans;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Character structures
|
||||||
|
enum EOverlayType
|
||||||
|
{
|
||||||
|
eOT_Frozen = FOURCC('FRZN'),
|
||||||
|
eOT_Hypermode = FOURCC('HYPR'),
|
||||||
|
eOT_Acid = FOURCC('ACID'),
|
||||||
|
eOT_XRay = FOURCC('XRAY')
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SOverlayModel
|
||||||
|
{
|
||||||
|
EOverlayType Type;
|
||||||
|
CAssetID ModelID;
|
||||||
|
CAssetID SkinID;
|
||||||
|
};
|
||||||
|
|
||||||
struct SSetCharacter
|
struct SSetCharacter
|
||||||
{
|
{
|
||||||
|
u32 ID;
|
||||||
TString Name;
|
TString Name;
|
||||||
TResPtr<CModel> pModel;
|
TResPtr<CModel> pModel;
|
||||||
TResPtr<CSkin> pSkin;
|
TResPtr<CSkin> pSkin;
|
||||||
TResPtr<CSkeleton> pSkeleton;
|
TResPtr<CSkeleton> pSkeleton;
|
||||||
|
std::vector<SOverlayModel> OverlayModels;
|
||||||
|
CAssetID AnimDataID;
|
||||||
|
|
||||||
std::vector<CAssetID> GenericParticles;
|
std::vector<CAssetID> GenericParticles;
|
||||||
std::vector<CAssetID> ElectricParticles;
|
std::vector<CAssetID> ElectricParticles;
|
||||||
std::vector<CAssetID> SwooshParticles;
|
std::vector<CAssetID> SwooshParticles;
|
||||||
std::vector<CAssetID> SpawnParticles;
|
std::vector<CAssetID> SpawnParticles;
|
||||||
std::vector<CAssetID> EffectParticles;
|
std::vector<CAssetID> EffectParticles;
|
||||||
CAssetID IceModel;
|
std::vector<CAssetID> SoundEffects;
|
||||||
CAssetID IceSkin;
|
|
||||||
CAssetID SpatialPrimitives;
|
CAssetID SpatialPrimitives;
|
||||||
std::set<u32> UsedAnimationIndices;
|
std::set<u32> UsedAnimationIndices;
|
||||||
};
|
};
|
||||||
|
@ -114,16 +133,49 @@ public:
|
||||||
// Character dependencies
|
// Character dependencies
|
||||||
for (u32 iChar = 0; iChar < mCharacters.size(); iChar++)
|
for (u32 iChar = 0; iChar < mCharacters.size(); iChar++)
|
||||||
{
|
{
|
||||||
CSetCharacterDependency *pCharTree = CSetCharacterDependency::BuildTree(this, iChar);
|
CSetCharacterDependency *pCharTree = CSetCharacterDependency::BuildTree( mCharacters[iChar] );
|
||||||
ASSERT(pCharTree);
|
ASSERT(pCharTree);
|
||||||
pTree->AddChild(pCharTree);
|
pTree->AddChild(pCharTree);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 iAnim = 0; iAnim < mAnimations.size(); iAnim++)
|
// Animation dependencies
|
||||||
|
if (Game() <= eEchoes)
|
||||||
{
|
{
|
||||||
CSetAnimationDependency *pAnimTree = CSetAnimationDependency::BuildTree(this, iAnim);
|
for (u32 iAnim = 0; iAnim < mAnimations.size(); iAnim++)
|
||||||
ASSERT(pAnimTree);
|
{
|
||||||
pTree->AddChild(pAnimTree);
|
CSetAnimationDependency *pAnimTree = CSetAnimationDependency::BuildTree(this, iAnim);
|
||||||
|
ASSERT(pAnimTree);
|
||||||
|
pTree->AddChild(pAnimTree);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const SSetCharacter& rkChar = mCharacters[0];
|
||||||
|
std::set<CAnimPrimitive> PrimitiveSet;
|
||||||
|
|
||||||
|
// Animations
|
||||||
|
for (u32 iAnim = 0; iAnim < mAnimations.size(); iAnim++)
|
||||||
|
{
|
||||||
|
const SAnimation& rkAnim = mAnimations[iAnim];
|
||||||
|
rkAnim.pMetaAnim->GetUniquePrimitives(PrimitiveSet);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSourceAnimData *pAnimData = (CSourceAnimData*) gpResourceStore->LoadResource(rkChar.AnimDataID, "SAND");
|
||||||
|
if (pAnimData)
|
||||||
|
pAnimData->AddTransitionDependencies(pTree);
|
||||||
|
|
||||||
|
// Event particles/sounds
|
||||||
|
for (auto Iter = PrimitiveSet.begin(); Iter != PrimitiveSet.end(); Iter++)
|
||||||
|
{
|
||||||
|
const CAnimPrimitive& rkPrim = *Iter;
|
||||||
|
pTree->AddDependency(rkPrim.Animation());
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 iSound = 0; iSound < rkChar.SoundEffects.size(); iSound++)
|
||||||
|
{
|
||||||
|
pTree->AddDependency(rkChar.SoundEffects[iSound]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pTree;
|
return pTree;
|
||||||
|
|
|
@ -136,30 +136,32 @@ void CAnimationParameters::Write(IOutputStream& rSCLY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const SSetCharacter* CAnimationParameters::GetCurrentSetCharacter(s32 NodeIndex /*= -1*/)
|
||||||
|
{
|
||||||
|
CAnimSet *pSet = AnimSet();
|
||||||
|
|
||||||
|
if (pSet && pSet->Type() == eAnimSet)
|
||||||
|
{
|
||||||
|
if (NodeIndex == -1)
|
||||||
|
NodeIndex = mCharIndex;
|
||||||
|
|
||||||
|
if (mCharIndex != -1 && pSet->NumCharacters() > (u32) NodeIndex)
|
||||||
|
return pSet->Character(NodeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
CModel* CAnimationParameters::GetCurrentModel(s32 NodeIndex /*= -1*/)
|
CModel* CAnimationParameters::GetCurrentModel(s32 NodeIndex /*= -1*/)
|
||||||
{
|
{
|
||||||
if (!mCharacterID.IsValid()) return nullptr;
|
const SSetCharacter *pkChar = GetCurrentSetCharacter(NodeIndex);
|
||||||
|
return pkChar ? pkChar->pModel : nullptr;
|
||||||
CAnimSet *pSet = AnimSet();
|
|
||||||
if (!pSet) return nullptr;
|
|
||||||
if (pSet->Type() != eAnimSet) return nullptr;
|
|
||||||
if (NodeIndex == -1) NodeIndex = mCharIndex;
|
|
||||||
|
|
||||||
if (pSet->NumCharacters() <= (u32) NodeIndex) return nullptr;
|
|
||||||
return pSet->Character(NodeIndex)->pModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
TString CAnimationParameters::GetCurrentCharacterName(s32 NodeIndex /*= -1*/)
|
||||||
{
|
{
|
||||||
if (!mCharacterID.IsValid()) return "";
|
const SSetCharacter *pkChar = GetCurrentSetCharacter(NodeIndex);
|
||||||
|
return pkChar ? pkChar->Name : "";
|
||||||
CAnimSet *pSet = AnimSet();
|
|
||||||
if (!pSet) return "";
|
|
||||||
if (pSet->Type() != eAnimSet) return "";
|
|
||||||
if (NodeIndex == -1) NodeIndex = mCharIndex;
|
|
||||||
|
|
||||||
if (pSet->NumCharacters() <= (u32) NodeIndex) return "";
|
|
||||||
return pSet->Character(NodeIndex)->Name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ ACCESSORS ************
|
// ************ ACCESSORS ************
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
#ifndef CANIMATIONPARAMETERS_H
|
#ifndef CANIMATIONPARAMETERS_H
|
||||||
#define CANIMATIONPARAMETERS_H
|
#define CANIMATIONPARAMETERS_H
|
||||||
|
|
||||||
#include "CAnimSet.h"
|
|
||||||
#include "Core/Resource/TResPtr.h"
|
#include "Core/Resource/TResPtr.h"
|
||||||
#include "Core/Resource/Model/CModel.h"
|
#include "Core/Resource/Model/CModel.h"
|
||||||
#include <Common/EGame.h>
|
#include <Common/EGame.h>
|
||||||
|
@ -22,6 +21,7 @@ public:
|
||||||
CAnimationParameters(IInputStream& rSCLY, EGame Game);
|
CAnimationParameters(IInputStream& rSCLY, EGame Game);
|
||||||
void Write(IOutputStream& rSCLY);
|
void Write(IOutputStream& rSCLY);
|
||||||
|
|
||||||
|
const SSetCharacter* GetCurrentSetCharacter(s32 NodeIndex = -1);
|
||||||
CModel* GetCurrentModel(s32 NodeIndex = -1);
|
CModel* GetCurrentModel(s32 NodeIndex = -1);
|
||||||
TString GetCurrentCharacterName(s32 NodeIndex = -1);
|
TString GetCurrentCharacterName(s32 NodeIndex = -1);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
#ifndef CSOURCEANIMDATA_H
|
||||||
|
#define CSOURCEANIMDATA_H
|
||||||
|
|
||||||
|
#include "Core/Resource/CResource.h"
|
||||||
|
#include "IMetaTransition.h"
|
||||||
|
|
||||||
|
class CSourceAnimData : public CResource
|
||||||
|
{
|
||||||
|
DECLARE_RESOURCE_TYPE(eSourceAnimData)
|
||||||
|
friend class CAnimSetLoader;
|
||||||
|
|
||||||
|
struct STransition
|
||||||
|
{
|
||||||
|
CAssetID AnimA;
|
||||||
|
CAssetID AnimB;
|
||||||
|
IMetaTransition *pTransition;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHalfTransition
|
||||||
|
{
|
||||||
|
CAssetID Anim;
|
||||||
|
IMetaTransition *pTransition;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<STransition> mTransitions;
|
||||||
|
std::vector<SHalfTransition> mHalfTransitions;
|
||||||
|
IMetaTransition *mpDefaultTransition;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CSourceAnimData(CResourceEntry *pEntry = 0)
|
||||||
|
: CResource(pEntry)
|
||||||
|
, mpDefaultTransition(nullptr)
|
||||||
|
{}
|
||||||
|
|
||||||
|
~CSourceAnimData()
|
||||||
|
{
|
||||||
|
for (u32 TransIdx = 0; TransIdx < mTransitions.size(); TransIdx++)
|
||||||
|
delete mTransitions[TransIdx].pTransition;
|
||||||
|
|
||||||
|
for (u32 HalfIdx = 0; HalfIdx < mHalfTransitions.size(); HalfIdx++)
|
||||||
|
delete mHalfTransitions[HalfIdx].pTransition;
|
||||||
|
|
||||||
|
delete mpDefaultTransition;
|
||||||
|
}
|
||||||
|
|
||||||
|
CDependencyTree* BuildDependencyTree() const
|
||||||
|
{
|
||||||
|
// SAND normally has dependencies from meta-transitions and events
|
||||||
|
// However, all of these can be character-specific. To simplify things, all SAND
|
||||||
|
// dependencies are being added to the CHAR dependency tree instead. Therefore the
|
||||||
|
// SAND dependency tree is left empty.
|
||||||
|
return new CDependencyTree();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddTransitionDependencies(CDependencyTree *pTree)
|
||||||
|
{
|
||||||
|
// Note: All CHAR animations must have been added to the tree before this function is run
|
||||||
|
std::set<IMetaTransition*> UsedTransitions;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
// Find all relevant primitives
|
||||||
|
std::set<CAnimPrimitive> PrimSet;
|
||||||
|
|
||||||
|
if (UsedTransitions.find(mpDefaultTransition) == UsedTransitions.end())
|
||||||
|
{
|
||||||
|
mpDefaultTransition->GetUniquePrimitives(PrimSet);
|
||||||
|
UsedTransitions.insert(mpDefaultTransition);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 TransitionIdx = 0; TransitionIdx < mTransitions.size(); TransitionIdx++)
|
||||||
|
{
|
||||||
|
const STransition& rkTransition = mTransitions[TransitionIdx];
|
||||||
|
IMetaTransition *pTransition = rkTransition.pTransition;
|
||||||
|
|
||||||
|
if ( pTree->HasDependency(rkTransition.AnimA) &&
|
||||||
|
pTree->HasDependency(rkTransition.AnimB) &&
|
||||||
|
UsedTransitions.find(pTransition) == UsedTransitions.end() )
|
||||||
|
{
|
||||||
|
pTransition->GetUniquePrimitives(PrimSet);
|
||||||
|
UsedTransitions.insert(pTransition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u32 HalfIdx = 0; HalfIdx < mHalfTransitions.size(); HalfIdx++)
|
||||||
|
{
|
||||||
|
const SHalfTransition& rkHalfTrans = mHalfTransitions[HalfIdx];
|
||||||
|
IMetaTransition *pTransition = rkHalfTrans.pTransition;
|
||||||
|
|
||||||
|
if ( pTree->HasDependency(rkHalfTrans.Anim) &&
|
||||||
|
UsedTransitions.find(pTransition) == UsedTransitions.end() )
|
||||||
|
{
|
||||||
|
pTransition->GetUniquePrimitives(PrimSet);
|
||||||
|
UsedTransitions.insert(pTransition);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have no new primitives then we've exhausted all usable transitions; break out
|
||||||
|
if (PrimSet.empty())
|
||||||
|
break;
|
||||||
|
|
||||||
|
// Add all transition primitives to the tree
|
||||||
|
for (auto Iter = PrimSet.begin(); Iter != PrimSet.end(); Iter++)
|
||||||
|
pTree->AddDependency(Iter->Animation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CSOURCEANIMDATA_H
|
|
@ -3,24 +3,24 @@
|
||||||
// ************ CMetaAnimFactory ************
|
// ************ CMetaAnimFactory ************
|
||||||
CMetaAnimFactory gMetaAnimFactory;
|
CMetaAnimFactory gMetaAnimFactory;
|
||||||
|
|
||||||
IMetaAnimation* CMetaAnimFactory::LoadFromStream(IInputStream& rInput)
|
IMetaAnimation* CMetaAnimFactory::LoadFromStream(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
EMetaAnimationType Type = (EMetaAnimationType) rInput.ReadLong();
|
EMetaAnimationType Type = (EMetaAnimationType) rInput.ReadLong();
|
||||||
|
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case eMAT_Play:
|
case eMAT_Play:
|
||||||
return new CMetaAnimPlay(rInput);
|
return new CMetaAnimPlay(rInput, Game);
|
||||||
|
|
||||||
case eMAT_Blend:
|
case eMAT_Blend:
|
||||||
case eMAT_PhaseBlend:
|
case eMAT_PhaseBlend:
|
||||||
return new CMetaAnimBlend(Type, rInput);
|
return new CMetaAnimBlend(Type, rInput, Game);
|
||||||
|
|
||||||
case eMAT_Random:
|
case eMAT_Random:
|
||||||
return new CMetaAnimRandom(rInput);
|
return new CMetaAnimRandom(rInput, Game);
|
||||||
|
|
||||||
case eMAT_Sequence:
|
case eMAT_Sequence:
|
||||||
return new CMetaAnimSequence(rInput);
|
return new CMetaAnimSequence(rInput, Game);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log::Error("Unrecognized meta-animation type: " + TString::FromInt32(Type, 0, 10));
|
Log::Error("Unrecognized meta-animation type: " + TString::FromInt32(Type, 0, 10));
|
||||||
|
@ -29,9 +29,9 @@ IMetaAnimation* CMetaAnimFactory::LoadFromStream(IInputStream& rInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaAnimationPlay ************
|
// ************ CMetaAnimationPlay ************
|
||||||
CMetaAnimPlay::CMetaAnimPlay(IInputStream& rInput)
|
CMetaAnimPlay::CMetaAnimPlay(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
mPrimitive = CAnimPrimitive(rInput);
|
mPrimitive = CAnimPrimitive(rInput, Game);
|
||||||
mUnknownA = rInput.ReadFloat();
|
mUnknownA = rInput.ReadFloat();
|
||||||
mUnknownB = rInput.ReadLong();
|
mUnknownB = rInput.ReadLong();
|
||||||
}
|
}
|
||||||
|
@ -47,12 +47,12 @@ void CMetaAnimPlay::GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) cons
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaAnimBlend ************
|
// ************ CMetaAnimBlend ************
|
||||||
CMetaAnimBlend::CMetaAnimBlend(EMetaAnimationType Type, IInputStream& rInput)
|
CMetaAnimBlend::CMetaAnimBlend(EMetaAnimationType Type, IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
ASSERT(Type == eMAT_Blend || Type == eMAT_PhaseBlend);
|
ASSERT(Type == eMAT_Blend || Type == eMAT_PhaseBlend);
|
||||||
mType = Type;
|
mType = Type;
|
||||||
mpMetaAnimA = gMetaAnimFactory.LoadFromStream(rInput);
|
mpMetaAnimA = gMetaAnimFactory.LoadFromStream(rInput, Game);
|
||||||
mpMetaAnimB = gMetaAnimFactory.LoadFromStream(rInput);
|
mpMetaAnimB = gMetaAnimFactory.LoadFromStream(rInput, Game);
|
||||||
mUnknownA = rInput.ReadFloat();
|
mUnknownA = rInput.ReadFloat();
|
||||||
mUnknownB = rInput.ReadBool();
|
mUnknownB = rInput.ReadBool();
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ void CMetaAnimBlend::GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) con
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaAnimRandom ************
|
// ************ CMetaAnimRandom ************
|
||||||
CMetaAnimRandom::CMetaAnimRandom(IInputStream& rInput)
|
CMetaAnimRandom::CMetaAnimRandom(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
u32 NumPairs = rInput.ReadLong();
|
u32 NumPairs = rInput.ReadLong();
|
||||||
mProbabilityPairs.reserve(NumPairs);
|
mProbabilityPairs.reserve(NumPairs);
|
||||||
|
@ -83,7 +83,7 @@ CMetaAnimRandom::CMetaAnimRandom(IInputStream& rInput)
|
||||||
for (u32 iAnim = 0; iAnim < NumPairs; iAnim++)
|
for (u32 iAnim = 0; iAnim < NumPairs; iAnim++)
|
||||||
{
|
{
|
||||||
SAnimProbabilityPair Pair;
|
SAnimProbabilityPair Pair;
|
||||||
Pair.pAnim = gMetaAnimFactory.LoadFromStream(rInput);
|
Pair.pAnim = gMetaAnimFactory.LoadFromStream(rInput, Game);
|
||||||
Pair.Probability = rInput.ReadLong();
|
Pair.Probability = rInput.ReadLong();
|
||||||
mProbabilityPairs.push_back(Pair);
|
mProbabilityPairs.push_back(Pair);
|
||||||
}
|
}
|
||||||
|
@ -107,14 +107,14 @@ void CMetaAnimRandom::GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) co
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaAnimSequence ************
|
// ************ CMetaAnimSequence ************
|
||||||
CMetaAnimSequence::CMetaAnimSequence(IInputStream& rInput)
|
CMetaAnimSequence::CMetaAnimSequence(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
u32 NumAnims = rInput.ReadLong();
|
u32 NumAnims = rInput.ReadLong();
|
||||||
mAnimations.reserve(NumAnims);
|
mAnimations.reserve(NumAnims);
|
||||||
|
|
||||||
for (u32 iAnim = 0; iAnim < NumAnims; iAnim++)
|
for (u32 iAnim = 0; iAnim < NumAnims; iAnim++)
|
||||||
{
|
{
|
||||||
IMetaAnimation *pAnim = gMetaAnimFactory.LoadFromStream(rInput);
|
IMetaAnimation *pAnim = gMetaAnimFactory.LoadFromStream(rInput, Game);
|
||||||
mAnimations.push_back(pAnim);
|
mAnimations.push_back(pAnim);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@ enum EMetaAnimationType
|
||||||
class CMetaAnimFactory
|
class CMetaAnimFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class IMetaAnimation* LoadFromStream(IInputStream& rInput);
|
class IMetaAnimation* LoadFromStream(IInputStream& rInput, EGame Game);
|
||||||
};
|
};
|
||||||
extern CMetaAnimFactory gMetaAnimFactory;
|
extern CMetaAnimFactory gMetaAnimFactory;
|
||||||
|
|
||||||
|
@ -32,9 +32,9 @@ class CAnimPrimitive
|
||||||
public:
|
public:
|
||||||
CAnimPrimitive() : mID(0) {}
|
CAnimPrimitive() : mID(0) {}
|
||||||
|
|
||||||
CAnimPrimitive(IInputStream& rInput)
|
CAnimPrimitive(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
mpAnim = gpResourceStore->LoadResource(rInput.ReadLong(), "ANIM");
|
mpAnim = gpResourceStore->LoadResource( CAssetID(rInput, Game), "ANIM" );
|
||||||
mID = rInput.ReadLong();
|
mID = rInput.ReadLong();
|
||||||
mName = rInput.ReadString();
|
mName = rInput.ReadString();
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public:
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const = 0;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const = 0;
|
||||||
|
|
||||||
// Static
|
// Static
|
||||||
static IMetaAnimation* LoadFromStream(IInputStream& rInput);
|
static IMetaAnimation* LoadFromStream(IInputStream& rInput, EGame Game);
|
||||||
};
|
};
|
||||||
|
|
||||||
// CMetaAnimPlay - plays an animation
|
// CMetaAnimPlay - plays an animation
|
||||||
|
@ -70,7 +70,7 @@ protected:
|
||||||
u32 mUnknownB;
|
u32 mUnknownB;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMetaAnimPlay(IInputStream& rInput);
|
CMetaAnimPlay(IInputStream& rInput, EGame Game);
|
||||||
virtual EMetaAnimationType Type() const;
|
virtual EMetaAnimationType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ protected:
|
||||||
bool mUnknownB;
|
bool mUnknownB;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMetaAnimBlend(EMetaAnimationType Type, IInputStream& rInput);
|
CMetaAnimBlend(EMetaAnimationType Type, IInputStream& rInput, EGame Game);
|
||||||
~CMetaAnimBlend();
|
~CMetaAnimBlend();
|
||||||
virtual EMetaAnimationType Type() const;
|
virtual EMetaAnimationType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
|
@ -117,7 +117,7 @@ protected:
|
||||||
std::vector<SAnimProbabilityPair> mProbabilityPairs;
|
std::vector<SAnimProbabilityPair> mProbabilityPairs;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMetaAnimRandom(IInputStream& rInput);
|
CMetaAnimRandom(IInputStream& rInput, EGame Game);
|
||||||
~CMetaAnimRandom();
|
~CMetaAnimRandom();
|
||||||
virtual EMetaAnimationType Type() const;
|
virtual EMetaAnimationType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
|
@ -130,7 +130,7 @@ protected:
|
||||||
std::vector<IMetaAnimation*> mAnimations;
|
std::vector<IMetaAnimation*> mAnimations;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMetaAnimSequence(IInputStream& rInput);
|
CMetaAnimSequence(IInputStream& rInput, EGame Game);
|
||||||
~CMetaAnimSequence();
|
~CMetaAnimSequence();
|
||||||
virtual EMetaAnimationType Type() const;
|
virtual EMetaAnimationType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
|
|
|
@ -4,21 +4,24 @@
|
||||||
// ************ CMetaTransFactory ************
|
// ************ CMetaTransFactory ************
|
||||||
CMetaTransFactory gMetaTransFactory;
|
CMetaTransFactory gMetaTransFactory;
|
||||||
|
|
||||||
IMetaTransition* CMetaTransFactory::LoadFromStream(IInputStream& rInput)
|
IMetaTransition* CMetaTransFactory::LoadFromStream(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
EMetaTransitionType Type = (EMetaTransitionType) rInput.ReadLong();
|
EMetaTransitionType Type = (EMetaTransitionType) rInput.ReadLong();
|
||||||
|
|
||||||
switch (Type)
|
switch (Type)
|
||||||
{
|
{
|
||||||
case eMTT_MetaAnim:
|
case eMTT_MetaAnim:
|
||||||
return new CMetaTransMetaAnim(rInput);
|
return new CMetaTransMetaAnim(rInput, Game);
|
||||||
|
|
||||||
case eMTT_Trans:
|
case eMTT_Trans:
|
||||||
case eMTT_PhaseTrans:
|
case eMTT_PhaseTrans:
|
||||||
return new CMetaTransTrans(Type, rInput);
|
return new CMetaTransTrans(Type, rInput, Game);
|
||||||
|
|
||||||
case eMTT_Snap:
|
case eMTT_Snap:
|
||||||
return new CMetaTransSnap(rInput);
|
return new CMetaTransSnap(rInput, Game);
|
||||||
|
|
||||||
|
case eMTT_Type4:
|
||||||
|
return new CMetaTransType4(rInput, Game);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Log::Error("Unrecognized meta-transition type: " + TString::FromInt32(Type, 0, 10));
|
Log::Error("Unrecognized meta-transition type: " + TString::FromInt32(Type, 0, 10));
|
||||||
|
@ -27,9 +30,9 @@ IMetaTransition* CMetaTransFactory::LoadFromStream(IInputStream& rInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaTransMetaAnim ************
|
// ************ CMetaTransMetaAnim ************
|
||||||
CMetaTransMetaAnim::CMetaTransMetaAnim(IInputStream& rInput)
|
CMetaTransMetaAnim::CMetaTransMetaAnim(IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
mpAnim = gMetaAnimFactory.LoadFromStream(rInput);
|
mpAnim = gMetaAnimFactory.LoadFromStream(rInput, Game);
|
||||||
}
|
}
|
||||||
|
|
||||||
CMetaTransMetaAnim::~CMetaTransMetaAnim()
|
CMetaTransMetaAnim::~CMetaTransMetaAnim()
|
||||||
|
@ -48,15 +51,23 @@ void CMetaTransMetaAnim::GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaTransTrans ************
|
// ************ CMetaTransTrans ************
|
||||||
CMetaTransTrans::CMetaTransTrans(EMetaTransitionType Type, IInputStream& rInput)
|
CMetaTransTrans::CMetaTransTrans(EMetaTransitionType Type, IInputStream& rInput, EGame Game)
|
||||||
{
|
{
|
||||||
ASSERT(Type == eMTT_Trans || Type == eMTT_PhaseTrans);
|
ASSERT(Type == eMTT_Trans || Type == eMTT_PhaseTrans);
|
||||||
mType = Type;
|
mType = Type;
|
||||||
mUnknownA = rInput.ReadFloat();
|
|
||||||
mUnknownB = rInput.ReadLong();
|
if (Game <= eEchoes)
|
||||||
mUnknownC = rInput.ReadBool();
|
{
|
||||||
mUnknownD = rInput.ReadBool();
|
mUnknownA = rInput.ReadFloat();
|
||||||
mUnknownE = rInput.ReadLong();
|
mUnknownB = rInput.ReadLong();
|
||||||
|
mUnknownC = rInput.ReadBool();
|
||||||
|
mUnknownD = rInput.ReadBool();
|
||||||
|
mUnknownE = rInput.ReadLong();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
rInput.Skip(0x13);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
EMetaTransitionType CMetaTransTrans::Type() const
|
EMetaTransitionType CMetaTransTrans::Type() const
|
||||||
|
@ -69,7 +80,7 @@ void CMetaTransTrans::GetUniquePrimitives(std::set<CAnimPrimitive>&) const
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ CMetaTransSnap ************
|
// ************ CMetaTransSnap ************
|
||||||
CMetaTransSnap::CMetaTransSnap(IInputStream&)
|
CMetaTransSnap::CMetaTransSnap(IInputStream&, EGame)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,3 +92,18 @@ EMetaTransitionType CMetaTransSnap::Type() const
|
||||||
void CMetaTransSnap::GetUniquePrimitives(std::set<CAnimPrimitive>&) const
|
void CMetaTransSnap::GetUniquePrimitives(std::set<CAnimPrimitive>&) const
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ************ CMetaTransType4 ************
|
||||||
|
CMetaTransType4::CMetaTransType4(IInputStream& rInput, EGame)
|
||||||
|
{
|
||||||
|
rInput.Skip(0x14);
|
||||||
|
}
|
||||||
|
|
||||||
|
EMetaTransitionType CMetaTransType4::Type() const
|
||||||
|
{
|
||||||
|
return eMTT_Type4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMetaTransType4::GetUniquePrimitives(std::set<CAnimPrimitive>&) const
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -11,14 +11,15 @@ enum EMetaTransitionType
|
||||||
eMTT_MetaAnim = 0,
|
eMTT_MetaAnim = 0,
|
||||||
eMTT_Trans = 1,
|
eMTT_Trans = 1,
|
||||||
eMTT_PhaseTrans = 2, // note: structure shared with eMTT_Trans
|
eMTT_PhaseTrans = 2, // note: structure shared with eMTT_Trans
|
||||||
eMTT_Snap = 3
|
eMTT_Snap = 3,
|
||||||
|
eMTT_Type4 = 4 // MP3 only
|
||||||
};
|
};
|
||||||
|
|
||||||
// Factory class
|
// Factory class
|
||||||
class CMetaTransFactory
|
class CMetaTransFactory
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
class IMetaTransition* LoadFromStream(IInputStream& rInput);
|
class IMetaTransition* LoadFromStream(IInputStream& rInput, EGame Game);
|
||||||
};
|
};
|
||||||
extern CMetaTransFactory gMetaTransFactory;
|
extern CMetaTransFactory gMetaTransFactory;
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ class CMetaTransMetaAnim : public IMetaTransition
|
||||||
IMetaAnimation *mpAnim;
|
IMetaAnimation *mpAnim;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMetaTransMetaAnim(IInputStream& rInput);
|
CMetaTransMetaAnim(IInputStream& rInput, EGame Game);
|
||||||
~CMetaTransMetaAnim();
|
~CMetaTransMetaAnim();
|
||||||
virtual EMetaTransitionType Type() const;
|
virtual EMetaTransitionType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
|
@ -55,7 +56,7 @@ class CMetaTransTrans : public IMetaTransition
|
||||||
u32 mUnknownE;
|
u32 mUnknownE;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CMetaTransTrans(EMetaTransitionType Type, IInputStream& rInput);
|
CMetaTransTrans(EMetaTransitionType Type, IInputStream& rInput, EGame Game);
|
||||||
virtual EMetaTransitionType Type() const;
|
virtual EMetaTransitionType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
};
|
};
|
||||||
|
@ -64,7 +65,16 @@ public:
|
||||||
class CMetaTransSnap : public IMetaTransition
|
class CMetaTransSnap : public IMetaTransition
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CMetaTransSnap(IInputStream& rInput);
|
CMetaTransSnap(IInputStream& rInput, EGame Game);
|
||||||
|
virtual EMetaTransitionType Type() const;
|
||||||
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// CMetaTransType4
|
||||||
|
class CMetaTransType4 : public IMetaTransition
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CMetaTransType4(IInputStream& rInput, EGame Game);
|
||||||
virtual EMetaTransitionType Type() const;
|
virtual EMetaTransitionType Type() const;
|
||||||
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
virtual void GetUniquePrimitives(std::set<CAnimPrimitive>& rPrimSet) const;
|
||||||
};
|
};
|
||||||
|
|
|
@ -351,6 +351,7 @@ void CResTypeInfo::CResTypeInfoFactory::InitTypes()
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSourceAnimData, "Source Animation Data");
|
CResTypeInfo *pType = new CResTypeInfo(eSourceAnimData, "Source Animation Data");
|
||||||
AddExtension(pType, "SAND", eCorruptionProto, eCorruption);
|
AddExtension(pType, "SAND", eCorruptionProto, eCorruption);
|
||||||
pType->mHidden = true;
|
pType->mHidden = true;
|
||||||
|
pType->mCanHaveDependencies = false; // all dependencies are added to the CHAR dependency tree
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
CResTypeInfo *pType = new CResTypeInfo(eSpatialPrimitive, "Spatial Primitive");
|
CResTypeInfo *pType = new CResTypeInfo(eSpatialPrimitive, "Spatial Primitive");
|
||||||
|
|
|
@ -52,6 +52,9 @@ private:
|
||||||
CAnimationParameters mUnknownAnimParams;
|
CAnimationParameters mUnknownAnimParams;
|
||||||
std::vector<SScanInfoSecondaryModel> mSecondaryModels;
|
std::vector<SScanInfoSecondaryModel> mSecondaryModels;
|
||||||
|
|
||||||
|
// MP3
|
||||||
|
std::vector<CAssetID> mDependencyList;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScan(CResourceEntry *pEntry = 0)
|
CScan(CResourceEntry *pEntry = 0)
|
||||||
: CResource(pEntry)
|
: CResource(pEntry)
|
||||||
|
@ -63,12 +66,20 @@ public:
|
||||||
|
|
||||||
CDependencyTree* BuildDependencyTree() const
|
CDependencyTree* BuildDependencyTree() const
|
||||||
{
|
{
|
||||||
// note: not handling Corruption yet
|
|
||||||
if (Game() >= eCorruptionProto)
|
|
||||||
Log::Warning("CScan::BuildDependencyTree not handling Corruption dependencies");
|
|
||||||
|
|
||||||
CDependencyTree *pTree = new CDependencyTree();
|
CDependencyTree *pTree = new CDependencyTree();
|
||||||
|
|
||||||
|
// Corruption's SCAN has a list of all assets - just grab that
|
||||||
|
if (Game() >= eCorruptionProto)
|
||||||
|
{
|
||||||
|
for (u32 iDep = 0; iDep < mDependencyList.size(); iDep++)
|
||||||
|
{
|
||||||
|
pTree->AddDependency(mDependencyList[iDep]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return pTree;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise add all the dependencies we need from the properties
|
||||||
if (Game() <= ePrime)
|
if (Game() <= ePrime)
|
||||||
pTree->AddDependency(mFrameID);
|
pTree->AddDependency(mFrameID);
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "Core/CAudioManager.h"
|
#include "Core/CAudioManager.h"
|
||||||
#include "Core/GameProject/CGameProject.h"
|
#include "Core/GameProject/CGameProject.h"
|
||||||
|
|
||||||
void CAnimEventLoader::LoadEvents(IInputStream& rEVNT, bool IsEchoes)
|
void CAnimEventLoader::LoadEvents(IInputStream& rEVNT)
|
||||||
{
|
{
|
||||||
u32 Version = rEVNT.ReadLong();
|
u32 Version = rEVNT.ReadLong();
|
||||||
ASSERT(Version == 1 || Version == 2);
|
ASSERT(Version == 1 || Version == 2);
|
||||||
|
@ -12,9 +12,7 @@ void CAnimEventLoader::LoadEvents(IInputStream& rEVNT, bool IsEchoes)
|
||||||
|
|
||||||
for (u32 iLoop = 0; iLoop < NumLoopEvents; iLoop++)
|
for (u32 iLoop = 0; iLoop < NumLoopEvents; iLoop++)
|
||||||
{
|
{
|
||||||
rEVNT.Seek(0x2, SEEK_CUR);
|
LoadLoopEvent(rEVNT);
|
||||||
rEVNT.ReadString();
|
|
||||||
rEVNT.Seek(0x1C, SEEK_CUR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// User Events
|
// User Events
|
||||||
|
@ -22,10 +20,7 @@ void CAnimEventLoader::LoadEvents(IInputStream& rEVNT, bool IsEchoes)
|
||||||
|
|
||||||
for (u32 iUser = 0; iUser < NumUserEvents; iUser++)
|
for (u32 iUser = 0; iUser < NumUserEvents; iUser++)
|
||||||
{
|
{
|
||||||
rEVNT.Seek(0x2, SEEK_CUR);
|
LoadUserEvent(rEVNT);
|
||||||
rEVNT.ReadString();
|
|
||||||
rEVNT.Seek(0x1F, SEEK_CUR);
|
|
||||||
rEVNT.ReadString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Effect Events
|
// Effect Events
|
||||||
|
@ -33,20 +28,7 @@ void CAnimEventLoader::LoadEvents(IInputStream& rEVNT, bool IsEchoes)
|
||||||
|
|
||||||
for (u32 iFX = 0; iFX < NumEffectEvents; iFX++)
|
for (u32 iFX = 0; iFX < NumEffectEvents; iFX++)
|
||||||
{
|
{
|
||||||
rEVNT.Seek(0x2, SEEK_CUR);
|
LoadEffectEvent(rEVNT);
|
||||||
rEVNT.ReadString();
|
|
||||||
rEVNT.Seek(0x13, SEEK_CUR);
|
|
||||||
u32 CharIndex = rEVNT.ReadLong();
|
|
||||||
rEVNT.Seek(0xC, SEEK_CUR);
|
|
||||||
CAssetID ParticleID = rEVNT.ReadLong();
|
|
||||||
mpEventData->AddEvent(CharIndex, ParticleID);
|
|
||||||
|
|
||||||
if (IsEchoes)
|
|
||||||
rEVNT.Seek(0x4, SEEK_CUR);
|
|
||||||
else
|
|
||||||
rEVNT.ReadString();
|
|
||||||
|
|
||||||
rEVNT.Seek(0x8, SEEK_CUR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sound Events
|
// Sound Events
|
||||||
|
@ -56,21 +38,92 @@ void CAnimEventLoader::LoadEvents(IInputStream& rEVNT, bool IsEchoes)
|
||||||
|
|
||||||
for (u32 iSound = 0; iSound < NumSoundEvents; iSound++)
|
for (u32 iSound = 0; iSound < NumSoundEvents; iSound++)
|
||||||
{
|
{
|
||||||
rEVNT.Seek(0x2, SEEK_CUR);
|
LoadSoundEvent(rEVNT);
|
||||||
rEVNT.ReadString();
|
}
|
||||||
rEVNT.Seek(0x13, SEEK_CUR);
|
}
|
||||||
u32 CharIndex = rEVNT.ReadLong();
|
}
|
||||||
rEVNT.Seek(0x4, SEEK_CUR);
|
|
||||||
u32 SoundID = rEVNT.ReadLong() & 0xFFFF;
|
|
||||||
rEVNT.Seek(0x8, SEEK_CUR);
|
|
||||||
if (IsEchoes) rEVNT.Seek(0xC, SEEK_CUR);
|
|
||||||
|
|
||||||
if (SoundID != 0xFFFF)
|
s32 CAnimEventLoader::LoadEventBase(IInputStream& rEVNT)
|
||||||
|
{
|
||||||
|
rEVNT.Skip(0x2);
|
||||||
|
rEVNT.ReadString();
|
||||||
|
rEVNT.Skip(mGame < eCorruptionProto ? 0x13 : 0x17);
|
||||||
|
s32 CharacterIndex = rEVNT.ReadLong();
|
||||||
|
rEVNT.Skip(mGame < eCorruptionProto ? 0x4 : 0x18);
|
||||||
|
return CharacterIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimEventLoader::LoadLoopEvent(IInputStream& rEVNT)
|
||||||
|
{
|
||||||
|
LoadEventBase(rEVNT);
|
||||||
|
rEVNT.Skip(0x1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimEventLoader::LoadUserEvent(IInputStream& rEVNT)
|
||||||
|
{
|
||||||
|
LoadEventBase(rEVNT);
|
||||||
|
rEVNT.Skip(0x4);
|
||||||
|
rEVNT.ReadString();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimEventLoader::LoadEffectEvent(IInputStream& rEVNT)
|
||||||
|
{
|
||||||
|
s32 CharIndex = LoadEventBase(rEVNT);
|
||||||
|
rEVNT.Skip(mGame < eCorruptionProto ? 0x8 : 0x4);
|
||||||
|
CAssetID ParticleID(rEVNT, mGame);
|
||||||
|
mpEventData->AddEvent(CharIndex, ParticleID);
|
||||||
|
|
||||||
|
if (mGame <= ePrime)
|
||||||
|
rEVNT.ReadString();
|
||||||
|
else if (mGame <= eEchoes)
|
||||||
|
rEVNT.Skip(0x4);
|
||||||
|
|
||||||
|
rEVNT.Skip(0x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CAnimEventLoader::LoadSoundEvent(IInputStream& rEVNT)
|
||||||
|
{
|
||||||
|
s32 CharIndex = LoadEventBase(rEVNT);
|
||||||
|
|
||||||
|
// Metroid Prime 1/2
|
||||||
|
if (mGame <= eEchoes)
|
||||||
|
{
|
||||||
|
u32 SoundID = rEVNT.ReadLong() & 0xFFFF;
|
||||||
|
rEVNT.Skip(0x8);
|
||||||
|
if (mGame >= eEchoes) rEVNT.Skip(0xC);
|
||||||
|
|
||||||
|
if (SoundID != 0xFFFF)
|
||||||
|
{
|
||||||
|
SSoundInfo SoundInfo = gpResourceStore->Project()->AudioManager()->GetSoundInfo(SoundID);
|
||||||
|
|
||||||
|
if (SoundInfo.pAudioGroup)
|
||||||
|
mpEventData->AddEvent(CharIndex, SoundInfo.pAudioGroup->ID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Metroid Prime 3
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CAssetID SoundID(rEVNT, mGame);
|
||||||
|
mpEventData->AddEvent(CharIndex, SoundID);
|
||||||
|
rEVNT.Skip(0x8);
|
||||||
|
|
||||||
|
for (u32 StructIdx = 0; StructIdx < 2; StructIdx++)
|
||||||
|
{
|
||||||
|
u32 StructType = rEVNT.ReadLong();
|
||||||
|
ASSERT(StructType <= 2);
|
||||||
|
|
||||||
|
if (StructType == 1)
|
||||||
{
|
{
|
||||||
SSoundInfo SoundInfo = gpResourceStore->Project()->AudioManager()->GetSoundInfo(SoundID);
|
rEVNT.Skip(4);
|
||||||
|
}
|
||||||
if (SoundInfo.pAudioGroup)
|
else if (StructType == 2)
|
||||||
mpEventData->AddEvent(CharIndex, SoundInfo.pAudioGroup->ID());
|
{
|
||||||
|
// This is a maya spline
|
||||||
|
rEVNT.Skip(2);
|
||||||
|
u32 KnotCount = rEVNT.ReadLong();
|
||||||
|
rEVNT.Skip(0xA * KnotCount);
|
||||||
|
rEVNT.Skip(9);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,7 +134,8 @@ CAnimEventData* CAnimEventLoader::LoadEVNT(IInputStream& rEVNT, CResourceEntry *
|
||||||
{
|
{
|
||||||
CAnimEventLoader Loader;
|
CAnimEventLoader Loader;
|
||||||
Loader.mpEventData = new CAnimEventData(pEntry);
|
Loader.mpEventData = new CAnimEventData(pEntry);
|
||||||
Loader.LoadEvents(rEVNT, false);
|
Loader.mGame = ePrime;
|
||||||
|
Loader.LoadEvents(rEVNT);
|
||||||
return Loader.mpEventData;
|
return Loader.mpEventData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +143,38 @@ CAnimEventData* CAnimEventLoader::LoadAnimSetEvents(IInputStream& rANCS)
|
||||||
{
|
{
|
||||||
CAnimEventLoader Loader;
|
CAnimEventLoader Loader;
|
||||||
Loader.mpEventData = new CAnimEventData();
|
Loader.mpEventData = new CAnimEventData();
|
||||||
Loader.LoadEvents(rANCS, true);
|
Loader.mGame = eEchoes;
|
||||||
|
Loader.LoadEvents(rANCS);
|
||||||
|
return Loader.mpEventData;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAnimEventData* CAnimEventLoader::LoadCorruptionCharacterEventSet(IInputStream& rCHAR)
|
||||||
|
{
|
||||||
|
CAnimEventLoader Loader;
|
||||||
|
Loader.mpEventData = new CAnimEventData();
|
||||||
|
Loader.mGame = eCorruption;
|
||||||
|
|
||||||
|
// Read event set header
|
||||||
|
rCHAR.Skip(0x4); // Skip animation ID
|
||||||
|
rCHAR.ReadString(); // Skip set name
|
||||||
|
|
||||||
|
// Read effect events
|
||||||
|
u32 NumEffectEvents = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 EventIdx = 0; EventIdx < NumEffectEvents; EventIdx++)
|
||||||
|
{
|
||||||
|
rCHAR.ReadString();
|
||||||
|
Loader.LoadEffectEvent(rCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read sound events
|
||||||
|
u32 NumSoundEvents = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 EventIdx = 0; EventIdx < NumSoundEvents; EventIdx++)
|
||||||
|
{
|
||||||
|
rCHAR.ReadString();
|
||||||
|
Loader.LoadSoundEvent(rCHAR);
|
||||||
|
}
|
||||||
|
|
||||||
return Loader.mpEventData;
|
return Loader.mpEventData;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,13 +7,20 @@
|
||||||
class CAnimEventLoader
|
class CAnimEventLoader
|
||||||
{
|
{
|
||||||
TResPtr<CAnimEventData> mpEventData;
|
TResPtr<CAnimEventData> mpEventData;
|
||||||
|
EGame mGame;
|
||||||
|
|
||||||
CAnimEventLoader() {}
|
CAnimEventLoader() {}
|
||||||
void LoadEvents(IInputStream& rEVNT, bool IsEchoes);
|
void LoadEvents(IInputStream& rEVNT);
|
||||||
|
s32 LoadEventBase(IInputStream& rEVNT);
|
||||||
|
void LoadLoopEvent(IInputStream& rEVNT);
|
||||||
|
void LoadUserEvent(IInputStream& rEVNT);
|
||||||
|
void LoadEffectEvent(IInputStream& rEVNT);
|
||||||
|
void LoadSoundEvent(IInputStream& rEVNT);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CAnimEventData* LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry);
|
static CAnimEventData* LoadEVNT(IInputStream& rEVNT, CResourceEntry *pEntry);
|
||||||
static CAnimEventData* LoadAnimSetEvents(IInputStream& rANCS);
|
static CAnimEventData* LoadAnimSetEvents(IInputStream& rANCS);
|
||||||
|
static CAnimEventData* LoadCorruptionCharacterEventSet(IInputStream& rCHAR);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CANIMEVENTLOADER_H
|
#endif // CANIMEVENTLOADER_H
|
||||||
|
|
|
@ -9,13 +9,89 @@ CAnimSetLoader::CAnimSetLoader()
|
||||||
|
|
||||||
CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
|
CAnimSet* CAnimSetLoader::LoadCorruptionCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
// For now, we only read enough to fetch the model
|
pSet->mCharacters.emplace_back( SSetCharacter() );;
|
||||||
rCHAR.Seek(0x1, SEEK_CUR);
|
SSetCharacter& rChar = pSet->mCharacters.back();
|
||||||
pSet->mCharacters.resize(1);
|
|
||||||
SSetCharacter& rNode = pSet->mCharacters[0];
|
// Character Header
|
||||||
|
rChar.ID = rCHAR.ReadByte();
|
||||||
|
rChar.Name = rCHAR.ReadString();
|
||||||
|
rChar.pModel = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CMDL");
|
||||||
|
rChar.pSkin = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CSKR");
|
||||||
|
|
||||||
|
u32 NumOverlays = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 iOverlay = 0; iOverlay < NumOverlays; iOverlay++)
|
||||||
|
{
|
||||||
|
SOverlayModel Overlay;
|
||||||
|
Overlay.Type = (EOverlayType) rCHAR.ReadLong();
|
||||||
|
Overlay.ModelID = CAssetID(rCHAR, e64Bit);
|
||||||
|
Overlay.SkinID = CAssetID(rCHAR, e64Bit);
|
||||||
|
rChar.OverlayModels.push_back(Overlay);
|
||||||
|
}
|
||||||
|
|
||||||
|
rChar.pSkeleton = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CINF");
|
||||||
|
rChar.AnimDataID = CAssetID(rCHAR, e64Bit);
|
||||||
|
|
||||||
|
// PAS Database
|
||||||
|
LoadPASDatabase(rCHAR);
|
||||||
|
|
||||||
|
// Particle Resource Data
|
||||||
|
LoadParticleResourceData(rCHAR, &rChar, 10);
|
||||||
|
|
||||||
|
// Events
|
||||||
|
u32 NumEventSets = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 iSet = 0; iSet < NumEventSets; iSet++)
|
||||||
|
{
|
||||||
|
CAnimEventData *pEvents = CAnimEventLoader::LoadCorruptionCharacterEventSet(rCHAR);
|
||||||
|
pSet->mAnimEvents.push_back(pEvents);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animations
|
||||||
|
u32 NumAnimations = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 AnimIdx = 0; AnimIdx < NumAnimations; AnimIdx++)
|
||||||
|
{
|
||||||
|
SAnimation Anim;
|
||||||
|
Anim.Name = rCHAR.ReadString();
|
||||||
|
Anim.pMetaAnim = gMetaAnimFactory.LoadFromStream(rCHAR, mGame);
|
||||||
|
pSet->mAnimations.push_back(Anim);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animation Bounds
|
||||||
|
u32 NumAnimationBounds = rCHAR.ReadLong();
|
||||||
|
rCHAR.Skip(NumAnimationBounds * 0x20);
|
||||||
|
rCHAR.Skip(1);
|
||||||
|
|
||||||
|
// Bool Array
|
||||||
|
u32 BoolArraySize = rCHAR.ReadLong();
|
||||||
|
rCHAR.Skip(BoolArraySize);
|
||||||
|
|
||||||
|
// Collision Primitives
|
||||||
|
u32 NumPrimitiveSets = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 SetIdx = 0; SetIdx < NumPrimitiveSets; SetIdx++)
|
||||||
|
{
|
||||||
|
rCHAR.ReadString();
|
||||||
|
u32 NumPrimitives = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 PrimIdx = 0; PrimIdx < NumPrimitives; PrimIdx++)
|
||||||
|
{
|
||||||
|
rCHAR.Skip(0x34);
|
||||||
|
rCHAR.ReadString();
|
||||||
|
rCHAR.Skip(4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sound Resources
|
||||||
|
u32 NumSounds = rCHAR.ReadLong();
|
||||||
|
|
||||||
|
for (u32 SoundIdx = 0; SoundIdx < NumSounds; SoundIdx++)
|
||||||
|
{
|
||||||
|
CAssetID SoundID(rCHAR, e64Bit);
|
||||||
|
rChar.SoundEffects.push_back(SoundID);
|
||||||
|
}
|
||||||
|
|
||||||
rNode.Name = rCHAR.ReadString();
|
|
||||||
rNode.pModel = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CMDL");
|
|
||||||
return pSet;
|
return pSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,22 +99,25 @@ CAnimSet* CAnimSetLoader::LoadReturnsCHAR(IInputStream& rCHAR)
|
||||||
{
|
{
|
||||||
// For now, we only read enough to fetch the model
|
// For now, we only read enough to fetch the model
|
||||||
rCHAR.Seek(0x16, SEEK_CUR);
|
rCHAR.Seek(0x16, SEEK_CUR);
|
||||||
pSet->mCharacters.resize(1);
|
|
||||||
SSetCharacter& rNode = pSet->mCharacters[0];
|
|
||||||
|
|
||||||
rNode.Name = rCHAR.ReadString();
|
pSet->mCharacters.emplace_back( SSetCharacter() );;
|
||||||
|
SSetCharacter& rChar = pSet->mCharacters.back();
|
||||||
|
|
||||||
|
rChar.ID = 0;
|
||||||
|
rChar.Name = rCHAR.ReadString();
|
||||||
rCHAR.Seek(0x14, SEEK_CUR);
|
rCHAR.Seek(0x14, SEEK_CUR);
|
||||||
rCHAR.ReadString();
|
rCHAR.ReadString();
|
||||||
rNode.pModel = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CMDL");
|
rChar.pModel = gpResourceStore->LoadResource(rCHAR.ReadLongLong(), "CMDL");
|
||||||
return pSet;
|
return pSet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4)
|
void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4)
|
||||||
{
|
{
|
||||||
// For now, just parse the data; don't store it
|
// For now, just parse the data; don't store it
|
||||||
rPAS4.Seek(0x4, SEEK_CUR); // Skipping PAS4 FourCC
|
u32 Magic = rPAS4.ReadLong();
|
||||||
u32 AnimStateCount = rPAS4.ReadLong();
|
u32 AnimStateCount = rPAS4.ReadLong();
|
||||||
rPAS4.Seek(0x4, SEEK_CUR); // Skipping default anim state
|
rPAS4.Seek(0x4, SEEK_CUR); // Skipping default anim state
|
||||||
|
ASSERT(Magic == FOURCC('PAS4'));
|
||||||
|
|
||||||
for (u32 iState = 0; iState < AnimStateCount; iState++)
|
for (u32 iState = 0; iState < AnimStateCount; iState++)
|
||||||
{
|
{
|
||||||
|
@ -72,6 +151,41 @@ void CAnimSetLoader::LoadPASDatabase(IInputStream& rPAS4)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CAnimSetLoader::LoadParticleResourceData(IInputStream& rFile, SSetCharacter *pChar, u16 CharVersion)
|
||||||
|
{
|
||||||
|
u32 ParticleCount = rFile.ReadLong();
|
||||||
|
pChar->GenericParticles.reserve(ParticleCount);
|
||||||
|
|
||||||
|
for (u32 iPart = 0; iPart < ParticleCount; iPart++)
|
||||||
|
pChar->GenericParticles.push_back( CAssetID(rFile, mGame) );
|
||||||
|
|
||||||
|
u32 SwooshCount = rFile.ReadLong();
|
||||||
|
pChar->SwooshParticles.reserve(SwooshCount);
|
||||||
|
|
||||||
|
for (u32 iSwoosh = 0; iSwoosh < SwooshCount; iSwoosh++)
|
||||||
|
pChar->SwooshParticles.push_back( CAssetID(rFile, mGame) );
|
||||||
|
|
||||||
|
if (CharVersion >= 6 && mGame <= eEchoes) rFile.Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
|
u32 ElectricCount = rFile.ReadLong();
|
||||||
|
pChar->ElectricParticles.reserve(ElectricCount);
|
||||||
|
|
||||||
|
for (u32 iElec = 0; iElec < ElectricCount; iElec++)
|
||||||
|
pChar->ElectricParticles.push_back( CAssetID(rFile, mGame) );
|
||||||
|
|
||||||
|
if (mGame >= eEchoes)
|
||||||
|
{
|
||||||
|
u32 SpawnCount = rFile.ReadLong();
|
||||||
|
pChar->SpawnParticles.reserve(SpawnCount);
|
||||||
|
|
||||||
|
for (u32 iSpawn = 0; iSpawn < SpawnCount; iSpawn++)
|
||||||
|
pChar->SpawnParticles.push_back( CAssetID(rFile, mGame) );
|
||||||
|
}
|
||||||
|
|
||||||
|
rFile.Seek(0x4, SEEK_CUR);
|
||||||
|
if (mGame >= eEchoes) rFile.Seek(0x4, SEEK_CUR);
|
||||||
|
}
|
||||||
|
|
||||||
void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
||||||
{
|
{
|
||||||
u16 Version = rANCS.ReadShort();
|
u16 Version = rANCS.ReadShort();
|
||||||
|
@ -84,7 +198,7 @@ void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
||||||
{
|
{
|
||||||
SAnimation Anim;
|
SAnimation Anim;
|
||||||
Anim.Name = rANCS.ReadString();
|
Anim.Name = rANCS.ReadString();
|
||||||
Anim.pMetaAnim = gMetaAnimFactory.LoadFromStream(rANCS);
|
Anim.pMetaAnim = gMetaAnimFactory.LoadFromStream(rANCS, mGame);
|
||||||
pSet->mAnimations.push_back(Anim);
|
pSet->mAnimations.push_back(Anim);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,11 +212,11 @@ void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
||||||
Trans.Unknown = rANCS.ReadLong();
|
Trans.Unknown = rANCS.ReadLong();
|
||||||
Trans.AnimIdA = rANCS.ReadLong();
|
Trans.AnimIdA = rANCS.ReadLong();
|
||||||
Trans.AnimIdB = rANCS.ReadLong();
|
Trans.AnimIdB = rANCS.ReadLong();
|
||||||
Trans.pMetaTrans = gMetaTransFactory.LoadFromStream(rANCS);
|
Trans.pMetaTrans = gMetaTransFactory.LoadFromStream(rANCS, mGame);
|
||||||
pSet->mTransitions.push_back(Trans);
|
pSet->mTransitions.push_back(Trans);
|
||||||
}
|
}
|
||||||
|
|
||||||
pSet->mpDefaultTransition = gMetaTransFactory.LoadFromStream(rANCS);
|
pSet->mpDefaultTransition = gMetaTransFactory.LoadFromStream(rANCS, mGame);
|
||||||
|
|
||||||
// Additive Animations
|
// Additive Animations
|
||||||
u32 NumAdditive = rANCS.ReadLong();
|
u32 NumAdditive = rANCS.ReadLong();
|
||||||
|
@ -130,14 +244,14 @@ void CAnimSetLoader::LoadAnimationSet(IInputStream& rANCS)
|
||||||
{
|
{
|
||||||
SHalfTransition Trans;
|
SHalfTransition Trans;
|
||||||
Trans.AnimID = rANCS.ReadLong();
|
Trans.AnimID = rANCS.ReadLong();
|
||||||
Trans.pMetaTrans = gMetaTransFactory.LoadFromStream(rANCS);
|
Trans.pMetaTrans = gMetaTransFactory.LoadFromStream(rANCS, mGame);
|
||||||
pSet->mHalfTransitions.push_back(Trans);
|
pSet->mHalfTransitions.push_back(Trans);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skipping MP1 ANIM asset list
|
// Skipping MP1 ANIM asset list
|
||||||
// Events
|
// Events
|
||||||
if (mVersion >= eEchoesDemo)
|
if (mGame >= eEchoesDemo)
|
||||||
{
|
{
|
||||||
u32 EventDataCount = rANCS.ReadLong();
|
u32 EventDataCount = rANCS.ReadLong();
|
||||||
pSet->mAnimEvents.reserve(EventDataCount);
|
pSet->mAnimEvents.reserve(EventDataCount);
|
||||||
|
@ -260,20 +374,6 @@ void CAnimSetLoader::ProcessPrimitives()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ************ STATIC ************
|
// ************ STATIC ************
|
||||||
CAnimSet* CAnimSetLoader::LoadANCSOrCHAR(IInputStream& rFile, CResourceEntry *pEntry)
|
|
||||||
{
|
|
||||||
if (!rFile.IsValid()) return nullptr;
|
|
||||||
u8 Test = rFile.PeekByte();
|
|
||||||
|
|
||||||
if (Test == 0x3 || Test == 0x5 || Test == 0x59)
|
|
||||||
return LoadCHAR(rFile, pEntry);
|
|
||||||
else if (Test == 0x0)
|
|
||||||
return LoadANCS(rFile, pEntry);
|
|
||||||
|
|
||||||
Log::Error("Failed to determine animset format for " + rFile.GetSourceString() + "; first byte is " + TString::HexString(Test, 2));
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
if (!rANCS.IsValid()) return nullptr;
|
if (!rANCS.IsValid()) return nullptr;
|
||||||
|
@ -287,7 +387,7 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
|
|
||||||
CAnimSetLoader Loader;
|
CAnimSetLoader Loader;
|
||||||
Loader.pSet = new CAnimSet(pEntry);
|
Loader.pSet = new CAnimSet(pEntry);
|
||||||
Loader.mVersion = pEntry->Game();
|
Loader.mGame = pEntry->Game();
|
||||||
|
|
||||||
u32 NodeCount = rANCS.ReadLong();
|
u32 NodeCount = rANCS.ReadLong();
|
||||||
Loader.pSet->mCharacters.resize(NodeCount);
|
Loader.pSet->mCharacters.resize(NodeCount);
|
||||||
|
@ -296,11 +396,11 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
SSetCharacter *pChar = &Loader.pSet->mCharacters[iNode];
|
SSetCharacter *pChar = &Loader.pSet->mCharacters[iNode];
|
||||||
|
|
||||||
rANCS.Seek(0x4, SEEK_CUR); // Skipping node self-index
|
pChar->ID = rANCS.ReadLong();
|
||||||
u16 Unknown1 = rANCS.ReadShort();
|
u16 CharVersion = rANCS.ReadShort();
|
||||||
if (iNode == 0 && Loader.mVersion == eUnknownGame)
|
if (iNode == 0 && Loader.mGame == eUnknownGame)
|
||||||
{
|
{
|
||||||
Loader.mVersion = (Unknown1 == 0xA) ? eEchoes : ePrime; // Best version indicator we know of unfortunately
|
Loader.mGame = (CharVersion == 0xA) ? eEchoes : ePrime;
|
||||||
}
|
}
|
||||||
pChar->Name = rANCS.ReadString();
|
pChar->Name = rANCS.ReadString();
|
||||||
pChar->pModel = gpResourceStore->LoadResource(rANCS.ReadLong(), "CMDL");
|
pChar->pModel = gpResourceStore->LoadResource(rANCS.ReadLong(), "CMDL");
|
||||||
|
@ -315,7 +415,7 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
for (u32 iAnim = 0; iAnim < AnimCount; iAnim++)
|
for (u32 iAnim = 0; iAnim < AnimCount; iAnim++)
|
||||||
{
|
{
|
||||||
rANCS.Seek(0x4, SEEK_CUR);
|
rANCS.Seek(0x4, SEEK_CUR);
|
||||||
if (Loader.mVersion == ePrime) rANCS.Seek(0x1, SEEK_CUR);
|
if (Loader.mGame == ePrime) rANCS.Seek(0x1, SEEK_CUR);
|
||||||
rANCS.ReadString();
|
rANCS.ReadString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -323,37 +423,7 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
Loader.LoadPASDatabase(rANCS);
|
Loader.LoadPASDatabase(rANCS);
|
||||||
|
|
||||||
// Particles
|
// Particles
|
||||||
u32 ParticleCount = rANCS.ReadLong();
|
Loader.LoadParticleResourceData(rANCS, pChar, CharVersion);
|
||||||
pChar->GenericParticles.reserve(ParticleCount);
|
|
||||||
|
|
||||||
for (u32 iPart = 0; iPart < ParticleCount; iPart++)
|
|
||||||
pChar->GenericParticles.push_back( CAssetID(rANCS, e32Bit) );
|
|
||||||
|
|
||||||
u32 SwooshCount = rANCS.ReadLong();
|
|
||||||
pChar->SwooshParticles.reserve(SwooshCount);
|
|
||||||
|
|
||||||
for (u32 iSwoosh = 0; iSwoosh < SwooshCount; iSwoosh++)
|
|
||||||
pChar->SwooshParticles.push_back( CAssetID(rANCS, e32Bit) );
|
|
||||||
|
|
||||||
if (Unknown1 != 5) rANCS.Seek(0x4, SEEK_CUR);
|
|
||||||
|
|
||||||
u32 ElectricCount = rANCS.ReadLong();
|
|
||||||
pChar->ElectricParticles.reserve(ElectricCount);
|
|
||||||
|
|
||||||
for (u32 iElec = 0; iElec < ElectricCount; iElec++)
|
|
||||||
pChar->ElectricParticles.push_back( CAssetID(rANCS, e32Bit) );
|
|
||||||
|
|
||||||
if (Loader.mVersion == eEchoes)
|
|
||||||
{
|
|
||||||
u32 SpawnCount = rANCS.ReadLong();
|
|
||||||
pChar->SpawnParticles.reserve(SpawnCount);
|
|
||||||
|
|
||||||
for (u32 iSpawn = 0; iSpawn < SpawnCount; iSpawn++)
|
|
||||||
pChar->SpawnParticles.push_back( CAssetID(rANCS, e32Bit) );
|
|
||||||
}
|
|
||||||
|
|
||||||
rANCS.Seek(0x4, SEEK_CUR);
|
|
||||||
if (Loader.mVersion == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
|
||||||
|
|
||||||
u32 AnimCount2 = rANCS.ReadLong();
|
u32 AnimCount2 = rANCS.ReadLong();
|
||||||
for (u32 iAnim = 0; iAnim < AnimCount2; iAnim++)
|
for (u32 iAnim = 0; iAnim < AnimCount2; iAnim++)
|
||||||
|
@ -375,13 +445,17 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
CAssetID ParticleID(rANCS, e32Bit);
|
CAssetID ParticleID(rANCS, e32Bit);
|
||||||
if (ParticleID.IsValid()) pChar->EffectParticles.push_back(ParticleID);
|
if (ParticleID.IsValid()) pChar->EffectParticles.push_back(ParticleID);
|
||||||
|
|
||||||
if (Loader.mVersion == ePrime) rANCS.ReadString();
|
if (Loader.mGame == ePrime) rANCS.ReadString();
|
||||||
if (Loader.mVersion == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
if (Loader.mGame == eEchoes) rANCS.Seek(0x4, SEEK_CUR);
|
||||||
rANCS.Seek(0xC, SEEK_CUR);
|
rANCS.Seek(0xC, SEEK_CUR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pChar->IceModel = CAssetID(rANCS, e32Bit);
|
|
||||||
pChar->IceSkin = CAssetID(rANCS, e32Bit);
|
SOverlayModel Overlay;
|
||||||
|
Overlay.Type = eOT_Frozen;
|
||||||
|
Overlay.ModelID = CAssetID(rANCS, e32Bit);
|
||||||
|
Overlay.SkinID = CAssetID(rANCS, e32Bit);
|
||||||
|
pChar->OverlayModels.push_back(Overlay);
|
||||||
|
|
||||||
u32 AnimIndexCount = rANCS.ReadLong();
|
u32 AnimIndexCount = rANCS.ReadLong();
|
||||||
|
|
||||||
|
@ -391,7 +465,7 @@ CAnimSet* CAnimSetLoader::LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry)
|
||||||
pChar->UsedAnimationIndices.insert(AnimIndex);
|
pChar->UsedAnimationIndices.insert(AnimIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Loader.mVersion == eEchoes)
|
if (Loader.mGame == eEchoes)
|
||||||
{
|
{
|
||||||
pChar->SpatialPrimitives = rANCS.ReadLong();
|
pChar->SpatialPrimitives = rANCS.ReadLong();
|
||||||
rANCS.Seek(0x1, SEEK_CUR);
|
rANCS.Seek(0x1, SEEK_CUR);
|
||||||
|
@ -416,14 +490,14 @@ CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry)
|
||||||
|
|
||||||
if (Check == 0x5 || Check == 0x3)
|
if (Check == 0x5 || Check == 0x3)
|
||||||
{
|
{
|
||||||
Loader.mVersion = eCorruption;
|
Loader.mGame = eCorruption;
|
||||||
Loader.pSet = new CAnimSet(pEntry);
|
Loader.pSet = new CAnimSet(pEntry);
|
||||||
return Loader.LoadCorruptionCHAR(rCHAR);
|
return Loader.LoadCorruptionCHAR(rCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Check == 0x59)
|
if (Check == 0x59)
|
||||||
{
|
{
|
||||||
Loader.mVersion = eReturns;
|
Loader.mGame = eReturns;
|
||||||
Loader.pSet = new CAnimSet(pEntry);
|
Loader.pSet = new CAnimSet(pEntry);
|
||||||
return Loader.LoadReturnsCHAR(rCHAR);
|
return Loader.LoadReturnsCHAR(rCHAR);
|
||||||
}
|
}
|
||||||
|
@ -431,3 +505,48 @@ CAnimSet* CAnimSetLoader::LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry)
|
||||||
Log::FileError(rCHAR.GetSourceString(), "CHAR has invalid first byte: " + TString::HexString(Check, 2));
|
Log::FileError(rCHAR.GetSourceString(), "CHAR has invalid first byte: " + TString::HexString(Check, 2));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSourceAnimData* CAnimSetLoader::LoadSAND(IInputStream& rSAND, CResourceEntry *pEntry)
|
||||||
|
{
|
||||||
|
if (!rSAND.IsValid()) return nullptr;
|
||||||
|
|
||||||
|
// We only care about the transitions right now
|
||||||
|
CSourceAnimData *pData = new CSourceAnimData(pEntry);
|
||||||
|
|
||||||
|
u16 Unknown = rSAND.ReadShort(); // probably version
|
||||||
|
ASSERT(Unknown == 0);
|
||||||
|
|
||||||
|
// Transitions
|
||||||
|
u32 NumTransitions = rSAND.ReadLong();
|
||||||
|
|
||||||
|
for (u32 TransitionIdx = 0; TransitionIdx < NumTransitions; TransitionIdx++)
|
||||||
|
{
|
||||||
|
u8 UnkByte = rSAND.ReadByte();
|
||||||
|
ASSERT(UnkByte == 0);
|
||||||
|
|
||||||
|
CSourceAnimData::STransition Transition;
|
||||||
|
Transition.AnimA = CAssetID(rSAND, e64Bit);
|
||||||
|
Transition.AnimB = CAssetID(rSAND, e64Bit);
|
||||||
|
Transition.pTransition = gMetaTransFactory.LoadFromStream(rSAND, pEntry->Game());
|
||||||
|
pData->mTransitions.push_back(Transition);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Half Transitions
|
||||||
|
u32 NumHalfTransitions = rSAND.ReadLong();
|
||||||
|
|
||||||
|
for (u32 HalfIdx = 0; HalfIdx < NumHalfTransitions; HalfIdx++)
|
||||||
|
{
|
||||||
|
u8 UnkByte = rSAND.ReadByte();
|
||||||
|
ASSERT(UnkByte == 0);
|
||||||
|
|
||||||
|
CSourceAnimData::SHalfTransition HalfTrans;
|
||||||
|
HalfTrans.Anim = CAssetID(rSAND, e64Bit);
|
||||||
|
HalfTrans.pTransition = gMetaTransFactory.LoadFromStream(rSAND, pEntry->Game());
|
||||||
|
pData->mHalfTransitions.push_back(HalfTrans);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default Transition
|
||||||
|
pData->mpDefaultTransition = gMetaTransFactory.LoadFromStream(rSAND, pEntry->Game());
|
||||||
|
|
||||||
|
return pData;
|
||||||
|
}
|
||||||
|
|
|
@ -2,25 +2,27 @@
|
||||||
#define CCHARACTERLOADER_H
|
#define CCHARACTERLOADER_H
|
||||||
|
|
||||||
#include "Core/Resource/Animation/CAnimSet.h"
|
#include "Core/Resource/Animation/CAnimSet.h"
|
||||||
|
#include "Core/Resource/Animation/CSourceAnimData.h"
|
||||||
#include <Common/EGame.h>
|
#include <Common/EGame.h>
|
||||||
|
|
||||||
class CAnimSetLoader
|
class CAnimSetLoader
|
||||||
{
|
{
|
||||||
TResPtr<CAnimSet> pSet;
|
TResPtr<CAnimSet> pSet;
|
||||||
EGame mVersion;
|
EGame mGame;
|
||||||
|
|
||||||
CAnimSetLoader();
|
CAnimSetLoader();
|
||||||
CAnimSet* LoadCorruptionCHAR(IInputStream& rCHAR);
|
CAnimSet* LoadCorruptionCHAR(IInputStream& rCHAR);
|
||||||
CAnimSet* LoadReturnsCHAR(IInputStream& rCHAR);
|
CAnimSet* LoadReturnsCHAR(IInputStream& rCHAR);
|
||||||
void LoadPASDatabase(IInputStream& rPAS4);
|
void LoadPASDatabase(IInputStream& rPAS4);
|
||||||
|
void LoadParticleResourceData(IInputStream& rFile, SSetCharacter *pChar, u16 Version);
|
||||||
|
|
||||||
void LoadAnimationSet(IInputStream& rANCS);
|
void LoadAnimationSet(IInputStream& rANCS);
|
||||||
void ProcessPrimitives();
|
void ProcessPrimitives();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CAnimSet* LoadANCSOrCHAR(IInputStream& rFile, CResourceEntry *pEntry);
|
|
||||||
static CAnimSet* LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry);
|
static CAnimSet* LoadANCS(IInputStream& rANCS, CResourceEntry *pEntry);
|
||||||
static CAnimSet* LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry);
|
static CAnimSet* LoadCHAR(IInputStream& rCHAR, CResourceEntry *pEntry);
|
||||||
|
static CSourceAnimData* LoadSAND(IInputStream& rSAND, CResourceEntry *pEntry);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CCHARACTERLOADER_H
|
#endif // CCHARACTERLOADER_H
|
||||||
|
|
|
@ -466,7 +466,7 @@ CAnimation* CAnimationLoader::LoadANIM(IInputStream& rANIM, CResourceEntry *pEnt
|
||||||
{
|
{
|
||||||
// MP3/DKCR unsupported
|
// MP3/DKCR unsupported
|
||||||
if (pEntry->Game() > eEchoes)
|
if (pEntry->Game() > eEchoes)
|
||||||
return nullptr;
|
return new CAnimation(pEntry);
|
||||||
|
|
||||||
u32 CompressionType = rANIM.ReadLong();
|
u32 CompressionType = rANIM.ReadLong();
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ public:
|
||||||
case eScan: return new CScan(pEntry);
|
case eScan: return new CScan(pEntry);
|
||||||
case eSkeleton: return new CSkeleton(pEntry);
|
case eSkeleton: return new CSkeleton(pEntry);
|
||||||
case eSkin: return new CSkin(pEntry);
|
case eSkin: return new CSkin(pEntry);
|
||||||
|
case eSourceAnimData: return new CSourceAnimData(pEntry);
|
||||||
case eStaticGeometryMap: return new CPoiToWorld(pEntry);
|
case eStaticGeometryMap: return new CPoiToWorld(pEntry);
|
||||||
case eStringList: return new CStringList(pEntry);
|
case eStringList: return new CStringList(pEntry);
|
||||||
case eStringTable: return new CStringTable(pEntry);
|
case eStringTable: return new CStringTable(pEntry);
|
||||||
|
@ -88,6 +89,7 @@ public:
|
||||||
case eScan: pRes = CScanLoader::LoadSCAN(rInput, pEntry); break;
|
case eScan: pRes = CScanLoader::LoadSCAN(rInput, pEntry); break;
|
||||||
case eSkeleton: pRes = CSkeletonLoader::LoadCINF(rInput, pEntry); break;
|
case eSkeleton: pRes = CSkeletonLoader::LoadCINF(rInput, pEntry); break;
|
||||||
case eSkin: pRes = CSkinLoader::LoadCSKR(rInput, pEntry); break;
|
case eSkin: pRes = CSkinLoader::LoadCSKR(rInput, pEntry); break;
|
||||||
|
case eSourceAnimData: pRes = CAnimSetLoader::LoadSAND(rInput, pEntry); break;
|
||||||
case eStateMachine2: pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry); break;
|
case eStateMachine2: pRes = CUnsupportedFormatLoader::LoadFSM2(rInput, pEntry); break;
|
||||||
case eStaticGeometryMap: pRes = CPoiToWorldLoader::LoadEGMC(rInput, pEntry); break;
|
case eStaticGeometryMap: pRes = CPoiToWorldLoader::LoadEGMC(rInput, pEntry); break;
|
||||||
case eStringList: pRes = CAudioGroupLoader::LoadSTLC(rInput, pEntry); break;
|
case eStringList: pRes = CAudioGroupLoader::LoadSTLC(rInput, pEntry); break;
|
||||||
|
|
|
@ -44,7 +44,10 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
rSCAN.Seek(0x6, SEEK_CUR);
|
u16 InstanceSize = rSCAN.ReadShort();
|
||||||
|
u32 InstanceEnd = rSCAN.Tell() + InstanceSize;
|
||||||
|
rSCAN.Seek(0x4, SEEK_CUR);
|
||||||
|
|
||||||
u16 NumConnections = rSCAN.ReadShort();
|
u16 NumConnections = rSCAN.ReadShort();
|
||||||
if (NumConnections > 0) {
|
if (NumConnections > 0) {
|
||||||
Log::FileWarning(rSCAN.GetSourceString(), ScanInfoStart, "SNFO object in SCAN has connections");
|
Log::FileWarning(rSCAN.GetSourceString(), ScanInfoStart, "SNFO object in SCAN has connections");
|
||||||
|
@ -68,6 +71,7 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN)
|
||||||
LoadParamsMP2(rSCAN, NumProperties);
|
LoadParamsMP2(rSCAN, NumProperties);
|
||||||
break;
|
break;
|
||||||
case 0x12:
|
case 0x12:
|
||||||
|
case 0x15:
|
||||||
case 0x16:
|
case 0x16:
|
||||||
mpScan = new CScan(mpEntry);
|
mpScan = new CScan(mpEntry);
|
||||||
LoadParamsMP3(rSCAN, NumProperties);
|
LoadParamsMP3(rSCAN, NumProperties);
|
||||||
|
@ -77,6 +81,20 @@ CScan* CScanLoader::LoadScanMP2(IInputStream& rSCAN)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Load MP3 dependency list
|
||||||
|
if (mpScan->Game() == eCorruption)
|
||||||
|
{
|
||||||
|
rSCAN.GoTo(InstanceEnd);
|
||||||
|
u32 NumDeps = rSCAN.ReadLong();
|
||||||
|
|
||||||
|
for (u32 DepIdx = 0; DepIdx < NumDeps; DepIdx++)
|
||||||
|
{
|
||||||
|
rSCAN.Skip(4);
|
||||||
|
CAssetID ID(rSCAN, mpScan->Game());
|
||||||
|
mpScan->mDependencyList.push_back(ID);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return mpScan;
|
return mpScan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,10 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
|
||||||
Loader.mpSkeleton = pSkel;
|
Loader.mpSkeleton = pSkel;
|
||||||
EGame Game = pEntry->Game();
|
EGame Game = pEntry->Game();
|
||||||
|
|
||||||
|
// We don't support DKCR CINF right now
|
||||||
|
if (rCINF.PeekLong() == 0x9E220006)
|
||||||
|
return pSkel;
|
||||||
|
|
||||||
u32 NumBones = rCINF.ReadLong();
|
u32 NumBones = rCINF.ReadLong();
|
||||||
pSkel->mBones.reserve(NumBones);
|
pSkel->mBones.reserve(NumBones);
|
||||||
|
|
||||||
|
@ -61,7 +65,7 @@ CSkeleton* CSkeletonLoader::LoadCINF(IInputStream& rCINF, CResourceEntry *pEntry
|
||||||
u32 Check = rCINF.PeekLong();
|
u32 Check = rCINF.PeekLong();
|
||||||
Game = ((Check > 100 || Check == 0) ? eEchoes : ePrime);
|
Game = ((Check > 100 || Check == 0) ? eEchoes : ePrime);
|
||||||
}
|
}
|
||||||
if (Game == eEchoes)
|
if (Game >= eEchoes)
|
||||||
{
|
{
|
||||||
pBone->mRotation = CQuaternion(rCINF);
|
pBone->mRotation = CQuaternion(rCINF);
|
||||||
pBone->mLocalRotation = CQuaternion(rCINF);
|
pBone->mLocalRotation = CQuaternion(rCINF);
|
||||||
|
|
|
@ -5,9 +5,13 @@
|
||||||
CSkin* CSkinLoader::LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry)
|
CSkin* CSkinLoader::LoadCSKR(IInputStream& rCSKR, CResourceEntry *pEntry)
|
||||||
{
|
{
|
||||||
if (!rCSKR.IsValid()) return nullptr;
|
if (!rCSKR.IsValid()) return nullptr;
|
||||||
|
CSkin *pSkin = new CSkin(pEntry);
|
||||||
|
|
||||||
|
// We don't support MP3/DKCR CSKR yet
|
||||||
|
if (rCSKR.PeekLong() == FOURCC('SKIN'))
|
||||||
|
return pSkin;
|
||||||
|
|
||||||
u32 NumVertexGroups = rCSKR.ReadLong();
|
u32 NumVertexGroups = rCSKR.ReadLong();
|
||||||
CSkin *pSkin = new CSkin(pEntry);
|
|
||||||
pSkin->mVertGroups.resize(NumVertexGroups);
|
pSkin->mVertGroups.resize(NumVertexGroups);
|
||||||
|
|
||||||
for (u32 iGrp = 0; iGrp < NumVertexGroups; iGrp++)
|
for (u32 iGrp = 0; iGrp < NumVertexGroups; iGrp++)
|
||||||
|
|
|
@ -179,7 +179,8 @@ CResource* CScriptTemplate::FindDisplayAsset(CPropertyStruct *pProperties, u32&
|
||||||
|
|
||||||
if (pRes)
|
if (pRes)
|
||||||
{
|
{
|
||||||
rOutCharIndex = (it->ForceNodeIndex >= 0 && it->ForceNodeIndex < (s32) static_cast<CAnimSet*>(pRes)->NumCharacters() ? it->ForceNodeIndex : pChar->Get().CharacterIndex());
|
u32 MaxNumChars = static_cast<CAnimSet*>(pRes)->NumCharacters();
|
||||||
|
rOutCharIndex = (it->ForceNodeIndex >= 0 && it->ForceNodeIndex < (s32) MaxNumChars ? it->ForceNodeIndex : pChar->Get().CharacterIndex());
|
||||||
rOutAnimIndex = pChar->Get().AnimIndex();
|
rOutAnimIndex = pChar->Get().AnimIndex();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "Core/Render/CDrawUtil.h"
|
#include "Core/Render/CDrawUtil.h"
|
||||||
#include "Core/Render/CGraphics.h"
|
#include "Core/Render/CGraphics.h"
|
||||||
#include "Core/Render/CRenderer.h"
|
#include "Core/Render/CRenderer.h"
|
||||||
|
#include "Core/Resource/Animation/CAnimSet.h"
|
||||||
#include "Core/Resource/Script/CMasterTemplate.h"
|
#include "Core/Resource/Script/CMasterTemplate.h"
|
||||||
#include "Core/Resource/Script/CScriptLayer.h"
|
#include "Core/Resource/Script/CScriptLayer.h"
|
||||||
#include "Core/ScriptExtra/CScriptExtra.h"
|
#include "Core/ScriptExtra/CScriptExtra.h"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "Editor/Widgets/WDraggableSpinBox.h"
|
#include "Editor/Widgets/WDraggableSpinBox.h"
|
||||||
#include "Editor/Widgets/WIntegralSpinBox.h"
|
#include "Editor/Widgets/WIntegralSpinBox.h"
|
||||||
|
|
||||||
|
#include <Core/Resource/Animation/CAnimSet.h>
|
||||||
#include <Core/Resource/Script/IProperty.h>
|
#include <Core/Resource/Script/IProperty.h>
|
||||||
#include <Core/Resource/Script/IPropertyTemplate.h>
|
#include <Core/Resource/Script/IPropertyTemplate.h>
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ void IOutputStream::WriteString(const std::string& rkVal)
|
||||||
for (unsigned int i = 0; i < rkVal.size(); i++)
|
for (unsigned int i = 0; i < rkVal.size(); i++)
|
||||||
WriteByte(rkVal[i]);
|
WriteByte(rkVal[i]);
|
||||||
|
|
||||||
if ((rkVal.empty()) || (rkVal.back() != '\0'))
|
if (rkVal.empty() || rkVal.back() != '\0')
|
||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +65,7 @@ void IOutputStream::WriteString(const std::string& rkVal, unsigned long Count, b
|
||||||
for (unsigned int iChr = 0; iChr < Count; iChr++)
|
for (unsigned int iChr = 0; iChr < Count; iChr++)
|
||||||
WriteByte(rkVal[iChr]);
|
WriteByte(rkVal[iChr]);
|
||||||
|
|
||||||
if (Terminate && (rkVal[Count-1] != '\0'))
|
if (Terminate && (Count == 0 || rkVal[Count-1] != '\0'))
|
||||||
WriteByte(0);
|
WriteByte(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ void IOutputStream::WriteWideString(const std::wstring& rkVal)
|
||||||
for (unsigned int iChr = 0; iChr < rkVal.size(); iChr++)
|
for (unsigned int iChr = 0; iChr < rkVal.size(); iChr++)
|
||||||
WriteShort(rkVal[iChr]);
|
WriteShort(rkVal[iChr]);
|
||||||
|
|
||||||
if ((!rkVal.empty()) && (rkVal.back() != '\0'))
|
if (rkVal.empty() || rkVal.back() != '\0')
|
||||||
WriteShort(0);
|
WriteShort(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,7 +89,7 @@ void IOutputStream::WriteWideString(const std::wstring& rkVal, unsigned long Cou
|
||||||
for (unsigned int iChr = 0; iChr < Count; iChr++)
|
for (unsigned int iChr = 0; iChr < Count; iChr++)
|
||||||
WriteShort(rkVal[iChr]);
|
WriteShort(rkVal[iChr]);
|
||||||
|
|
||||||
if (Terminate && (rkVal[Count-1] != 0))
|
if (Terminate && (Count == 0 || rkVal[Count-1] != 0))
|
||||||
WriteShort(0);
|
WriteShort(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +99,6 @@ void IOutputStream::WriteSizedWideString(const std::wstring& rkVal)
|
||||||
WriteBytes(rkVal.data(), rkVal.size() * 2);
|
WriteBytes(rkVal.data(), rkVal.size() * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool IOutputStream::GoTo(long Address)
|
bool IOutputStream::GoTo(long Address)
|
||||||
{
|
{
|
||||||
return Seek(Address, SEEK_SET);
|
return Seek(Address, SEEK_SET);
|
||||||
|
|
Loading…
Reference in New Issue