Fully implemented delete, added an easy-to-use ID lookup system for undo commands, fixed a bunch of crashes when undoing/redoing after creating/deleting an object
This commit is contained in:
parent
63812ae4b2
commit
c4e05610f3
|
@ -158,16 +158,7 @@ CScriptObject* CGameArea::SpawnInstance(CScriptTemplate *pTemplate,
|
||||||
if (InstanceID == -1)
|
if (InstanceID == -1)
|
||||||
{
|
{
|
||||||
// Determine layer index
|
// Determine layer index
|
||||||
u32 LayerIndex = -1;
|
u32 LayerIndex = pLayer->AreaIndex();
|
||||||
|
|
||||||
for (u32 iLyr = 0; iLyr < mScriptLayers.size(); iLyr++)
|
|
||||||
{
|
|
||||||
if (mScriptLayers[iLyr] == pLayer)
|
|
||||||
{
|
|
||||||
LayerIndex = iLyr;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LayerIndex == -1)
|
if (LayerIndex == -1)
|
||||||
{
|
{
|
||||||
|
@ -202,8 +193,16 @@ CScriptObject* CGameArea::SpawnInstance(CScriptTemplate *pTemplate,
|
||||||
return pInstance;
|
return pInstance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CGameArea::AddInstanceToArea(CScriptObject *pInstance)
|
||||||
|
{
|
||||||
|
// Used for undo after deleting an instance.
|
||||||
|
// In the future the script loader should go through SpawnInstance to avoid the need for this function.
|
||||||
|
mObjectMap[pInstance->InstanceID()] = pInstance;
|
||||||
|
}
|
||||||
|
|
||||||
void CGameArea::DeleteInstance(CScriptObject *pInstance)
|
void CGameArea::DeleteInstance(CScriptObject *pInstance)
|
||||||
{
|
{
|
||||||
|
pInstance->BreakAllLinks();
|
||||||
pInstance->Layer()->RemoveInstance(pInstance);
|
pInstance->Layer()->RemoveInstance(pInstance);
|
||||||
pInstance->Template()->RemoveObject(pInstance);
|
pInstance->Template()->RemoveObject(pInstance);
|
||||||
|
|
||||||
|
@ -213,6 +212,5 @@ void CGameArea::DeleteInstance(CScriptObject *pInstance)
|
||||||
if (mpPoiToWorldMap && mpPoiToWorldMap->HasPoiMappings(pInstance->InstanceID()))
|
if (mpPoiToWorldMap && mpPoiToWorldMap->HasPoiMappings(pInstance->InstanceID()))
|
||||||
mpPoiToWorldMap->RemovePoi(pInstance->InstanceID());
|
mpPoiToWorldMap->RemovePoi(pInstance->InstanceID());
|
||||||
|
|
||||||
pInstance->BreakAllLinks();
|
|
||||||
delete pInstance;
|
delete pInstance;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ public:
|
||||||
const CQuaternion& rkRotation = CQuaternion::skIdentity,
|
const CQuaternion& rkRotation = CQuaternion::skIdentity,
|
||||||
const CVector3f& rkScale = CVector3f::skOne,
|
const CVector3f& rkScale = CVector3f::skOne,
|
||||||
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
|
u32 SuggestedID = -1, u32 SuggestedLayerIndex = -1);
|
||||||
|
void AddInstanceToArea(CScriptObject *pInstance);
|
||||||
void DeleteInstance(CScriptObject *pInstance);
|
void DeleteInstance(CScriptObject *pInstance);
|
||||||
|
|
||||||
// Inline Accessors
|
// Inline Accessors
|
||||||
|
|
|
@ -292,3 +292,15 @@ void CScriptCooker::WriteLayer(EGame Game, CScriptLayer *pLayer, IOutputStream&
|
||||||
else
|
else
|
||||||
Cooker.WriteLayerMP2(pLayer);
|
Cooker.WriteLayerMP2(pLayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CScriptCooker::CookInstance(EGame Game, CScriptObject *pInstance, IOutputStream& rOut)
|
||||||
|
{
|
||||||
|
CScriptCooker Cooker;
|
||||||
|
Cooker.mpSCLY = &rOut;
|
||||||
|
Cooker.mVersion = Game;
|
||||||
|
|
||||||
|
if (Game <= ePrime)
|
||||||
|
Cooker.WriteInstanceMP1(pInstance);
|
||||||
|
else
|
||||||
|
Cooker.WriteInstanceMP2(pInstance);
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ class CScriptCooker
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void WriteLayer(EGame Game, CScriptLayer *pLayer, IOutputStream& rOut);
|
static void WriteLayer(EGame Game, CScriptLayer *pLayer, IOutputStream& rOut);
|
||||||
|
static void CookInstance(EGame Game, CScriptObject *pInstance, IOutputStream& rOut);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSCRIPTCOOKER_H
|
#endif // CSCRIPTCOOKER_H
|
||||||
|
|
|
@ -11,7 +11,7 @@ CScriptLoader::CScriptLoader()
|
||||||
mpObj = nullptr;
|
mpObj = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
IPropertyTemplate *pTemp = pProp->Template();
|
IPropertyTemplate *pTemp = pProp->Template();
|
||||||
|
|
||||||
|
@ -20,31 +20,31 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
|
|
||||||
case eBoolProperty: {
|
case eBoolProperty: {
|
||||||
TBoolProperty *pBoolCast = static_cast<TBoolProperty*>(pProp);
|
TBoolProperty *pBoolCast = static_cast<TBoolProperty*>(pProp);
|
||||||
pBoolCast->Set( (SCLY.ReadByte() != 0) );
|
pBoolCast->Set( (rSCLY.ReadByte() != 0) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eByteProperty: {
|
case eByteProperty: {
|
||||||
TByteProperty *pByteCast = static_cast<TByteProperty*>(pProp);
|
TByteProperty *pByteCast = static_cast<TByteProperty*>(pProp);
|
||||||
pByteCast->Set(SCLY.ReadByte());
|
pByteCast->Set(rSCLY.ReadByte());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eShortProperty: {
|
case eShortProperty: {
|
||||||
TShortProperty *pShortCast = static_cast<TShortProperty*>(pProp);
|
TShortProperty *pShortCast = static_cast<TShortProperty*>(pProp);
|
||||||
pShortCast->Set(SCLY.ReadShort());
|
pShortCast->Set(rSCLY.ReadShort());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eLongProperty: {
|
case eLongProperty: {
|
||||||
TLongProperty *pLongCast = static_cast<TLongProperty*>(pProp);
|
TLongProperty *pLongCast = static_cast<TLongProperty*>(pProp);
|
||||||
pLongCast->Set(SCLY.ReadLong());
|
pLongCast->Set(rSCLY.ReadLong());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eBitfieldProperty: {
|
case eBitfieldProperty: {
|
||||||
TBitfieldProperty *pBitfieldCast = static_cast<TBitfieldProperty*>(pProp);
|
TBitfieldProperty *pBitfieldCast = static_cast<TBitfieldProperty*>(pProp);
|
||||||
pBitfieldCast->Set(SCLY.ReadLong());
|
pBitfieldCast->Set(rSCLY.ReadLong());
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
u32 mask = 0;
|
u32 mask = 0;
|
||||||
|
@ -54,7 +54,7 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
|
|
||||||
u32 check = pBitfieldCast->Get() & ~mask;
|
u32 check = pBitfieldCast->Get() & ~mask;
|
||||||
if (check != 0)
|
if (check != 0)
|
||||||
Log::FileWarning(SCLY.GetSourceString(), SCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + TString::HexString(check, true, true, 8));
|
Log::FileWarning(rSCLY.GetSourceString(), rSCLY.Tell() - 4, "Bitfield property \"" + pBitfieldTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has flags set that aren't in the template: " + TString::HexString(check, true, true, 8));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,11 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
case eEnumProperty: {
|
case eEnumProperty: {
|
||||||
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(pProp);
|
TEnumProperty *pEnumCast = static_cast<TEnumProperty*>(pProp);
|
||||||
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pTemp);
|
CEnumTemplate *pEnumTemp = static_cast<CEnumTemplate*>(pTemp);
|
||||||
u32 ID = SCLY.ReadLong();
|
u32 ID = rSCLY.ReadLong();
|
||||||
|
|
||||||
// Validate
|
// Validate
|
||||||
u32 Index = pEnumTemp->EnumeratorIndex(ID);
|
u32 Index = pEnumTemp->EnumeratorIndex(ID);
|
||||||
if (Index == -1) Log::FileError(SCLY.GetSourceString(), SCLY.Tell() - 4, "Enum property \"" + pEnumTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has invalid enumerator value: " + TString::HexString(ID, true, true, 8));
|
if (Index == -1) Log::FileError(rSCLY.GetSourceString(), rSCLY.Tell() - 4, "Enum property \"" + pEnumTemp->Name() + "\" in struct \"" + pTemp->Name() + "\" has invalid enumerator value: " + TString::HexString(ID, true, true, 8));
|
||||||
|
|
||||||
pEnumCast->Set(ID);
|
pEnumCast->Set(ID);
|
||||||
break;
|
break;
|
||||||
|
@ -74,32 +74,32 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
|
|
||||||
case eFloatProperty: {
|
case eFloatProperty: {
|
||||||
TFloatProperty *pFloatCast = static_cast<TFloatProperty*>(pProp);
|
TFloatProperty *pFloatCast = static_cast<TFloatProperty*>(pProp);
|
||||||
pFloatCast->Set(SCLY.ReadFloat());
|
pFloatCast->Set(rSCLY.ReadFloat());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eStringProperty: {
|
case eStringProperty: {
|
||||||
TStringProperty *pStringCast = static_cast<TStringProperty*>(pProp);
|
TStringProperty *pStringCast = static_cast<TStringProperty*>(pProp);
|
||||||
pStringCast->Set(SCLY.ReadString());
|
pStringCast->Set(rSCLY.ReadString());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eVector3Property: {
|
case eVector3Property: {
|
||||||
TVector3Property *pVector3Cast = static_cast<TVector3Property*>(pProp);
|
TVector3Property *pVector3Cast = static_cast<TVector3Property*>(pProp);
|
||||||
pVector3Cast->Set(CVector3f(SCLY));
|
pVector3Cast->Set(CVector3f(rSCLY));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eColorProperty: {
|
case eColorProperty: {
|
||||||
TColorProperty *pColorCast = static_cast<TColorProperty*>(pProp);
|
TColorProperty *pColorCast = static_cast<TColorProperty*>(pProp);
|
||||||
pColorCast->Set(CColor(SCLY));
|
pColorCast->Set(CColor(rSCLY));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eFileProperty: {
|
case eFileProperty: {
|
||||||
TFileProperty *pFileCast = static_cast<TFileProperty*>(pProp);
|
TFileProperty *pFileCast = static_cast<TFileProperty*>(pProp);
|
||||||
|
|
||||||
CUniqueID ResID = (mVersion < eCorruptionProto ? SCLY.ReadLong() : SCLY.ReadLongLong());
|
CUniqueID ResID = (mVersion < eCorruptionProto ? rSCLY.ReadLong() : rSCLY.ReadLongLong());
|
||||||
const TStringList& rkExtensions = static_cast<CFileTemplate*>(pTemp)->Extensions();
|
const TStringList& rkExtensions = static_cast<CFileTemplate*>(pTemp)->Extensions();
|
||||||
|
|
||||||
CResourceInfo Info(ResID, CFourCC(!rkExtensions.empty() ? rkExtensions.front() : "UNKN"));
|
CResourceInfo Info(ResID, CFourCC(!rkExtensions.empty() ? rkExtensions.front() : "UNKN"));
|
||||||
|
@ -118,38 +118,38 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(pProp);
|
CPropertyStruct *pStructCast = static_cast<CPropertyStruct*>(pProp);
|
||||||
|
|
||||||
if (mVersion < eEchoesDemo)
|
if (mVersion < eEchoesDemo)
|
||||||
LoadStructMP1(SCLY, pStructCast, static_cast<CStructTemplate*>(pStructCast->Template()));
|
LoadStructMP1(rSCLY, pStructCast, static_cast<CStructTemplate*>(pStructCast->Template()));
|
||||||
else
|
else
|
||||||
LoadStructMP2(SCLY, pStructCast, static_cast<CStructTemplate*>(pTemp));
|
LoadStructMP2(rSCLY, pStructCast, static_cast<CStructTemplate*>(pTemp));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eArrayProperty: {
|
case eArrayProperty: {
|
||||||
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
CArrayProperty *pArrayCast = static_cast<CArrayProperty*>(pProp);
|
||||||
int Size = SCLY.ReadLong();
|
int Count = rSCLY.ReadLong();
|
||||||
|
|
||||||
pArrayCast->Resize(Size);
|
pArrayCast->Resize(Count);
|
||||||
|
|
||||||
for (int iElem = 0; iElem < Size; iElem++)
|
for (int iElem = 0; iElem < Count; iElem++)
|
||||||
{
|
{
|
||||||
if (mVersion < eEchoesDemo)
|
if (mVersion < eEchoesDemo)
|
||||||
LoadStructMP1(SCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
LoadStructMP1(rSCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
||||||
else
|
else
|
||||||
LoadStructMP2(SCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
LoadStructMP2(rSCLY, static_cast<CPropertyStruct*>(pArrayCast->PropertyByIndex(iElem)), pArrayCast->SubStructTemplate());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eCharacterProperty: {
|
case eCharacterProperty: {
|
||||||
TCharacterProperty *pAnimCast = static_cast<TCharacterProperty*>(pProp);
|
TCharacterProperty *pAnimCast = static_cast<TCharacterProperty*>(pProp);
|
||||||
pAnimCast->Set(CAnimationParameters(SCLY, mVersion));
|
pAnimCast->Set(CAnimationParameters(rSCLY, mpMaster->GetGame()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case eMayaSplineProperty: {
|
case eMayaSplineProperty: {
|
||||||
TMayaSplineProperty *pSplineCast = static_cast<TMayaSplineProperty*>(pProp);
|
TMayaSplineProperty *pSplineCast = static_cast<TMayaSplineProperty*>(pProp);
|
||||||
std::vector<u8> Buffer(Size);
|
std::vector<u8> Buffer(Size);
|
||||||
SCLY.ReadBytes(Buffer.data(), Buffer.size());
|
rSCLY.ReadBytes(Buffer.data(), Buffer.size());
|
||||||
pSplineCast->Set(Buffer);
|
pSplineCast->Set(Buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -157,16 +157,16 @@ void CScriptLoader::ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY)
|
||||||
case eUnknownProperty: {
|
case eUnknownProperty: {
|
||||||
TUnknownProperty *pUnknownCast = static_cast<TUnknownProperty*>(pProp);
|
TUnknownProperty *pUnknownCast = static_cast<TUnknownProperty*>(pProp);
|
||||||
std::vector<u8> Buffer(Size);
|
std::vector<u8> Buffer(Size);
|
||||||
SCLY.ReadBytes(Buffer.data(), Buffer.size());
|
rSCLY.ReadBytes(Buffer.data(), Buffer.size());
|
||||||
pUnknownCast->Set(Buffer);
|
pUnknownCast->Set(Buffer);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptLoader::LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
|
void CScriptLoader::LoadStructMP1(IInputStream& rSCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
|
||||||
{
|
{
|
||||||
u32 StructStart = SCLY.Tell();
|
u32 StructStart = rSCLY.Tell();
|
||||||
|
|
||||||
// Verify property count
|
// Verify property count
|
||||||
u32 PropCount = pTemp->Count();
|
u32 PropCount = pTemp->Count();
|
||||||
|
@ -174,7 +174,7 @@ void CScriptLoader::LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct,
|
||||||
|
|
||||||
if (!pTemp->IsSingleProperty())
|
if (!pTemp->IsSingleProperty())
|
||||||
{
|
{
|
||||||
u32 FilePropCount = SCLY.ReadLong();
|
u32 FilePropCount = rSCLY.ReadLong();
|
||||||
Version = pTemp->VersionForPropertyCount(FilePropCount);
|
Version = pTemp->VersionForPropertyCount(FilePropCount);
|
||||||
|
|
||||||
if (Version == -1)
|
if (Version == -1)
|
||||||
|
@ -182,7 +182,7 @@ void CScriptLoader::LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct,
|
||||||
TIDString IDString = pTemp->IDString(true);
|
TIDString IDString = pTemp->IDString(true);
|
||||||
if (!IDString.IsEmpty()) IDString = " (" + IDString + ")";
|
if (!IDString.IsEmpty()) IDString = " (" + IDString + ")";
|
||||||
|
|
||||||
Log::FileWarning(SCLY.GetSourceString(), StructStart, "Struct \"" + pTemp->Name() + "\"" + IDString + " template prop count doesn't match file; template is " + TString::HexString(PropCount, true, true, 2) + ", file is " + TString::HexString(FilePropCount, true, true, 2));
|
Log::FileWarning(rSCLY.GetSourceString(), StructStart, "Struct \"" + pTemp->Name() + "\"" + IDString + " template prop count doesn't match file; template is " + TString::HexString(PropCount, true, true, 2) + ", file is " + TString::HexString(FilePropCount, true, true, 2));
|
||||||
Version = 0;
|
Version = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,38 +194,38 @@ void CScriptLoader::LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct,
|
||||||
IProperty *pProp = pStruct->PropertyByIndex(iProp);
|
IProperty *pProp = pStruct->PropertyByIndex(iProp);
|
||||||
|
|
||||||
if (pPropTemp->CookPreference() != eNeverCook && pPropTemp->IsInVersion(Version))
|
if (pPropTemp->CookPreference() != eNeverCook && pPropTemp->IsInVersion(Version))
|
||||||
ReadProperty(pProp, 0, SCLY);
|
ReadProperty(pProp, 0, rSCLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& SCLY)
|
CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
u32 ObjStart = SCLY.Tell();
|
u32 ObjStart = rSCLY.Tell();
|
||||||
u8 Type = SCLY.ReadByte();
|
u8 Type = rSCLY.ReadByte();
|
||||||
u32 Size = SCLY.ReadLong();
|
u32 Size = rSCLY.ReadLong();
|
||||||
u32 End = SCLY.Tell() + Size;
|
u32 End = rSCLY.Tell() + Size;
|
||||||
|
|
||||||
CScriptTemplate *pTemp = mpMaster->TemplateByID((u32) Type);
|
CScriptTemplate *pTemp = mpMaster->TemplateByID((u32) Type);
|
||||||
if (!pTemp)
|
if (!pTemp)
|
||||||
{
|
{
|
||||||
// No valid template for this object; can't load
|
// No valid template for this object; can't load
|
||||||
Log::FileError(SCLY.GetSourceString(), ObjStart, "Unknown object ID encountered: " + TString::HexString(Type));
|
Log::FileError(rSCLY.GetSourceString(), ObjStart, "Unknown object ID encountered: " + TString::HexString(Type));
|
||||||
SCLY.Seek(End, SEEK_SET);
|
rSCLY.Seek(End, SEEK_SET);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 InstanceID = SCLY.ReadLong();
|
u32 InstanceID = rSCLY.ReadLong();
|
||||||
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemp);
|
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemp);
|
||||||
|
|
||||||
// Load connections
|
// Load connections
|
||||||
u32 NumLinks = SCLY.ReadLong();
|
u32 NumLinks = rSCLY.ReadLong();
|
||||||
mpObj->mOutLinks.reserve(NumLinks);
|
mpObj->mOutLinks.reserve(NumLinks);
|
||||||
|
|
||||||
for (u32 iLink = 0; iLink < NumLinks; iLink++)
|
for (u32 iLink = 0; iLink < NumLinks; iLink++)
|
||||||
{
|
{
|
||||||
u32 State = SCLY.ReadLong();
|
u32 State = rSCLY.ReadLong();
|
||||||
u32 Message = SCLY.ReadLong();
|
u32 Message = rSCLY.ReadLong();
|
||||||
u32 ReceiverID = SCLY.ReadLong();
|
u32 ReceiverID = rSCLY.ReadLong();
|
||||||
|
|
||||||
CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID);
|
CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID);
|
||||||
mpObj->mOutLinks.push_back(pLink);
|
mpObj->mOutLinks.push_back(pLink);
|
||||||
|
@ -233,54 +233,54 @@ CScriptObject* CScriptLoader::LoadObjectMP1(IInputStream& SCLY)
|
||||||
|
|
||||||
// Load object...
|
// Load object...
|
||||||
CPropertyStruct *pBase = mpObj->mpProperties;
|
CPropertyStruct *pBase = mpObj->mpProperties;
|
||||||
LoadStructMP1(SCLY, pBase, static_cast<CStructTemplate*>(pBase->Template()));
|
LoadStructMP1(rSCLY, pBase, static_cast<CStructTemplate*>(pBase->Template()));
|
||||||
|
|
||||||
// Cleanup and return
|
// Cleanup and return
|
||||||
SCLY.Seek(End, SEEK_SET);
|
rSCLY.Seek(End, SEEK_SET);
|
||||||
|
|
||||||
mpObj->EvaluateProperties();
|
mpObj->EvaluateProperties();
|
||||||
return mpObj;
|
return mpObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream &SCLY)
|
CScriptLayer* CScriptLoader::LoadLayerMP1(IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
u32 LayerStart = SCLY.Tell();
|
u32 LayerStart = rSCLY.Tell();
|
||||||
|
|
||||||
SCLY.Seek(0x1, SEEK_CUR); // One unknown byte at the start of each layer
|
rSCLY.Seek(0x1, SEEK_CUR); // One unknown byte at the start of each layer
|
||||||
u32 NumObjects = SCLY.ReadLong();
|
u32 NumObjects = rSCLY.ReadLong();
|
||||||
|
|
||||||
mpLayer = new CScriptLayer(mpArea);
|
mpLayer = new CScriptLayer(mpArea);
|
||||||
mpLayer->Reserve(NumObjects);
|
mpLayer->Reserve(NumObjects);
|
||||||
|
|
||||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||||
{
|
{
|
||||||
CScriptObject *pObj = LoadObjectMP1(SCLY);
|
CScriptObject *pObj = LoadObjectMP1(rSCLY);
|
||||||
if (pObj)
|
if (pObj)
|
||||||
mpLayer->AddInstance(pObj);
|
mpLayer->AddInstance(pObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
// Layer sizes are always a multiple of 32 - skip end padding before returning
|
||||||
u32 Remaining = 32 - ((SCLY.Tell() - LayerStart) & 0x1F);
|
u32 Remaining = 32 - ((rSCLY.Tell() - LayerStart) & 0x1F);
|
||||||
SCLY.Seek(Remaining, SEEK_CUR);
|
rSCLY.Seek(Remaining, SEEK_CUR);
|
||||||
return mpLayer;
|
return mpLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CScriptLoader::LoadStructMP2(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
|
void CScriptLoader::LoadStructMP2(IInputStream& rSCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp)
|
||||||
{
|
{
|
||||||
// Verify property count
|
// Verify property count
|
||||||
u32 StructStart = SCLY.Tell();
|
u32 StructStart = rSCLY.Tell();
|
||||||
StructStart += 0;
|
StructStart += 0;
|
||||||
u32 PropCount = pTemp->Count();
|
u32 PropCount = pTemp->Count();
|
||||||
|
|
||||||
if (!pTemp->IsSingleProperty())
|
if (!pTemp->IsSingleProperty())
|
||||||
PropCount = SCLY.ReadShort();
|
PropCount = rSCLY.ReadShort();
|
||||||
|
|
||||||
// Parse properties
|
// Parse properties
|
||||||
for (u32 iProp = 0; iProp < PropCount; iProp++)
|
for (u32 iProp = 0; iProp < PropCount; iProp++)
|
||||||
{
|
{
|
||||||
IProperty *pProp;
|
IProperty *pProp;
|
||||||
IPropertyTemplate *pPropTemp;
|
IPropertyTemplate *pPropTemp;
|
||||||
u32 PropertyStart = SCLY.Tell();
|
u32 PropertyStart = rSCLY.Tell();
|
||||||
u32 PropertyID = -1;
|
u32 PropertyID = -1;
|
||||||
u16 PropertyLength = 0;
|
u16 PropertyLength = 0;
|
||||||
u32 NextProperty = 0;
|
u32 NextProperty = 0;
|
||||||
|
@ -292,79 +292,79 @@ void CScriptLoader::LoadStructMP2(IInputStream& SCLY, CPropertyStruct *pStruct,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PropertyID = SCLY.ReadLong();
|
PropertyID = rSCLY.ReadLong();
|
||||||
PropertyLength = SCLY.ReadShort();
|
PropertyLength = rSCLY.ReadShort();
|
||||||
NextProperty = SCLY.Tell() + PropertyLength;
|
NextProperty = rSCLY.Tell() + PropertyLength;
|
||||||
|
|
||||||
pProp = pStruct->PropertyByID(PropertyID);
|
pProp = pStruct->PropertyByID(PropertyID);
|
||||||
pPropTemp = pTemp->PropertyByID(PropertyID);
|
pPropTemp = pTemp->PropertyByID(PropertyID);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pPropTemp)
|
if (!pPropTemp)
|
||||||
Log::FileError(SCLY.GetSourceString(), PropertyStart, "Can't find template for property " + TString::HexString(PropertyID) + " - skipping");
|
Log::FileError(rSCLY.GetSourceString(), PropertyStart, "Can't find template for property " + TString::HexString(PropertyID) + " - skipping");
|
||||||
|
|
||||||
else
|
else
|
||||||
ReadProperty(pProp, PropertyLength, SCLY);
|
ReadProperty(pProp, PropertyLength, rSCLY);
|
||||||
|
|
||||||
if (NextProperty > 0)
|
if (NextProperty > 0)
|
||||||
SCLY.Seek(NextProperty, SEEK_SET);
|
rSCLY.Seek(NextProperty, SEEK_SET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& SCLY)
|
CScriptObject* CScriptLoader::LoadObjectMP2(IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
u32 ObjStart = SCLY.Tell();
|
u32 ObjStart = rSCLY.Tell();
|
||||||
u32 ObjectID = SCLY.ReadLong();
|
u32 ObjectID = rSCLY.ReadLong();
|
||||||
u16 ObjectSize = SCLY.ReadShort();
|
u16 ObjectSize = rSCLY.ReadShort();
|
||||||
u32 ObjEnd = SCLY.Tell() + ObjectSize;
|
u32 ObjEnd = rSCLY.Tell() + ObjectSize;
|
||||||
|
|
||||||
CScriptTemplate *pTemplate = mpMaster->TemplateByID(ObjectID);
|
CScriptTemplate *pTemplate = mpMaster->TemplateByID(ObjectID);
|
||||||
|
|
||||||
if (!pTemplate)
|
if (!pTemplate)
|
||||||
{
|
{
|
||||||
Log::FileError(SCLY.GetSourceString(), ObjStart, "Unknown object ID encountered: " + CFourCC(ObjectID).ToString());
|
Log::FileError(rSCLY.GetSourceString(), ObjStart, "Unknown object ID encountered: " + CFourCC(ObjectID).ToString());
|
||||||
SCLY.Seek(ObjEnd, SEEK_SET);
|
rSCLY.Seek(ObjEnd, SEEK_SET);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 InstanceID = SCLY.ReadLong();
|
u32 InstanceID = rSCLY.ReadLong();
|
||||||
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemplate);
|
mpObj = new CScriptObject(InstanceID, mpArea, mpLayer, pTemplate);
|
||||||
|
|
||||||
// Load connections
|
// Load connections
|
||||||
u32 NumConnections = SCLY.ReadShort();
|
u32 NumConnections = rSCLY.ReadShort();
|
||||||
mpObj->mOutLinks.reserve(NumConnections);
|
mpObj->mOutLinks.reserve(NumConnections);
|
||||||
|
|
||||||
for (u32 iCon = 0; iCon < NumConnections; iCon++)
|
for (u32 iCon = 0; iCon < NumConnections; iCon++)
|
||||||
{
|
{
|
||||||
u32 State = SCLY.ReadLong();
|
u32 State = rSCLY.ReadLong();
|
||||||
u32 Message = SCLY.ReadLong();
|
u32 Message = rSCLY.ReadLong();
|
||||||
u32 ReceiverID = SCLY.ReadLong();
|
u32 ReceiverID = rSCLY.ReadLong();
|
||||||
|
|
||||||
CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID);
|
CLink *pLink = new CLink(mpArea, State, Message, mpObj->mInstanceID, ReceiverID);
|
||||||
mpObj->mOutLinks.push_back(pLink);
|
mpObj->mOutLinks.push_back(pLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load object
|
// Load object
|
||||||
SCLY.Seek(0x6, SEEK_CUR); // Skip base struct ID + size
|
rSCLY.Seek(0x6, SEEK_CUR); // Skip base struct ID + size
|
||||||
LoadStructMP2(SCLY, mpObj->mpProperties, mpObj->mpTemplate->BaseStruct());
|
LoadStructMP2(rSCLY, mpObj->mpProperties, mpObj->mpTemplate->BaseStruct());
|
||||||
|
|
||||||
// Cleanup and return
|
// Cleanup and return
|
||||||
SCLY.Seek(ObjEnd, SEEK_SET);
|
rSCLY.Seek(ObjEnd, SEEK_SET);
|
||||||
mpObj->EvaluateProperties();
|
mpObj->EvaluateProperties();
|
||||||
return mpObj;
|
return mpObj;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& SCLY)
|
CScriptLayer* CScriptLoader::LoadLayerMP2(IInputStream& rSCLY)
|
||||||
{
|
{
|
||||||
SCLY.Seek(0x1, SEEK_CUR); // Skipping version. todo: verify this?
|
rSCLY.Seek(0x1, SEEK_CUR); // Skipping version. todo: verify this?
|
||||||
u32 NumObjects = SCLY.ReadLong();
|
u32 NumObjects = rSCLY.ReadLong();
|
||||||
|
|
||||||
mpLayer = new CScriptLayer(mpArea);
|
mpLayer = new CScriptLayer(mpArea);
|
||||||
mpLayer->Reserve(NumObjects);
|
mpLayer->Reserve(NumObjects);
|
||||||
|
|
||||||
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
for (u32 iObj = 0; iObj < NumObjects; iObj++)
|
||||||
{
|
{
|
||||||
CScriptObject *pObj = LoadObjectMP2(SCLY);
|
CScriptObject *pObj = LoadObjectMP2(rSCLY);
|
||||||
if (pObj)
|
if (pObj)
|
||||||
mpLayer->AddInstance(pObj);
|
mpLayer->AddInstance(pObj);
|
||||||
}
|
}
|
||||||
|
@ -396,3 +396,28 @@ CScriptLayer* CScriptLoader::LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EG
|
||||||
else
|
else
|
||||||
return Loader.LoadLayerMP2(rSCLY);
|
return Loader.LoadLayerMP2(rSCLY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CScriptObject* CScriptLoader::LoadInstance(IInputStream& rSCLY, CGameArea *pArea, CScriptLayer *pLayer, EGame Version, bool ForceReturnsFormat)
|
||||||
|
{
|
||||||
|
if (!rSCLY.IsValid()) return nullptr;
|
||||||
|
|
||||||
|
CScriptLoader Loader;
|
||||||
|
Loader.mVersion = (ForceReturnsFormat ? eReturns : Version);
|
||||||
|
Loader.mpMaster = CMasterTemplate::GetMasterForGame(Version);
|
||||||
|
Loader.mpArea = pArea;
|
||||||
|
Loader.mpLayer = pLayer;
|
||||||
|
|
||||||
|
if (!Loader.mpMaster)
|
||||||
|
{
|
||||||
|
Log::Write("This game doesn't have a master template; couldn't load script instance");
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Loader.mpMaster->IsLoadedSuccessfully())
|
||||||
|
CTemplateLoader::LoadGameTemplates(Version);
|
||||||
|
|
||||||
|
if (Loader.mVersion <= ePrime)
|
||||||
|
return Loader.LoadObjectMP1(rSCLY);
|
||||||
|
else
|
||||||
|
return Loader.LoadObjectMP2(rSCLY);
|
||||||
|
}
|
||||||
|
|
|
@ -16,18 +16,19 @@ class CScriptLoader
|
||||||
CMasterTemplate *mpMaster;
|
CMasterTemplate *mpMaster;
|
||||||
|
|
||||||
CScriptLoader();
|
CScriptLoader();
|
||||||
void ReadProperty(IProperty *pProp, u32 Size, IInputStream& SCLY);
|
void ReadProperty(IProperty *pProp, u32 Size, IInputStream& rSCLY);
|
||||||
|
|
||||||
void LoadStructMP1(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp);
|
void LoadStructMP1(IInputStream& rSCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp);
|
||||||
CScriptObject* LoadObjectMP1(IInputStream& SCLY);
|
CScriptObject* LoadObjectMP1(IInputStream& rSCLY);
|
||||||
CScriptLayer* LoadLayerMP1(IInputStream& SCLY);
|
CScriptLayer* LoadLayerMP1(IInputStream& rSCLY);
|
||||||
|
|
||||||
void LoadStructMP2(IInputStream& SCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp);
|
void LoadStructMP2(IInputStream& rSCLY, CPropertyStruct *pStruct, CStructTemplate *pTemp);
|
||||||
CScriptObject* LoadObjectMP2(IInputStream& SCLY);
|
CScriptObject* LoadObjectMP2(IInputStream& rSCLY);
|
||||||
CScriptLayer* LoadLayerMP2(IInputStream& SCLY);
|
CScriptLayer* LoadLayerMP2(IInputStream& rSCLY);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static CScriptLayer* LoadLayer(IInputStream& SCLY, CGameArea *pArea, EGame version);
|
static CScriptLayer* LoadLayer(IInputStream& rSCLY, CGameArea *pArea, EGame Version);
|
||||||
|
static CScriptObject* LoadInstance(IInputStream& rSCLY, CGameArea *pArea, CScriptLayer *pLayer,EGame Version, bool ForceReturnsFormat);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CSCRIPTLOADER_H
|
#endif // CSCRIPTLOADER_H
|
||||||
|
|
|
@ -15,7 +15,7 @@ CScriptObject::CScriptObject(u32 InstanceID, CGameArea *pArea, CScriptLayer *pLa
|
||||||
, mIsCheckingNearVisibleActivation(false)
|
, mIsCheckingNearVisibleActivation(false)
|
||||||
{
|
{
|
||||||
mpTemplate->AddObject(this);
|
mpTemplate->AddObject(this);
|
||||||
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty(nullptr);
|
mpProperties = (CPropertyStruct*) pTemplate->BaseStruct()->InstantiateProperty(this, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptObject::~CScriptObject()
|
CScriptObject::~CScriptObject()
|
||||||
|
@ -80,14 +80,16 @@ void CScriptObject::SetLayer(CScriptLayer *pLayer, u32 NewLayerIndex)
|
||||||
{
|
{
|
||||||
if (pLayer != mpLayer)
|
if (pLayer != mpLayer)
|
||||||
{
|
{
|
||||||
mpLayer->RemoveInstance(this);
|
if (mpLayer) mpLayer->RemoveInstance(this);
|
||||||
mpLayer = pLayer;
|
mpLayer = pLayer;
|
||||||
mpLayer->AddInstance(this, NewLayerIndex);
|
if (mpLayer) mpLayer->AddInstance(this, NewLayerIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CScriptObject::LayerIndex() const
|
u32 CScriptObject::LayerIndex() const
|
||||||
{
|
{
|
||||||
|
if (!mpLayer) return -1;
|
||||||
|
|
||||||
for (u32 iInst = 0; iInst < mpLayer->NumInstances(); iInst++)
|
for (u32 iInst = 0; iInst < mpLayer->NumInstances(); iInst++)
|
||||||
{
|
{
|
||||||
if (mpLayer->InstanceByIndex(iInst) == this)
|
if (mpLayer->InstanceByIndex(iInst) == this)
|
||||||
|
|
|
@ -32,13 +32,44 @@ TString IProperty::Name() const
|
||||||
|
|
||||||
u32 IProperty::ID() const
|
u32 IProperty::ID() const
|
||||||
{
|
{
|
||||||
return mpTemplate->PropertyID();
|
if (mpParent && mpParent->Type() == eArrayProperty)
|
||||||
|
return ArrayIndex();
|
||||||
|
else
|
||||||
|
return mpTemplate->PropertyID();
|
||||||
}
|
}
|
||||||
|
|
||||||
TIDString IProperty::IDString(bool FullPath) const
|
TIDString IProperty::IDString(bool FullPath) const
|
||||||
{
|
{
|
||||||
// todo: since this function just returns the template ID string, it doesn't correctly account for array properties;
|
TIDString Out;
|
||||||
return mpTemplate->IDString(FullPath);
|
|
||||||
|
if (ID() != 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
if (mpParent && FullPath)
|
||||||
|
{
|
||||||
|
Out = mpParent->IDString(true);
|
||||||
|
if (!Out.IsEmpty()) Out += ":";
|
||||||
|
}
|
||||||
|
|
||||||
|
Out += TString::HexString(ID(), true, true, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Out;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 IProperty::ArrayIndex() const
|
||||||
|
{
|
||||||
|
CArrayProperty *pArray = TPropCast<CArrayProperty>(mpParent);
|
||||||
|
|
||||||
|
if (pArray)
|
||||||
|
{
|
||||||
|
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
|
||||||
|
{
|
||||||
|
if (pArray->PropertyByIndex(iSub) == this)
|
||||||
|
return iSub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IProperty::ShouldCook()
|
bool IProperty::ShouldCook()
|
||||||
|
@ -74,7 +105,7 @@ void CPropertyStruct::Copy(const IProperty *pkProp)
|
||||||
mProperties.resize(pkSource->mProperties.size());
|
mProperties.resize(pkSource->mProperties.size());
|
||||||
|
|
||||||
for (u32 iSub = 0; iSub < mProperties.size(); iSub++)
|
for (u32 iSub = 0; iSub < mProperties.size(); iSub++)
|
||||||
mProperties[iSub] = pkSource->mProperties[iSub]->Clone(this);
|
mProperties[iSub] = pkSource->mProperties[iSub]->Clone(Instance(), this);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPropertyStruct::ShouldCook()
|
bool CPropertyStruct::ShouldCook()
|
||||||
|
@ -138,7 +169,7 @@ CPropertyStruct* CPropertyStruct::StructByIndex(u32 index) const
|
||||||
{
|
{
|
||||||
IProperty *pProp = PropertyByIndex(index);
|
IProperty *pProp = PropertyByIndex(index);
|
||||||
|
|
||||||
if (pProp->Type() == eStructProperty)
|
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
|
||||||
return static_cast<CPropertyStruct*>(pProp);
|
return static_cast<CPropertyStruct*>(pProp);
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -148,7 +179,7 @@ CPropertyStruct* CPropertyStruct::StructByID(u32 ID) const
|
||||||
{
|
{
|
||||||
IProperty *pProp = PropertyByID(ID);
|
IProperty *pProp = PropertyByID(ID);
|
||||||
|
|
||||||
if (pProp->Type() == eStructProperty)
|
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
|
||||||
return static_cast<CPropertyStruct*>(pProp);
|
return static_cast<CPropertyStruct*>(pProp);
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -158,7 +189,7 @@ CPropertyStruct* CPropertyStruct::StructByIDString(const TIDString& rkStr) const
|
||||||
{
|
{
|
||||||
IProperty *pProp = PropertyByIDString(rkStr);
|
IProperty *pProp = PropertyByIDString(rkStr);
|
||||||
|
|
||||||
if (pProp->Type() == eStructProperty)
|
if (pProp->Type() == eStructProperty || pProp->Type() == eArrayProperty)
|
||||||
return static_cast<CPropertyStruct*>(pProp);
|
return static_cast<CPropertyStruct*>(pProp);
|
||||||
else
|
else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -186,7 +217,7 @@ void CArrayProperty::Resize(int Size)
|
||||||
if (Size > OldSize)
|
if (Size > OldSize)
|
||||||
{
|
{
|
||||||
for (int iProp = OldSize; iProp < Size; iProp++)
|
for (int iProp = OldSize; iProp < Size; iProp++)
|
||||||
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(this);
|
mProperties[iProp] = static_cast<CArrayTemplate*>(mpTemplate)->CreateSubStruct(Instance(), this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <Math/CVector3f.h>
|
#include <Math/CVector3f.h>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
|
class CScriptObject;
|
||||||
class CScriptTemplate;
|
class CScriptTemplate;
|
||||||
class CStructTemplate;
|
class CStructTemplate;
|
||||||
class IPropertyTemplate;
|
class IPropertyTemplate;
|
||||||
|
@ -28,11 +29,13 @@ class IProperty
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class CPropertyStruct *mpParent;
|
class CPropertyStruct *mpParent;
|
||||||
|
CScriptObject *mpInstance;
|
||||||
IPropertyTemplate *mpTemplate;
|
IPropertyTemplate *mpTemplate;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
|
IProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
: mpParent(pParent)
|
: mpParent(pParent)
|
||||||
|
, mpInstance(pInstance)
|
||||||
, mpTemplate(pTemp)
|
, mpTemplate(pTemp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -42,12 +45,13 @@ public:
|
||||||
virtual TString ToString() const { return ""; }
|
virtual TString ToString() const { return ""; }
|
||||||
virtual IPropertyValue* RawValue() { return nullptr; }
|
virtual IPropertyValue* RawValue() { return nullptr; }
|
||||||
virtual void Copy(const IProperty *pkProp) = 0;
|
virtual void Copy(const IProperty *pkProp) = 0;
|
||||||
virtual IProperty* Clone(CPropertyStruct *pParent = 0) const = 0;
|
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent = 0) const = 0;
|
||||||
virtual bool Matches(const IProperty *pkProp) const = 0;
|
virtual bool Matches(const IProperty *pkProp) const = 0;
|
||||||
|
|
||||||
virtual bool ShouldCook(); // Can't be const because it calls MatchesDefault()
|
virtual bool ShouldCook(); // Can't be const because it calls MatchesDefault()
|
||||||
virtual bool MatchesDefault(); // Can't be const because RawValue() isn't const
|
virtual bool MatchesDefault(); // Can't be const because RawValue() isn't const
|
||||||
|
|
||||||
|
inline CScriptObject* Instance() const { return mpInstance; }
|
||||||
inline CPropertyStruct* Parent() const { return mpParent; }
|
inline CPropertyStruct* Parent() const { return mpParent; }
|
||||||
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
|
inline void SetParent(CPropertyStruct *pParent) { mpParent = pParent; }
|
||||||
|
|
||||||
|
@ -59,6 +63,7 @@ public:
|
||||||
TString Name() const;
|
TString Name() const;
|
||||||
u32 ID() const;
|
u32 ID() const;
|
||||||
TIDString IDString(bool FullPath) const;
|
TIDString IDString(bool FullPath) const;
|
||||||
|
u32 ArrayIndex() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -70,11 +75,11 @@ class TTypedProperty : public IProperty
|
||||||
friend class CScriptLoader;
|
friend class CScriptLoader;
|
||||||
ValueClass mValue;
|
ValueClass mValue;
|
||||||
public:
|
public:
|
||||||
TTypedProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
|
TTypedProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
: IProperty(pTemp, pParent) {}
|
: IProperty(pTemp, pInstance, pParent) {}
|
||||||
|
|
||||||
TTypedProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent, ValueType v)
|
TTypedProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, ValueType v)
|
||||||
: IProperty(pTemp, pParent), mValue(v) {}
|
: IProperty(pTemp, pInstance, pParent), mValue(v) {}
|
||||||
|
|
||||||
~TTypedProperty() {}
|
~TTypedProperty() {}
|
||||||
virtual EPropertyType Type() const { return TypeEnum; }
|
virtual EPropertyType Type() const { return TypeEnum; }
|
||||||
|
@ -89,11 +94,11 @@ public:
|
||||||
mValue.Set(pkCast->mValue.Get());
|
mValue.Set(pkCast->mValue.Get());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual TTypedProperty* Clone(CPropertyStruct *pParent) const
|
virtual TTypedProperty* Clone(class CScriptObject *pInstance, CPropertyStruct *pParent) const
|
||||||
{
|
{
|
||||||
if (!pParent) pParent = mpParent;
|
if (!pParent) pParent = mpParent;
|
||||||
|
|
||||||
TTypedProperty *pOut = new TTypedProperty(mpTemplate, pParent);
|
TTypedProperty *pOut = new TTypedProperty(mpTemplate, pInstance, pParent);
|
||||||
pOut->Copy(this);
|
pOut->Copy(this);
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
@ -123,11 +128,11 @@ typedef TTypedProperty<std::vector<u8>, eUnknownProperty, CUnknownValue>
|
||||||
* TStringProperty, TFileProperty, and TCharacterProperty get little subclasses in order to override some virtual functions.
|
* TStringProperty, TFileProperty, and TCharacterProperty get little subclasses in order to override some virtual functions.
|
||||||
*/
|
*/
|
||||||
#define IMPLEMENT_PROPERTY_CTORS(ClassName, ValueType) \
|
#define IMPLEMENT_PROPERTY_CTORS(ClassName, ValueType) \
|
||||||
ClassName(IPropertyTemplate *pTemp, CPropertyStruct *pParent) \
|
ClassName(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent) \
|
||||||
: TTypedProperty(pTemp, pParent) {} \
|
: TTypedProperty(pTemp, pInstance, pParent) {} \
|
||||||
\
|
\
|
||||||
ClassName(IPropertyTemplate *pTemp, CPropertyStruct *pParent, ValueType v) \
|
ClassName(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent, ValueType v) \
|
||||||
: TTypedProperty(pTemp, pParent, v) {}
|
: TTypedProperty(pTemp, pInstance, pParent, v) {}
|
||||||
|
|
||||||
class TStringProperty : public TTypedProperty<TString, eStringProperty, CStringValue>
|
class TStringProperty : public TTypedProperty<TString, eStringProperty, CStringValue>
|
||||||
{
|
{
|
||||||
|
@ -169,8 +174,8 @@ class CPropertyStruct : public IProperty
|
||||||
protected:
|
protected:
|
||||||
std::vector<IProperty*> mProperties;
|
std::vector<IProperty*> mProperties;
|
||||||
public:
|
public:
|
||||||
CPropertyStruct(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
|
CPropertyStruct(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
: IProperty(pTemp, pParent) {}
|
: IProperty(pTemp, pInstance, pParent) {}
|
||||||
|
|
||||||
~CPropertyStruct()
|
~CPropertyStruct()
|
||||||
{
|
{
|
||||||
|
@ -183,10 +188,10 @@ public:
|
||||||
|
|
||||||
virtual void Copy(const IProperty *pkProp);
|
virtual void Copy(const IProperty *pkProp);
|
||||||
|
|
||||||
virtual IProperty* Clone(CPropertyStruct *pParent) const
|
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const
|
||||||
{
|
{
|
||||||
if (!pParent) pParent = mpParent;
|
if (!pParent) pParent = mpParent;
|
||||||
CPropertyStruct *pOut = new CPropertyStruct(mpTemplate, pParent);
|
CPropertyStruct *pOut = new CPropertyStruct(mpTemplate, pInstance, pParent);
|
||||||
pOut->Copy(this);
|
pOut->Copy(this);
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
@ -245,16 +250,16 @@ class CArrayProperty : public CPropertyStruct
|
||||||
friend class CScriptLoader;
|
friend class CScriptLoader;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CArrayProperty(IPropertyTemplate *pTemp, CPropertyStruct *pParent)
|
CArrayProperty(IPropertyTemplate *pTemp, CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
: CPropertyStruct(pTemp, pParent) {}
|
: CPropertyStruct(pTemp, pInstance, pParent) {}
|
||||||
|
|
||||||
EPropertyType Type() const { return eArrayProperty; }
|
EPropertyType Type() const { return eArrayProperty; }
|
||||||
static inline EPropertyType StaticType() { return eArrayProperty; }
|
static inline EPropertyType StaticType() { return eArrayProperty; }
|
||||||
|
|
||||||
virtual IProperty* Clone(CPropertyStruct *pParent) const
|
virtual IProperty* Clone(CScriptObject *pInstance, CPropertyStruct *pParent) const
|
||||||
{
|
{
|
||||||
if (!pParent) pParent = mpParent;
|
if (!pParent) pParent = mpParent;
|
||||||
CArrayProperty *pOut = new CArrayProperty(mpTemplate, pParent);
|
CArrayProperty *pOut = new CArrayProperty(mpTemplate, pInstance, pParent);
|
||||||
pOut->Copy(this);
|
pOut->Copy(this);
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public:
|
||||||
virtual EPropertyType Type() const = 0;
|
virtual EPropertyType Type() const = 0;
|
||||||
virtual bool CanHaveDefault() const = 0;
|
virtual bool CanHaveDefault() const = 0;
|
||||||
virtual bool IsNumerical() const = 0;
|
virtual bool IsNumerical() const = 0;
|
||||||
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent) = 0;
|
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent) = 0;
|
||||||
virtual IPropertyTemplate* Clone(CScriptTemplate *pScript, CStructTemplate *pParent = 0) const = 0;
|
virtual IPropertyTemplate* Clone(CScriptTemplate *pScript, CStructTemplate *pParent = 0) const = 0;
|
||||||
|
|
||||||
virtual void Copy(const IPropertyTemplate *pkTemp)
|
virtual void Copy(const IPropertyTemplate *pkTemp)
|
||||||
|
@ -164,10 +164,10 @@ public:
|
||||||
virtual bool CanHaveDefault() const { return CanHaveDefaultValue; }
|
virtual bool CanHaveDefault() const { return CanHaveDefaultValue; }
|
||||||
virtual bool IsNumerical() const { return false; }
|
virtual bool IsNumerical() const { return false; }
|
||||||
|
|
||||||
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
|
typedef TTypedProperty<PropType, PropTypeEnum, ValueClass> TPropertyType;
|
||||||
TPropertyType *pOut = new TPropertyType(this, pParent, GetDefaultValue());
|
TPropertyType *pOut = new TPropertyType(this, pInstance, pParent, GetDefaultValue());
|
||||||
return pOut;
|
return pOut;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -321,9 +321,9 @@ public:
|
||||||
TCharacterTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
TCharacterTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
||||||
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
|
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
|
||||||
|
|
||||||
IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
return new TCharacterProperty(this, pParent, CAnimationParameters(Game()));
|
return new TCharacterProperty(this, pInstance, pParent, CAnimationParameters(Game()));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -339,9 +339,9 @@ public:
|
||||||
TStringTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
TStringTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
||||||
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
|
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
|
||||||
|
|
||||||
IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
return new TStringProperty(this, pParent);
|
return new TStringProperty(this, pInstance, pParent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -357,9 +357,9 @@ public:
|
||||||
TMayaSplineTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
TMayaSplineTemplate(u32 ID, const TString& rkName, ECookPreference CookPreference, CScriptTemplate *pScript, CMasterTemplate *pMaster, CStructTemplate *pParent = 0)
|
||||||
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
|
: TTypedPropertyTemplate(ID, rkName, CookPreference, pScript, pMaster, pParent) {}
|
||||||
|
|
||||||
IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
return new TMayaSplineProperty(this, pParent);
|
return new TMayaSplineProperty(this, pInstance, pParent);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -382,9 +382,9 @@ public:
|
||||||
virtual bool CanHaveDefault() const { return false; }
|
virtual bool CanHaveDefault() const { return false; }
|
||||||
virtual bool IsNumerical() const { return false; }
|
virtual bool IsNumerical() const { return false; }
|
||||||
|
|
||||||
IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
return new TFileProperty(this, pParent);
|
return new TFileProperty(this, pInstance, pParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_TEMPLATE_CLONE(CFileTemplate)
|
IMPLEMENT_TEMPLATE_CLONE(CFileTemplate)
|
||||||
|
@ -451,9 +451,9 @@ public:
|
||||||
virtual bool CanHaveDefault() const { return true; }
|
virtual bool CanHaveDefault() const { return true; }
|
||||||
virtual bool IsNumerical() const { return false; }
|
virtual bool IsNumerical() const { return false; }
|
||||||
|
|
||||||
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
TEnumProperty *pEnum = new TEnumProperty(this, pParent);
|
TEnumProperty *pEnum = new TEnumProperty(this, pInstance, pParent);
|
||||||
pEnum->Set(GetDefaultValue());
|
pEnum->Set(GetDefaultValue());
|
||||||
return pEnum;
|
return pEnum;
|
||||||
}
|
}
|
||||||
|
@ -546,9 +546,9 @@ public:
|
||||||
virtual bool CanHaveDefault() const { return true; }
|
virtual bool CanHaveDefault() const { return true; }
|
||||||
virtual bool IsNumerical() const { return false; }
|
virtual bool IsNumerical() const { return false; }
|
||||||
|
|
||||||
virtual IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
virtual IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
TBitfieldProperty *pBitfield = new TBitfieldProperty(this, pParent);
|
TBitfieldProperty *pBitfield = new TBitfieldProperty(this, pInstance, pParent);
|
||||||
pBitfield->Set(GetDefaultValue());
|
pBitfield->Set(GetDefaultValue());
|
||||||
return pBitfield;
|
return pBitfield;
|
||||||
}
|
}
|
||||||
|
@ -611,13 +611,13 @@ public:
|
||||||
bool CanHaveDefault() const { return false; }
|
bool CanHaveDefault() const { return false; }
|
||||||
bool IsNumerical() const { return false; }
|
bool IsNumerical() const { return false; }
|
||||||
|
|
||||||
IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
CPropertyStruct *pStruct = new CPropertyStruct(this, pParent);
|
CPropertyStruct *pStruct = new CPropertyStruct(this, pInstance, pParent);
|
||||||
|
|
||||||
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
|
for (u32 iSub = 0; iSub < mSubProperties.size(); iSub++)
|
||||||
{
|
{
|
||||||
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty(pStruct);
|
IProperty *pSubProp = mSubProperties[iSub]->InstantiateProperty(pInstance, pStruct);
|
||||||
pStruct->AddSubProperty(pSubProp);
|
pStruct->AddSubProperty(pSubProp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -708,9 +708,9 @@ public:
|
||||||
|
|
||||||
EPropertyType Type() const { return eArrayProperty; }
|
EPropertyType Type() const { return eArrayProperty; }
|
||||||
|
|
||||||
IProperty* InstantiateProperty(CPropertyStruct *pParent)
|
IProperty* InstantiateProperty(CScriptObject *pInstance, CPropertyStruct *pParent)
|
||||||
{
|
{
|
||||||
return new CArrayProperty(this, pParent);
|
return new CArrayProperty(this, pInstance, pParent);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMPLEMENT_TEMPLATE_CLONE(CArrayTemplate)
|
IMPLEMENT_TEMPLATE_CLONE(CArrayTemplate)
|
||||||
|
@ -740,9 +740,9 @@ public:
|
||||||
TString ElementName() const { return mElementName; }
|
TString ElementName() const { return mElementName; }
|
||||||
void SetElementName(const TString& rkName) { mElementName = rkName; }
|
void SetElementName(const TString& rkName) { mElementName = rkName; }
|
||||||
|
|
||||||
CPropertyStruct* CreateSubStruct(CArrayProperty *pArray)
|
CPropertyStruct* CreateSubStruct(CScriptObject *pInstance, CArrayProperty *pArray)
|
||||||
{
|
{
|
||||||
return (CPropertyStruct*) CStructTemplate::InstantiateProperty(pArray);
|
return (CPropertyStruct*) CStructTemplate::InstantiateProperty(pInstance, pArray);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include "Core/Render/CGraphics.h"
|
#include "Core/Render/CGraphics.h"
|
||||||
#include "Core/Render/CRenderer.h"
|
#include "Core/Render/CRenderer.h"
|
||||||
|
|
||||||
CCollisionNode::CCollisionNode(CScene *pScene, CSceneNode *pParent, CCollisionMeshGroup *pCollision)
|
CCollisionNode::CCollisionNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CCollisionMeshGroup *pCollision)
|
||||||
: CSceneNode(pScene, pParent)
|
: CSceneNode(pScene, NodeID, pParent)
|
||||||
{
|
{
|
||||||
SetCollision(pCollision);
|
SetCollision(pCollision);
|
||||||
SetName("Collision");
|
SetName("Collision");
|
||||||
|
|
|
@ -9,7 +9,7 @@ class CCollisionNode : public CSceneNode
|
||||||
TResPtr<CCollisionMeshGroup> mpCollision;
|
TResPtr<CCollisionMeshGroup> mpCollision;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCollisionNode(CScene *pScene, CSceneNode *pParent = 0, CCollisionMeshGroup *pCollision = 0);
|
CCollisionNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0, CCollisionMeshGroup *pCollision = 0);
|
||||||
ENodeType NodeType();
|
ENodeType NodeType();
|
||||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#include "Core/Render/CRenderer.h"
|
#include "Core/Render/CRenderer.h"
|
||||||
#include <Math/MathUtil.h>
|
#include <Math/MathUtil.h>
|
||||||
|
|
||||||
CLightNode::CLightNode(CScene *pScene, CSceneNode *pParent, CLight *Light)
|
CLightNode::CLightNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CLight *Light)
|
||||||
: CSceneNode(pScene, pParent)
|
: CSceneNode(pScene, NodeID, pParent)
|
||||||
{
|
{
|
||||||
mpLight = Light;
|
mpLight = Light;
|
||||||
mLocalAABox = CAABox::skOne;
|
mLocalAABox = CAABox::skOne;
|
||||||
|
|
|
@ -8,7 +8,7 @@ class CLightNode : public CSceneNode
|
||||||
{
|
{
|
||||||
CLight *mpLight;
|
CLight *mpLight;
|
||||||
public:
|
public:
|
||||||
CLightNode(CScene *pScene, CSceneNode *pParent = 0, CLight *Light = 0);
|
CLightNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0, CLight *Light = 0);
|
||||||
ENodeType NodeType();
|
ENodeType NodeType();
|
||||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
void Draw(FRenderOptions Options, int ComponentIndex, const SViewInfo& ViewInfo);
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
#include "Core/Render/CGraphics.h"
|
#include "Core/Render/CGraphics.h"
|
||||||
#include <Math/MathUtil.h>
|
#include <Math/MathUtil.h>
|
||||||
|
|
||||||
CModelNode::CModelNode(CScene *pScene, CSceneNode *pParent, CModel *pModel) : CSceneNode(pScene, pParent)
|
CModelNode::CModelNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CModel *pModel)
|
||||||
|
: CSceneNode(pScene, NodeID, pParent)
|
||||||
{
|
{
|
||||||
SetModel(pModel);
|
SetModel(pModel);
|
||||||
mScale = CVector3f(1.f);
|
mScale = CVector3f(1.f);
|
||||||
|
|
|
@ -15,7 +15,7 @@ class CModelNode : public CSceneNode
|
||||||
CColor mScanOverlayColor;
|
CColor mScanOverlayColor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CModelNode(CScene *pScene, CSceneNode *pParent = 0, CModel *pModel = 0);
|
explicit CModelNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0, CModel *pModel = 0);
|
||||||
|
|
||||||
virtual ENodeType NodeType();
|
virtual ENodeType NodeType();
|
||||||
virtual void PostLoad();
|
virtual void PostLoad();
|
||||||
|
|
|
@ -8,7 +8,8 @@
|
||||||
class CRootNode : public CSceneNode
|
class CRootNode : public CSceneNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit CRootNode(CScene *pScene, CSceneNode *pParent = 0) : CSceneNode(pScene, pParent) {}
|
explicit CRootNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0)
|
||||||
|
: CSceneNode(pScene, NodeID, pParent) {}
|
||||||
~CRootNode() {}
|
~CRootNode() {}
|
||||||
|
|
||||||
ENodeType NodeType() {
|
ENodeType NodeType() {
|
||||||
|
|
|
@ -17,7 +17,7 @@ CScene::CScene()
|
||||||
: mSplitTerrain(true)
|
: mSplitTerrain(true)
|
||||||
, mRanPostLoad(false)
|
, mRanPostLoad(false)
|
||||||
, mNumNodes(0)
|
, mNumNodes(0)
|
||||||
, mpSceneRootNode(new CRootNode(this, nullptr))
|
, mpSceneRootNode(new CRootNode(this, -1, nullptr))
|
||||||
, mpArea(nullptr)
|
, mpArea(nullptr)
|
||||||
, mpWorld(nullptr)
|
, mpWorld(nullptr)
|
||||||
, mpAreaRootNode(nullptr)
|
, mpAreaRootNode(nullptr)
|
||||||
|
@ -29,43 +29,76 @@ CScene::~CScene()
|
||||||
ClearScene();
|
ClearScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
CModelNode* CScene::CreateModelNode(CModel *pModel)
|
bool CScene::IsNodeIDUsed(u32 ID) const
|
||||||
|
{
|
||||||
|
return (mNodeMap.find(ID) != mNodeMap.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CScene::CreateNodeID(u32 SuggestedID /*= -1*/) const
|
||||||
|
{
|
||||||
|
if (SuggestedID != -1)
|
||||||
|
{
|
||||||
|
if (IsNodeIDUsed(SuggestedID))
|
||||||
|
Log::Error("Suggested node ID is already being used! New ID will be created.");
|
||||||
|
else
|
||||||
|
return SuggestedID;
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 ID = 0;
|
||||||
|
|
||||||
|
while (IsNodeIDUsed(ID))
|
||||||
|
ID++;
|
||||||
|
|
||||||
|
return ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
CModelNode* CScene::CreateModelNode(CModel *pModel, u32 NodeID /*= -1*/)
|
||||||
{
|
{
|
||||||
if (pModel == nullptr) return nullptr;
|
if (pModel == nullptr) return nullptr;
|
||||||
|
|
||||||
CModelNode *pNode = new CModelNode(this, mpAreaRootNode, pModel);
|
u32 ID = CreateNodeID(NodeID);
|
||||||
|
CModelNode *pNode = new CModelNode(this, ID, mpAreaRootNode, pModel);
|
||||||
mNodes[eModelNode].push_back(pNode);
|
mNodes[eModelNode].push_back(pNode);
|
||||||
|
mNodeMap[ID] = pNode;
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CStaticNode* CScene::CreateStaticNode(CStaticModel *pModel)
|
CStaticNode* CScene::CreateStaticNode(CStaticModel *pModel, u32 NodeID /*= -1*/)
|
||||||
{
|
{
|
||||||
if (pModel == nullptr) return nullptr;
|
if (pModel == nullptr) return nullptr;
|
||||||
|
|
||||||
CStaticNode *pNode = new CStaticNode(this, mpAreaRootNode, pModel);
|
u32 ID = CreateNodeID(NodeID);
|
||||||
|
CStaticNode *pNode = new CStaticNode(this, ID, mpAreaRootNode, pModel);
|
||||||
mNodes[eStaticNode].push_back(pNode);
|
mNodes[eStaticNode].push_back(pNode);
|
||||||
|
mNodeMap[ID] = pNode;
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CCollisionNode* CScene::CreateCollisionNode(CCollisionMeshGroup *pMesh)
|
CCollisionNode* CScene::CreateCollisionNode(CCollisionMeshGroup *pMesh, u32 NodeID /*= -1*/)
|
||||||
{
|
{
|
||||||
if (pMesh == nullptr) return nullptr;
|
if (pMesh == nullptr) return nullptr;
|
||||||
|
|
||||||
CCollisionNode *pNode = new CCollisionNode(this, mpAreaRootNode, pMesh);
|
u32 ID = CreateNodeID(NodeID);
|
||||||
|
CCollisionNode *pNode = new CCollisionNode(this, ID, mpAreaRootNode, pMesh);
|
||||||
mNodes[eCollisionNode].push_back(pNode);
|
mNodes[eCollisionNode].push_back(pNode);
|
||||||
|
mNodeMap[ID] = pNode;
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj)
|
CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj, u32 NodeID /*= -1*/)
|
||||||
{
|
{
|
||||||
if (pObj == nullptr) return nullptr;
|
if (pObj == nullptr) return nullptr;
|
||||||
|
|
||||||
CScriptNode *pNode = new CScriptNode(this, mpAreaRootNode, pObj);
|
u32 ID = CreateNodeID(NodeID);
|
||||||
|
u32 InstanceID = pObj->InstanceID();
|
||||||
|
|
||||||
|
CScriptNode *pNode = new CScriptNode(this, ID, mpAreaRootNode, pObj);
|
||||||
mNodes[eScriptNode].push_back(pNode);
|
mNodes[eScriptNode].push_back(pNode);
|
||||||
mScriptNodeMap[pObj->InstanceID()] = pNode;
|
mNodeMap[ID] = pNode;
|
||||||
|
mScriptMap[InstanceID] = pNode;
|
||||||
pNode->BuildLightList(mpArea);
|
pNode->BuildLightList(mpArea);
|
||||||
|
|
||||||
// AreaAttributes check
|
// AreaAttributes check
|
||||||
|
@ -81,12 +114,14 @@ CScriptNode* CScene::CreateScriptNode(CScriptObject *pObj)
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
CLightNode* CScene::CreateLightNode(CLight *pLight)
|
CLightNode* CScene::CreateLightNode(CLight *pLight, u32 NodeID /*= -1*/)
|
||||||
{
|
{
|
||||||
if (pLight == nullptr) return nullptr;
|
if (pLight == nullptr) return nullptr;
|
||||||
|
|
||||||
CLightNode *pNode = new CLightNode(this, mpAreaRootNode, pLight);
|
u32 ID = CreateNodeID(NodeID);
|
||||||
|
CLightNode *pNode = new CLightNode(this, ID, mpAreaRootNode, pLight);
|
||||||
mNodes[eLightNode].push_back(pNode);
|
mNodes[eLightNode].push_back(pNode);
|
||||||
|
mNodeMap[ID] = pNode;
|
||||||
mNumNodes++;
|
mNumNodes++;
|
||||||
return pNode;
|
return pNode;
|
||||||
}
|
}
|
||||||
|
@ -104,13 +139,17 @@ void CScene::DeleteNode(CSceneNode *pNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto MapIt = mNodeMap.find(pNode->ID());
|
||||||
|
if (MapIt != mNodeMap.end())
|
||||||
|
mNodeMap.erase(MapIt);
|
||||||
|
|
||||||
if (Type == eScriptNode)
|
if (Type == eScriptNode)
|
||||||
{
|
{
|
||||||
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
|
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
|
||||||
|
|
||||||
auto ScriptMapIt = mScriptNodeMap.find(pScript->Object()->InstanceID());
|
auto it = mScriptMap.find(pScript->Object()->InstanceID());
|
||||||
if (ScriptMapIt != mScriptNodeMap.end())
|
if (it != mScriptMap.end())
|
||||||
mScriptNodeMap.erase(ScriptMapIt);
|
mScriptMap.erase(it);
|
||||||
|
|
||||||
switch (pScript->Object()->ObjectTypeID())
|
switch (pScript->Object()->ObjectTypeID())
|
||||||
{
|
{
|
||||||
|
@ -140,7 +179,7 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||||
|
|
||||||
// Create nodes for new area
|
// Create nodes for new area
|
||||||
mpArea = pArea;
|
mpArea = pArea;
|
||||||
mpAreaRootNode = new CRootNode(this, mpSceneRootNode);
|
mpAreaRootNode = new CRootNode(this, -1, mpSceneRootNode);
|
||||||
|
|
||||||
// Create static nodes
|
// Create static nodes
|
||||||
u32 Count = mpArea->GetStaticModelCount();
|
u32 Count = mpArea->GetStaticModelCount();
|
||||||
|
@ -190,10 +229,11 @@ void CScene::SetActiveArea(CGameArea *pArea)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure script nodes have valid positions + build light lists
|
// Ensure script nodes have valid positions + build light lists
|
||||||
for (auto it = mScriptNodeMap.begin(); it != mScriptNodeMap.end(); it++)
|
for (CSceneIterator It(this, eScriptNode, true); It; ++It)
|
||||||
{
|
{
|
||||||
it->second->GeneratePosition();
|
CScriptNode *pScript = static_cast<CScriptNode*>(*It);
|
||||||
it->second->BuildLightList(mpArea);
|
pScript->GeneratePosition();
|
||||||
|
pScript->BuildLightList(mpArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 NumLightLayers = mpArea->GetLightLayerCount();
|
u32 NumLightLayers = mpArea->GetLightLayerCount();
|
||||||
|
@ -239,7 +279,7 @@ void CScene::ClearScene()
|
||||||
|
|
||||||
mNodes.clear();
|
mNodes.clear();
|
||||||
mAreaAttributesObjects.clear();
|
mAreaAttributesObjects.clear();
|
||||||
mScriptNodeMap.clear();
|
mNodeMap.clear();
|
||||||
mNumNodes = 0;
|
mNumNodes = 0;
|
||||||
|
|
||||||
mpArea = nullptr;
|
mpArea = nullptr;
|
||||||
|
@ -277,17 +317,25 @@ SRayIntersection CScene::SceneRayCast(const CRay& Ray, const SViewInfo& ViewInfo
|
||||||
return Tester.TestNodes(ViewInfo);
|
return Tester.TestNodes(ViewInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptNode* CScene::ScriptNodeByID(u32 InstanceID)
|
CSceneNode* CScene::NodeByID(u32 NodeID)
|
||||||
{
|
{
|
||||||
auto it = mScriptNodeMap.find(InstanceID);
|
auto it = mNodeMap.find(NodeID);
|
||||||
|
|
||||||
if (it != mScriptNodeMap.end()) return it->second;
|
if (it != mNodeMap.end()) return it->second;
|
||||||
|
else return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
CScriptNode* CScene::NodeForInstanceID(u32 InstanceID)
|
||||||
|
{
|
||||||
|
auto it = mScriptMap.find(InstanceID);
|
||||||
|
|
||||||
|
if (it != mScriptMap.end()) return it->second;
|
||||||
else return nullptr;
|
else return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
CScriptNode* CScene::NodeForObject(CScriptObject *pObj)
|
CScriptNode* CScene::NodeForObject(CScriptObject *pObj)
|
||||||
{
|
{
|
||||||
return ScriptNodeByID(pObj->InstanceID());
|
return NodeForInstanceID(pObj->InstanceID());
|
||||||
}
|
}
|
||||||
|
|
||||||
CLightNode* CScene::NodeForLight(CLight *pLight)
|
CLightNode* CScene::NodeForLight(CLight *pLight)
|
||||||
|
|
|
@ -38,19 +38,23 @@ class CScene
|
||||||
// Environment
|
// Environment
|
||||||
std::vector<CAreaAttributes> mAreaAttributesObjects;
|
std::vector<CAreaAttributes> mAreaAttributesObjects;
|
||||||
|
|
||||||
// Objects
|
// Node Management
|
||||||
std::unordered_map<u32, CScriptNode*> mScriptNodeMap;
|
std::unordered_map<u32, CSceneNode*> mNodeMap;
|
||||||
|
std::unordered_map<u32, CScriptNode*> mScriptMap;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScene();
|
CScene();
|
||||||
~CScene();
|
~CScene();
|
||||||
|
|
||||||
// Scene Management
|
// Scene Management
|
||||||
CModelNode* CreateModelNode(CModel *pModel);
|
bool IsNodeIDUsed(u32 ID) const;
|
||||||
CStaticNode* CreateStaticNode(CStaticModel *pModel);
|
u32 CreateNodeID(u32 SuggestedID = -1) const;
|
||||||
CCollisionNode* CreateCollisionNode(CCollisionMeshGroup *pMesh);
|
|
||||||
CScriptNode* CreateScriptNode(CScriptObject *pObj);
|
CModelNode* CreateModelNode(CModel *pModel, u32 NodeID = -1);
|
||||||
CLightNode* CreateLightNode(CLight *pLight);
|
CStaticNode* CreateStaticNode(CStaticModel *pModel, u32 NodeID = -1);
|
||||||
|
CCollisionNode* CreateCollisionNode(CCollisionMeshGroup *pMesh, u32 NodeID = -1);
|
||||||
|
CScriptNode* CreateScriptNode(CScriptObject *pObj, u32 NodeID = -1);
|
||||||
|
CLightNode* CreateLightNode(CLight *pLight, u32 NodeID = -1);
|
||||||
void DeleteNode(CSceneNode *pNode);
|
void DeleteNode(CSceneNode *pNode);
|
||||||
void SetActiveArea(CGameArea *pArea);
|
void SetActiveArea(CGameArea *pArea);
|
||||||
void SetActiveWorld(CWorld *pWorld);
|
void SetActiveWorld(CWorld *pWorld);
|
||||||
|
@ -58,7 +62,8 @@ public:
|
||||||
void ClearScene();
|
void ClearScene();
|
||||||
void AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo);
|
void AddSceneToRenderer(CRenderer *pRenderer, const SViewInfo& rkViewInfo);
|
||||||
SRayIntersection SceneRayCast(const CRay& rkRay, const SViewInfo& rkViewInfo);
|
SRayIntersection SceneRayCast(const CRay& rkRay, const SViewInfo& rkViewInfo);
|
||||||
CScriptNode* ScriptNodeByID(u32 InstanceID);
|
CSceneNode* NodeByID(u32 NodeID);
|
||||||
|
CScriptNode* NodeForInstanceID(u32 InstanceID);
|
||||||
CScriptNode* NodeForObject(CScriptObject *pObj);
|
CScriptNode* NodeForObject(CScriptObject *pObj);
|
||||||
CLightNode* NodeForLight(CLight *pLight);
|
CLightNode* NodeForLight(CLight *pLight);
|
||||||
|
|
||||||
|
|
|
@ -12,11 +12,12 @@
|
||||||
u32 CSceneNode::smNumNodes = 0;
|
u32 CSceneNode::smNumNodes = 0;
|
||||||
CColor CSceneNode::skSelectionTint = CColor::Integral(39, 154, 167);
|
CColor CSceneNode::skSelectionTint = CColor::Integral(39, 154, 167);
|
||||||
|
|
||||||
CSceneNode::CSceneNode(CScene *pScene, CSceneNode *pParent)
|
CSceneNode::CSceneNode(CScene *pScene, u32 NodeID, CSceneNode *pParent)
|
||||||
{
|
{
|
||||||
smNumNodes++;
|
smNumNodes++;
|
||||||
mpScene = pScene;
|
mpScene = pScene;
|
||||||
mpParent = pParent;
|
mpParent = pParent;
|
||||||
|
_mID = NodeID;
|
||||||
|
|
||||||
mPosition = CVector3f::skZero;
|
mPosition = CVector3f::skZero;
|
||||||
mRotation = CQuaternion::skIdentity;
|
mRotation = CQuaternion::skIdentity;
|
||||||
|
@ -341,6 +342,11 @@ CScene* CSceneNode::Scene() const
|
||||||
return mpScene;
|
return mpScene;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u32 CSceneNode::ID() const
|
||||||
|
{
|
||||||
|
return _mID;
|
||||||
|
}
|
||||||
|
|
||||||
CVector3f CSceneNode::LocalPosition() const
|
CVector3f CSceneNode::LocalPosition() const
|
||||||
{
|
{
|
||||||
return mPosition;
|
return mPosition;
|
||||||
|
|
|
@ -29,6 +29,8 @@ private:
|
||||||
bool _mInheritsRotation;
|
bool _mInheritsRotation;
|
||||||
bool _mInheritsScale;
|
bool _mInheritsScale;
|
||||||
|
|
||||||
|
u32 _mID;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static u32 smNumNodes;
|
static u32 smNumNodes;
|
||||||
TString mName;
|
TString mName;
|
||||||
|
@ -51,7 +53,7 @@ protected:
|
||||||
CColor mAmbientColor;
|
CColor mAmbientColor;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CSceneNode(CScene *pScene, CSceneNode *pParent = 0);
|
explicit CSceneNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0);
|
||||||
virtual ~CSceneNode();
|
virtual ~CSceneNode();
|
||||||
virtual ENodeType NodeType() = 0;
|
virtual ENodeType NodeType() = 0;
|
||||||
virtual void PostLoad() {}
|
virtual void PostLoad() {}
|
||||||
|
@ -94,6 +96,7 @@ public:
|
||||||
TString Name() const;
|
TString Name() const;
|
||||||
CSceneNode* Parent() const;
|
CSceneNode* Parent() const;
|
||||||
CScene* Scene() const;
|
CScene* Scene() const;
|
||||||
|
u32 ID() const;
|
||||||
CVector3f LocalPosition() const;
|
CVector3f LocalPosition() const;
|
||||||
CVector3f AbsolutePosition() const;
|
CVector3f AbsolutePosition() const;
|
||||||
CQuaternion LocalRotation() const;
|
CQuaternion LocalRotation() const;
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
#include <Common/AnimUtil.h>
|
#include <Common/AnimUtil.h>
|
||||||
#include <Math/MathUtil.h>
|
#include <Math/MathUtil.h>
|
||||||
|
|
||||||
CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pObject)
|
CScriptNode::CScriptNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CScriptObject *pObject)
|
||||||
: CSceneNode(pScene, pParent)
|
: CSceneNode(pScene, NodeID, pParent)
|
||||||
, mGameModeVisibility(eUntested)
|
, mGameModeVisibility(eUntested)
|
||||||
{
|
{
|
||||||
mpVolumePreviewNode = nullptr;
|
mpVolumePreviewNode = nullptr;
|
||||||
|
@ -21,7 +21,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
|
||||||
mpInstance = pObject;
|
mpInstance = pObject;
|
||||||
SetActiveModel(nullptr);
|
SetActiveModel(nullptr);
|
||||||
mpBillboard = nullptr;
|
mpBillboard = nullptr;
|
||||||
mpCollisionNode = new CCollisionNode(pScene, this);
|
mpCollisionNode = new CCollisionNode(pScene, -1, this);
|
||||||
mpCollisionNode->SetInheritance(true, true, false);
|
mpCollisionNode->SetInheritance(true, true, false);
|
||||||
|
|
||||||
if (mpInstance)
|
if (mpInstance)
|
||||||
|
@ -43,7 +43,7 @@ CScriptNode::CScriptNode(CScene *pScene, CSceneNode *pParent, CScriptObject *pOb
|
||||||
mpCollisionNode->SetCollision(mpInstance->GetCollision());
|
mpCollisionNode->SetCollision(mpInstance->GetCollision());
|
||||||
|
|
||||||
// Create preview volume node
|
// Create preview volume node
|
||||||
mpVolumePreviewNode = new CModelNode(pScene, this, nullptr);
|
mpVolumePreviewNode = new CModelNode(pScene, -1, this, nullptr);
|
||||||
|
|
||||||
if (pTemp->ScaleType() == CScriptTemplate::eScaleVolume)
|
if (pTemp->ScaleType() == CScriptTemplate::eScaleVolume)
|
||||||
{
|
{
|
||||||
|
@ -259,14 +259,14 @@ void CScriptNode::DrawSelection()
|
||||||
{
|
{
|
||||||
// Don't draw in links if the other object is selected.
|
// Don't draw in links if the other object is selected.
|
||||||
CLink *pLink = mpInstance->Link(eIncoming, iIn);
|
CLink *pLink = mpInstance->Link(eIncoming, iIn);
|
||||||
CScriptNode *pLinkNode = mpScene->ScriptNodeByID(pLink->SenderID());
|
CScriptNode *pLinkNode = mpScene->NodeForInstanceID(pLink->SenderID());
|
||||||
if (pLinkNode && !pLinkNode->IsSelected()) CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::skTransparentRed);
|
if (pLinkNode && !pLinkNode->IsSelected()) CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::skTransparentRed);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (u32 iOut = 0; iOut < mpInstance->NumLinks(eOutgoing); iOut++)
|
for (u32 iOut = 0; iOut < mpInstance->NumLinks(eOutgoing); iOut++)
|
||||||
{
|
{
|
||||||
CLink *pLink = mpInstance->Link(eOutgoing, iOut);
|
CLink *pLink = mpInstance->Link(eOutgoing, iOut);
|
||||||
CScriptNode *pLinkNode = mpScene->ScriptNodeByID(pLink->ReceiverID());
|
CScriptNode *pLinkNode = mpScene->NodeForInstanceID(pLink->ReceiverID());
|
||||||
if (pLinkNode) CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::skTransparentGreen);
|
if (pLinkNode) CDrawUtil::DrawLine(CenterPoint(), pLinkNode->CenterPoint(), CColor::skTransparentGreen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,7 +549,7 @@ void CScriptNode::GeneratePosition()
|
||||||
if (NumLinks == 1)
|
if (NumLinks == 1)
|
||||||
{
|
{
|
||||||
u32 LinkedID = (mpInstance->NumLinks(eIncoming) > 0 ? mpInstance->Link(eIncoming, 0)->SenderID() : mpInstance->Link(eOutgoing, 0)->ReceiverID());
|
u32 LinkedID = (mpInstance->NumLinks(eIncoming) > 0 ? mpInstance->Link(eIncoming, 0)->SenderID() : mpInstance->Link(eOutgoing, 0)->ReceiverID());
|
||||||
CScriptNode *pNode = mpScene->ScriptNodeByID(LinkedID);
|
CScriptNode *pNode = mpScene->NodeForInstanceID(LinkedID);
|
||||||
pNode->GeneratePosition();
|
pNode->GeneratePosition();
|
||||||
mPosition = pNode->AbsolutePosition();
|
mPosition = pNode->AbsolutePosition();
|
||||||
mPosition.z += (pNode->AABox().Size().z / 2.f);
|
mPosition.z += (pNode->AABox().Size().z / 2.f);
|
||||||
|
@ -564,7 +564,7 @@ void CScriptNode::GeneratePosition()
|
||||||
|
|
||||||
for (u32 iIn = 0; iIn < mpInstance->NumLinks(eIncoming); iIn++)
|
for (u32 iIn = 0; iIn < mpInstance->NumLinks(eIncoming); iIn++)
|
||||||
{
|
{
|
||||||
CScriptNode *pNode = mpScene->ScriptNodeByID(mpInstance->Link(eIncoming, iIn)->SenderID());
|
CScriptNode *pNode = mpScene->NodeForInstanceID(mpInstance->Link(eIncoming, iIn)->SenderID());
|
||||||
|
|
||||||
if (pNode)
|
if (pNode)
|
||||||
{
|
{
|
||||||
|
@ -575,7 +575,7 @@ void CScriptNode::GeneratePosition()
|
||||||
|
|
||||||
for (u32 iOut = 0; iOut < mpInstance->NumLinks(eOutgoing); iOut++)
|
for (u32 iOut = 0; iOut < mpInstance->NumLinks(eOutgoing); iOut++)
|
||||||
{
|
{
|
||||||
CScriptNode *pNode = mpScene->ScriptNodeByID(mpInstance->Link(eOutgoing, iOut)->ReceiverID());
|
CScriptNode *pNode = mpScene->NodeForInstanceID(mpInstance->Link(eOutgoing, iOut)->ReceiverID());
|
||||||
|
|
||||||
if (pNode)
|
if (pNode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -30,7 +30,7 @@ class CScriptNode : public CSceneNode
|
||||||
} mGameModeVisibility;
|
} mGameModeVisibility;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScriptNode(CScene *pScene, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
|
CScriptNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0, CScriptObject *pObject = 0);
|
||||||
ENodeType NodeType();
|
ENodeType NodeType();
|
||||||
void PostLoad();
|
void PostLoad();
|
||||||
void OnTransformed();
|
void OnTransformed();
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
#include <Common/AnimUtil.h>
|
#include <Common/AnimUtil.h>
|
||||||
#include <Math/MathUtil.h>
|
#include <Math/MathUtil.h>
|
||||||
|
|
||||||
CStaticNode::CStaticNode(CScene *pScene, CSceneNode *pParent, CStaticModel *pModel)
|
CStaticNode::CStaticNode(CScene *pScene, u32 NodeID, CSceneNode *pParent, CStaticModel *pModel)
|
||||||
: CSceneNode(pScene, pParent)
|
: CSceneNode(pScene, NodeID, pParent)
|
||||||
{
|
{
|
||||||
mpModel = pModel;
|
mpModel = pModel;
|
||||||
mLocalAABox = mpModel->AABox();
|
mLocalAABox = mpModel->AABox();
|
||||||
|
|
|
@ -9,7 +9,7 @@ class CStaticNode : public CSceneNode
|
||||||
CStaticModel *mpModel;
|
CStaticModel *mpModel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CStaticNode(CScene *pScene, CSceneNode *pParent = 0, CStaticModel *pModel = 0);
|
CStaticNode(CScene *pScene, u32 NodeID, CSceneNode *pParent = 0, CStaticModel *pModel = 0);
|
||||||
ENodeType NodeType();
|
ENodeType NodeType();
|
||||||
void PostLoad();
|
void PostLoad();
|
||||||
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
void AddToRenderer(CRenderer *pRenderer, const SViewInfo& ViewInfo);
|
||||||
|
|
|
@ -20,7 +20,7 @@ protected:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CScriptExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0)
|
explicit CScriptExtra(CScriptObject *pInstance, CScene *pScene, CSceneNode *pParent = 0)
|
||||||
: CSceneNode(pScene, pParent),
|
: CSceneNode(pScene, -1, pParent),
|
||||||
mpInstance(pInstance),
|
mpInstance(pInstance),
|
||||||
mGame(pInstance->Template()->Game())
|
mGame(pInstance->Template()->Game())
|
||||||
{
|
{
|
||||||
|
|
|
@ -53,7 +53,7 @@ void CSplinePathExtra::AddWaypoints()
|
||||||
if ( (pLink->State() == 0x49533030 && pLink->Message() == 0x41544348) || // InternalState00/Attach
|
if ( (pLink->State() == 0x49533030 && pLink->Message() == 0x41544348) || // InternalState00/Attach
|
||||||
(pLink->State() == 0x4D4F5450 && pLink->Message() == 0x41544348) ) // MotionPath/Attach
|
(pLink->State() == 0x4D4F5450 && pLink->Message() == 0x41544348) ) // MotionPath/Attach
|
||||||
{
|
{
|
||||||
CScriptNode *pNode = mpScene->ScriptNodeByID(pLink->ReceiverID());
|
CScriptNode *pNode = mpScene->NodeForInstanceID(pLink->ReceiverID());
|
||||||
|
|
||||||
if (pNode && pNode->Object()->ObjectTypeID() == 0x57415950) // Waypoint
|
if (pNode && pNode->Object()->ObjectTypeID() == 0x57415950) // Waypoint
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,7 +85,7 @@ void CWaypointExtra::BuildLinks()
|
||||||
|
|
||||||
if (IsPathLink(pLink))
|
if (IsPathLink(pLink))
|
||||||
{
|
{
|
||||||
CScriptNode *pNode = mpScene->ScriptNodeByID(pLink->ReceiverID());
|
CScriptNode *pNode = mpScene->NodeForInstanceID(pLink->ReceiverID());
|
||||||
|
|
||||||
SWaypointLink Link;
|
SWaypointLink Link;
|
||||||
Link.pWaypoint = pNode;
|
Link.pWaypoint = pNode;
|
||||||
|
@ -117,7 +117,7 @@ bool CWaypointExtra::IsPathLink(CLink *pLink)
|
||||||
|
|
||||||
if (Valid)
|
if (Valid)
|
||||||
{
|
{
|
||||||
CScriptNode *pNode = mpScene->ScriptNodeByID(pLink->ReceiverID());
|
CScriptNode *pNode = mpScene->NodeForInstanceID(pLink->ReceiverID());
|
||||||
|
|
||||||
if (pNode)
|
if (pNode)
|
||||||
return pNode->Object()->ObjectTypeID() == mpInstance->ObjectTypeID();
|
return pNode->Object()->ObjectTypeID() == mpInstance->ObjectTypeID();
|
||||||
|
|
|
@ -138,7 +138,6 @@ HEADERS += \
|
||||||
WorldEditor/CInstancesModel.h \
|
WorldEditor/CInstancesModel.h \
|
||||||
Undo/CEditScriptPropertyCommand.h \
|
Undo/CEditScriptPropertyCommand.h \
|
||||||
Undo/CResizeScriptArrayCommand.h \
|
Undo/CResizeScriptArrayCommand.h \
|
||||||
Undo/CBasicPropertyCommand.h \
|
|
||||||
Undo/IUndoCommand.h \
|
Undo/IUndoCommand.h \
|
||||||
WorldEditor/WEditorProperties.h \
|
WorldEditor/WEditorProperties.h \
|
||||||
Undo/CChangeLayerCommand.h \
|
Undo/CChangeLayerCommand.h \
|
||||||
|
@ -154,7 +153,8 @@ HEADERS += \
|
||||||
Undo/CCreateInstanceCommand.h \
|
Undo/CCreateInstanceCommand.h \
|
||||||
WorldEditor/CTemplateMimeData.h \
|
WorldEditor/CTemplateMimeData.h \
|
||||||
WorldEditor/CTemplateListView.h \
|
WorldEditor/CTemplateListView.h \
|
||||||
CSelectionIterator.h
|
CSelectionIterator.h \
|
||||||
|
Undo/ObjReferences.h
|
||||||
|
|
||||||
# Source Files
|
# Source Files
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
@ -202,7 +202,6 @@ SOURCES += \
|
||||||
WorldEditor/CInstancesModel.cpp \
|
WorldEditor/CInstancesModel.cpp \
|
||||||
Undo/CEditScriptPropertyCommand.cpp \
|
Undo/CEditScriptPropertyCommand.cpp \
|
||||||
Undo/CResizeScriptArrayCommand.cpp \
|
Undo/CResizeScriptArrayCommand.cpp \
|
||||||
Undo/CBasicPropertyCommand.cpp \
|
|
||||||
WorldEditor/WEditorProperties.cpp \
|
WorldEditor/WEditorProperties.cpp \
|
||||||
Undo/CChangeLayerCommand.cpp \
|
Undo/CChangeLayerCommand.cpp \
|
||||||
WorldEditor/CTemplateEditDialog.cpp \
|
WorldEditor/CTemplateEditDialog.cpp \
|
||||||
|
|
|
@ -31,7 +31,7 @@ CModelEditorWindow::CModelEditorWindow(QWidget *parent) :
|
||||||
mpScene = new CScene();
|
mpScene = new CScene();
|
||||||
mpCurrentMat = nullptr;
|
mpCurrentMat = nullptr;
|
||||||
mpCurrentModel = nullptr;
|
mpCurrentModel = nullptr;
|
||||||
mpCurrentModelNode = new CModelNode(mpScene);
|
mpCurrentModelNode = new CModelNode(mpScene, -1);
|
||||||
mpCurrentPass = nullptr;
|
mpCurrentPass = nullptr;
|
||||||
mIgnoreSignals = false;
|
mIgnoreSignals = false;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@ CAddLinkCommand::CAddLinkCommand(CWorldEditor *pEditor, CLink Link)
|
||||||
{
|
{
|
||||||
mAffectedInstances << mLink.Sender();
|
mAffectedInstances << mLink.Sender();
|
||||||
|
|
||||||
if (mLink.Sender() != mLink.Receiver())
|
if (mLink.SenderID() != mLink.ReceiverID())
|
||||||
mAffectedInstances << mLink.Receiver();
|
mAffectedInstances << mLink.Receiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ void CAddLinkCommand::undo()
|
||||||
pReceiver->RemoveLink(eIncoming, pLink);
|
pReceiver->RemoveLink(eIncoming, pLink);
|
||||||
delete pLink;
|
delete pLink;
|
||||||
|
|
||||||
mpEditor->InstanceLinksModified(mAffectedInstances);
|
mpEditor->InstanceLinksModified(mAffectedInstances.DereferenceList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CAddLinkCommand::redo()
|
void CAddLinkCommand::redo()
|
||||||
|
@ -31,5 +31,5 @@ void CAddLinkCommand::redo()
|
||||||
pLink->Sender()->AddLink(eOutgoing, pLink, -1);
|
pLink->Sender()->AddLink(eOutgoing, pLink, -1);
|
||||||
pLink->Receiver()->AddLink(eIncoming, pLink, -1);
|
pLink->Receiver()->AddLink(eIncoming, pLink, -1);
|
||||||
|
|
||||||
mpEditor->InstanceLinksModified(mAffectedInstances);
|
mpEditor->InstanceLinksModified(mAffectedInstances.DereferenceList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CADDLINKCOMMAND_H
|
#define CADDLINKCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
#include <Core/Resource/Script/CLink.h>
|
#include <Core/Resource/Script/CLink.h>
|
||||||
|
|
||||||
|
@ -9,7 +10,7 @@ class CAddLinkCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CWorldEditor *mpEditor;
|
CWorldEditor *mpEditor;
|
||||||
CLink mLink;
|
CLink mLink;
|
||||||
QList<CScriptObject*> mAffectedInstances;
|
CInstancePtrList mAffectedInstances;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAddLinkCommand(CWorldEditor *pEditor, CLink Link);
|
CAddLinkCommand(CWorldEditor *pEditor, CLink Link);
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
#include "CBasicPropertyCommand.h"
|
|
||||||
#include <Core/Resource/Script/IPropertyTemplate.h>
|
|
||||||
|
|
||||||
CBasicPropertyCommand::CBasicPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, const QString& rkCommandName /*="Edit Property"*/)
|
|
||||||
: IUndoCommand(rkCommandName)
|
|
||||||
, mpProperty(pProp)
|
|
||||||
, mpTemplate(mpProperty->Template())
|
|
||||||
, mpBaseStruct(pProp->RootStruct())
|
|
||||||
, mpEditor(pEditor)
|
|
||||||
, mIsInArray(false)
|
|
||||||
{
|
|
||||||
// Check for array
|
|
||||||
IProperty *pChild = mpProperty;
|
|
||||||
IProperty *pParent = mpProperty->Parent();
|
|
||||||
|
|
||||||
while (pParent)
|
|
||||||
{
|
|
||||||
if (pParent->Type() == eArrayProperty)
|
|
||||||
{
|
|
||||||
mIsInArray = true;
|
|
||||||
|
|
||||||
// Find array index
|
|
||||||
CArrayProperty *pArray = static_cast<CArrayProperty*>(pParent);
|
|
||||||
|
|
||||||
for (u32 iSub = 0; iSub < pArray->Count(); iSub++)
|
|
||||||
{
|
|
||||||
if (pArray->PropertyByIndex(iSub) == pChild)
|
|
||||||
{
|
|
||||||
mArrayIndices << iSub;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pChild = pParent;
|
|
||||||
pParent = pParent->Parent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CBasicPropertyCommand::UpdateArraySubProperty()
|
|
||||||
{
|
|
||||||
// If an array has been sized down and then back up, then we might have a pointer to an invalid property.
|
|
||||||
// Since we can't assume our pointer is still valid, we'll use the template to find the corresponding property.
|
|
||||||
IPropertyTemplate *pTemp = mpTemplate;
|
|
||||||
CStructTemplate *pParent = mpTemplate->Parent();
|
|
||||||
|
|
||||||
QVector<u32> SubIndices;
|
|
||||||
int IndexIndex = 0;
|
|
||||||
|
|
||||||
while (pParent)
|
|
||||||
{
|
|
||||||
if (pParent->Type() != eArrayProperty || static_cast<CArrayTemplate*>(pParent)->Count() > 1)
|
|
||||||
{
|
|
||||||
for (u32 iSub = 0; iSub < pParent->Count(); iSub++)
|
|
||||||
{
|
|
||||||
if (pParent->PropertyByIndex(iSub) == pTemp)
|
|
||||||
{
|
|
||||||
SubIndices << iSub;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
SubIndices << 0;
|
|
||||||
|
|
||||||
if (pParent->Type() == eArrayProperty)
|
|
||||||
{
|
|
||||||
SubIndices << mArrayIndices[IndexIndex];
|
|
||||||
IndexIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
pTemp = pParent;
|
|
||||||
pParent = pParent->Parent();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find corresponding property
|
|
||||||
mpProperty = mpBaseStruct;
|
|
||||||
|
|
||||||
for (int iChild = SubIndices.size() - 1; iChild >= 0; iChild--)
|
|
||||||
mpProperty = static_cast<CPropertyStruct*>(mpProperty)->PropertyByIndex(SubIndices[iChild]);
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
#ifndef CBASICPROPERTYCOMMAND_H
|
|
||||||
#define CBASICPROPERTYCOMMAND_H
|
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
|
||||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
|
||||||
|
|
||||||
class CBasicPropertyCommand : public IUndoCommand
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
IProperty *mpProperty;
|
|
||||||
IPropertyTemplate *mpTemplate;
|
|
||||||
CPropertyStruct *mpBaseStruct;
|
|
||||||
CWorldEditor *mpEditor;
|
|
||||||
|
|
||||||
bool mIsInArray;
|
|
||||||
QVector<u32> mArrayIndices;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CBasicPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, const QString& rkCommandName = "Edit Property");
|
|
||||||
virtual void UpdateArraySubProperty();
|
|
||||||
virtual bool AffectsCleanState() const { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // CBASICPROPERTYCOMMAND_H
|
|
|
@ -2,41 +2,46 @@
|
||||||
|
|
||||||
CChangeLayerCommand::CChangeLayerCommand(CWorldEditor *pEditor, const QList<CScriptNode*>& rkNodeList, CScriptLayer *pNewLayer)
|
CChangeLayerCommand::CChangeLayerCommand(CWorldEditor *pEditor, const QList<CScriptNode*>& rkNodeList, CScriptLayer *pNewLayer)
|
||||||
: IUndoCommand("Change Layer")
|
: IUndoCommand("Change Layer")
|
||||||
, mNodeList(rkNodeList)
|
|
||||||
, mpNewLayer(pNewLayer)
|
, mpNewLayer(pNewLayer)
|
||||||
, mpEditor(pEditor)
|
, mpEditor(pEditor)
|
||||||
{
|
{
|
||||||
foreach (CScriptNode *pNode, mNodeList)
|
foreach (CScriptNode *pNode, rkNodeList)
|
||||||
{
|
{
|
||||||
CScriptLayer *pLayer = pNode->Object()->Layer();
|
CScriptLayer *pLayer = pNode->Object()->Layer();
|
||||||
|
|
||||||
if (pLayer == pNewLayer)
|
if (pLayer != pNewLayer && !mNodes.contains(pNode))
|
||||||
{
|
{
|
||||||
mNodeList.removeOne(pNode);
|
mNodes << pNode;
|
||||||
continue;
|
mOldLayers[pNode->ID()] = pLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
mOldLayers[pNode] = pLayer;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CChangeLayerCommand::undo()
|
void CChangeLayerCommand::undo()
|
||||||
{
|
{
|
||||||
mpEditor->InstancesLayerAboutToChange();
|
mpEditor->InstancesLayerAboutToChange();
|
||||||
|
QList<CSceneNode*> Nodes = mNodes.DereferenceList();
|
||||||
|
|
||||||
foreach (CScriptNode *pNode, mNodeList)
|
QList<CScriptNode*> ScriptNodes;
|
||||||
pNode->Object()->SetLayer(mOldLayers[pNode]);
|
foreach (CSceneNode *pNode, Nodes) ScriptNodes << static_cast<CScriptNode*>(pNode);
|
||||||
|
|
||||||
mpEditor->InstancesLayerChanged(mNodeList);
|
foreach (CScriptNode *pNode, ScriptNodes)
|
||||||
|
pNode->Object()->SetLayer(mOldLayers[pNode->ID()]);
|
||||||
|
|
||||||
|
mpEditor->InstancesLayerChanged(ScriptNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CChangeLayerCommand::redo()
|
void CChangeLayerCommand::redo()
|
||||||
{
|
{
|
||||||
mpEditor->InstancesLayerAboutToChange();
|
mpEditor->InstancesLayerAboutToChange();
|
||||||
|
QList<CSceneNode*> Nodes = mNodes.DereferenceList();
|
||||||
|
|
||||||
foreach (CScriptNode *pNode, mNodeList)
|
QList<CScriptNode*> ScriptNodes;
|
||||||
|
foreach (CSceneNode *pNode, Nodes) ScriptNodes << static_cast<CScriptNode*>(pNode);
|
||||||
|
|
||||||
|
foreach (CScriptNode *pNode, ScriptNodes)
|
||||||
pNode->Object()->SetLayer(mpNewLayer);
|
pNode->Object()->SetLayer(mpNewLayer);
|
||||||
|
|
||||||
mpEditor->InstancesLayerChanged(mNodeList);
|
mpEditor->InstancesLayerChanged(ScriptNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,14 @@
|
||||||
#define CCHANGELAYERCOMMAND_H
|
#define CCHANGELAYERCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
#include <Core/Scene/CScriptNode.h>
|
#include <Core/Scene/CScriptNode.h>
|
||||||
|
|
||||||
class CChangeLayerCommand : public IUndoCommand
|
class CChangeLayerCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
QList<CScriptNode*> mNodeList;
|
CNodePtrList mNodes;
|
||||||
QMap<CScriptNode*, CScriptLayer*> mOldLayers;
|
QMap<u32, CScriptLayer*> mOldLayers;
|
||||||
CScriptLayer *mpNewLayer;
|
CScriptLayer *mpNewLayer;
|
||||||
CWorldEditor *mpEditor;
|
CWorldEditor *mpEditor;
|
||||||
|
|
||||||
|
|
|
@ -2,22 +2,26 @@
|
||||||
#define CCLEARSELECTIONCOMMAND_H
|
#define CCLEARSELECTIONCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
|
#include "Editor/CSelectionIterator.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
|
||||||
class CClearSelectionCommand : public IUndoCommand
|
class CClearSelectionCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
QList<CSceneNode*> mOldSelection;
|
|
||||||
CNodeSelection *mpSelection;
|
CNodeSelection *mpSelection;
|
||||||
|
CNodePtrList mOldSelection;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CClearSelectionCommand(CNodeSelection *pSelection)
|
CClearSelectionCommand(CNodeSelection *pSelection)
|
||||||
: IUndoCommand("Clear Selection"),
|
: IUndoCommand("Clear Selection"),
|
||||||
mOldSelection(pSelection->SelectedNodeList()),
|
|
||||||
mpSelection(pSelection)
|
mpSelection(pSelection)
|
||||||
{}
|
{
|
||||||
|
for (CSelectionIterator It(pSelection); It; ++It)
|
||||||
|
mOldSelection << *It;
|
||||||
|
}
|
||||||
|
|
||||||
void undo() { mpSelection->SetSelectedNodes(mOldSelection); }
|
void undo() { mpSelection->SetSelectedNodes(mOldSelection.DereferenceList()); }
|
||||||
void redo() { mpSelection->Clear(); }
|
void redo() { mpSelection->Clear(); }
|
||||||
bool AffectsCleanState() const { return false; }
|
bool AffectsCleanState() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
|
@ -16,13 +16,14 @@ CCreateInstanceCommand::CCreateInstanceCommand(CWorldEditor *pEditor, CScriptTem
|
||||||
|
|
||||||
void CCreateInstanceCommand::undo()
|
void CCreateInstanceCommand::undo()
|
||||||
{
|
{
|
||||||
mpEditor->NotifyNodeAboutToBeDeleted(mpNewNode);
|
mpEditor->NotifyNodeAboutToBeDeleted(*mpNewNode);
|
||||||
mpEditor->Selection()->SetSelectedNodes(mOldSelection);
|
mpEditor->Selection()->SetSelectedNodes(mOldSelection.DereferenceList());
|
||||||
mpScene->DeleteNode(mpNewNode);
|
mpScene->DeleteNode(*mpNewNode);
|
||||||
mpArea->DeleteInstance(mpNewInstance);
|
mpArea->DeleteInstance(*mpNewInstance);
|
||||||
|
mpEditor->NotifyNodeDeleted();
|
||||||
|
|
||||||
mpNewNode = nullptr;
|
mpNewNode = nullptr;
|
||||||
mpNewInstance = nullptr;
|
mpNewInstance = nullptr;
|
||||||
mpEditor->NotifyNodeDeleted();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CCreateInstanceCommand::redo()
|
void CCreateInstanceCommand::redo()
|
||||||
|
@ -30,10 +31,12 @@ void CCreateInstanceCommand::redo()
|
||||||
mpEditor->NotifyNodeAboutToBeSpawned();
|
mpEditor->NotifyNodeAboutToBeSpawned();
|
||||||
|
|
||||||
CScriptLayer *pLayer = (mLayerIndex == -1 ? mpArea->GetGeneratorLayer() : mpArea->GetScriptLayer(mLayerIndex));
|
CScriptLayer *pLayer = (mLayerIndex == -1 ? mpArea->GetGeneratorLayer() : mpArea->GetScriptLayer(mLayerIndex));
|
||||||
mpNewInstance = mpArea->SpawnInstance(mpTemplate, pLayer, mSpawnPosition);
|
CScriptObject *pNewInst = mpArea->SpawnInstance(mpTemplate, pLayer, mSpawnPosition);
|
||||||
mpNewNode = mpScene->CreateScriptNode(mpNewInstance);
|
CScriptNode *pNewNode = mpScene->CreateScriptNode(pNewInst);
|
||||||
mpNewNode->SetPosition(mSpawnPosition);
|
pNewNode->SetPosition(mSpawnPosition);
|
||||||
|
mpEditor->NotifyNodeSpawned(pNewNode);
|
||||||
|
mpEditor->Selection()->ClearAndSelectNode(pNewNode);
|
||||||
|
|
||||||
mpEditor->NotifyNodeSpawned(mpNewNode);
|
mpNewInstance = pNewInst;
|
||||||
mpEditor->Selection()->ClearAndSelectNode(mpNewNode);
|
mpNewNode = pNewNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,9 +18,9 @@ class CCreateInstanceCommand : public IUndoCommand
|
||||||
u32 mLayerIndex;
|
u32 mLayerIndex;
|
||||||
CVector3f mSpawnPosition;
|
CVector3f mSpawnPosition;
|
||||||
|
|
||||||
QList<CSceneNode*> mOldSelection;
|
CNodePtrList mOldSelection;
|
||||||
CScriptObject *mpNewInstance;
|
CInstancePtr mpNewInstance;
|
||||||
CScriptNode *mpNewNode;
|
CNodePtr mpNewNode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CCreateInstanceCommand(CWorldEditor *pEditor, CScriptTemplate *pTemplate, CScriptLayer *pLayer, const CVector3f& rkPosition);
|
CCreateInstanceCommand(CWorldEditor *pEditor, CScriptTemplate *pTemplate, CScriptLayer *pLayer, const CVector3f& rkPosition);
|
||||||
|
|
|
@ -48,7 +48,7 @@ void CDeleteLinksCommand::undo()
|
||||||
|
|
||||||
SNewLink Link;
|
SNewLink Link;
|
||||||
Link.pDelLink = &mLinks[iLink];
|
Link.pDelLink = &mLinks[iLink];
|
||||||
Link.pLink = new CLink(mpEditor->ActiveArea(), rDelLink.State, rDelLink.Message, rDelLink.pSender->InstanceID(), rDelLink.pReceiver->InstanceID());
|
Link.pLink = new CLink(mpEditor->ActiveArea(), rDelLink.State, rDelLink.Message, rDelLink.pSender.InstanceID(), rDelLink.pReceiver.InstanceID());
|
||||||
NewLinks << Link;
|
NewLinks << Link;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ void CDeleteLinksCommand::undo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify world editor
|
// Notify world editor
|
||||||
mpEditor->OnLinksModified(mAffectedInstances);
|
mpEditor->OnLinksModified(mAffectedInstances.DereferenceList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeleteLinksCommand::redo()
|
void CDeleteLinksCommand::redo()
|
||||||
|
@ -93,5 +93,5 @@ void CDeleteLinksCommand::redo()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Notify world editor
|
// Notify world editor
|
||||||
mpEditor->OnLinksModified(mAffectedInstances);
|
mpEditor->OnLinksModified(mAffectedInstances.DereferenceList());
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,25 +2,27 @@
|
||||||
#define CDELETELINKSCOMMAND_H
|
#define CDELETELINKSCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
|
|
||||||
class CDeleteLinksCommand : public IUndoCommand
|
class CDeleteLinksCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CWorldEditor *mpEditor;
|
CWorldEditor *mpEditor;
|
||||||
QList<CScriptObject*> mAffectedInstances;
|
CInstancePtrList mAffectedInstances;
|
||||||
|
|
||||||
struct SDeletedLink
|
struct SDeletedLink
|
||||||
{
|
{
|
||||||
u32 State;
|
u32 State;
|
||||||
u32 Message;
|
u32 Message;
|
||||||
CScriptObject *pSender;
|
CInstancePtr pSender;
|
||||||
CScriptObject *pReceiver;
|
CInstancePtr pReceiver;
|
||||||
u32 SenderIndex;
|
u32 SenderIndex;
|
||||||
u32 ReceiverIndex;
|
u32 ReceiverIndex;
|
||||||
};
|
};
|
||||||
QVector<SDeletedLink> mLinks;
|
QVector<SDeletedLink> mLinks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
CDeleteLinksCommand() {}
|
||||||
CDeleteLinksCommand(CWorldEditor *pEditor, CScriptObject *pObject, ELinkType Type, const QVector<u32>& rkIndices);
|
CDeleteLinksCommand(CWorldEditor *pEditor, CScriptObject *pObject, ELinkType Type, const QVector<u32>& rkIndices);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
|
|
|
@ -1,35 +1,142 @@
|
||||||
#include "CDeleteSelectionCommand.h"
|
#include "CDeleteSelectionCommand.h"
|
||||||
#include "Editor/CSelectionIterator.h"
|
#include "Editor/CSelectionIterator.h"
|
||||||
|
#include <FileIO/FileIO.h>
|
||||||
|
#include <Core/Resource/Cooker/CScriptCooker.h>
|
||||||
|
#include <Core/Resource/Factory/CScriptLoader.h>
|
||||||
|
|
||||||
CDeleteSelectionCommand::CDeleteSelectionCommand(CWorldEditor *pEditor)
|
CDeleteSelectionCommand::CDeleteSelectionCommand(CWorldEditor *pEditor)
|
||||||
: IUndoCommand("Delete")
|
: IUndoCommand("Delete")
|
||||||
, mpEditor(pEditor)
|
, mpEditor(pEditor)
|
||||||
{
|
{
|
||||||
mOldSelection = pEditor->Selection()->SelectedNodeList();
|
QSet<CLink*> Links;
|
||||||
|
|
||||||
for (CSelectionIterator It(pEditor->Selection()); It; ++It)
|
for (CSelectionIterator It(pEditor->Selection()); It; ++It)
|
||||||
{
|
{
|
||||||
|
mOldSelection << *It;
|
||||||
|
|
||||||
if (It->NodeType() == eScriptNode)
|
if (It->NodeType() == eScriptNode)
|
||||||
mNodesToDelete << *It;
|
{
|
||||||
|
CScriptNode *pScript = static_cast<CScriptNode*>(*It);
|
||||||
|
CScriptObject *pInst = pScript->Object();
|
||||||
|
|
||||||
|
mDeletedNodes.push_back(SDeletedNode());
|
||||||
|
SDeletedNode& rNode = mDeletedNodes.back();
|
||||||
|
|
||||||
|
rNode.NodePtr = CNodePtr(pScript);
|
||||||
|
rNode.NodeID = pScript->ID();
|
||||||
|
rNode.Position = pScript->LocalPosition();
|
||||||
|
rNode.Rotation = pScript->LocalRotation();
|
||||||
|
rNode.Scale = pScript->LocalScale();
|
||||||
|
|
||||||
|
rNode.pArea = pInst->Area();
|
||||||
|
rNode.pLayer = pInst->Layer();
|
||||||
|
rNode.LayerIndex = pInst->LayerIndex();
|
||||||
|
|
||||||
|
for (u32 iType = 0; iType < 2; iType++)
|
||||||
|
{
|
||||||
|
ELinkType Type = (iType == 0 ? eOutgoing : eIncoming);
|
||||||
|
|
||||||
|
for (u32 iLink = 0; iLink < pInst->NumLinks(Type); iLink++)
|
||||||
|
{
|
||||||
|
CLink *pLink = pInst->Link(Type, iLink);
|
||||||
|
|
||||||
|
if (!Links.contains(pLink))
|
||||||
|
{
|
||||||
|
SDeletedLink Link;
|
||||||
|
Link.State = pLink->State();
|
||||||
|
Link.Message = pLink->Message();
|
||||||
|
Link.SenderID = pLink->SenderID();
|
||||||
|
Link.SenderIndex = pLink->SenderIndex();
|
||||||
|
Link.ReceiverID = pLink->ReceiverID();
|
||||||
|
Link.ReceiverIndex = pLink->ReceiverIndex();
|
||||||
|
Link.pSender = pLink->Sender();
|
||||||
|
Link.pReceiver = pLink->Receiver();
|
||||||
|
mDeletedLinks << Link;
|
||||||
|
Links << pLink;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CVectorOutStream PropertyDataOut(&rNode.InstanceData, IOUtil::eBigEndian);
|
||||||
|
CScriptCooker::CookInstance(eReturns, pInst, PropertyDataOut);
|
||||||
|
}
|
||||||
|
|
||||||
else
|
else
|
||||||
mNewSelection << *It;
|
mNewSelection << *It;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qSort(mDeletedNodes.begin(), mDeletedNodes.end(), [](SDeletedNode& rLeft, SDeletedNode& rRight) -> bool {
|
||||||
|
return (rLeft.NodeID < rRight.NodeID);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeleteSelectionCommand::undo()
|
void CDeleteSelectionCommand::undo()
|
||||||
{
|
{
|
||||||
//foreach (CSceneNode *pNode, mNodesToDelete)
|
QList<u32> NewInstanceIDs;
|
||||||
// pNode->SetDeleted(false);
|
|
||||||
//mpEditor->Selection()->SetSelectedNodes(mOldSelection);
|
// Spawn nodes
|
||||||
|
for (int iNode = 0; iNode < mDeletedNodes.size(); iNode++)
|
||||||
|
{
|
||||||
|
SDeletedNode& rNode = mDeletedNodes[iNode];
|
||||||
|
mpEditor->NotifyNodeAboutToBeSpawned();
|
||||||
|
|
||||||
|
CMemoryInStream Mem(rNode.InstanceData.data(), rNode.InstanceData.size(), IOUtil::eBigEndian);
|
||||||
|
CScriptObject *pInstance = CScriptLoader::LoadInstance(Mem, rNode.pArea, rNode.pLayer, rNode.pArea->Version(), true);
|
||||||
|
CScriptNode *pNode = mpEditor->Scene()->CreateScriptNode(pInstance, rNode.NodeID);
|
||||||
|
rNode.pArea->AddInstanceToArea(pInstance);
|
||||||
|
rNode.pLayer->AddInstance(pInstance, rNode.LayerIndex);
|
||||||
|
|
||||||
|
if (!pInstance->PositionProperty()) pNode->SetPosition(rNode.Position);
|
||||||
|
if (!pInstance->RotationProperty()) pNode->SetRotation(rNode.Rotation);
|
||||||
|
if (!pInstance->ScaleProperty()) pNode->SetScale(rNode.Scale);
|
||||||
|
|
||||||
|
NewInstanceIDs << pInstance->InstanceID();
|
||||||
|
mpEditor->NotifyNodeSpawned(*rNode.NodePtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort links by sender index, add outgoing
|
||||||
|
qSort(mDeletedLinks.begin(), mDeletedLinks.end(), [](SDeletedLink& rLeft, SDeletedLink& rRight) -> bool {
|
||||||
|
return (rLeft.SenderIndex < rRight.SenderIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int iLink = 0; iLink < mDeletedLinks.size(); iLink++)
|
||||||
|
{
|
||||||
|
SDeletedLink& rLink = mDeletedLinks[iLink];
|
||||||
|
|
||||||
|
// Adding to the sender is only needed if the sender is not one of the nodes we just spawned. If it is, it already has this link.
|
||||||
|
if (!NewInstanceIDs.contains(rLink.SenderID))
|
||||||
|
{
|
||||||
|
CLink *pLink = new CLink(rLink.pSender->Area(), rLink.State, rLink.Message, rLink.SenderID, rLink.ReceiverID);
|
||||||
|
rLink.pSender->AddLink(eOutgoing, pLink, rLink.SenderIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort links by receiver index, add incoming
|
||||||
|
qSort(mDeletedLinks.begin(), mDeletedLinks.end(), [](SDeletedLink& rLeft, SDeletedLink& rRight) -> bool {
|
||||||
|
return (rLeft.ReceiverIndex < rRight.ReceiverIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
for (int iLink = 0; iLink < mDeletedLinks.size(); iLink++)
|
||||||
|
{
|
||||||
|
SDeletedLink& rLink = mDeletedLinks[iLink];
|
||||||
|
CLink *pLink = rLink.pSender->Link(eOutgoing, rLink.SenderIndex);
|
||||||
|
rLink.pReceiver->AddLink(eIncoming, pLink, rLink.ReceiverIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add selection and done
|
||||||
|
mpEditor->Selection()->SetSelectedNodes(mOldSelection.DereferenceList());
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDeleteSelectionCommand::redo()
|
void CDeleteSelectionCommand::redo()
|
||||||
{
|
{
|
||||||
mpEditor->Selection()->SetSelectedNodes(mNewSelection);
|
mpEditor->Selection()->SetSelectedNodes(mNewSelection.DereferenceList());
|
||||||
|
|
||||||
foreach (CSceneNode *pNode, mNodesToDelete)
|
for (int iNode = 0; iNode < mDeletedNodes.size(); iNode++)
|
||||||
{
|
{
|
||||||
|
SDeletedNode& rNode = mDeletedNodes[iNode];
|
||||||
|
CSceneNode *pNode = *rNode.NodePtr;
|
||||||
CScriptObject *pInst = static_cast<CScriptNode*>(pNode)->Object();
|
CScriptObject *pInst = static_cast<CScriptNode*>(pNode)->Object();
|
||||||
|
|
||||||
mpEditor->NotifyNodeAboutToBeDeleted(pNode);
|
mpEditor->NotifyNodeAboutToBeDeleted(pNode);
|
||||||
mpEditor->Scene()->DeleteNode(pNode);
|
mpEditor->Scene()->DeleteNode(pNode);
|
||||||
mpEditor->ActiveArea()->DeleteInstance(pInst);
|
mpEditor->ActiveArea()->DeleteInstance(pInst);
|
||||||
|
|
|
@ -1,16 +1,49 @@
|
||||||
#ifndef CDELETESELECTIONCOMMAND_H
|
#ifndef CDELETESELECTIONCOMMAND_H
|
||||||
#define CDELETESELECTIONCOMMAND_H
|
#define CDELETESELECTIONCOMMAND_H
|
||||||
|
|
||||||
|
#include "CDeleteLinksCommand.h"
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
|
||||||
|
// todo: currently only supports deleting script nodes; needs support for light nodes as well
|
||||||
|
// plus maybe it should be extensible enough to support other possible types
|
||||||
class CDeleteSelectionCommand : public IUndoCommand
|
class CDeleteSelectionCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CWorldEditor *mpEditor;
|
CWorldEditor *mpEditor;
|
||||||
QList<CSceneNode*> mNodesToDelete;
|
CNodePtrList mOldSelection;
|
||||||
QList<CSceneNode*> mOldSelection;
|
CNodePtrList mNewSelection;
|
||||||
QList<CSceneNode*> mNewSelection;
|
|
||||||
|
struct SDeletedNode
|
||||||
|
{
|
||||||
|
// Node Info
|
||||||
|
CNodePtr NodePtr;
|
||||||
|
u32 NodeID;
|
||||||
|
CVector3f Position;
|
||||||
|
CQuaternion Rotation;
|
||||||
|
CVector3f Scale;
|
||||||
|
|
||||||
|
// Instance Info
|
||||||
|
CGameArea *pArea;
|
||||||
|
CScriptLayer *pLayer;
|
||||||
|
u32 LayerIndex;
|
||||||
|
std::vector<char> InstanceData;
|
||||||
|
};
|
||||||
|
QVector<SDeletedNode> mDeletedNodes;
|
||||||
|
|
||||||
|
struct SDeletedLink
|
||||||
|
{
|
||||||
|
u32 State;
|
||||||
|
u32 Message;
|
||||||
|
u32 SenderID;
|
||||||
|
u32 SenderIndex;
|
||||||
|
u32 ReceiverID;
|
||||||
|
u32 ReceiverIndex;
|
||||||
|
CInstancePtr pSender;
|
||||||
|
CInstancePtr pReceiver;
|
||||||
|
};
|
||||||
|
QVector<SDeletedLink> mDeletedLinks;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CDeleteSelectionCommand(CWorldEditor *pEditor);
|
CDeleteSelectionCommand(CWorldEditor *pEditor);
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
#define CDESELECTNODECOMMAND_H
|
#define CDESELECTNODECOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
|
||||||
class CDeselectNodeCommand : public IUndoCommand
|
class CDeselectNodeCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CSceneNode *mpNode;
|
CNodePtr mpNode;
|
||||||
CNodeSelection *mpSelection;
|
CNodeSelection *mpSelection;
|
||||||
public:
|
public:
|
||||||
CDeselectNodeCommand(CNodeSelection *pSelection, CSceneNode *pNode)
|
CDeselectNodeCommand(CNodeSelection *pSelection, CSceneNode *pNode)
|
||||||
|
@ -16,8 +17,8 @@ public:
|
||||||
, mpSelection(pSelection)
|
, mpSelection(pSelection)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void undo() { mpSelection->SelectNode(mpNode); }
|
void undo() { mpSelection->SelectNode(*mpNode); }
|
||||||
void redo() { mpSelection->DeselectNode(mpNode); }
|
void redo() { mpSelection->DeselectNode(*mpNode); }
|
||||||
bool AffectsCleanState() const { return false; }
|
bool AffectsCleanState() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,42 +9,49 @@ CEditLinkCommand::CEditLinkCommand(CWorldEditor *pEditor, CLink *pLink, CLink Ne
|
||||||
{
|
{
|
||||||
mOldSenderIndex = pLink->SenderIndex();
|
mOldSenderIndex = pLink->SenderIndex();
|
||||||
mOldReceiverIndex = pLink->ReceiverIndex();
|
mOldReceiverIndex = pLink->ReceiverIndex();
|
||||||
|
|
||||||
mAffectedInstances << pLink->Sender();
|
mAffectedInstances << pLink->Sender();
|
||||||
if (pLink->Receiver() != pLink->Sender()) mAffectedInstances << pLink->Receiver();
|
if (pLink->ReceiverID() != pLink->SenderID()) mAffectedInstances << pLink->Receiver();
|
||||||
if (NewLink.Sender() != pLink->Sender()) mAffectedInstances << NewLink.Sender();
|
if (NewLink.SenderID() != pLink->SenderID()) mAffectedInstances << NewLink.Sender();
|
||||||
if (NewLink.Receiver() != pLink->Receiver()) mAffectedInstances << NewLink.Receiver();
|
if (NewLink.ReceiverID() != pLink->ReceiverID()) mAffectedInstances << NewLink.Receiver();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditLinkCommand::undo()
|
void CEditLinkCommand::undo()
|
||||||
{
|
{
|
||||||
|
CLink *pLink = *mpEditLink;
|
||||||
|
|
||||||
if (mOldLink.Sender() != mNewLink.Sender())
|
if (mOldLink.Sender() != mNewLink.Sender())
|
||||||
{
|
{
|
||||||
mNewLink.Sender()->RemoveLink(eOutgoing, mpEditLink);
|
mNewLink.Sender()->RemoveLink(eOutgoing, pLink);
|
||||||
mOldLink.Sender()->AddLink(eOutgoing, mpEditLink, mOldSenderIndex);
|
mOldLink.Sender()->AddLink(eOutgoing, pLink, mOldSenderIndex);
|
||||||
}
|
}
|
||||||
if (mOldLink.Receiver() != mNewLink.Receiver())
|
if (mOldLink.Receiver() != mNewLink.Receiver())
|
||||||
{
|
{
|
||||||
mNewLink.Receiver()->RemoveLink(eIncoming, mpEditLink);
|
mNewLink.Receiver()->RemoveLink(eIncoming, pLink);
|
||||||
mOldLink.Receiver()->AddLink(eIncoming, mpEditLink, mOldReceiverIndex);
|
mOldLink.Receiver()->AddLink(eIncoming, pLink, mOldReceiverIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
*mpEditLink = mOldLink;
|
*pLink = mOldLink;
|
||||||
mpEditor->OnLinksModified(mAffectedInstances);
|
mpEditor->OnLinksModified(mAffectedInstances.DereferenceList());
|
||||||
|
mpEditLink.SetLink(pLink); // note: This is done to account for situations where the sender has changed
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditLinkCommand::redo()
|
void CEditLinkCommand::redo()
|
||||||
{
|
{
|
||||||
|
CLink *pLink = *mpEditLink;
|
||||||
|
|
||||||
if (mOldLink.Sender() != mNewLink.Sender())
|
if (mOldLink.Sender() != mNewLink.Sender())
|
||||||
{
|
{
|
||||||
mOldLink.Sender()->RemoveLink(eOutgoing, mpEditLink);
|
mOldLink.Sender()->RemoveLink(eOutgoing, pLink);
|
||||||
mNewLink.Sender()->AddLink(eOutgoing, mpEditLink);
|
mNewLink.Sender()->AddLink(eOutgoing, pLink);
|
||||||
}
|
}
|
||||||
if (mOldLink.Receiver() != mNewLink.Receiver())
|
if (mOldLink.Receiver() != mNewLink.Receiver())
|
||||||
{
|
{
|
||||||
mOldLink.Receiver()->RemoveLink(eIncoming, mpEditLink);
|
mOldLink.Receiver()->RemoveLink(eIncoming, pLink);
|
||||||
mNewLink.Receiver()->AddLink(eIncoming, mpEditLink);
|
mNewLink.Receiver()->AddLink(eIncoming, pLink);
|
||||||
}
|
}
|
||||||
|
|
||||||
*mpEditLink = mNewLink;
|
*pLink = mNewLink;
|
||||||
mpEditor->OnLinksModified(mAffectedInstances);
|
mpEditor->OnLinksModified(mAffectedInstances.DereferenceList());
|
||||||
|
mpEditLink.SetLink(pLink);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,23 +2,25 @@
|
||||||
#define CEDITLINKCOMMAND_H
|
#define CEDITLINKCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/WorldEditor/CWorldEditor.h"
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
#include <Core/Resource/Script/CLink.h>
|
#include <Core/Resource/Script/CLink.h>
|
||||||
|
|
||||||
class CEditLinkCommand : public IUndoCommand
|
class CEditLinkCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CWorldEditor *mpEditor;
|
CWorldEditor *mpEditor;
|
||||||
CLink *mpEditLink;
|
CLinkPtr mpEditLink;
|
||||||
|
|
||||||
CLink mOldLink;
|
CLink mOldLink;
|
||||||
CLink mNewLink;
|
CLink mNewLink;
|
||||||
u32 mOldSenderIndex;
|
u32 mOldSenderIndex;
|
||||||
u32 mOldReceiverIndex;
|
u32 mOldReceiverIndex;
|
||||||
|
|
||||||
QList<CScriptObject*> mAffectedInstances;
|
CInstancePtrList mAffectedInstances;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CEditLinkCommand(CWorldEditor *pEditor, CLink *pLink, CLink NewLink);
|
CEditLinkCommand(CWorldEditor *pEditor, CLink *pLink, CLink NewLink);
|
||||||
|
QList<CScriptObject*> AffectedInstances() const;
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
bool AffectsCleanState() const { return true; }
|
bool AffectsCleanState() const { return true; }
|
||||||
|
|
|
@ -2,11 +2,13 @@
|
||||||
#include "EUndoCommand.h"
|
#include "EUndoCommand.h"
|
||||||
|
|
||||||
CEditScriptPropertyCommand::CEditScriptPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, IPropertyValue *pOldValue, bool IsDone, const QString& rkCommandName /*= "Edit Property"*/)
|
CEditScriptPropertyCommand::CEditScriptPropertyCommand(IProperty *pProp, CWorldEditor *pEditor, IPropertyValue *pOldValue, bool IsDone, const QString& rkCommandName /*= "Edit Property"*/)
|
||||||
: CBasicPropertyCommand(pProp, pEditor, rkCommandName)
|
: IUndoCommand(rkCommandName)
|
||||||
|
, mpProp(pProp)
|
||||||
|
, mpEditor(pEditor)
|
||||||
, mCommandEnded(IsDone)
|
, mCommandEnded(IsDone)
|
||||||
{
|
{
|
||||||
mpOldValue = pOldValue;
|
mpOldValue = pOldValue;
|
||||||
mpNewValue = mpProperty->RawValue()->Clone();
|
mpNewValue = pProp->RawValue()->Clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
CEditScriptPropertyCommand::~CEditScriptPropertyCommand()
|
CEditScriptPropertyCommand::~CEditScriptPropertyCommand()
|
||||||
|
@ -26,7 +28,7 @@ bool CEditScriptPropertyCommand::mergeWith(const QUndoCommand *pkOther)
|
||||||
{
|
{
|
||||||
const CEditScriptPropertyCommand *pkCmd = static_cast<const CEditScriptPropertyCommand*>(pkOther);
|
const CEditScriptPropertyCommand *pkCmd = static_cast<const CEditScriptPropertyCommand*>(pkOther);
|
||||||
|
|
||||||
if (pkCmd->mpProperty == mpProperty)
|
if (pkCmd->mpProp == mpProp)
|
||||||
{
|
{
|
||||||
mpNewValue->Copy(pkCmd->mpNewValue);
|
mpNewValue->Copy(pkCmd->mpNewValue);
|
||||||
mCommandEnded = pkCmd->mCommandEnded;
|
mCommandEnded = pkCmd->mCommandEnded;
|
||||||
|
@ -39,15 +41,15 @@ bool CEditScriptPropertyCommand::mergeWith(const QUndoCommand *pkOther)
|
||||||
|
|
||||||
void CEditScriptPropertyCommand::undo()
|
void CEditScriptPropertyCommand::undo()
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
IProperty *pProp = *mpProp;
|
||||||
mpProperty->RawValue()->Copy(mpOldValue);
|
pProp->RawValue()->Copy(mpOldValue);
|
||||||
mpEditor->OnPropertyModified(mpProperty);
|
mpEditor->OnPropertyModified(pProp);
|
||||||
mCommandEnded = true;
|
mCommandEnded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditScriptPropertyCommand::redo()
|
void CEditScriptPropertyCommand::redo()
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
IProperty *pProp = *mpProp;
|
||||||
mpProperty->RawValue()->Copy(mpNewValue);
|
pProp->RawValue()->Copy(mpNewValue);
|
||||||
mpEditor->OnPropertyModified(mpProperty);
|
mpEditor->OnPropertyModified(pProp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
#ifndef CEDITSCRIPTPROPERTYCOMMAND_H
|
#ifndef CEDITSCRIPTPROPERTYCOMMAND_H
|
||||||
#define CEDITSCRIPTPROPERTYCOMMAND_H
|
#define CEDITSCRIPTPROPERTYCOMMAND_H
|
||||||
|
|
||||||
#include "CBasicPropertyCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
|
|
||||||
class CEditScriptPropertyCommand : public CBasicPropertyCommand
|
class CEditScriptPropertyCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
|
CWorldEditor *mpEditor;
|
||||||
|
CPropertyPtr mpProp;
|
||||||
IPropertyValue *mpOldValue;
|
IPropertyValue *mpOldValue;
|
||||||
IPropertyValue *mpNewValue;
|
IPropertyValue *mpNewValue;
|
||||||
bool mCommandEnded;
|
bool mCommandEnded;
|
||||||
|
@ -17,6 +21,7 @@ public:
|
||||||
bool mergeWith(const QUndoCommand *pkOther);
|
bool mergeWith(const QUndoCommand *pkOther);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
|
bool AffectsCleanState() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CEDITSCRIPTPROPERTYCOMMAND_H
|
#endif // CEDITSCRIPTPROPERTYCOMMAND_H
|
||||||
|
|
|
@ -2,14 +2,15 @@
|
||||||
#define CINVERTSELECTIONCOMMAND_H
|
#define CINVERTSELECTIONCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
|
||||||
class CInvertSelectionCommand : public IUndoCommand
|
class CInvertSelectionCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CNodeSelection *mpSelection;
|
CNodeSelection *mpSelection;
|
||||||
QList<CSceneNode*> mOldSelection;
|
CNodePtrList mOldSelection;
|
||||||
QList<CSceneNode*> mNewSelection;
|
CNodePtrList mNewSelection;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CInvertSelectionCommand(CNodeSelection *pSelection, CScene *pScene, FNodeFlags NodeFlags)
|
CInvertSelectionCommand(CNodeSelection *pSelection, CScene *pScene, FNodeFlags NodeFlags)
|
||||||
|
@ -25,8 +26,8 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() { mpSelection->SetSelectedNodes(mOldSelection); }
|
void undo() { mpSelection->SetSelectedNodes(mOldSelection.DereferenceList()); }
|
||||||
void redo() { mpSelection->SetSelectedNodes(mNewSelection); }
|
void redo() { mpSelection->SetSelectedNodes(mNewSelection.DereferenceList()); }
|
||||||
bool AffectsCleanState() const { return false; }
|
bool AffectsCleanState() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,22 @@
|
||||||
#include "CResizeScriptArrayCommand.h"
|
#include "CResizeScriptArrayCommand.h"
|
||||||
|
|
||||||
CResizeScriptArrayCommand::CResizeScriptArrayCommand(IProperty *pProp, CWorldEditor *pEditor, CPropertyModel *pModel, int NewSize)
|
CResizeScriptArrayCommand::CResizeScriptArrayCommand(IProperty *pProp, CWorldEditor *pEditor, CPropertyModel *pModel, int NewSize)
|
||||||
: CBasicPropertyCommand(pProp, pEditor)
|
: IUndoCommand("Edit Property")
|
||||||
, mpArray(static_cast<CArrayProperty*>(mpProperty))
|
, mpEditor(pEditor)
|
||||||
|
, mpArray(pProp)
|
||||||
, mpModel(pModel)
|
, mpModel(pModel)
|
||||||
, mOldSize(mpArray->Count())
|
, mOldSize(static_cast<CArrayProperty*>(pProp)->Count())
|
||||||
, mNewSize(NewSize)
|
, mNewSize(NewSize)
|
||||||
{
|
{
|
||||||
mNewSizeLarger = mNewSize > mOldSize;
|
mNewSizeLarger = mNewSize > mOldSize;
|
||||||
|
|
||||||
if (!mNewSizeLarger)
|
if (!mNewSizeLarger)
|
||||||
{
|
{
|
||||||
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(pProp);
|
||||||
|
|
||||||
for (int iSub = mNewSize; iSub < mOldSize; iSub++)
|
for (int iSub = mNewSize; iSub < mOldSize; iSub++)
|
||||||
{
|
{
|
||||||
mDeletedProperties << mpArray->PropertyByIndex(iSub)->Clone();
|
mDeletedProperties << pArray->PropertyByIndex(iSub)->Clone(nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,11 +31,16 @@ void CResizeScriptArrayCommand::undo()
|
||||||
{
|
{
|
||||||
if (mNewSize != mOldSize)
|
if (mNewSize != mOldSize)
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
// Update parents
|
||||||
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(*mpArray);
|
||||||
|
|
||||||
QModelIndex Index = mpModel->IndexForProperty(mpProperty);
|
foreach (IProperty *pProp, mDeletedProperties)
|
||||||
|
pProp->SetParent(pArray);
|
||||||
|
|
||||||
|
// Resize array
|
||||||
|
QModelIndex Index = mpModel->IndexForProperty(pArray);
|
||||||
mpModel->ArrayAboutToBeResized(Index, (u32) mOldSize);
|
mpModel->ArrayAboutToBeResized(Index, (u32) mOldSize);
|
||||||
mpArray->Resize(mOldSize);
|
pArray->Resize(mOldSize);
|
||||||
|
|
||||||
if (!mNewSizeLarger)
|
if (!mNewSizeLarger)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +49,7 @@ void CResizeScriptArrayCommand::undo()
|
||||||
for (int iSub = 0; iSub < NumNewElements; iSub++)
|
for (int iSub = 0; iSub < NumNewElements; iSub++)
|
||||||
{
|
{
|
||||||
u32 Idx = iSub + mNewSize;
|
u32 Idx = iSub + mNewSize;
|
||||||
mpArray->PropertyByIndex(Idx)->Copy(mDeletedProperties[iSub]);
|
pArray->PropertyByIndex(Idx)->Copy(mDeletedProperties[iSub]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,24 +62,10 @@ void CResizeScriptArrayCommand::redo()
|
||||||
// Whether we're increasing or decreasing in size, there's no need to restore deleted properties on redo.
|
// Whether we're increasing or decreasing in size, there's no need to restore deleted properties on redo.
|
||||||
if (mNewSize != mOldSize)
|
if (mNewSize != mOldSize)
|
||||||
{
|
{
|
||||||
if (mIsInArray) UpdateArraySubProperty();
|
CArrayProperty *pArray = static_cast<CArrayProperty*>(*mpArray);
|
||||||
|
QModelIndex Index = mpModel->IndexForProperty(pArray);
|
||||||
QModelIndex Index = mpModel->IndexForProperty(mpProperty);
|
|
||||||
mpModel->ArrayAboutToBeResized(Index, (u32) mNewSize);
|
mpModel->ArrayAboutToBeResized(Index, (u32) mNewSize);
|
||||||
mpArray->Resize(mNewSize);
|
pArray->Resize(mNewSize);
|
||||||
mpModel->ArrayResized(Index, (u32) mOldSize);
|
mpModel->ArrayResized(Index, (u32) mOldSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CResizeScriptArrayCommand::UpdateArraySubProperty()
|
|
||||||
{
|
|
||||||
CArrayProperty *pOldArray = mpArray;
|
|
||||||
CBasicPropertyCommand::UpdateArraySubProperty();
|
|
||||||
mpArray = static_cast<CArrayProperty*>(mpProperty);
|
|
||||||
|
|
||||||
if (pOldArray != mpArray)
|
|
||||||
{
|
|
||||||
for (int iDel = 0; iDel < mDeletedProperties.size(); iDel++)
|
|
||||||
mDeletedProperties[iDel]->SetParent(mpArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,13 +1,17 @@
|
||||||
#ifndef CRESIZESCRIPTARRAYCOMMAND_H
|
#ifndef CRESIZESCRIPTARRAYCOMMAND_H
|
||||||
#define CRESIZESCRIPTARRAYCOMMAND_H
|
#define CRESIZESCRIPTARRAYCOMMAND_H
|
||||||
|
|
||||||
#include "CBasicPropertyCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/PropertyEdit/CPropertyModel.h"
|
#include "Editor/PropertyEdit/CPropertyModel.h"
|
||||||
|
#include "Editor/WorldEditor/CWorldEditor.h"
|
||||||
#include <QUndoCommand>
|
#include <QUndoCommand>
|
||||||
|
|
||||||
class CResizeScriptArrayCommand : public CBasicPropertyCommand
|
// todo: make this more general... it shouldn't be relying on a CPropertyModel pointer
|
||||||
|
class CResizeScriptArrayCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CArrayProperty *mpArray;
|
CWorldEditor *mpEditor;
|
||||||
|
CPropertyPtr mpArray;
|
||||||
QVector<IProperty*> mDeletedProperties;
|
QVector<IProperty*> mDeletedProperties;
|
||||||
CPropertyModel *mpModel;
|
CPropertyModel *mpModel;
|
||||||
|
|
||||||
|
@ -20,7 +24,7 @@ public:
|
||||||
~CResizeScriptArrayCommand();
|
~CResizeScriptArrayCommand();
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
virtual void UpdateArraySubProperty();
|
bool AffectsCleanState() const { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CRESIZESCRIPTARRAYCOMMAND_H
|
#endif // CRESIZESCRIPTARRAYCOMMAND_H
|
||||||
|
|
|
@ -9,23 +9,23 @@ CRotateNodeCommand::CRotateNodeCommand()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& nodes, const CVector3f& /*pivot*/, const CQuaternion& delta, ETransformSpace transformSpace)
|
CRotateNodeCommand::CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& /*rkPivot*/, const CQuaternion& rkDelta, ETransformSpace TransformSpace)
|
||||||
: IUndoCommand("Rotate"),
|
: IUndoCommand("Rotate"),
|
||||||
mpEditor(pEditor),
|
mpEditor(pEditor),
|
||||||
mCommandEnded(false)
|
mCommandEnded(false)
|
||||||
{
|
{
|
||||||
mNodeList.reserve(nodes.size());
|
mNodeList.reserve(rkNodes.size());
|
||||||
|
|
||||||
foreach (CSceneNode *pNode, nodes)
|
foreach (CSceneNode *pNode, rkNodes)
|
||||||
{
|
{
|
||||||
SNodeRotate rotate;
|
SNodeRotate Rotate;
|
||||||
rotate.pNode = pNode;
|
Rotate.pNode = pNode;
|
||||||
rotate.initialPos = pNode->LocalPosition();
|
Rotate.InitialPos = pNode->LocalPosition();
|
||||||
rotate.initialRot = pNode->LocalRotation();
|
Rotate.InitialRot = pNode->LocalRotation();
|
||||||
pNode->Rotate(delta, transformSpace);
|
pNode->Rotate(rkDelta, TransformSpace);
|
||||||
rotate.newPos = pNode->LocalPosition();
|
Rotate.NewPos = pNode->LocalPosition();
|
||||||
rotate.newRot = pNode->LocalRotation();
|
Rotate.NewRot = pNode->LocalRotation();
|
||||||
mNodeList.push_back(rotate);
|
mNodeList.push_back(Rotate);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
|
@ -40,26 +40,26 @@ int CRotateNodeCommand::id() const
|
||||||
return eRotateNodeCmd;
|
return eRotateNodeCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRotateNodeCommand::mergeWith(const QUndoCommand *other)
|
bool CRotateNodeCommand::mergeWith(const QUndoCommand *pkOther)
|
||||||
{
|
{
|
||||||
if (mCommandEnded) return false;
|
if (mCommandEnded) return false;
|
||||||
|
|
||||||
if (other->id() == eRotateNodeCmd)
|
if (pkOther->id() == eRotateNodeCmd)
|
||||||
{
|
{
|
||||||
const CRotateNodeCommand *pCmd = static_cast<const CRotateNodeCommand*>(other);
|
const CRotateNodeCommand *pkCmd = static_cast<const CRotateNodeCommand*>(pkOther);
|
||||||
|
|
||||||
if (pCmd->mCommandEnded)
|
if (pkCmd->mCommandEnded)
|
||||||
{
|
{
|
||||||
mCommandEnded = true;
|
mCommandEnded = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mpEditor == pCmd->mpEditor) && (mNodeList.size() == pCmd->mNodeList.size()))
|
if ((mpEditor == pkCmd->mpEditor) && (mNodeList.size() == pkCmd->mNodeList.size()))
|
||||||
{
|
{
|
||||||
for (int iNode = 0; iNode < mNodeList.size(); iNode++)
|
for (int iNode = 0; iNode < mNodeList.size(); iNode++)
|
||||||
{
|
{
|
||||||
mNodeList[iNode].newPos = pCmd->mNodeList[iNode].newPos;
|
mNodeList[iNode].NewPos = pkCmd->mNodeList[iNode].NewPos;
|
||||||
mNodeList[iNode].newRot = pCmd->mNodeList[iNode].newRot;
|
mNodeList[iNode].NewRot = pkCmd->mNodeList[iNode].NewRot;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -73,10 +73,10 @@ void CRotateNodeCommand::undo()
|
||||||
{
|
{
|
||||||
if (!mpEditor) return;
|
if (!mpEditor) return;
|
||||||
|
|
||||||
foreach (SNodeRotate rotate, mNodeList)
|
foreach (SNodeRotate Rotate, mNodeList)
|
||||||
{
|
{
|
||||||
rotate.pNode->SetPosition(rotate.initialPos);
|
Rotate.pNode->SetPosition(Rotate.InitialPos);
|
||||||
rotate.pNode->SetRotation(rotate.initialRot);
|
Rotate.pNode->SetRotation(Rotate.InitialRot);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
|
@ -87,10 +87,10 @@ void CRotateNodeCommand::redo()
|
||||||
{
|
{
|
||||||
if (!mpEditor) return;
|
if (!mpEditor) return;
|
||||||
|
|
||||||
foreach (SNodeRotate rotate, mNodeList)
|
foreach (SNodeRotate Rotate, mNodeList)
|
||||||
{
|
{
|
||||||
rotate.pNode->SetPosition(rotate.newPos);
|
Rotate.pNode->SetPosition(Rotate.NewPos);
|
||||||
rotate.pNode->SetRotation(rotate.newRot);
|
Rotate.pNode->SetRotation(Rotate.NewRot);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CROTATENODECOMMAND_H
|
#define CROTATENODECOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
@ -10,11 +11,11 @@ class CRotateNodeCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
struct SNodeRotate
|
struct SNodeRotate
|
||||||
{
|
{
|
||||||
CSceneNode *pNode;
|
CNodePtr pNode;
|
||||||
CVector3f initialPos;
|
CVector3f InitialPos;
|
||||||
CQuaternion initialRot;
|
CQuaternion InitialRot;
|
||||||
CVector3f newPos;
|
CVector3f NewPos;
|
||||||
CQuaternion newRot;
|
CQuaternion NewRot;
|
||||||
};
|
};
|
||||||
QList<SNodeRotate> mNodeList;
|
QList<SNodeRotate> mNodeList;
|
||||||
INodeEditor *mpEditor;
|
INodeEditor *mpEditor;
|
||||||
|
@ -22,10 +23,10 @@ class CRotateNodeCommand : public IUndoCommand
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CRotateNodeCommand();
|
CRotateNodeCommand();
|
||||||
CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& nodes, const CVector3f& pivot, const CQuaternion& delta, ETransformSpace transformSpace);
|
CRotateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& rkPivot, const CQuaternion& rkDelta, ETransformSpace TransformSpace);
|
||||||
~CRotateNodeCommand();
|
~CRotateNodeCommand();
|
||||||
int id() const;
|
int id() const;
|
||||||
bool mergeWith(const QUndoCommand *other);
|
bool mergeWith(const QUndoCommand *pkOther);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
bool AffectsCleanState() const { return true; }
|
bool AffectsCleanState() const { return true; }
|
||||||
|
|
|
@ -9,23 +9,23 @@ CScaleNodeCommand::CScaleNodeCommand()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& nodes, const CVector3f& /*pivot*/, const CVector3f& delta)
|
CScaleNodeCommand::CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& /*rkPivot*/, const CVector3f& rkDelta)
|
||||||
: IUndoCommand("Scale"),
|
: IUndoCommand("Scale"),
|
||||||
mpEditor(pEditor),
|
mpEditor(pEditor),
|
||||||
mCommandEnded(false)
|
mCommandEnded(false)
|
||||||
{
|
{
|
||||||
mNodeList.reserve(nodes.size());
|
mNodeList.reserve(rkNodes.size());
|
||||||
|
|
||||||
foreach (CSceneNode *pNode, nodes)
|
foreach (CSceneNode *pNode, rkNodes)
|
||||||
{
|
{
|
||||||
SNodeScale scale;
|
SNodeScale Scale;
|
||||||
scale.pNode = pNode;
|
Scale.pNode = pNode;
|
||||||
scale.initialPos = pNode->LocalPosition();
|
Scale.InitialPos = pNode->LocalPosition();
|
||||||
scale.initialScale = pNode->LocalScale();
|
Scale.InitialScale = pNode->LocalScale();
|
||||||
pNode->Scale(delta);
|
pNode->Scale(rkDelta);
|
||||||
scale.newPos = pNode->LocalPosition();
|
Scale.NewPos = pNode->LocalPosition();
|
||||||
scale.newScale = pNode->LocalScale();
|
Scale.NewScale = pNode->LocalScale();
|
||||||
mNodeList.push_back(scale);
|
mNodeList.push_back(Scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
|
@ -40,26 +40,26 @@ int CScaleNodeCommand::id() const
|
||||||
return eScaleNodeCmd;
|
return eScaleNodeCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CScaleNodeCommand::mergeWith(const QUndoCommand *other)
|
bool CScaleNodeCommand::mergeWith(const QUndoCommand *pkOther)
|
||||||
{
|
{
|
||||||
if (mCommandEnded) return false;
|
if (mCommandEnded) return false;
|
||||||
|
|
||||||
if (other->id() == eScaleNodeCmd)
|
if (pkOther->id() == eScaleNodeCmd)
|
||||||
{
|
{
|
||||||
const CScaleNodeCommand *pCmd = static_cast<const CScaleNodeCommand*>(other);
|
const CScaleNodeCommand *pkCmd = static_cast<const CScaleNodeCommand*>(pkOther);
|
||||||
|
|
||||||
if (pCmd->mCommandEnded)
|
if (pkCmd->mCommandEnded)
|
||||||
{
|
{
|
||||||
mCommandEnded = true;
|
mCommandEnded = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mpEditor == pCmd->mpEditor) && (mNodeList.size() == pCmd->mNodeList.size()))
|
if ((mpEditor == pkCmd->mpEditor) && (mNodeList.size() == pkCmd->mNodeList.size()))
|
||||||
{
|
{
|
||||||
for (int iNode = 0; iNode < mNodeList.size(); iNode++)
|
for (int iNode = 0; iNode < mNodeList.size(); iNode++)
|
||||||
{
|
{
|
||||||
mNodeList[iNode].newPos = pCmd->mNodeList[iNode].newPos;
|
mNodeList[iNode].NewPos = pkCmd->mNodeList[iNode].NewPos;
|
||||||
mNodeList[iNode].newScale = pCmd->mNodeList[iNode].newScale;
|
mNodeList[iNode].NewScale = pkCmd->mNodeList[iNode].NewScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -73,10 +73,10 @@ void CScaleNodeCommand::undo()
|
||||||
{
|
{
|
||||||
if (!mpEditor) return;
|
if (!mpEditor) return;
|
||||||
|
|
||||||
foreach (SNodeScale scale, mNodeList)
|
foreach (SNodeScale Scale, mNodeList)
|
||||||
{
|
{
|
||||||
scale.pNode->SetPosition(scale.initialPos);
|
Scale.pNode->SetPosition(Scale.InitialPos);
|
||||||
scale.pNode->SetScale(scale.initialScale);
|
Scale.pNode->SetScale(Scale.InitialScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
|
@ -87,10 +87,10 @@ void CScaleNodeCommand::redo()
|
||||||
{
|
{
|
||||||
if (!mpEditor) return;
|
if (!mpEditor) return;
|
||||||
|
|
||||||
foreach (SNodeScale scale, mNodeList)
|
foreach (SNodeScale Scale, mNodeList)
|
||||||
{
|
{
|
||||||
scale.pNode->SetPosition(scale.newPos);
|
Scale.pNode->SetPosition(Scale.NewPos);
|
||||||
scale.pNode->SetScale(scale.newScale);
|
Scale.pNode->SetScale(Scale.NewScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CSCALENODECOMMAND_H
|
#define CSCALENODECOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
@ -10,11 +11,11 @@ class CScaleNodeCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
struct SNodeScale
|
struct SNodeScale
|
||||||
{
|
{
|
||||||
CSceneNode *pNode;
|
CNodePtr pNode;
|
||||||
CVector3f initialPos;
|
CVector3f InitialPos;
|
||||||
CVector3f initialScale;
|
CVector3f InitialScale;
|
||||||
CVector3f newPos;
|
CVector3f NewPos;
|
||||||
CVector3f newScale;
|
CVector3f NewScale;
|
||||||
};
|
};
|
||||||
QList<SNodeScale> mNodeList;
|
QList<SNodeScale> mNodeList;
|
||||||
INodeEditor *mpEditor;
|
INodeEditor *mpEditor;
|
||||||
|
@ -22,10 +23,10 @@ class CScaleNodeCommand : public IUndoCommand
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CScaleNodeCommand();
|
CScaleNodeCommand();
|
||||||
CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& nodes, const CVector3f& pivot, const CVector3f& delta);
|
CScaleNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& rkPivot, const CVector3f& rkDelta);
|
||||||
~CScaleNodeCommand();
|
~CScaleNodeCommand();
|
||||||
int id() const;
|
int id() const;
|
||||||
bool mergeWith(const QUndoCommand *other);
|
bool mergeWith(const QUndoCommand *pkOther);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
bool AffectsCleanState() const { return true; }
|
bool AffectsCleanState() const { return true; }
|
||||||
|
|
|
@ -2,27 +2,30 @@
|
||||||
#define CSELECTALLCOMMAND_H
|
#define CSELECTALLCOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
|
#include "Editor/CSelectionIterator.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
|
||||||
class CSelectAllCommand : public IUndoCommand
|
class CSelectAllCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
QList<CSceneNode*> mOldSelection;
|
CNodePtrList mOldSelection;
|
||||||
QList<CSceneNode*> mNewSelection;
|
CNodePtrList mNewSelection;
|
||||||
CNodeSelection *mpSelection;
|
CNodeSelection *mpSelection;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CSelectAllCommand(CNodeSelection *pSelection, CScene *pScene, FNodeFlags NodeFlags)
|
CSelectAllCommand(CNodeSelection *pSelection, CScene *pScene, FNodeFlags NodeFlags)
|
||||||
: IUndoCommand("Select All")
|
: IUndoCommand("Select All")
|
||||||
, mOldSelection(pSelection->SelectedNodeList())
|
|
||||||
, mpSelection(pSelection)
|
, mpSelection(pSelection)
|
||||||
{
|
{
|
||||||
|
for (CSelectionIterator It(pSelection); It; ++It)
|
||||||
|
mOldSelection << *It;
|
||||||
for (CSceneIterator It(pScene, NodeFlags); It; ++It)
|
for (CSceneIterator It(pScene, NodeFlags); It; ++It)
|
||||||
mNewSelection << *It;
|
mNewSelection << *It;
|
||||||
}
|
}
|
||||||
|
|
||||||
void undo() { mpSelection->SetSelectedNodes(mOldSelection); }
|
void undo() { mpSelection->SetSelectedNodes(mOldSelection.DereferenceList()); }
|
||||||
void redo() { mpSelection->SetSelectedNodes(mNewSelection); }
|
void redo() { mpSelection->SetSelectedNodes(mNewSelection.DereferenceList()); }
|
||||||
bool AffectsCleanState() const { return false; }
|
bool AffectsCleanState() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,13 @@
|
||||||
#define CSELECTNODECOMMAND_H
|
#define CSELECTNODECOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
|
||||||
class CSelectNodeCommand : public IUndoCommand
|
class CSelectNodeCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
CSceneNode *mpNode;
|
CNodePtr mpNode;
|
||||||
CNodeSelection *mpSelection;
|
CNodeSelection *mpSelection;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -17,8 +18,8 @@ public:
|
||||||
, mpSelection(pSelection)
|
, mpSelection(pSelection)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void undo() { mpSelection->DeselectNode(mpNode); }
|
void undo() { mpSelection->DeselectNode(*mpNode); }
|
||||||
void redo() { mpSelection->SelectNode(mpNode); }
|
void redo() { mpSelection->SelectNode(*mpNode); }
|
||||||
bool AffectsCleanState() const { return false; }
|
bool AffectsCleanState() const { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,53 +9,49 @@ CTranslateNodeCommand::CTranslateNodeCommand()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
CTranslateNodeCommand::CTranslateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& nodes, const CVector3f& delta, ETransformSpace transformSpace)
|
CTranslateNodeCommand::CTranslateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& Delta, ETransformSpace TransformSpace)
|
||||||
: IUndoCommand("Translate"),
|
: IUndoCommand("Translate"),
|
||||||
mpEditor(pEditor),
|
mpEditor(pEditor),
|
||||||
mCommandEnded(false)
|
mCommandEnded(false)
|
||||||
{
|
{
|
||||||
mNodeList.reserve(nodes.size());
|
mNodeList.reserve(rkNodes.size());
|
||||||
|
|
||||||
foreach (CSceneNode *pNode, nodes)
|
foreach (CSceneNode *pNode, rkNodes)
|
||||||
{
|
{
|
||||||
SNodeTranslate translate;
|
SNodeTranslate Translate;
|
||||||
translate.pNode = pNode;
|
Translate.pNode = pNode;
|
||||||
translate.initialPos = pNode->LocalPosition();
|
Translate.InitialPos = pNode->LocalPosition();
|
||||||
pNode->Translate(delta, transformSpace);
|
pNode->Translate(Delta, TransformSpace);
|
||||||
translate.newPos = pNode->LocalPosition();
|
Translate.NewPos = pNode->LocalPosition();
|
||||||
mNodeList.push_back(translate);
|
mNodeList.push_back(Translate);
|
||||||
}
|
}
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
}
|
}
|
||||||
|
|
||||||
CTranslateNodeCommand::~CTranslateNodeCommand()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
int CTranslateNodeCommand::id() const
|
int CTranslateNodeCommand::id() const
|
||||||
{
|
{
|
||||||
return eTranslateNodeCmd;
|
return eTranslateNodeCmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CTranslateNodeCommand::mergeWith(const QUndoCommand *other)
|
bool CTranslateNodeCommand::mergeWith(const QUndoCommand *pkOther)
|
||||||
{
|
{
|
||||||
if (mCommandEnded) return false;
|
if (mCommandEnded) return false;
|
||||||
|
|
||||||
if (other->id() == eTranslateNodeCmd)
|
if (pkOther->id() == eTranslateNodeCmd)
|
||||||
{
|
{
|
||||||
const CTranslateNodeCommand *pCmd = static_cast<const CTranslateNodeCommand*>(other);
|
const CTranslateNodeCommand *pkCmd = static_cast<const CTranslateNodeCommand*>(pkOther);
|
||||||
|
|
||||||
if (pCmd->mCommandEnded)
|
if (pkCmd->mCommandEnded)
|
||||||
{
|
{
|
||||||
mCommandEnded = true;
|
mCommandEnded = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mpEditor == pCmd->mpEditor) && (mNodeList.size() == pCmd->mNodeList.size()))
|
if ((mpEditor == pkCmd->mpEditor) && (mNodeList.size() == pkCmd->mNodeList.size()))
|
||||||
{
|
{
|
||||||
for (int iNode = 0; iNode < mNodeList.size(); iNode++)
|
for (int iNode = 0; iNode < mNodeList.size(); iNode++)
|
||||||
mNodeList[iNode].newPos = pCmd->mNodeList[iNode].newPos;
|
mNodeList[iNode].NewPos = pkCmd->mNodeList[iNode].NewPos;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +64,8 @@ void CTranslateNodeCommand::undo()
|
||||||
{
|
{
|
||||||
if (!mpEditor) return;
|
if (!mpEditor) return;
|
||||||
|
|
||||||
foreach (SNodeTranslate translate, mNodeList)
|
foreach (SNodeTranslate Translate, mNodeList)
|
||||||
translate.pNode->SetPosition(translate.initialPos);
|
Translate.pNode->SetPosition(Translate.InitialPos);
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
mpEditor->UpdateGizmoUI();
|
mpEditor->UpdateGizmoUI();
|
||||||
|
@ -79,8 +75,8 @@ void CTranslateNodeCommand::redo()
|
||||||
{
|
{
|
||||||
if (!mpEditor) return;
|
if (!mpEditor) return;
|
||||||
|
|
||||||
foreach (SNodeTranslate translate, mNodeList)
|
foreach (SNodeTranslate Translate, mNodeList)
|
||||||
translate.pNode->SetPosition(translate.newPos);
|
Translate.pNode->SetPosition(Translate.NewPos);
|
||||||
|
|
||||||
mpEditor->NotifySelectionTransformed();
|
mpEditor->NotifySelectionTransformed();
|
||||||
mpEditor->UpdateGizmoUI();
|
mpEditor->UpdateGizmoUI();
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define CTRANSLATENODECOMMAND_H
|
#define CTRANSLATENODECOMMAND_H
|
||||||
|
|
||||||
#include "IUndoCommand.h"
|
#include "IUndoCommand.h"
|
||||||
|
#include "ObjReferences.h"
|
||||||
#include <Core/Scene/CSceneNode.h>
|
#include <Core/Scene/CSceneNode.h>
|
||||||
#include "Editor/INodeEditor.h"
|
#include "Editor/INodeEditor.h"
|
||||||
#include <QList>
|
#include <QList>
|
||||||
|
@ -10,9 +11,9 @@ class CTranslateNodeCommand : public IUndoCommand
|
||||||
{
|
{
|
||||||
struct SNodeTranslate
|
struct SNodeTranslate
|
||||||
{
|
{
|
||||||
CSceneNode *pNode;
|
CNodePtr pNode;
|
||||||
CVector3f initialPos;
|
CVector3f InitialPos;
|
||||||
CVector3f newPos;
|
CVector3f NewPos;
|
||||||
};
|
};
|
||||||
QList<SNodeTranslate> mNodeList;
|
QList<SNodeTranslate> mNodeList;
|
||||||
INodeEditor *mpEditor;
|
INodeEditor *mpEditor;
|
||||||
|
@ -20,10 +21,9 @@ class CTranslateNodeCommand : public IUndoCommand
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CTranslateNodeCommand();
|
CTranslateNodeCommand();
|
||||||
CTranslateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& nodes, const CVector3f& delta, ETransformSpace transformSpace);
|
CTranslateNodeCommand(INodeEditor *pEditor, const QList<CSceneNode*>& rkNodes, const CVector3f& rkDelta, ETransformSpace TransformSpace);
|
||||||
~CTranslateNodeCommand();
|
|
||||||
int id() const;
|
int id() const;
|
||||||
bool mergeWith(const QUndoCommand *other);
|
bool mergeWith(const QUndoCommand *pkOther);
|
||||||
void undo();
|
void undo();
|
||||||
void redo();
|
void redo();
|
||||||
bool AffectsCleanState() const { return true; }
|
bool AffectsCleanState() const { return true; }
|
||||||
|
|
|
@ -0,0 +1,177 @@
|
||||||
|
#ifndef OBJREFERENCES
|
||||||
|
#define OBJREFERENCES
|
||||||
|
|
||||||
|
#include <Core/Resource/CGameArea.h>
|
||||||
|
#include <Core/Resource/Script/CLink.h>
|
||||||
|
#include <Core/Resource/Script/CScriptObject.h>
|
||||||
|
#include <Core/Scene/CScene.h>
|
||||||
|
#include <Core/Scene/CSceneNode.h>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The basic idea here is that over the course of editing and generally making changes
|
||||||
|
* in the editor, stuff tends to get created and deleted. When things are deleted they
|
||||||
|
* are actually deleted from memory, and recreated from scratch on undo. This poses a
|
||||||
|
* problem for undo actions that need to operate on a specific object because if their
|
||||||
|
* target object has been deleted and remade then the undo actions are stuck with a
|
||||||
|
* garbage pointer to deleted data. This generally results in crashes.
|
||||||
|
*
|
||||||
|
* These pointer classes solve the problem by encapsulating a reference to the object
|
||||||
|
* using IDs and indices instead of storing a direct pointer to the object itself. This
|
||||||
|
* way the correct object is always looked up from the area/scene/etc that it's from and
|
||||||
|
* the pointer is always valid. They are designed to be as easy and pain-free to use as
|
||||||
|
* possible.
|
||||||
|
*
|
||||||
|
* Most of this stuff could be moved to Core if it turns out to be useful in other places.
|
||||||
|
* QList dependencies would need to be removed but they could easily be replaced with
|
||||||
|
* std::list instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define DEFINE_PTR_LIST_CLASS(ClassName, PtrClassName, DereferencedClassName) \
|
||||||
|
class ClassName : public QList<PtrClassName> \
|
||||||
|
{ \
|
||||||
|
public: \
|
||||||
|
ClassName() : QList<PtrClassName>() {} \
|
||||||
|
\
|
||||||
|
ClassName(const QList<DereferencedClassName>& rkIn) \
|
||||||
|
{ \
|
||||||
|
foreach (DereferencedClassName InObj, rkIn) \
|
||||||
|
{ \
|
||||||
|
*this << InObj; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
QList<DereferencedClassName> DereferenceList() const \
|
||||||
|
{ \
|
||||||
|
QList<DereferencedClassName> Out; \
|
||||||
|
\
|
||||||
|
foreach (const PtrClassName& rkPtr, *this) \
|
||||||
|
Out << *rkPtr; \
|
||||||
|
\
|
||||||
|
return Out; \
|
||||||
|
} \
|
||||||
|
};
|
||||||
|
|
||||||
|
class CNodePtr
|
||||||
|
{
|
||||||
|
u32 mNodeID;
|
||||||
|
CScene *mpScene;
|
||||||
|
bool mValid;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CNodePtr() { SetNode(nullptr); }
|
||||||
|
CNodePtr(CSceneNode *pNode) { SetNode(pNode); }
|
||||||
|
|
||||||
|
inline void SetNode(CSceneNode *pNode)
|
||||||
|
{
|
||||||
|
mNodeID = pNode ? pNode->ID() : 0;
|
||||||
|
mpScene = pNode ? pNode->Scene() : nullptr;
|
||||||
|
mValid = pNode ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool Valid() const { return mValid; }
|
||||||
|
inline u32 NodeID() const { return mNodeID; }
|
||||||
|
inline CScene* Scene() const { return mpScene; }
|
||||||
|
inline CSceneNode* operator* () const { return mValid ? mpScene->NodeByID(mNodeID) : nullptr; }
|
||||||
|
inline CSceneNode* operator->() const { return mValid ? mpScene->NodeByID(mNodeID) : nullptr; }
|
||||||
|
inline CNodePtr& operator=(CSceneNode *pNode) { SetNode(pNode); return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const CNodePtr& rkOther) const
|
||||||
|
{
|
||||||
|
return (mNodeID == rkOther.mNodeID && mpScene == rkOther.mpScene);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CInstancePtr
|
||||||
|
{
|
||||||
|
u32 mInstanceID;
|
||||||
|
CGameArea *mpArea;
|
||||||
|
bool mValid;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CInstancePtr() { SetInstance(nullptr); }
|
||||||
|
CInstancePtr(CScriptObject *pInst) { SetInstance(pInst); }
|
||||||
|
|
||||||
|
inline void SetInstance(CScriptObject *pInst)
|
||||||
|
{
|
||||||
|
mInstanceID = pInst ? pInst->InstanceID() : 0;
|
||||||
|
mpArea = pInst ? pInst->Area() : nullptr;
|
||||||
|
mValid = pInst ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u32 InstanceID() const { return mInstanceID; }
|
||||||
|
inline CGameArea* Area() const { return mpArea; }
|
||||||
|
inline CScriptObject* operator* () const { return mValid ? mpArea->InstanceByID(mInstanceID) : nullptr; }
|
||||||
|
inline CScriptObject* operator->() const { return mValid ? mpArea->InstanceByID(mInstanceID) : nullptr; }
|
||||||
|
inline CInstancePtr& operator=(CScriptObject *pInst) { SetInstance(pInst); return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const CInstancePtr& rkOther) const
|
||||||
|
{
|
||||||
|
return (mInstanceID == rkOther.mInstanceID && mpArea == rkOther.mpArea);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CPropertyPtr
|
||||||
|
{
|
||||||
|
CInstancePtr mpInstance;
|
||||||
|
TIDString mPropertyID;
|
||||||
|
bool mValid;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CPropertyPtr() { SetProperty(nullptr); }
|
||||||
|
CPropertyPtr(IProperty *pProp) { SetProperty(pProp); }
|
||||||
|
|
||||||
|
inline void SetProperty(IProperty *pProp)
|
||||||
|
{
|
||||||
|
mpInstance = pProp ? pProp->Instance() : nullptr;
|
||||||
|
mPropertyID = pProp ? pProp->IDString(true) : "";
|
||||||
|
mValid = pProp ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline CInstancePtr InstancePtr() const { return mpInstance; }
|
||||||
|
inline TIDString PropertyID() const { return mPropertyID; }
|
||||||
|
inline IProperty* operator* () const { return mValid ? mpInstance->PropertyByIDString(mPropertyID) : nullptr; }
|
||||||
|
inline IProperty* operator->() const { return mValid ? mpInstance->PropertyByIDString(mPropertyID) : nullptr; }
|
||||||
|
inline CPropertyPtr& operator=(IProperty *pProp) { SetProperty(pProp); return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const CPropertyPtr& rkOther) const
|
||||||
|
{
|
||||||
|
return (mpInstance == rkOther.mpInstance && mPropertyID == rkOther.mPropertyID);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class CLinkPtr
|
||||||
|
{
|
||||||
|
CInstancePtr mpInstance;
|
||||||
|
u32 mLinkIndex;
|
||||||
|
bool mValid;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CLinkPtr() { SetLink(nullptr); }
|
||||||
|
CLinkPtr(CLink *pLink) { SetLink(pLink); }
|
||||||
|
|
||||||
|
inline void SetLink(CLink *pLink)
|
||||||
|
{
|
||||||
|
mpInstance = pLink ? pLink->Sender() : 0;
|
||||||
|
mLinkIndex = pLink ? pLink->SenderIndex() : 0;
|
||||||
|
mValid = pLink ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline u32 LinkIndex() const { return mLinkIndex; }
|
||||||
|
inline CLink* operator* () const { return mValid ? mpInstance->Link(eOutgoing, mLinkIndex) : nullptr; }
|
||||||
|
inline CLink* operator->() const { return mValid ? mpInstance->Link(eOutgoing, mLinkIndex) : nullptr; }
|
||||||
|
inline CLinkPtr& operator=(CLink *pLink) { SetLink(pLink); return *this; }
|
||||||
|
|
||||||
|
inline bool operator==(const CLinkPtr& rkOther) const
|
||||||
|
{
|
||||||
|
return (mpInstance == rkOther.mpInstance && mLinkIndex == rkOther.mLinkIndex);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DEFINE_PTR_LIST_CLASS(CNodePtrList, CNodePtr, CSceneNode*)
|
||||||
|
DEFINE_PTR_LIST_CLASS(CInstancePtrList, CInstancePtr, CScriptObject*)
|
||||||
|
DEFINE_PTR_LIST_CLASS(CPropertyPtrList, CPropertyPtr, IProperty*)
|
||||||
|
DEFINE_PTR_LIST_CLASS(CLinkPtrList, CLinkPtr, CLink*)
|
||||||
|
|
||||||
|
#endif // OBJREFERENCES
|
||||||
|
|
|
@ -35,7 +35,7 @@ CInstancesModel::CInstancesModel(QObject *pParent) : QAbstractItemModel(pParent)
|
||||||
mModelType = eLayers;
|
mModelType = eLayers;
|
||||||
mShowColumnEnabled = true;
|
mShowColumnEnabled = true;
|
||||||
mBaseItems << "Script";
|
mBaseItems << "Script";
|
||||||
mAddingOrRemovingRows = false;
|
mChangingLayout = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CInstancesModel::~CInstancesModel()
|
CInstancesModel::~CInstancesModel()
|
||||||
|
@ -377,15 +377,21 @@ CScriptObject* CInstancesModel::IndexObject(const QModelIndex& index) const
|
||||||
// ************ PUBLIC SLOTS ************
|
// ************ PUBLIC SLOTS ************
|
||||||
void CInstancesModel::NodeAboutToBeCreated()
|
void CInstancesModel::NodeAboutToBeCreated()
|
||||||
{
|
{
|
||||||
if (!mAddingOrRemovingRows)
|
if (!mChangingLayout)
|
||||||
{
|
{
|
||||||
emit layoutAboutToBeChanged();
|
emit layoutAboutToBeChanged();
|
||||||
mAddingOrRemovingRows = true;
|
mChangingLayout = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInstancesModel::NodeCreated(CSceneNode *pNode)
|
void CInstancesModel::NodeCreated(CSceneNode *pNode)
|
||||||
{
|
{
|
||||||
|
if (mChangingLayout)
|
||||||
|
{
|
||||||
|
emit layoutChanged();
|
||||||
|
mChangingLayout = false;
|
||||||
|
}
|
||||||
|
|
||||||
if (mModelType == eTypes)
|
if (mModelType == eTypes)
|
||||||
{
|
{
|
||||||
if (pNode->NodeType() == eScriptNode)
|
if (pNode->NodeType() == eScriptNode)
|
||||||
|
@ -411,22 +417,13 @@ void CInstancesModel::NodeCreated(CSceneNode *pNode)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit layoutChanged();
|
|
||||||
mAddingOrRemovingRows = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInstancesModel::NodeAboutToBeDeleted(CSceneNode *pNode)
|
void CInstancesModel::NodeAboutToBeDeleted(CSceneNode *pNode)
|
||||||
{
|
{
|
||||||
if (!mAddingOrRemovingRows)
|
if (pNode->NodeType() == eScriptNode)
|
||||||
{
|
{
|
||||||
emit layoutAboutToBeChanged();
|
if (mModelType == eTypes)
|
||||||
mAddingOrRemovingRows = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mModelType == eTypes)
|
|
||||||
{
|
|
||||||
if (pNode->NodeType() == eScriptNode)
|
|
||||||
{
|
{
|
||||||
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
|
CScriptNode *pScript = static_cast<CScriptNode*>(pNode);
|
||||||
CScriptObject *pObj = pScript->Object();
|
CScriptObject *pObj = pScript->Object();
|
||||||
|
@ -439,14 +436,29 @@ void CInstancesModel::NodeAboutToBeDeleted(CSceneNode *pNode)
|
||||||
mTemplateList.removeOne(pObj->Template());
|
mTemplateList.removeOne(pObj->Template());
|
||||||
endRemoveRows();
|
endRemoveRows();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (!mChangingLayout)
|
||||||
|
{
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
mChangingLayout = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (!mChangingLayout)
|
||||||
|
{
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
mChangingLayout = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInstancesModel::NodeDeleted()
|
void CInstancesModel::NodeDeleted()
|
||||||
{
|
{
|
||||||
emit layoutChanged();
|
if (mChangingLayout)
|
||||||
mAddingOrRemovingRows = false;
|
{
|
||||||
|
emit layoutChanged();
|
||||||
|
mChangingLayout = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CInstancesModel::PropertyModified(CScriptObject *pInst, IProperty *pProp)
|
void CInstancesModel::PropertyModified(CScriptObject *pInst, IProperty *pProp)
|
||||||
|
|
|
@ -37,7 +37,7 @@ private:
|
||||||
QList<CScriptTemplate*> mTemplateList;
|
QList<CScriptTemplate*> mTemplateList;
|
||||||
QStringList mBaseItems;
|
QStringList mBaseItems;
|
||||||
bool mShowColumnEnabled;
|
bool mShowColumnEnabled;
|
||||||
bool mAddingOrRemovingRows;
|
bool mChangingLayout;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CInstancesModel(QObject *pParent = 0);
|
explicit CInstancesModel(QObject *pParent = 0);
|
||||||
|
|
|
@ -25,7 +25,7 @@ CPoiMapModel::CPoiMapModel(CWorldEditor *pEditor, QObject *pParent /*= 0*/)
|
||||||
for (u32 iPoi = 0; iPoi < mpPoiToWorld->NumMappedPOIs(); iPoi++)
|
for (u32 iPoi = 0; iPoi < mpPoiToWorld->NumMappedPOIs(); iPoi++)
|
||||||
{
|
{
|
||||||
const CPoiToWorld::SPoiMap *pkMap = mpPoiToWorld->MapByIndex(iPoi);
|
const CPoiToWorld::SPoiMap *pkMap = mpPoiToWorld->MapByIndex(iPoi);
|
||||||
CScriptNode *pPoiNode = mpEditor->Scene()->ScriptNodeByID(pkMap->PoiID);
|
CScriptNode *pPoiNode = mpEditor->Scene()->NodeForInstanceID(pkMap->PoiID);
|
||||||
|
|
||||||
if (pPoiNode)
|
if (pPoiNode)
|
||||||
{
|
{
|
||||||
|
@ -183,7 +183,7 @@ CScriptNode* CPoiMapModel::PoiNodePointer(const QModelIndex& rkIndex) const
|
||||||
if ((u32) rkIndex.row() < mpPoiToWorld->NumMappedPOIs())
|
if ((u32) rkIndex.row() < mpPoiToWorld->NumMappedPOIs())
|
||||||
{
|
{
|
||||||
const CPoiToWorld::SPoiMap *pkMap = mpPoiToWorld->MapByIndex(rkIndex.row());
|
const CPoiToWorld::SPoiMap *pkMap = mpPoiToWorld->MapByIndex(rkIndex.row());
|
||||||
return mpEditor->Scene()->ScriptNodeByID(pkMap->PoiID);
|
return mpEditor->Scene()->NodeForInstanceID(pkMap->PoiID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -260,7 +260,7 @@ void WModifyTab::OnLinkTableDoubleClick(QModelIndex Index)
|
||||||
else if (sender() == ui->OutLinksTableView)
|
else if (sender() == ui->OutLinksTableView)
|
||||||
InstanceID = pNode->Object()->Link(eOutgoing, Index.row())->ReceiverID();
|
InstanceID = pNode->Object()->Link(eOutgoing, Index.row())->ReceiverID();
|
||||||
|
|
||||||
CScriptNode *pLinkedNode = pNode->Scene()->ScriptNodeByID(InstanceID);
|
CScriptNode *pLinkedNode = pNode->Scene()->NodeForInstanceID(InstanceID);
|
||||||
|
|
||||||
if (pLinkedNode)
|
if (pLinkedNode)
|
||||||
mpWorldEditor->ClearAndSelectNode(pLinkedNode);
|
mpWorldEditor->ClearAndSelectNode(pLinkedNode);
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
CVectorOutStream::CVectorOutStream()
|
CVectorOutStream::CVectorOutStream()
|
||||||
{
|
{
|
||||||
mDataEndianness = IOUtil::eBigEndian;
|
mDataEndianness = IOUtil::eBigEndian;
|
||||||
|
mpVector = new std::vector<char>;
|
||||||
|
mOwnsVector = true;
|
||||||
mPos = 0;
|
mPos = 0;
|
||||||
mUsed = 0;
|
mUsed = 0;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +12,8 @@ CVectorOutStream::CVectorOutStream()
|
||||||
CVectorOutStream::CVectorOutStream(IOUtil::EEndianness DataEndianness)
|
CVectorOutStream::CVectorOutStream(IOUtil::EEndianness DataEndianness)
|
||||||
{
|
{
|
||||||
mDataEndianness = DataEndianness;
|
mDataEndianness = DataEndianness;
|
||||||
|
mpVector = new std::vector<char>;
|
||||||
|
mOwnsVector = true;
|
||||||
mPos = 0;
|
mPos = 0;
|
||||||
mUsed = 0;
|
mUsed = 0;
|
||||||
}
|
}
|
||||||
|
@ -17,23 +21,34 @@ CVectorOutStream::CVectorOutStream(IOUtil::EEndianness DataEndianness)
|
||||||
CVectorOutStream::CVectorOutStream(unsigned long InitialSize, IOUtil::EEndianness DataEndianness)
|
CVectorOutStream::CVectorOutStream(unsigned long InitialSize, IOUtil::EEndianness DataEndianness)
|
||||||
{
|
{
|
||||||
mDataEndianness = DataEndianness;
|
mDataEndianness = DataEndianness;
|
||||||
mVector.resize(InitialSize);
|
mpVector = new std::vector<char>(InitialSize);
|
||||||
|
mOwnsVector = true;
|
||||||
|
mPos = 0;
|
||||||
|
mUsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CVectorOutStream::CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness)
|
||||||
|
{
|
||||||
|
mDataEndianness = DataEndianness;
|
||||||
|
mpVector = pVector;
|
||||||
|
mOwnsVector = false;
|
||||||
mPos = 0;
|
mPos = 0;
|
||||||
mUsed = 0;
|
mUsed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CVectorOutStream::~CVectorOutStream()
|
CVectorOutStream::~CVectorOutStream()
|
||||||
{
|
{
|
||||||
|
if (mOwnsVector) delete mpVector;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVectorOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
void CVectorOutStream::WriteBytes(void *pSrc, unsigned long Count)
|
||||||
{
|
{
|
||||||
if (!IsValid()) return;
|
if (!IsValid()) return;
|
||||||
|
|
||||||
if ((mPos + Count) > mVector.size())
|
if ((mPos + Count) > mpVector->size())
|
||||||
mVector.resize(mPos + Count);
|
mpVector->resize(mPos + Count);
|
||||||
|
|
||||||
memcpy(mVector.data() + mPos, pSrc, Count);
|
memcpy(mpVector->data() + mPos, pSrc, Count);
|
||||||
mPos += Count;
|
mPos += Count;
|
||||||
if (mPos > mUsed) mUsed = mPos;
|
if (mPos > mUsed) mUsed = mPos;
|
||||||
}
|
}
|
||||||
|
@ -68,8 +83,8 @@ bool CVectorOutStream::Seek(long Offset, long Origin)
|
||||||
if (mPos > mUsed)
|
if (mPos > mUsed)
|
||||||
mUsed = mPos;
|
mUsed = mPos;
|
||||||
|
|
||||||
if (mPos > (signed long) mVector.size())
|
if (mPos > (signed long) mpVector->size())
|
||||||
mVector.resize(mPos);
|
mpVector->resize(mPos);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -96,27 +111,35 @@ long CVectorOutStream::Size() const
|
||||||
|
|
||||||
long CVectorOutStream::SizeRemaining() const
|
long CVectorOutStream::SizeRemaining() const
|
||||||
{
|
{
|
||||||
return mVector.size() - mPos;
|
return mpVector->size() - mPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CVectorOutStream::SetVector(std::vector<char> *pVector)
|
||||||
|
{
|
||||||
|
if (mOwnsVector) delete mpVector;
|
||||||
|
mpVector = pVector;
|
||||||
|
mPos = 0;
|
||||||
|
mUsed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* CVectorOutStream::Data()
|
void* CVectorOutStream::Data()
|
||||||
{
|
{
|
||||||
return mVector.data();
|
return mpVector->data();
|
||||||
}
|
}
|
||||||
|
|
||||||
void* CVectorOutStream::DataAtPosition()
|
void* CVectorOutStream::DataAtPosition()
|
||||||
{
|
{
|
||||||
return mVector.data() + mPos;
|
return mpVector->data() + mPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVectorOutStream::Expand(unsigned long Amount)
|
void CVectorOutStream::Expand(unsigned long Amount)
|
||||||
{
|
{
|
||||||
mVector.resize(mVector.size() + Amount);
|
mpVector->resize(mpVector->size() + Amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVectorOutStream::Contract()
|
void CVectorOutStream::Shrink()
|
||||||
{
|
{
|
||||||
mVector.resize(mUsed);
|
mpVector->resize(mUsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CVectorOutStream::Reset()
|
void CVectorOutStream::Reset()
|
||||||
|
@ -127,6 +150,6 @@ void CVectorOutStream::Reset()
|
||||||
|
|
||||||
void CVectorOutStream::Clear()
|
void CVectorOutStream::Clear()
|
||||||
{
|
{
|
||||||
mVector.clear();
|
mpVector->clear();
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,8 @@
|
||||||
|
|
||||||
class CVectorOutStream : public IOutputStream
|
class CVectorOutStream : public IOutputStream
|
||||||
{
|
{
|
||||||
std::vector<char> mVector;
|
std::vector<char> *mpVector;
|
||||||
|
bool mOwnsVector;
|
||||||
long mPos;
|
long mPos;
|
||||||
long mUsed;
|
long mUsed;
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ public:
|
||||||
CVectorOutStream();
|
CVectorOutStream();
|
||||||
CVectorOutStream(IOUtil::EEndianness DataEndianness);
|
CVectorOutStream(IOUtil::EEndianness DataEndianness);
|
||||||
CVectorOutStream(unsigned long InitialSize, IOUtil::EEndianness DataEndianness);
|
CVectorOutStream(unsigned long InitialSize, IOUtil::EEndianness DataEndianness);
|
||||||
|
CVectorOutStream(std::vector<char> *pVector, IOUtil::EEndianness DataEndianness);
|
||||||
~CVectorOutStream();
|
~CVectorOutStream();
|
||||||
|
|
||||||
void WriteBytes(void *pSrc, unsigned long Count);
|
void WriteBytes(void *pSrc, unsigned long Count);
|
||||||
|
@ -23,10 +25,11 @@ public:
|
||||||
bool IsValid() const;
|
bool IsValid() const;
|
||||||
long Size() const;
|
long Size() const;
|
||||||
long SizeRemaining() const;
|
long SizeRemaining() const;
|
||||||
|
void SetVector(std::vector<char> *pVector);
|
||||||
void *Data();
|
void *Data();
|
||||||
void *DataAtPosition();
|
void *DataAtPosition();
|
||||||
void Expand(unsigned long Amount);
|
void Expand(unsigned long Amount);
|
||||||
void Contract();
|
void Shrink();
|
||||||
void Reset();
|
void Reset();
|
||||||
void Clear();
|
void Clear();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue