Added AnimationParameters property type, decreased contents margins for struct properties in the modify tab, other minor fixes/cleanup

This commit is contained in:
parax0 2015-09-21 04:30:24 -06:00
parent 97ef20d0d2
commit 19b3ae59be
18 changed files with 581 additions and 172 deletions

View File

@ -148,7 +148,9 @@ SOURCES += \
Resource/cooker/CTemplateWriter.cpp \ Resource/cooker/CTemplateWriter.cpp \
Resource/cooker/CWorldCooker.cpp \ Resource/cooker/CWorldCooker.cpp \
Resource/script/CPropertyTemplate.cpp \ Resource/script/CPropertyTemplate.cpp \
Resource/script/CProperty.cpp Resource/script/CProperty.cpp \
Resource/CAnimationParameters.cpp \
UI/WAnimParamsEditor.cpp
HEADERS += \ HEADERS += \
Common/AnimUtil.h \ Common/AnimUtil.h \
@ -208,7 +210,6 @@ HEADERS += \
Scene/CModelNode.h \ Scene/CModelNode.h \
Scene/CSceneNode.h \ Scene/CSceneNode.h \
Scene/CStaticNode.h \ Scene/CStaticNode.h \
Resource/script/EAttribType.h \
Resource/CAnimSet.h \ Resource/CAnimSet.h \
Resource/factory/CAnimSetLoader.h \ Resource/factory/CAnimSetLoader.h \
Resource/factory/CScriptLoader.h \ Resource/factory/CScriptLoader.h \
@ -279,7 +280,6 @@ HEADERS += \
UI/WPropertyEditor.h \ UI/WPropertyEditor.h \
UI/WVectorEditor.h \ UI/WVectorEditor.h \
Resource/script/CMasterTemplate.h \ Resource/script/CMasterTemplate.h \
Resource/script/CTemplateCategory.h \
Resource/factory/CTemplateLoader.h \ Resource/factory/CTemplateLoader.h \
Core/CAreaAttributes.h \ Core/CAreaAttributes.h \
UI/WorldEditor/CLinkModel.h \ UI/WorldEditor/CLinkModel.h \
@ -314,7 +314,9 @@ HEADERS += \
Resource/cooker/CTemplateWriter.h \ Resource/cooker/CTemplateWriter.h \
Resource/cooker/CWorldCooker.h \ Resource/cooker/CWorldCooker.h \
Resource/script/CPropertyTemplate.h \ Resource/script/CPropertyTemplate.h \
Resource/script/EVolumeShape.h Resource/script/EVolumeShape.h \
Resource/CAnimationParameters.h \
UI/WAnimParamsEditor.h
FORMS += \ FORMS += \
UI/CWorldEditorWindow.ui \ UI/CWorldEditorWindow.ui \

View File

@ -0,0 +1,142 @@
#include "CAnimationParameters.h"
#include "CAnimSet.h"
#include <Core/CResCache.h>
#include <Core/Log.h>
#include <iostream>
CAnimationParameters::CAnimationParameters()
{
mGame = ePrime;
mpCharSet = nullptr;
mNodeIndex = 0;
mUnknown1 = 0;
mUnknown2 = 0;
mUnknown3 = 0;
mUnknown4 = 0;
}
CAnimationParameters::CAnimationParameters(CInputStream& SCLY, EGame game)
{
mGame = game;
mpCharSet = nullptr;
mNodeIndex = 0;
mUnknown1 = 0;
mUnknown2 = 0;
mUnknown3 = 0;
mUnknown4 = 0;
if (game <= eEchoes)
{
u32 animSetID = SCLY.ReadLong();
mNodeIndex = SCLY.ReadLong();
mUnknown1 = SCLY.ReadLong();
mpCharSet = gResCache.GetResource(animSetID, "ANCS");
mResToken = CToken(mpCharSet);
}
else if (game <= eCorruption)
{
u64 charID = SCLY.ReadLongLong();
mUnknown1 = SCLY.ReadLong();
mpCharSet = gResCache.GetResource(charID, "CHAR");
mResToken = CToken(mpCharSet);
}
else if (game == eReturns)
{
SCLY.Seek(-6, SEEK_CUR);
u32 offset = SCLY.Tell();
u32 propID = SCLY.ReadLong();
SCLY.Seek(2, SEEK_CUR);
mUnknown1 = (u32) SCLY.ReadByte();
mUnknown1 &= 0xFF;
if (mUnknown1 == 0x60)
{
u64 charID = SCLY.ReadLongLong();
mUnknown2 = SCLY.ReadLong();
mUnknown3 = SCLY.ReadLong();
mUnknown4 = SCLY.ReadLong();
mpCharSet = gResCache.GetResource(charID, "CHAR");
mResToken = CToken(mpCharSet);
}
else if (mUnknown1 != 0x80)
{
Log::FileError(SCLY.GetSourceString(), offset,
"Unexpected AnimationParameters byte: " + StringUtil::ToHexString(mUnknown1, true, true, 2) + " (property " + StringUtil::ToHexString(propID, true, true, 8) + ")");
}
}
}
CModel* CAnimationParameters::GetCurrentModel(s32 nodeIndex)
{
if (!mpCharSet) return nullptr;
if (mpCharSet->Type() != eAnimSet) return nullptr;
if (nodeIndex == -1) nodeIndex = mNodeIndex;
CAnimSet *pSet = static_cast<CAnimSet*>(mpCharSet);
if (pSet->getNodeCount() <= nodeIndex) return nullptr;
return pSet->getNodeModel(nodeIndex);
}
// ************ GETTERS ************
EGame CAnimationParameters::Version()
{
return mGame;
}
CResource* CAnimationParameters::Resource()
{
return mpCharSet;
}
u32 CAnimationParameters::CharacterIndex()
{
return mNodeIndex;
}
u32 CAnimationParameters::Unknown(u32 index)
{
switch (index)
{
case 0: return mUnknown1;
case 1: return mUnknown2;
case 2: return mUnknown3;
case 3: return mUnknown4;
default: return 0;
}
}
// ************ SETTERS ************
void CAnimationParameters::SetResource(CResource *pRes)
{
if ((pRes->Type() == eAnimSet) || (pRes->Type() == eCharacter))
{
mpCharSet = pRes;
mResToken = CToken(pRes);
mNodeIndex = 0;
}
else
Log::Error("Resource with invalid type passed to CAnimationParameters: " + pRes->Source());
}
void CAnimationParameters::SetNodeIndex(u32 index)
{
mNodeIndex = index;
}
void CAnimationParameters::SetUnknown(u32 index, u32 value)
{
switch (index)
{
case 0: mUnknown1 = value;
case 1: mUnknown2 = value;
case 2: mUnknown3 = value;
case 3: mUnknown4 = value;
}
}

View File

@ -0,0 +1,38 @@
#ifndef CANIMATIONPARAMETERS_H
#define CANIMATIONPARAMETERS_H
#include "CResource.h"
#include "model/CModel.h"
#include <Core/CToken.h>
#include "EFormatVersion.h"
class CAnimationParameters
{
EGame mGame;
CResource *mpCharSet;
CToken mResToken;
u32 mNodeIndex;
u32 mUnknown1;
u32 mUnknown2;
u32 mUnknown3;
u32 mUnknown4;
public:
CAnimationParameters();
CAnimationParameters(CInputStream& SCLY, EGame game);
CModel* GetCurrentModel(s32 nodeIndex = -1);
// Getters
EGame Version();
CResource* Resource();
u32 CharacterIndex();
u32 Unknown(u32 index);
// Setters
void SetResource(CResource *pRes);
void SetNodeIndex(u32 index);
void SetUnknown(u32 index, u32 value);
};
#endif // CANIMATIONPARAMETERS_H

View File

@ -102,6 +102,10 @@ CPropertyStruct* CScriptLoader::LoadStructMP1(CInputStream& SCLY, CStructTemplat
pProp = LoadStructMP1(SCLY, StructTmp); pProp = LoadStructMP1(SCLY, StructTmp);
break; break;
} }
case eAnimParamsProperty: {
pProp = new CAnimParamsProperty(CAnimationParameters(SCLY, mVersion));
break;
}
default: default:
pProp = new CUnknownProperty(); pProp = new CUnknownProperty();
break; break;
@ -192,15 +196,17 @@ CScriptLayer* CScriptLoader::LoadLayerMP1(CInputStream &SCLY)
void CScriptLoader::LoadStructMP2(CInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp) void CScriptLoader::LoadStructMP2(CInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
{ {
// Verify property count // Verify property count
u32 propCount = pTemp->Count();
if (!pTemp->IsSingleProperty()) if (!pTemp->IsSingleProperty())
{ {
u16 numProperties = SCLY.ReadShort(); u16 numProperties = SCLY.ReadShort();
if (numProperties != pTemp->Count()) if ((numProperties != propCount) && (mVersion < eReturns))
Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 2, "Struct \"" + pTemp->Name() + "\" template property count doesn't match file"); Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 2, "Struct \"" + pTemp->Name() + "\" template property count doesn't match file");
propCount = numProperties;
} }
// Parse properties // Parse properties
u32 propCount = pTemp->Count();
pStruct->Reserve(propCount); pStruct->Reserve(propCount);
for (u32 iProp = 0; iProp < propCount; iProp++) for (u32 iProp = 0; iProp < propCount; iProp++)
@ -351,6 +357,11 @@ void CScriptLoader::LoadStructMP2(CInputStream& SCLY, CPropertyStruct *pStruct,
break; break;
} }
case eAnimParamsProperty: {
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(pProp);
pAnimCast->Set(CAnimationParameters(SCLY, mVersion));
break;
}
} }
} }

View File

@ -1,6 +1,5 @@
#include "CTemplateLoader.h" #include "CTemplateLoader.h"
#include "CWorldLoader.h" #include "CWorldLoader.h"
#include "../script/EAttribType.h"
#include <Core/Log.h> #include <Core/Log.h>
void CTemplateLoader::LoadStructProperties(tinyxml2::XMLElement *pElem, CStructTemplate *pTemp, const std::string& templateName) void CTemplateLoader::LoadStructProperties(tinyxml2::XMLElement *pElem, CStructTemplate *pTemp, const std::string& templateName)

View File

@ -2,7 +2,6 @@
#define CMASTERTEMPLATE_H #define CMASTERTEMPLATE_H
#include "CScriptTemplate.h" #include "CScriptTemplate.h"
#include "CTemplateCategory.h"
#include "../EFormatVersion.h" #include "../EFormatVersion.h"
#include <Common/types.h> #include <Common/types.h>
#include <map> #include <map>
@ -22,7 +21,6 @@ class CMasterTemplate
std::map<u32, CScriptTemplate*> mTemplates; std::map<u32, CScriptTemplate*> mTemplates;
std::map<u32, std::string> mStates; std::map<u32, std::string> mStates;
std::map<u32, std::string> mMessages; std::map<u32, std::string> mMessages;
std::vector<CTemplateCategory> mCategories;
bool mHasPropList; bool mHasPropList;
std::map<u32, CPropertyTemplate*> mPropertyList; std::map<u32, CPropertyTemplate*> mPropertyList;

View File

@ -96,18 +96,19 @@ CPropertyStruct* CPropertyStruct::CopyFromTemplate(CStructTemplate *pTemp)
switch (pPropTemp->Type()) switch (pPropTemp->Type())
{ {
case eBoolProperty: pProp = new CBoolProperty(false); break; case eBoolProperty: pProp = new CBoolProperty(false); break;
case eByteProperty: pProp = new CByteProperty(0); break; case eByteProperty: pProp = new CByteProperty(0); break;
case eShortProperty: pProp = new CShortProperty(0); break; case eShortProperty: pProp = new CShortProperty(0); break;
case eLongProperty: pProp = new CLongProperty(0); break; case eLongProperty: pProp = new CLongProperty(0); break;
case eFloatProperty: pProp = new CFloatProperty(0.f); break; case eFloatProperty: pProp = new CFloatProperty(0.f); break;
case eStringProperty: pProp = new CStringProperty(""); break; case eStringProperty: pProp = new CStringProperty(""); break;
case eVector3Property: pProp = new CVector3Property(CVector3f::skZero); break; case eVector3Property: pProp = new CVector3Property(CVector3f::skZero); break;
case eColorProperty: pProp = new CColorProperty(CColor::skBlack); break; case eColorProperty: pProp = new CColorProperty(CColor::skBlack); break;
case eFileProperty: pProp = new CFileProperty(); break; case eFileProperty: pProp = new CFileProperty(); break;
case eArrayProperty: pProp = new CArrayProperty(); break; case eArrayProperty: pProp = new CArrayProperty(); break;
case eUnknownProperty: pProp = new CUnknownProperty(); break; case eAnimParamsProperty: pProp = new CAnimParamsProperty(); break;
case eStructProperty: pProp = CPropertyStruct::CopyFromTemplate(static_cast<CStructTemplate*>(pPropTemp)); break; case eUnknownProperty: pProp = new CUnknownProperty(); break;
case eStructProperty: pProp = CPropertyStruct::CopyFromTemplate(static_cast<CStructTemplate*>(pPropTemp)); break;
} }
if (pProp) if (pProp)

View File

@ -7,6 +7,7 @@
* It's a bit hard to read, should be reorganized at some point * It's a bit hard to read, should be reorganized at some point
*/ */
#include "../CResource.h" #include "../CResource.h"
#include "../CAnimationParameters.h"
#include "CPropertyTemplate.h" #include "CPropertyTemplate.h"
#include "EPropertyType.h" #include "EPropertyType.h"
#include <Common/CColor.h> #include <Common/CColor.h>
@ -54,17 +55,18 @@ public:
inline t Get() { return mValue; } inline t Get() { return mValue; }
inline void Set(t v) { mValue = v; } inline void Set(t v) { mValue = v; }
}; };
typedef __CProperty<bool, eBoolProperty> CBoolProperty; typedef __CProperty<bool, eBoolProperty> CBoolProperty;
typedef __CProperty<char, eByteProperty> CByteProperty; typedef __CProperty<char, eByteProperty> CByteProperty;
typedef __CProperty<short, eShortProperty> CShortProperty; typedef __CProperty<short, eShortProperty> CShortProperty;
typedef __CProperty<long, eLongProperty> CLongProperty; typedef __CProperty<long, eLongProperty> CLongProperty;
typedef __CProperty<float, eFloatProperty> CFloatProperty; typedef __CProperty<float, eFloatProperty> CFloatProperty;
typedef __CProperty<std::string, eStringProperty> CStringProperty; typedef __CProperty<std::string, eStringProperty> CStringProperty;
typedef __CProperty<CVector3f, eVector3Property> CVector3Property; typedef __CProperty<CVector3f, eVector3Property> CVector3Property;
typedef __CProperty<CColor, eColorProperty> CColorProperty; typedef __CProperty<CColor, eColorProperty> CColorProperty;
typedef __CProperty<CResource*, eFileProperty> CFileProperty; typedef __CProperty<CResource*, eFileProperty> CFileProperty;
typedef __CProperty<std::vector<u8>, eArrayProperty> CArrayProperty; typedef __CProperty<CAnimationParameters, eAnimParamsProperty> CAnimParamsProperty;
typedef __CProperty<std::vector<u8>, eUnknownProperty> CUnknownProperty; typedef __CProperty<std::vector<u8>, eArrayProperty> CArrayProperty;
typedef __CProperty<std::vector<u8>, eUnknownProperty> CUnknownProperty;
/* /*
* Template specialization for CFileProperty to allow a token for resources * Template specialization for CFileProperty to allow a token for resources

View File

@ -3,37 +3,39 @@
EPropertyType PropStringToPropEnum(std::string prop) EPropertyType PropStringToPropEnum(std::string prop)
{ {
if (prop == "bool") return eBoolProperty; if (prop == "bool") return eBoolProperty;
if (prop == "byte") return eByteProperty; if (prop == "byte") return eByteProperty;
if (prop == "short") return eShortProperty; if (prop == "short") return eShortProperty;
if (prop == "long") return eLongProperty; if (prop == "long") return eLongProperty;
if (prop == "float") return eFloatProperty; if (prop == "float") return eFloatProperty;
if (prop == "string") return eStringProperty; if (prop == "string") return eStringProperty;
if (prop == "color") return eColorProperty; if (prop == "color") return eColorProperty;
if (prop == "vector3f") return eVector3Property; if (prop == "vector3f") return eVector3Property;
if (prop == "file") return eFileProperty; if (prop == "file") return eFileProperty;
if (prop == "struct") return eStructProperty; if (prop == "struct") return eStructProperty;
if (prop == "array") return eArrayProperty; if (prop == "array") return eArrayProperty;
if (prop == "unknown") return eUnknownProperty; if (prop == "animparams") return eAnimParamsProperty;
return eInvalidProperty; if (prop == "unknown") return eUnknownProperty;
return eInvalidProperty;
} }
std::string PropEnumToPropString(EPropertyType prop) std::string PropEnumToPropString(EPropertyType prop)
{ {
switch (prop) switch (prop)
{ {
case eBoolProperty: return "bool"; case eBoolProperty: return "bool";
case eByteProperty: return "byte"; case eByteProperty: return "byte";
case eShortProperty: return "short"; case eShortProperty: return "short";
case eLongProperty: return "long"; case eLongProperty: return "long";
case eFloatProperty: return "float"; case eFloatProperty: return "float";
case eStringProperty: return "string"; case eStringProperty: return "string";
case eColorProperty: return "color"; case eColorProperty: return "color";
case eVector3Property: return "vector3f"; case eVector3Property: return "vector3f";
case eFileProperty: return "file"; case eFileProperty: return "file";
case eStructProperty: return "struct"; case eStructProperty: return "struct";
case eArrayProperty: return "array"; case eArrayProperty: return "array";
case eUnknownProperty: return "unknown"; case eAnimParamsProperty: return "animparams";
case eUnknownProperty: return "unknown";
case eInvalidProperty: case eInvalidProperty:
default: default:

View File

@ -5,7 +5,6 @@
#include "CProperty.h" #include "CProperty.h"
#include "CPropertyTemplate.h" #include "CPropertyTemplate.h"
#include "CScriptTemplate.h" #include "CScriptTemplate.h"
#include "EAttribType.h"
#include "../model/CModel.h" #include "../model/CModel.h"
class CGameArea; class CGameArea;

View File

@ -108,6 +108,8 @@ t TFetchProperty(CPropertyStruct *pProperties, const TIDString& ID)
CStructTemplate* CScriptTemplate::BaseStructByCount(s32 propCount) CStructTemplate* CScriptTemplate::BaseStructByCount(s32 propCount)
{ {
if (mPropertySets.size() == 1) return mPropertySets[0].pBaseStruct;
for (u32 iSet = 0; iSet < mPropertySets.size(); iSet++) for (u32 iSet = 0; iSet < mPropertySets.size(); iSet++)
if (mPropertySets[iSet].pBaseStruct->Count() == propCount) if (mPropertySets[iSet].pBaseStruct->Count() == propCount)
return mPropertySets[iSet].pBaseStruct; return mPropertySets[iSet].pBaseStruct;
@ -206,7 +208,6 @@ CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties)
for (auto it = mAssets.begin(); it != mAssets.end(); it++) for (auto it = mAssets.begin(); it != mAssets.end(); it++)
{ {
CResource *pRes = nullptr; CResource *pRes = nullptr;
int animSetIndex = -1;
// File // File
if (it->AssetSource == SEditorAsset::eFile) if (it->AssetSource == SEditorAsset::eFile)
@ -226,46 +227,16 @@ CModel* CScriptTemplate::FindDisplayModel(CPropertyStruct *pProperties)
pRes = pFile->Get(); pRes = pFile->Get();
} }
else if (pProp->Type() == eStructProperty) else if (pProp->Type() == eAnimParamsProperty)
{ {
CPropertyStruct *pStruct = static_cast<CPropertyStruct*>(pProp); CAnimParamsProperty *pParams = static_cast<CAnimParamsProperty*>(pProp);
pRes = pParams->Get().GetCurrentModel(it->ForceNodeIndex);
// Slightly hacky code to fetch the correct parameters for each game
EGame game = mpMaster->GetGame();
if (game <= eCorruption)
pRes = static_cast<CFileProperty*>(pStruct->PropertyByIndex(0))->Get();
else
pRes = static_cast<CFileProperty*>(pStruct->PropertyByIndex(1))->Get();
if (it->ForceNodeIndex >= 0)
animSetIndex = it->ForceNodeIndex;
else if (game >= eCorruptionProto)
animSetIndex = 0;
else
animSetIndex = static_cast<CLongProperty*>(pStruct->PropertyByIndex(1))->Get();
} }
} }
// Verify resource exists + is correct type // Verify resource exists + is correct type
if (pRes) if (pRes && (pRes->Type() == eModel))
{ return static_cast<CModel*>(pRes);
if ((it->AssetType == SEditorAsset::eModel) && (pRes->Type() == eModel))
return static_cast<CModel*>(pRes);
if ((it->AssetType == SEditorAsset::eAnimParams) && ((pRes->Type() == eAnimSet)))
{
CAnimSet *pSet = static_cast<CAnimSet*>(pRes);
if (animSetIndex < pSet->getNodeCount())
{
CModel *pModel = pSet->getNodeModel(animSetIndex);
if (pModel && (pModel->Type() == eModel))
return pModel;
}
}
}
} }
return nullptr; return nullptr;

View File

@ -5,7 +5,6 @@
#include "CProperty.h" #include "CProperty.h"
#include "EPropertyType.h" #include "EPropertyType.h"
#include "EVolumeShape.h" #include "EVolumeShape.h"
#include "EAttribType.h"
#include <Common/CFourCC.h> #include <Common/CFourCC.h>
#include <Common/types.h> #include <Common/types.h>
#include <list> #include <list>

View File

@ -1,46 +0,0 @@
#ifndef CTEMPLATECATEGORY_H
#define CTEMPLATECATEGORY_H
#include "CScriptTemplate.h"
#include <algorithm>
class CTemplateCategory
{
std::string mCategoryName;
std::vector<CScriptTemplate*> mTemplates;
public:
CTemplateCategory() {}
inline CTemplateCategory(const std::string& Name) {
SetName(Name);
}
inline void SetName(const std::string& Name) {
mCategoryName = Name;
}
inline void AddTemplate(CScriptTemplate *pTmp) {
mTemplates.push_back(pTmp);
}
inline void Sort() {
std::sort(mTemplates.begin(), mTemplates.end(), [](CScriptTemplate* pA, CScriptTemplate* pB) -> bool {
return (pA->TemplateName() < pB->TemplateName());
});
}
inline u32 NumTemplates() {
return mTemplates.size();
}
inline CScriptTemplate* GetTemplate(u32 index) {
return mTemplates[index];
}
inline CScriptTemplate* operator[](u32 index) {
return mTemplates[index];
}
};
#endif // CTEMPLATECATEGORY_H

View File

@ -1,26 +0,0 @@
#ifndef EATTRIBTYPE
#define EATTRIBTYPE
#include <Common/EnumUtil.h>
#include <string>
enum EAttribType
{
eNameAttrib = 0x1,
ePositionAttrib = 0x2,
eRotationAttrib = 0x4,
eScaleAttrib = 0x8,
eModelAttrib = 0x10,
eAnimSetAttrib = 0x20,
eVolumeAttrib = 0x40,
eVulnerabilityAttrib = 0x80,
eInvalidAttrib = 0x80000000
};
DEFINE_ENUM_FLAGS(EAttribType)
// functions defined in CScriptTemplate.cpp
EAttribType AttribStringToAttribEnum(const std::string& Attrib);
std::string AttribEnumToAttribString(EAttribType Attrib);
#endif // EATTRIBTYPE

View File

@ -17,6 +17,7 @@ enum EPropertyType
eFileProperty, eFileProperty,
eStructProperty, eStructProperty,
eArrayProperty, eArrayProperty,
eAnimParamsProperty,
eUnknownProperty, eUnknownProperty,
eInvalidProperty eInvalidProperty
}; };

237
UI/WAnimParamsEditor.cpp Normal file
View File

@ -0,0 +1,237 @@
#include "WAnimParamsEditor.h"
#include <Core/CResCache.h>
#include <Resource/CAnimSet.h>
WAnimParamsEditor::WAnimParamsEditor(QWidget *pParent)
: QWidget(pParent),
mpGroupBox(new QGroupBox("Animation Parameters", this)),
mpGroupLayout(nullptr),
mpSelector(nullptr),
mpCharComboBox(nullptr)
{
for (u32 iBox = 0; iBox < 4; iBox++)
mpSpinBoxes[iBox] = nullptr;
for (u32 iLabel = 0; iLabel < 5; iLabel++) {
mpLabels[iLabel] = nullptr;
mpValueLayouts[iLabel] = nullptr;
}
QVBoxLayout *pLayout = new QVBoxLayout(this);
pLayout->addWidget(mpGroupBox);
pLayout->setContentsMargins(0,0,0,0);
setLayout(pLayout);
}
WAnimParamsEditor::WAnimParamsEditor(const CAnimationParameters& params, QWidget *pParent)
: QWidget(pParent),
mpGroupBox(new QGroupBox("Animation Parameters", this)),
mpGroupLayout(nullptr),
mpSelector(nullptr),
mpCharComboBox(nullptr)
{
for (u32 iBox = 0; iBox < 4; iBox++)
mpSpinBoxes[iBox] = nullptr;
for (u32 iLabel = 0; iLabel < 5; iLabel++) {
mpLabels[iLabel] = nullptr;
mpValueLayouts[iLabel] = nullptr;
}
QVBoxLayout *pLayout = new QVBoxLayout(this);
pLayout->addWidget(mpGroupBox);
pLayout->setContentsMargins(0,0,0,0);
setLayout(pLayout);
mParams = params;
SetupUI();
}
WAnimParamsEditor::~WAnimParamsEditor()
{
}
void WAnimParamsEditor::SetTitle(const QString& title)
{
mpGroupBox->setTitle(title);
}
void WAnimParamsEditor::SetParameters(const CAnimationParameters& params)
{
mParams = params;
SetupUI();
}
// ************ PRIVATE SLOTS ************
void WAnimParamsEditor::OnResourceChanged(QString path)
{
CResource *pRes = gResCache.GetResource(path.toStdString());
if (pRes->Type() != eAnimSet) pRes = nullptr;
mParams.SetResource(pRes);
emit ParametersChanged(mParams);
}
void WAnimParamsEditor::OnCharacterChanged(int index)
{
mParams.SetNodeIndex(index);
emit ParametersChanged(mParams);
}
void WAnimParamsEditor::OnUnknownChanged()
{
for (u32 iBox = 0; iBox < 4; iBox++)
if (mpSpinBoxes[iBox])
mParams.SetUnknown(iBox, mpSpinBoxes[iBox]->value());
emit ParametersChanged(mParams);
}
// ************ PRIVATE ************
void WAnimParamsEditor::SetupUI()
{
// Clean existing layout
if (!mLayoutWidgets.isEmpty())
{
foreach (QObject *pObject, mLayoutWidgets)
delete pObject;
mpSelector = nullptr;
mpCharComboBox = nullptr;
for (u32 iBox = 0; iBox < 4; iBox++)
mpSpinBoxes[iBox] = nullptr;
for (u32 iLabel = 0; iLabel < 5; iLabel++) {
mpLabels[iLabel] = nullptr;
mpValueLayouts[iLabel] = nullptr;
}
mLayoutWidgets.clear();
}
delete mpGroupLayout;
mpGroupLayout = new QVBoxLayout(mpGroupBox);
mpGroupLayout->setContentsMargins(5,5,5,5);
mpGroupBox->setLayout(mpGroupLayout);
// Create resource selector
mpLabels[0] = new QLabel(mParams.Version() <= eEchoes ? "AnimSet" : "Character");
mpSelector = new WResourceSelector(this);
mpSelector->SetAllowedExtensions(mParams.Version() <= eEchoes ? "ANCS" : "CHAR");
mpSelector->AdjustPreviewToParent(true);
mpSelector->SetResource(mParams.Resource());
mpValueLayouts[0] = new QHBoxLayout(this);
mpValueLayouts[0]->addWidget(mpLabels[0], 0);
mpValueLayouts[0]->addWidget(mpSelector, 1);
mpValueLayouts[0]->setSpacing(5);
mpGroupLayout->addLayout(mpValueLayouts[0]);
mLayoutWidgets << mpLabels[0] << mpSelector << mpValueLayouts[0];
connect(mpSelector, SIGNAL(ResourceChanged(QString)), this, SLOT(OnResourceChanged(QString)));
// Create MP1/2 widgets
if (mParams.Version() <= eEchoes)
{
// Create character select combo box
mpCharComboBox = new QComboBox(this);
CAnimSet *pSet = static_cast<CAnimSet*>(mParams.Resource());
for (u32 iChar = 0; iChar < pSet->getNodeCount(); iChar++)
mpCharComboBox->addItem(QString::fromStdString(pSet->getNodeName(iChar)));
mpCharComboBox->setCurrentIndex(mParams.CharacterIndex());
mpLabels[1] = new QLabel("Character", this);
// Create unknown spin box
mpSpinBoxes[0] = new WIntegralSpinBox(this);
mpSpinBoxes[0]->setRange(-2147483648, 2147483647);
mpSpinBoxes[0]->setFocusPolicy(Qt::StrongFocus);
mpSpinBoxes[0]->setContextMenuPolicy(Qt::NoContextMenu);
mpSpinBoxes[0]->setValue(mParams.Unknown(0));
mpLabels[2] = new QLabel("Unknown", this);
// Create layouts
mpValueLayouts[1] = new QHBoxLayout(this);
mpValueLayouts[1]->addWidget(mpLabels[1], 0);
mpValueLayouts[1]->addWidget(mpCharComboBox, 1);
mpValueLayouts[1]->setSpacing(5);
mpValueLayouts[2] = new QHBoxLayout(this);
mpValueLayouts[2]->addWidget(mpLabels[2], 0);
mpValueLayouts[2]->addWidget(mpSpinBoxes[0], 1);
mpValueLayouts[2]->setSpacing(5);
mpGroupLayout->addLayout(mpValueLayouts[1]);
mpGroupLayout->addLayout(mpValueLayouts[2]);
// Finish UI
mLayoutWidgets << mpLabels[1] << mpCharComboBox << mpLabels[2] << mpSpinBoxes[0] << mpValueLayouts[1] << mpValueLayouts[2];
connect(mpCharComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCharacterChanged(int)));
connect(mpSpinBoxes[0], SIGNAL(valueChanged(int)), this, SLOT(OnUnknownChanged()));
}
// Create MP3 widgets
else if (mParams.Version() <= eCorruption)
{
// Create unknown spin box
mpSpinBoxes[0] = new WIntegralSpinBox(this);
mpSpinBoxes[0]->setRange(-2147483648, 2147483647);
mpSpinBoxes[0]->setFocusPolicy(Qt::StrongFocus);
mpSpinBoxes[0]->setContextMenuPolicy(Qt::NoContextMenu);
mpSpinBoxes[0]->setValue(mParams.Unknown(0));
mpLabels[1] = new QLabel("Unknown", this);
// Create layouts
mpValueLayouts[1] = new QHBoxLayout(this);
mpValueLayouts[1]->addWidget(mpLabels[1], 0);
mpValueLayouts[1]->addWidget(mpSpinBoxes[0], 1);
mpValueLayouts[1]->setSpacing(5);
mpGroupLayout->addLayout(mpValueLayouts[1]);
// Finish UI
mLayoutWidgets << mpLabels[1] << mpSpinBoxes[0] << mpValueLayouts[1];
connect(mpSpinBoxes[0], SIGNAL(valueChanged(int)), this, SLOT(OnUnknownChanged()));
}
// Create DKCR widgets
else if (mParams.Version() == eReturns)
{
// Create unknown spin box A
mpSpinBoxes[0] = new WIntegralSpinBox(this);
mpSpinBoxes[0]->setRange(0, 255);
mpSpinBoxes[0]->setFocusPolicy(Qt::StrongFocus);
mpSpinBoxes[0]->setContextMenuPolicy(Qt::NoContextMenu);
mpSpinBoxes[0]->setValue(mParams.Unknown(0));
mpLabels[1] = new QLabel("Unknown", this);
mpValueLayouts[1] = new QHBoxLayout(this);
mpValueLayouts[1]->addWidget(mpLabels[1], 0);
mpValueLayouts[1]->addWidget(mpSpinBoxes[0], 1);
mpValueLayouts[1]->setSpacing(5);
mpGroupLayout->addLayout(mpValueLayouts[1]);
mLayoutWidgets << mpLabels[1] << mpSpinBoxes[0] << mpValueLayouts[1];
connect(mpSpinBoxes[0], SIGNAL(valueChanged(int)), this, SLOT(OnUnknownChanged()));
// Create unknown spin box B/C/D
for (u32 iBox = 1; iBox < 4; iBox++)
{
mpSpinBoxes[iBox] = new WIntegralSpinBox(this);
mpSpinBoxes[iBox]->setRange(-2147483648, 2147483647);
mpSpinBoxes[iBox]->setFocusPolicy(Qt::StrongFocus);
mpSpinBoxes[iBox]->setContextMenuPolicy(Qt::NoContextMenu);
mpSpinBoxes[iBox]->setValue(mParams.Unknown(iBox));
mpLabels[iBox+1] = new QLabel("Unknown", this);
mpValueLayouts[iBox+1] = new QHBoxLayout(this);
mpValueLayouts[iBox+1]->addWidget(mpLabels[iBox+1], 0);
mpValueLayouts[iBox+1]->addWidget(mpSpinBoxes[iBox], 1);
mpValueLayouts[iBox+1]->setSpacing(5);
mpGroupLayout->addLayout(mpValueLayouts[iBox+1]);
mLayoutWidgets << mpLabels[iBox+1] << mpSpinBoxes[iBox] << mpValueLayouts[iBox+1];
connect(mpSpinBoxes[iBox], SIGNAL(valueChanged(int)), this, SLOT(OnUnknownChanged()));
}
}
}

50
UI/WAnimParamsEditor.h Normal file
View File

@ -0,0 +1,50 @@
#ifndef WANIMPARAMSEDITOR_H
#define WANIMPARAMSEDITOR_H
#include <QWidget>
#include <QComboBox>
#include <QGroupBox>
#include <QSpinBox>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QVector>
#include "WIntegralSpinBox.h"
#include "WResourceSelector.h"
#include <Resource/CAnimationParameters.h>
class WAnimParamsEditor : public QWidget
{
Q_OBJECT
CAnimationParameters mParams;
QGroupBox *mpGroupBox;
QVBoxLayout *mpGroupLayout;
QHBoxLayout *mpValueLayouts[5];
QLabel *mpLabels[5];
WResourceSelector *mpSelector;
QComboBox *mpCharComboBox;
WIntegralSpinBox *mpSpinBoxes[4];
QVector<QObject*> mLayoutWidgets;
public:
WAnimParamsEditor(QWidget *pParent = 0);
WAnimParamsEditor(const CAnimationParameters& params, QWidget *pParent = 0);
~WAnimParamsEditor();
void SetTitle(const QString& title);
void SetParameters(const CAnimationParameters& params);
signals:
void ParametersChanged(const CAnimationParameters& params);
private slots:
void OnResourceChanged(QString path);
void OnCharacterChanged(int index);
void OnUnknownChanged();
private:
void SetupUI();
};
#endif // WANIMPARAMSEDITOR_H

View File

@ -4,12 +4,16 @@
#include "WResourceSelector.h" #include "WResourceSelector.h"
#include "WColorPicker.h" #include "WColorPicker.h"
#include "WVectorEditor.h" #include "WVectorEditor.h"
#include "WAnimParamsEditor.h"
#include <Resource/CAnimSet.h>
#include <QCheckBox> #include <QCheckBox>
#include <QSpinBox> #include <QComboBox>
#include <QDoubleSpinBox> #include <QDoubleSpinBox>
#include <QLineEdit>
#include <QGroupBox>
#include <QFontMetrics> #include <QFontMetrics>
#include <QGroupBox>
#include <QLineEdit>
#include <QSpinBox>
static const QString gskNullProperty = "[NULL]"; static const QString gskNullProperty = "[NULL]";
static const QString gskUnsupportedType = "Invalid property type"; static const QString gskUnsupportedType = "Invalid property type";
@ -218,9 +222,10 @@ void WPropertyEditor::CreateEditor()
case eStructProperty: case eStructProperty:
{ {
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(mpProperty); CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(mpProperty);
QGroupBox *pGroupBox = new QGroupBox(this);
QGroupBox *pGroupBox = new QGroupBox(this);
QVBoxLayout *pStructLayout = new QVBoxLayout(pGroupBox); QVBoxLayout *pStructLayout = new QVBoxLayout(pGroupBox);
pStructLayout->setContentsMargins(5,5,5,5);
pGroupBox->setLayout(pStructLayout); pGroupBox->setLayout(pStructLayout);
pGroupBox->setTitle(QString::fromStdString(pStructCast->Name())); pGroupBox->setTitle(QString::fromStdString(pStructCast->Name()));
mUI.PropertyName->hide(); mUI.PropertyName->hide();
@ -235,6 +240,20 @@ void WPropertyEditor::CreateEditor()
break; break;
} }
// AnimParams - WAnimParamsEditor
case eAnimParamsProperty:
{
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(mpProperty);
CAnimationParameters params = pAnimCast->Get();
WAnimParamsEditor *pEditor = new WAnimParamsEditor(params, this);
pEditor->SetTitle(QString::fromStdString(pAnimCast->Name()));
mUI.PropertyName->hide();
mUI.EditorWidget = pEditor;
break;
}
// Invalid // Invalid
case eInvalidProperty: case eInvalidProperty:
default: default:
@ -243,7 +262,9 @@ void WPropertyEditor::CreateEditor()
} }
// For some reason setting a minimum size on group boxes flattens it... // For some reason setting a minimum size on group boxes flattens it...
if ((mpProperty->Type() != eStructProperty) && (mpProperty->Type() != eVector3Property)) if ((mpProperty->Type() != eStructProperty) &&
(mpProperty->Type() != eVector3Property) &&
(mpProperty->Type() != eAnimParamsProperty))
{ {
mUI.EditorWidget->setMinimumHeight(21); mUI.EditorWidget->setMinimumHeight(21);
mUI.EditorWidget->setMaximumHeight(21); mUI.EditorWidget->setMaximumHeight(21);
@ -361,6 +382,14 @@ void WPropertyEditor::UpdateEditor()
break; break;
} }
case eAnimParamsProperty:
{
CAnimParamsProperty *pAnimCast = static_cast<CAnimParamsProperty*>(mpProperty);
WAnimParamsEditor *pEditor = static_cast<WAnimParamsEditor*>(mUI.EditorWidget);
pEditor->SetParameters(pAnimCast->Get());
break;
}
} }
} }