123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719 |
- /*
- * Copyright (c) Contributors to the Open 3D Engine Project.
- * For complete copyright and license terms please see the LICENSE at the root of this distribution.
- *
- * SPDX-License-Identifier: Apache-2.0 OR MIT
- *
- */
- // Description : StaticObject implementation.
- #include "EditorDefs.h"
- #include "EntityObject.h"
- // AzToolsFramework
- #include <AzToolsFramework/API/ComponentEntityObjectBus.h>
- // Editor
- #include "Settings.h"
- #include "Viewport.h"
- #include "Include/IObjectManager.h"
- #include "Objects/ObjectManager.h"
- #include "ViewManager.h"
- #include "AnimationContext.h"
- #include "HitContext.h"
- static constexpr int VIEW_DISTANCE_MULTIPLIER_MAX = 100;
- namespace
- {
- CEntityObject* s_pPropertyPanelEntityObject = nullptr;
- };
- //////////////////////////////////////////////////////////////////////////
- CEntityObject::CEntityObject()
- {
- m_bLoadFailed = false;
- m_box.min.Set(0, 0, 0);
- m_box.max.Set(0, 0, 0);
- m_proximityRadius = 0;
- m_innerRadius = 0;
- m_outerRadius = 0;
- m_boxSizeX = 1;
- m_boxSizeY = 1;
- m_boxSizeZ = 1;
- m_bProjectInAllDirs = false;
- m_bProjectorHasTexture = false;
- m_bDisplayBBox = true;
- m_bBBoxSelection = false;
- m_bDisplaySolidBBox = false;
- m_bDisplayAbsoluteRadius = false;
- m_bIconOnTop = false;
- m_bDisplayArrow = false;
- m_entityId = 0;
- m_bVisible = true;
- m_bCalcPhysics = true;
- m_bLight = false;
- m_bAreaLight = false;
- m_fAreaWidth = 1;
- m_fAreaHeight = 1;
- m_fAreaLightSize = 0.05f;
- m_bBoxProjectedCM = false;
- m_fBoxWidth = 1;
- m_fBoxHeight = 1;
- m_fBoxLength = 1;
- m_bEnableReload = true;
- m_lightColor = Vec3(1, 1, 1);
- SetColor(QColor(255, 255, 0));
- // Init Variables.
- mv_castShadow = true;
- mv_outdoor = false;
- mv_recvWind = false;
- mv_renderNearest = false;
- mv_noDecals = false;
- mv_createdThroughPool = false;
- mv_obstructionMultiplier = 1.f;
- mv_obstructionMultiplier.SetLimits(0.f, 1.f, 0.01f);
- mv_hiddenInGame = false;
- mv_ratioLOD = 100;
- mv_viewDistanceMultiplier = 1.0f;
- mv_ratioLOD.SetLimits(0, 255);
- mv_viewDistanceMultiplier.SetLimits(0.0f, VIEW_DISTANCE_MULTIPLIER_MAX);
- m_physicsState = nullptr;
- m_attachmentType = eAT_Pivot;
- // cache all the variable callbacks, must match order of enum defined in header
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaHeightChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaLightChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaLightSizeChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnAreaWidthChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxHeightChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxLengthChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxProjectionChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxSizeXChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxSizeYChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxSizeZChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnBoxWidthChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnColorChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnInnerRadiusChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnOuterRadiusChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectInAllDirsChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectorFOVChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnProjectorTextureChange(var); });
- m_onSetCallbacksCache.emplace_back([this](IVariable* var) { OnRadiusChange(var); });
- }
- CEntityObject::~CEntityObject()
- {
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::InitVariables()
- {
- mv_castShadow.SetFlags(mv_castShadow.GetFlags() | IVariable::UI_INVISIBLE);
- AddVariable(mv_outdoor, "OutdoorOnly", tr("Outdoor Only"));
- AddVariable(mv_castShadow, "CastShadow", tr("Cast Shadow"));
- AddVariable(mv_ratioLOD, "LodRatio");
- AddVariable(mv_viewDistanceMultiplier, "ViewDistanceMultiplier");
- AddVariable(mv_hiddenInGame, "HiddenInGame");
- AddVariable(mv_recvWind, "RecvWind", tr("Receive Wind"));
- // [artemk]: Add RenderNearest entity param because of animator request.
- // This will cause that slot zero is rendered with ENTITY_SLOT_RENDER_NEAREST flag raised.
- AddVariable(mv_renderNearest, "RenderNearest");
- mv_renderNearest.SetDescription("Used to eliminate z-buffer artifacts when rendering from first person view");
- AddVariable(mv_noDecals, "NoStaticDecals");
- AddVariable(mv_createdThroughPool, "CreatedThroughPool", tr("Created Through Pool"));
- AddVariable(mv_obstructionMultiplier, "ObstructionMultiplier", tr("Obstruction Multiplier"));
- }
- //////////////////////////////////////////////////////////////////////////&
- void CEntityObject::Done()
- {
- DeleteEntity();
- ReleaseEventTargets();
- RemoveAllEntityLinks();
- CBaseObject::Done();
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::FreeGameData()
- {
- DeleteEntity();
- }
- //////////////////////////////////////////////////////////////////////////
- bool CEntityObject::Init(IEditor* pEditor, CBaseObject* pPrev, const QString& file)
- {
- CBaseObject::Init(pEditor, pPrev, file);
- if (pPrev)
- {
- CEntityObject* pPreviousEntity = ( CEntityObject* )pPrev;
- // Clone Properties.
- if (pPreviousEntity->m_pProperties)
- {
- m_pProperties = CloneProperties(pPreviousEntity->m_pProperties);
- }
- if (pPreviousEntity->m_pProperties2)
- {
- m_pProperties2 = CloneProperties(pPreviousEntity->m_pProperties2);
- }
- mv_createdThroughPool = pPreviousEntity->mv_createdThroughPool;
- }
- else if (!file.isEmpty())
- {
- SetUniqueName(file);
- m_entityClass = file;
- }
- ResetCallbacks();
- return true;
- }
- //////////////////////////////////////////////////////////////////////////
- /*static*/ CEntityObject* CEntityObject::FindFromEntityId(const AZ::EntityId& id)
- {
- CEntityObject* retEntity = nullptr;
- AzToolsFramework::ComponentEntityEditorRequestBus::EventResult(retEntity, id, &AzToolsFramework::ComponentEntityEditorRequestBus::Events::GetSandboxObject);
- return retEntity;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::SetTransformDelegate(ITransformDelegate* pTransformDelegate)
- {
- CBaseObject::SetTransformDelegate(pTransformDelegate);
- if (this == s_pPropertyPanelEntityObject)
- {
- return;
- }
- ForceVariableUpdate();
- ResetCallbacks();
- }
- //////////////////////////////////////////////////////////////////////////
- bool CEntityObject::ConvertFromObject(CBaseObject* object)
- {
- CBaseObject::ConvertFromObject(object);
- if (qobject_cast<CEntityObject*>(object))
- {
- CEntityObject* pObject = ( CEntityObject* )object;
- mv_outdoor = pObject->mv_outdoor;
- mv_ratioLOD = pObject->mv_ratioLOD;
- mv_viewDistanceMultiplier = pObject->mv_viewDistanceMultiplier;
- mv_hiddenInGame = pObject->mv_hiddenInGame;
- mv_recvWind = pObject->mv_recvWind;
- mv_renderNearest = pObject->mv_renderNearest;
- mv_noDecals = pObject->mv_noDecals;
- mv_createdThroughPool = pObject->mv_createdThroughPool;
- mv_obstructionMultiplier = pObject->mv_obstructionMultiplier;
- return true;
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::GetLocalBounds(AABB& box)
- {
- box = m_box;
- }
- //////////////////////////////////////////////////////////////////////////
- bool CEntityObject::HitTest(HitContext& hc)
- {
- if (!hc.b2DViewport)
- {
- // Test 3D viewport.
- }
- //////////////////////////////////////////////////////////////////////////
- if ((m_bDisplayBBox && gSettings.viewports.bShowTriggerBounds) || hc.b2DViewport || (m_bDisplayBBox && m_bBBoxSelection))
- {
- float hitEpsilon = hc.view->GetScreenScaleFactor(GetWorldPos()) * 0.01f;
- float hitDist;
- float fScale = GetScale().x;
- AABB boxScaled;
- boxScaled.min = m_box.min * fScale;
- boxScaled.max = m_box.max * fScale;
- Matrix34 invertWTM = GetWorldTM();
- invertWTM.Invert();
- Vec3 xformedRaySrc = invertWTM.TransformPoint(hc.raySrc);
- Vec3 xformedRayDir = invertWTM.TransformVector(hc.rayDir);
- xformedRayDir.Normalize();
- {
- Vec3 intPnt;
- if (m_bBBoxSelection)
- {
- // Check intersection with bbox.
- if (Intersect::Ray_AABB(xformedRaySrc, xformedRayDir, boxScaled, intPnt))
- {
- hc.dist = xformedRaySrc.GetDistance(intPnt);
- hc.object = this;
- return true;
- }
- }
- else
- {
- // Check intersection with bbox edges.
- if (Intersect::Ray_AABBEdge(xformedRaySrc, xformedRayDir, boxScaled, hitEpsilon, hitDist, intPnt))
- {
- hc.dist = xformedRaySrc.GetDistance(intPnt);
- hc.object = this;
- return true;
- }
- }
- }
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- bool CEntityObject::HitTestRect(HitContext& hc)
- {
- bool bResult = CBaseObject::HitTestRect(hc);
- if (bResult)
- {
- hc.object = this;
- }
- return bResult;
- }
- //////////////////////////////////////////////////////////////////////////
- IVariable* CEntityObject::FindVariableInSubBlock(CVarBlockPtr& properties, IVariable* pSubBlockVar, const char* pVarName)
- {
- IVariable* pVar = pSubBlockVar ? pSubBlockVar->FindVariable(pVarName) : properties->FindVariable(pVarName);
- return pVar;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::AdjustLightProperties(CVarBlockPtr& properties, const char* pSubBlock)
- {
- IVariable* pSubBlockVar = pSubBlock ? properties->FindVariable(pSubBlock) : nullptr;
- if (IVariable* pRadius = FindVariableInSubBlock(properties, pSubBlockVar, "Radius"))
- {
- // The value of 0.01 was found through asking Crysis 2 designer
- // team.
- pRadius->SetLimits(0.01f, 100.0f, 0.0f, true, false);
- }
- if (IVariable* pBoxSizeX = FindVariableInSubBlock(properties, pSubBlockVar, "BoxSizeX"))
- {
- pBoxSizeX->SetLimits(0.01f, 100.0f, 0.0f, true, false);
- }
- if (IVariable* pBoxSizeY = FindVariableInSubBlock(properties, pSubBlockVar, "BoxSizeY"))
- {
- pBoxSizeY->SetLimits(0.01f, 100.0f, 0.0f, true, false);
- }
- if (IVariable* pBoxSizeZ = FindVariableInSubBlock(properties, pSubBlockVar, "BoxSizeZ"))
- {
- pBoxSizeZ->SetLimits(0.01f, 100.0f, 0.0f, true, false);
- }
- if (IVariable* pProjectorFov = FindVariableInSubBlock(properties, pSubBlockVar, "fProjectorFov"))
- {
- pProjectorFov->SetLimits(0.01f, 180.0f, 0.0f, true, true);
- }
- if (IVariable* pPlaneWidth = FindVariableInSubBlock(properties, pSubBlockVar, "fPlaneWidth"))
- {
- pPlaneWidth->SetLimits(0.01f, 10.0f, 0.0f, true, false);
- pPlaneWidth->SetHumanName("SourceWidth");
- }
- if (IVariable* pPlaneHeight = FindVariableInSubBlock(properties, pSubBlockVar, "fPlaneHeight"))
- {
- pPlaneHeight->SetLimits(0.01f, 10.0f, 0.0f, true, false);
- pPlaneHeight->SetHumanName("SourceDiameter");
- }
- // For backwards compatibility with old lights (avoids changing settings in Lua which will break loading compatibility).
- // Todo: Change the Lua property names on the next big light refactor.
- if (IVariable* pAreaLight = FindVariableInSubBlock(properties, pSubBlockVar, "bAreaLight"))
- {
- pAreaLight->SetHumanName("PlanarLight");
- }
- if (IVariable* pCastShadowVarLegacy = FindVariableInSubBlock(properties, pSubBlockVar, "bCastShadow"))
- {
- pCastShadowVarLegacy->SetFlags(pCastShadowVarLegacy->GetFlags() | IVariable::UI_INVISIBLE);
- const QString zeroPrefix("0");
- if (!pCastShadowVarLegacy->GetDisplayValue().startsWith(zeroPrefix))
- {
- pCastShadowVarLegacy->SetDisplayValue(zeroPrefix);
- }
- }
- if (IVariable* pFade = FindVariableInSubBlock(properties, pSubBlockVar, "vFadeDimensionsLeft"))
- {
- pFade->SetFlags(pFade->GetFlags() | IVariable::UI_INVISIBLE);
- }
- if (IVariable* pFade = FindVariableInSubBlock(properties, pSubBlockVar, "vFadeDimensionsRight"))
- {
- pFade->SetFlags(pFade->GetFlags() | IVariable::UI_INVISIBLE);
- }
- if (IVariable* pFade = FindVariableInSubBlock(properties, pSubBlockVar, "vFadeDimensionsNear"))
- {
- pFade->SetFlags(pFade->GetFlags() | IVariable::UI_INVISIBLE);
- }
- if (IVariable* pFade = FindVariableInSubBlock(properties, pSubBlockVar, "vFadeDimensionsFar"))
- {
- pFade->SetFlags(pFade->GetFlags() | IVariable::UI_INVISIBLE);
- }
- if (IVariable* pFade = FindVariableInSubBlock(properties, pSubBlockVar, "vFadeDimensionsTop"))
- {
- pFade->SetFlags(pFade->GetFlags() | IVariable::UI_INVISIBLE);
- }
- if (IVariable* pFade = FindVariableInSubBlock(properties, pSubBlockVar, "vFadeDimensionsBottom"))
- {
- pFade->SetFlags(pFade->GetFlags() | IVariable::UI_INVISIBLE);
- }
- if (IVariable* pSortPriority = FindVariableInSubBlock(properties, pSubBlockVar, "SortPriority"))
- {
- pSortPriority->SetLimits(0, 255, 1, true, true);
- }
- if (IVariable* pAttenFalloffMax = FindVariableInSubBlock(properties, pSubBlockVar, "fAttenuationFalloffMax"))
- {
- pAttenFalloffMax->SetLimits(0.0f, 1.0f, 1.0f / 255.0f, true, true);
- }
- if (IVariable* pVer = FindVariableInSubBlock(properties, pSubBlockVar, "_nVersion"))
- {
- int version = -1;
- pVer->Get(version);
- if (version == -1)
- {
- version++;
- pVer->Set(version);
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::SetName(const QString& name)
- {
- if (name == GetName())
- {
- return;
- }
- const QString oldName = GetName();
- CBaseObject::SetName(name);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::SetSelected(bool bSelect)
- {
- CBaseObject::SetSelected(bSelect);
- if (bSelect)
- {
- UpdateLightProperty();
- }
- }
- template <typename T>
- struct IVariableType {};
- template <>
- struct IVariableType<bool>
- {
- enum
- {
- value = IVariable::BOOL
- };
- };
- template <>
- struct IVariableType<int>
- {
- enum
- {
- value = IVariable::INT
- };
- };
- template <>
- struct IVariableType<float>
- {
- enum
- {
- value = IVariable::FLOAT
- };
- };
- template <>
- struct IVariableType<QString>
- {
- enum
- {
- value = IVariable::STRING
- };
- };
- template <>
- struct IVariableType<Vec3>
- {
- enum
- {
- value = IVariable::VECTOR
- };
- };
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::Serialize(CObjectArchive& ar)
- {
- CBaseObject::Serialize(ar);
- XmlNodeRef xmlNode = ar.node;
- if (ar.bLoading)
- {
- // Load
- QString entityClass = m_entityClass;
- m_bLoadFailed = false;
- xmlNode->getAttr("EntityClass", entityClass);
- m_physicsState = xmlNode->findChild("PhysicsState");
- Vec3 angles;
- // Backward compatibility, with FarCry levels.
- if (xmlNode->getAttr("Angles", angles))
- {
- angles = DEG2RAD(angles);
- angles.z += gf_PI / 2;
- Quat quat;
- quat.SetRotationXYZ(Ang3(angles));
- SetRotation(quat);
- }
- // Load Event Targets.
- ReleaseEventTargets();
- XmlNodeRef eventTargets = xmlNode->findChild("EventTargets");
- if (eventTargets)
- {
- for (int i = 0; i < eventTargets->getChildCount(); i++)
- {
- XmlNodeRef eventTarget = eventTargets->getChild(i);
- CEntityEventTarget et;
- et.target = nullptr;
- GUID targetId = GUID_NULL;
- eventTarget->getAttr("TargetId", targetId);
- eventTarget->getAttr("Event", et.event);
- eventTarget->getAttr("SourceEvent", et.sourceEvent);
- m_eventTargets.emplace_back(AZStd::move(et));
- if (targetId != GUID_NULL)
- {
- ar.SetResolveCallback(
- this, targetId,
- [this,i](CBaseObject* object) { ResolveEventTarget(object, i); });
- }
- }
- }
- XmlNodeRef propsNode = xmlNode->findChild("Properties");
- XmlNodeRef props2Node = xmlNode->findChild("Properties2");
- QString attachmentType;
- xmlNode->getAttr("AttachmentType", attachmentType);
- if (attachmentType == "CharacterBone")
- {
- m_attachmentType = eAT_CharacterBone;
- }
- else
- {
- m_attachmentType = eAT_Pivot;
- }
- xmlNode->getAttr("AttachmentTarget", m_attachmentTarget);
- if (ar.bUndo)
- {
- RemoveAllEntityLinks();
- PostLoad(ar);
- }
- }
- else
- {
- if (m_attachmentType != eAT_Pivot)
- {
- if (m_attachmentType == eAT_CharacterBone)
- {
- xmlNode->setAttr("AttachmentType", "CharacterBone");
- }
- xmlNode->setAttr("AttachmentTarget", m_attachmentTarget.toUtf8().data());
- }
- // Saving.
- if (!m_entityClass.isEmpty())
- {
- xmlNode->setAttr("EntityClass", m_entityClass.toUtf8().data());
- }
- if (m_physicsState)
- {
- xmlNode->addChild(m_physicsState);
- }
- //! Save properties.
- if (m_pProperties)
- {
- XmlNodeRef propsNode = xmlNode->newChild("Properties");
- m_pProperties->Serialize(propsNode, ar.bLoading);
- }
- //! Save properties.
- if (m_pProperties2)
- {
- XmlNodeRef propsNode = xmlNode->newChild("Properties2");
- m_pProperties2->Serialize(propsNode, ar.bLoading);
- }
- // Save Event Targets.
- if (!m_eventTargets.empty())
- {
- XmlNodeRef eventTargets = xmlNode->newChild("EventTargets");
- for (int i = 0; i < m_eventTargets.size(); i++)
- {
- CEntityEventTarget& et = m_eventTargets[i];
- GUID targetId = GUID_NULL;
- if (et.target != nullptr)
- {
- targetId = et.target->GetId();
- }
- XmlNodeRef eventTarget = eventTargets->newChild("EventTarget");
- eventTarget->setAttr("TargetId", targetId);
- eventTarget->setAttr("Event", et.event.toUtf8().data());
- eventTarget->setAttr("SourceEvent", et.sourceEvent.toUtf8().data());
- }
- }
- // Save Entity Links.
- SaveLink(xmlNode);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::PostLoad(CObjectArchive& ar)
- {
- //////////////////////////////////////////////////////////////////////////
- // Load Links.
- XmlNodeRef linksNode = ar.node->findChild("EntityLinks");
- LoadLink(linksNode, &ar);
- }
- //////////////////////////////////////////////////////////////////////////
- XmlNodeRef CEntityObject::Export([[maybe_unused]] const QString& levelPath, XmlNodeRef& xmlExportNode)
- {
- if (m_bLoadFailed)
- {
- return nullptr;
- }
- // Do not export entity with bad id.
- if (!m_entityId)
- {
- return XmlHelpers::CreateXmlNode("Temp");
- }
- // Export entities to entities.ini
- XmlNodeRef objNode = xmlExportNode->newChild("Entity");
- objNode->setAttr("Name", GetName().toUtf8().data());
- Vec3 pos = GetPos(), scale = GetScale();
- Quat rotate = GetRotation();
- if (GetParent())
- {
- if (qobject_cast<CEntityObject*>(GetParent()))
- {
- // Store parent entity id.
- CEntityObject* parentEntity = ( CEntityObject* )GetParent();
- if (parentEntity)
- {
- objNode->setAttr("ParentId", parentEntity->GetEntityId());
- if (m_attachmentType != eAT_Pivot)
- {
- if (m_attachmentType == eAT_CharacterBone)
- {
- objNode->setAttr("AttachmentType", "CharacterBone");
- }
- objNode->setAttr("AttachmentTarget", m_attachmentTarget.toUtf8().data());
- }
- }
- }
- else
- {
- // Export world coordinates.
- AffineParts ap;
- ap.SpectralDecompose(GetWorldTM());
- pos = ap.pos;
- rotate = ap.rot;
- scale = ap.scale;
- }
- }
- if (!IsEquivalent(pos, Vec3(0, 0, 0), 0))
- {
- objNode->setAttr("Pos", pos);
- }
- if (!rotate.IsIdentity())
- {
- objNode->setAttr("Rotate", rotate);
- }
- if (!IsEquivalent(scale, Vec3(1, 1, 1), 0))
- {
- objNode->setAttr("Scale", scale);
- }
- objNode->setTag("Entity");
- objNode->setAttr("EntityClass", m_entityClass.toUtf8().data());
- objNode->setAttr("EntityId", m_entityId);
- if (mv_ratioLOD != 100)
- {
- objNode->setAttr("LodRatio", ( int )mv_ratioLOD);
- }
- if (fabs(mv_viewDistanceMultiplier - 1.f) > FLT_EPSILON)
- {
- objNode->setAttr("ViewDistanceMultiplier", mv_viewDistanceMultiplier);
- }
- if (mv_recvWind)
- {
- objNode->setAttr("RecvWind", true);
- }
- if (mv_noDecals)
- {
- objNode->setAttr("NoDecals", true);
- }
- if (mv_outdoor)
- {
- objNode->setAttr("OutdoorOnly", true);
- }
- if (mv_hiddenInGame)
- {
- objNode->setAttr("HiddenInGame", true);
- }
- if (mv_createdThroughPool)
- {
- objNode->setAttr("CreatedThroughPool", true);
- }
- if (mv_obstructionMultiplier != 1.f)
- {
- objNode->setAttr("ObstructionMultiplier", (float)mv_obstructionMultiplier);
- }
- if (m_physicsState)
- {
- objNode->addChild(m_physicsState);
- }
- // Export Event Targets.
- if (!m_eventTargets.empty())
- {
- XmlNodeRef eventTargets = objNode->newChild("EventTargets");
- for (int i = 0; i < m_eventTargets.size(); i++)
- {
- CEntityEventTarget& et = m_eventTargets[i];
- int entityId = 0;
- if (et.target)
- {
- if (qobject_cast<CEntityObject*>(et.target))
- {
- entityId = (( CEntityObject* )et.target)->GetEntityId();
- }
- }
- XmlNodeRef eventTarget = eventTargets->newChild("EventTarget");
- eventTarget->setAttr("Target", entityId);
- eventTarget->setAttr("Event", et.event.toUtf8().data());
- eventTarget->setAttr("SourceEvent", et.sourceEvent.toUtf8().data());
- }
- }
- // Save Entity Links.
- if (!m_links.empty())
- {
- XmlNodeRef linksNode = objNode->newChild("EntityLinks");
- for (size_t i = 0, num = m_links.size(); i < num; i++)
- {
- if (m_links[i].target)
- {
- XmlNodeRef linkNode = linksNode->newChild("Link");
- linkNode->setAttr("TargetId", m_links[i].target->GetEntityId());
- linkNode->setAttr("Name", m_links[i].name.toUtf8().data());
- }
- }
- }
- //! Export properties.
- if (m_pProperties)
- {
- XmlNodeRef propsNode = objNode->newChild("Properties");
- m_pProperties->Serialize(propsNode, false);
- }
- //! Export properties.
- if (m_pProperties2)
- {
- XmlNodeRef propsNode = objNode->newChild("Properties2");
- m_pProperties2->Serialize(propsNode, false);
- }
- return objNode;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnEvent(ObjectEvent event)
- {
- CBaseObject::OnEvent(event);
- switch (event)
- {
- case EVENT_RELOAD_ENTITY:
- GetIEditor()->GetErrorReport()->SetCurrentValidatorObject(this);
- break;
- case EVENT_RELOAD_GEOM:
- GetIEditor()->GetErrorReport()->SetCurrentValidatorObject(this);
- break;
- case EVENT_FREE_GAME_DATA:
- FreeGameData();
- break;
- case EVENT_CONFIG_SPEC_CHANGE:
- {
- break;
- }
- default:
- break;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::UpdateVisibility(bool bVisible)
- {
- CBaseObject::UpdateVisibility(bVisible);
- bool bVisibleWithSpec = bVisible;
- if (bVisibleWithSpec != static_cast<bool>(m_bVisible))
- {
- m_bVisible = bVisibleWithSpec;
- }
- size_t const numChildren = GetChildCount();
- for (size_t i = 0; i < numChildren; ++i)
- {
- CBaseObject* const pChildObject = GetChild(i);
- pChildObject->SetHidden(!m_bVisible);
- if (qobject_cast<CEntityObject*>(pChildObject))
- {
- pChildObject->UpdateVisibility(m_bVisible);
- }
- }
- };
- //////////////////////////////////////////////////////////////////////////
- IVariable* CEntityObject::GetLightVariable(const char* name0) const
- {
- if (m_pProperties2)
- {
- IVariable* pLightProperties = m_pProperties2->FindVariable("LightProperties_Base");
- if (pLightProperties)
- {
- for (int i = 0; i < pLightProperties->GetNumVariables(); ++i)
- {
- IVariable* pChild = pLightProperties->GetVariable(i);
- if (pChild == nullptr)
- {
- continue;
- }
- QString name(pChild->GetName());
- if (name == name0)
- {
- return pChild;
- }
- }
- }
- }
- return m_pProperties ? m_pProperties->FindVariable(name0) : nullptr;
- }
- //////////////////////////////////////////////////////////////////////////
- QString CEntityObject::GetLightAnimation() const
- {
- IVariable* pStyleGroup = GetLightVariable("Style");
- if (pStyleGroup)
- {
- for (int i = 0; i < pStyleGroup->GetNumVariables(); ++i)
- {
- IVariable* pChild = pStyleGroup->GetVariable(i);
- if (pChild == nullptr)
- {
- continue;
- }
- QString name(pChild->GetName());
- if (name == "lightanimation_LightAnimation")
- {
- QString lightAnimationName;
- pChild->Get(lightAnimationName);
- return lightAnimationName;
- }
- }
- }
- return "";
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::ResolveEventTarget(CBaseObject* object, unsigned int index)
- {
- // Find target id.
- assert(index < m_eventTargets.size());
- if (object)
- {
- object->AddEventListener(this);
- }
- m_eventTargets[index].target = object;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::RemoveAllEntityLinks()
- {
- while (!m_links.empty())
- {
- RemoveEntityLink(static_cast<int>(m_links.size() - 1));
- }
- m_links.clear();
- SetModified(false);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::ReleaseEventTargets()
- {
- while (!m_eventTargets.empty())
- {
- RemoveEventTarget(static_cast<int>(m_eventTargets.size() - 1), false);
- }
- m_eventTargets.clear();
- SetModified(false);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::LoadLink(XmlNodeRef xmlNode, CObjectArchive* pArchive)
- {
- RemoveAllEntityLinks();
- if (!xmlNode)
- {
- return;
- }
- QString name;
- GUID targetId;
- for (int i = 0; i < xmlNode->getChildCount(); i++)
- {
- XmlNodeRef linkNode = xmlNode->getChild(i);
- linkNode->getAttr("Name", name);
- if (linkNode->getAttr("TargetId", targetId))
- {
- int version = 0;
- linkNode->getAttr("Version", version);
- GUID newTargetId = pArchive ? pArchive->ResolveID(targetId) : targetId;
- // Backwards compatibility with old bone attachment system
- const char kOldBoneLinkPrefix = '@';
- if (version == 0 && !name.isEmpty() && name[0] == kOldBoneLinkPrefix)
- {
- CBaseObject* pObject = FindObject(newTargetId);
- if (qobject_cast<CEntityObject*>(pObject))
- {
- CEntityObject* pTargetEntity = static_cast<CEntityObject*>(pObject);
- Quat relRot(IDENTITY);
- linkNode->getAttr("RelRot", relRot);
- Vec3 relPos(IDENTITY);
- linkNode->getAttr("RelPos", relPos);
- SetAttachType(eAT_CharacterBone);
- SetAttachTarget(name.mid(1).toUtf8().data());
- pTargetEntity->AttachChild(this);
- SetPos(relPos);
- SetRotation(relRot);
- }
- }
- else
- {
- AddEntityLink(name, newTargetId);
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::SaveLink(XmlNodeRef xmlNode)
- {
- if (m_links.empty())
- {
- return;
- }
- XmlNodeRef linksNode = xmlNode->newChild("EntityLinks");
- for (size_t i = 0, num = m_links.size(); i < num; i++)
- {
- XmlNodeRef linkNode = linksNode->newChild("Link");
- linkNode->setAttr("TargetId", m_links[i].targetId);
- linkNode->setAttr("Name", m_links[i].name.toUtf8().data());
- linkNode->setAttr("Version", 1);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnObjectEvent(CBaseObject* target, int event)
- {
- // When event target is deleted.
- if (event == CBaseObject::ON_DELETE)
- {
- // Find this target in events list and remove.
- int numTargets = static_cast<int>(m_eventTargets.size());
- for (int i = 0; i < numTargets; i++)
- {
- if (m_eventTargets[i].target == target)
- {
- RemoveEventTarget(i);
- numTargets = static_cast<int>(m_eventTargets.size());
- i--;
- }
- }
- }
- else if (event == CBaseObject::ON_PREDELETE)
- {
- int numTargets = static_cast<int>(m_links.size());
- for (int i = 0; i < numTargets; i++)
- {
- if (m_links[i].target == target)
- {
- RemoveEntityLink(i);
- numTargets = static_cast<int>(m_eventTargets.size());
- i--;
- }
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- int CEntityObject::AddEventTarget(CBaseObject* target, const QString& event, const QString& sourceEvent, [[maybe_unused]] bool bUpdateScript)
- {
- StoreUndo();
- CEntityEventTarget et;
- et.target = target;
- et.event = event;
- et.sourceEvent = sourceEvent;
- // Assign event target.
- if (et.target)
- {
- et.target->AddEventListener(this);
- }
- m_eventTargets.push_back(et);
- SetModified(false);
- return static_cast<int>(m_eventTargets.size() - 1);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::RemoveEventTarget(int index, [[maybe_unused]] bool bUpdateScript)
- {
- if (index >= 0 && index < m_eventTargets.size())
- {
- StoreUndo();
- if (m_eventTargets[index].target)
- {
- m_eventTargets[index].target->RemoveEventListener(this);
- }
- m_eventTargets.erase(m_eventTargets.begin() + index);
- SetModified(false);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- int CEntityObject::AddEntityLink(const QString& name, GUID targetEntityId)
- {
- CEntityObject* target = nullptr;
- if (targetEntityId != GUID_NULL)
- {
- CBaseObject* pObject = FindObject(targetEntityId);
- if (qobject_cast<CEntityObject*>(pObject))
- {
- target = ( CEntityObject* )pObject;
- // Legacy entities and AZ entities shouldn't be linked.
- if (target->GetType() == OBJTYPE_AZENTITY || GetType() == OBJTYPE_AZENTITY)
- {
- return -1;
- }
- }
- }
- StoreUndo();
- CEntityLink lnk;
- lnk.targetId = targetEntityId;
- lnk.target = target;
- lnk.name = name;
- m_links.push_back(lnk);
- SetModified(false);
- return static_cast<int>(m_links.size() - 1);
- }
- //////////////////////////////////////////////////////////////////////////
- bool CEntityObject::EntityLinkExists(const QString& name, GUID targetEntityId)
- {
- for (size_t i = 0, num = m_links.size(); i < num; ++i)
- {
- if (m_links[i].targetId == targetEntityId && name.compare(m_links[i].name, Qt::CaseInsensitive) == 0)
- {
- return true;
- }
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::RemoveEntityLink(int index)
- {
- if (index >= 0 && index < m_links.size())
- {
- CEntityLink& link = m_links[index];
- StoreUndo();
- if (link.target)
- {
- link.target->RemoveEventListener(this);
- link.target->EntityUnlinked(link.name, GetId());
- }
- m_links.erase(m_links.begin() + index);
- SetModified(false);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::RenameEntityLink(int index, const QString& newName)
- {
- if (index >= 0 && index < m_links.size())
- {
- StoreUndo();
- m_links[index].name = newName;
- SetModified(false);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnRadiusChange(IVariable* var)
- {
- var->Get(m_proximityRadius);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnInnerRadiusChange(IVariable* var)
- {
- var->Get(m_innerRadius);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnOuterRadiusChange(IVariable* var)
- {
- var->Get(m_outerRadius);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxSizeXChange(IVariable* var)
- {
- var->Get(m_boxSizeX);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxSizeYChange(IVariable* var)
- {
- var->Get(m_boxSizeY);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxSizeZChange(IVariable* var)
- {
- var->Get(m_boxSizeZ);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnProjectorFOVChange(IVariable* var)
- {
- var->Get(m_projectorFOV);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnProjectInAllDirsChange(IVariable* var)
- {
- int value;
- var->Get(value);
- m_bProjectInAllDirs = value;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnProjectorTextureChange(IVariable* var)
- {
- QString texture;
- var->Get(texture);
- m_bProjectorHasTexture = !texture.isEmpty();
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnAreaLightChange(IVariable* var)
- {
- int value;
- var->Get(value);
- m_bAreaLight = value;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnAreaWidthChange(IVariable* var)
- {
- var->Get(m_fAreaWidth);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnAreaHeightChange(IVariable* var)
- {
- var->Get(m_fAreaHeight);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnAreaLightSizeChange(IVariable* var)
- {
- var->Get(m_fAreaLightSize);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnColorChange(IVariable* var)
- {
- var->Get(m_lightColor);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxProjectionChange(IVariable* var)
- {
- int value;
- var->Get(value);
- m_bBoxProjectedCM = value;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxWidthChange(IVariable* var)
- {
- var->Get(m_fBoxWidth);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxHeightChange(IVariable* var)
- {
- var->Get(m_fBoxHeight);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnBoxLengthChange(IVariable* var)
- {
- var->Get(m_fBoxLength);
- }
- //////////////////////////////////////////////////////////////////////////
- CVarBlock* CEntityObject::CloneProperties(CVarBlock* srcProperties)
- {
- assert(srcProperties);
- return srcProperties->Clone(true);
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::OnLoadFailed()
- {
- m_bLoadFailed = true;
- CErrorRecord err;
- err.error = tr("Entity %1 Failed to Spawn (Script: %2)").arg(GetName(), m_entityClass);
- err.pObject = this;
- GetIEditor()->GetErrorReport()->ReportError(err);
- }
- //////////////////////////////////////////////////////////////////////////
- //! Analyze errors for this object.
- void CEntityObject::Validate(IErrorReport* report)
- {
- CBaseObject::Validate(report);
- if (!m_entityClass.isEmpty())
- {
- CErrorRecord err;
- err.error = tr("Entity %1 Failed to Spawn (Script: %2)").arg(GetName(), m_entityClass);
- err.pObject = this;
- report->ReportError(err);
- return;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::GatherUsedResources(CUsedResources& resources)
- {
- CBaseObject::GatherUsedResources(resources);
- if (m_pProperties)
- {
- m_pProperties->GatherUsedResources(resources);
- }
- if (m_pProperties2)
- {
- m_pProperties2->GatherUsedResources(resources);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- bool CEntityObject::IsSimilarObject(CBaseObject* pObject)
- {
- if (pObject->GetClassDesc() == GetClassDesc() && pObject->metaObject() == metaObject())
- {
- CEntityObject* pEntity = ( CEntityObject* )pObject;
- if (m_entityClass == pEntity->m_entityClass &&
- m_proximityRadius == pEntity->m_proximityRadius &&
- m_innerRadius == pEntity->m_innerRadius &&
- m_outerRadius == pEntity->m_outerRadius)
- {
- return true;
- }
- }
- return false;
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::PreInitLightProperty()
- {
- if (!IsLight() || !m_pProperties)
- {
- return;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::UpdateLightProperty()
- {
- if (!IsLight() || !m_pProperties)
- {
- return;
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::ForceVariableUpdate()
- {
- if (m_pProperties)
- {
- m_pProperties->OnSetValues();
- }
- if (m_pProperties2)
- {
- m_pProperties2->OnSetValues();
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::ResetCallbacks()
- {
- ClearCallbacks();
- CVarBlock* pProperties = m_pProperties;
- CVarBlock* pProperties2 = m_pProperties2;
- if (pProperties)
- {
- m_callbacks.reserve(6);
- //@FIXME Hack to display radii of properties.
- // wires properties from param block, to this entity internal variables.
- IVariable* var = nullptr;
- var = pProperties->FindVariable("Radius", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_proximityRadius);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnRadiusChange]);
- }
- else
- {
- var = pProperties->FindVariable("radius", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_proximityRadius);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnRadiusChange]);
- }
- }
- var = pProperties->FindVariable("InnerRadius", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_innerRadius);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnInnerRadiusChange]);
- }
- var = pProperties->FindVariable("OuterRadius", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_outerRadius);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnOuterRadiusChange]);
- }
- var = pProperties->FindVariable("BoxSizeX", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_boxSizeX);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxSizeXChange]);
- }
- var = pProperties->FindVariable("BoxSizeY", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_boxSizeY);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxSizeYChange]);
- }
- var = pProperties->FindVariable("BoxSizeZ", false);
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_boxSizeZ);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxSizeZChange]);
- }
- var = pProperties->FindVariable("fAttenuationBulbSize");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_fAreaLightSize);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnAreaLightSizeChange]);
- }
- IVariable* pProjector = pProperties->FindVariable("Projector");
- if (pProjector)
- {
- var = pProjector->FindVariable("fProjectorFov");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_projectorFOV);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnProjectorFOVChange]);
- }
- var = pProjector->FindVariable("bProjectInAllDirs");
- if (var && var->GetType() == IVariable::BOOL)
- {
- int value;
- var->Get(value);
- m_bProjectInAllDirs = value;
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnProjectInAllDirsChange]);
- }
- var = pProjector->FindVariable("texture_Texture");
- if (var && var->GetType() == IVariable::STRING)
- {
- QString projectorTexture;
- var->Get(projectorTexture);
- m_bProjectorHasTexture = !projectorTexture.isEmpty();
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnProjectorTextureChange]);
- }
- }
- IVariable* pColorGroup = pProperties->FindVariable("Color", false);
- if (pColorGroup)
- {
- const int nChildCount = pColorGroup->GetNumVariables();
- for (int i = 0; i < nChildCount; ++i)
- {
- IVariable* pChild = pColorGroup->GetVariable(i);
- if (!pChild)
- {
- continue;
- }
- QString name(pChild->GetName());
- if (name == "clrDiffuse")
- {
- pChild->Get(m_lightColor);
- SetVariableCallback(pChild, &m_onSetCallbacksCache[VariableCallbackIndex::OnColorChange]);
- break;
- }
- }
- }
- IVariable* pType = pProperties->FindVariable("Shape");
- if (pType)
- {
- var = pType->FindVariable("bAreaLight");
- if (var && var->GetType() == IVariable::BOOL)
- {
- int value;
- var->Get(value);
- m_bAreaLight = value;
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnAreaLightChange]);
- }
- var = pType->FindVariable("fPlaneWidth");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_fAreaWidth);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnAreaWidthChange]);
- }
- var = pType->FindVariable("fPlaneHeight");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_fAreaHeight);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnAreaHeightChange]);
- }
- }
- IVariable* pProjection = pProperties->FindVariable("Projection");
- if (pProjection)
- {
- var = pProjection->FindVariable("bBoxProject");
- if (var && var->GetType() == IVariable::BOOL)
- {
- int value;
- var->Get(value);
- m_bBoxProjectedCM = value;
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxProjectionChange]);
- }
- var = pProjection->FindVariable("fBoxWidth");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_fBoxWidth);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxWidthChange]);
- }
- var = pProjection->FindVariable("fBoxHeight");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_fBoxHeight);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxHeightChange]);
- }
- var = pProjection->FindVariable("fBoxLength");
- if (var && (var->GetType() == IVariable::FLOAT || var->GetType() == IVariable::INT))
- {
- var->Get(m_fBoxLength);
- SetVariableCallback(var, &m_onSetCallbacksCache[VariableCallbackIndex::OnBoxLengthChange]);
- }
- }
- // Each property must have callback to our OnPropertyChange.
- pProperties->AddOnSetCallback(&m_onSetCallbacksCache[VariableCallbackIndex::OnPropertyChange]);
- }
- if (pProperties2)
- {
- pProperties2->AddOnSetCallback(&m_onSetCallbacksCache[VariableCallbackIndex::OnPropertyChange]);
- }
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::SetVariableCallback(IVariable* pVar, IVariable::OnSetCallback* func)
- {
- pVar->AddOnSetCallback(func);
- m_callbacks.push_back(std::make_pair(pVar, func));
- }
- //////////////////////////////////////////////////////////////////////////
- void CEntityObject::ClearCallbacks()
- {
- if (m_pProperties)
- {
- m_pProperties->RemoveOnSetCallback(&m_onSetCallbacksCache[VariableCallbackIndex::OnPropertyChange]);
- }
- if (m_pProperties2)
- {
- m_pProperties2->RemoveOnSetCallback(&m_onSetCallbacksCache[VariableCallbackIndex::OnPropertyChange]);
- }
- for (auto iter = m_callbacks.begin(); iter != m_callbacks.end(); ++iter)
- {
- iter->first->RemoveOnSetCallback(iter->second);
- }
- m_callbacks.clear();
- }
- template <typename T>
- T CEntityObject::GetEntityProperty(const char* pName, T defaultvalue) const
- {
- CVarBlock* pProperties = GetProperties2();
- IVariable* pVariable = nullptr;
- if (pProperties)
- {
- pVariable = pProperties->FindVariable(pName);
- }
- if (!pVariable)
- {
- pProperties = GetProperties();
- if (pProperties)
- {
- pVariable = pProperties->FindVariable(pName);
- }
- if (!pVariable)
- {
- return defaultvalue;
- }
- }
- if (pVariable->GetType() != IVariableType<T>::value)
- {
- return defaultvalue;
- }
- T value;
- pVariable->Get(value);
- return value;
- }
- template <typename T>
- void CEntityObject::SetEntityProperty(const char* pName, T value)
- {
- CVarBlock* pProperties = GetProperties2();
- IVariable* pVariable = nullptr;
- if (pProperties)
- {
- pVariable = pProperties->FindVariable(pName);
- }
- if (!pVariable)
- {
- pProperties = GetProperties();
- if (pProperties)
- {
- pVariable = pProperties->FindVariable(pName);
- }
- if (!pVariable)
- {
- throw std::runtime_error((QString("\"") + pName + "\" is an invalid property.").toUtf8().data());
- }
- }
- if (pVariable->GetType() != IVariableType<T>::value)
- {
- throw std::logic_error("Data type is invalid.");
- }
- pVariable->Set(value);
- }
- bool CEntityObject::GetEntityPropertyBool(const char* name) const
- {
- return GetEntityProperty<bool>(name, false);
- }
- int CEntityObject::GetEntityPropertyInteger(const char* name) const
- {
- return GetEntityProperty<int>(name, 0);
- }
- float CEntityObject::GetEntityPropertyFloat(const char* name) const
- {
- return GetEntityProperty<float>(name, 0.0f);
- }
- QString CEntityObject::GetEntityPropertyString(const char* name) const
- {
- return GetEntityProperty<QString>(name, "");
- }
- void CEntityObject::SetEntityPropertyBool(const char* name, bool value)
- {
- SetEntityProperty<bool>(name, value);
- }
- void CEntityObject::SetEntityPropertyInteger(const char* name, int value)
- {
- SetEntityProperty<int>(name, value);
- }
- void CEntityObject::SetEntityPropertyFloat(const char* name, float value)
- {
- SetEntityProperty<float>(name, value);
- }
- void CEntityObject::SetEntityPropertyString(const char* name, const QString& value)
- {
- SetEntityProperty<QString>(name, value);
- }
- #include <Objects/moc_EntityObject.cpp>
|