1 // Copyright 2001-2019 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "BaseEnv/Utils/BaseEnv_EntityClassRegistrar.h"
6 #include <Cry3DEngine/I3DEngine.h>
7 #include <CryEntitySystem/IEntityClass.h>
8 #include <CryRenderer/IRenderAuxGeom.h>
9 #include <CryRenderer/IRenderer.h>
10 #include <GameObjects/GameObject.h>
11 #include <GameObjects/GameObjectSystem.h>
13 #include "BaseEnv/BaseEnv_BaseEnv.h"
14 #include "CrySchematyc2/IEntityAttributesProxy.h"
15 #include "BaseEnv/Utils/BaseEnv_EntityFoundationProperties.h"
16 #include "BaseEnv/Utils/BaseEnv_EntityGameObjectExtension.h"
17 #include "BaseEnv/Utils/BaseEnv_EntityMap.h"
18 #include "BaseEnv/Utils/BaseEnv_EntityUserData.h"
20 namespace SchematycBaseEnv
22 class CGameObjectExtensionCreator
: public IGameObjectExtensionCreatorBase
26 // IGameObjectExtensionCreatorBase
28 virtual IGameObjectExtension
* Create(IEntity
*pEntity
)
30 return pEntity
->GetOrCreateComponentClass
<CEntityGameObjectExtension
>();
33 virtual void GetGameObjectExtensionRMIData(void** ppRMI
, size_t* pCount
)
35 CEntityGameObjectExtension::GetGameObjectExtensionRMIData(ppRMI
, pCount
);
38 // ~IGameObjectExtensionCreatorBase
41 class CEntityFoundationPreviewExtension
: public Schematyc2::IFoundationPreviewExtension
45 inline CEntityFoundationPreviewExtension()
49 // IFoundationPreviewExtension
51 virtual Schematyc2::IObject
* BeginPreview(const Schematyc2::SGUID
& classGUID
, EntityId selectedEntityId
) override
53 Schematyc2::IObject
* pObject
= nullptr;
54 Schematyc2::ILibClassConstPtr pLibClass
= gEnv
->pSchematyc2
->GetLibRegistry().GetClass(classGUID
);
57 IEntityClass
* pEntityClass
= gEnv
->pEntitySystem
->GetClassRegistry()->FindClass(pLibClass
->GetName());
60 static const SEntityUserData
userData(true, Schematyc2::EObjectFlags::None
);
61 SEntitySpawnParams entitySpawnParams
;
62 entitySpawnParams
.pClass
= pEntityClass
;
63 entitySpawnParams
.sName
= SCHEMATYC2_PREVIEW_ENTITY_NAME
;
64 entitySpawnParams
.pUserData
= const_cast<SEntityUserData
*>(&userData
);
65 IEntity
* pEntity
= gEnv
->pEntitySystem
->SpawnEntity(entitySpawnParams
, true);
68 m_entityId
= pEntity
->GetId();
69 pObject
= CBaseEnv::GetInstance().GetGameEntityMap().FindObject(m_entityId
);
71 IEntity
* pSelectedEntity
= gEnv
->pEntitySystem
->GetEntity(selectedEntityId
);
74 SEntityEvent entityEvent
;
75 entityEvent
.event
= ENTITY_EVENT_RESET
;
76 pSelectedEntity
->SendEvent(entityEvent
);
83 virtual void RenderPreview(const SRendParams
& params
, const SRenderingPassInfo
& passInfo
) override
87 IEntity
* pEntity
= gEnv
->pEntitySystem
->GetEntity(m_entityId
);
90 if(pEntity
->GetRenderNode())
92 pEntity
->GetRenderNode()->Render(params
, passInfo
);
94 gEnv
->pRenderer
->GetIRenderAuxGeom()->Submit();
99 virtual void EndPreview() override
103 gEnv
->pEntitySystem
->RemoveEntity(m_entityId
);
108 // ~IFoundationPreviewExtension
115 DECLARE_SHARED_POINTERS(CEntityFoundationPreviewExtension
)
117 IEntityComponent
* CreateGameObjectEntityProxy(IEntity
* pEntity
, SEntitySpawnParams
& spawnParams
, void* pUserData
)
119 IGameObject
* pGameObject
= nullptr;
120 IEntityComponent
* pEntityProxy
= gEnv
->pGameFramework
->GetIGameObjectSystem()->CreateGameObjectEntityProxy(*pEntity
, &pGameObject
);
121 CRY_ASSERT(pGameObject
);
124 static bool bHasRegistered
= false;
127 bHasRegistered
= true;
129 static CGameObjectExtensionCreator s_gameObjectExtensionCreator
;
130 gEnv
->pGameFramework
->GetIGameObjectSystem()->RegisterExtension(CEntityGameObjectExtension::s_szExtensionName
, &s_gameObjectExtensionCreator
, nullptr);
133 if(pGameObject
->ActivateExtension(CEntityGameObjectExtension::s_szExtensionName
))
135 pGameObject
->SetUserData(spawnParams
.pUserData
);
142 static const Schematyc2::SGUID s_entityFoundationGUID
= "be845278-0dd2-409f-b8be-97895607c256";
144 void CEntityClassRegistrar::Init()
146 gEnv
->pSchematyc2
->GetLibRegistry().Signals().classRegistration
.Connect(Schematyc2::LibClassRegistrationSignal::Delegate::FromMemberFunction
<CEntityClassRegistrar
, &CEntityClassRegistrar::OnClassRegistration
>(*this), m_connectionScope
); // TODO : Can we filter by foundation guid?
149 void CEntityClassRegistrar::Refresh()
151 Schematyc2::IFoundationPtr pEntityFoundation
= gEnv
->pSchematyc2
->GetEnvRegistry().CreateFoundation(s_entityFoundationGUID
, "Entity");
152 CRY_ASSERT(pEntityFoundation
);
153 if(pEntityFoundation
)
155 pEntityFoundation
->SetProperties(Schematyc2::Properties::MakeShared
<SEntityFoundationProperties
>());
156 pEntityFoundation
->UseNamespace("Base");
157 pEntityFoundation
->UseNamespace("Utils");
158 pEntityFoundation
->UseNamespace("Debug::UDR");
159 //pEntityFoundation->UseNamespace("Types");
160 // TODO: Workaround until recursion works.
161 pEntityFoundation
->UseNamespace("Types::Bool");
162 pEntityFoundation
->UseNamespace("Types::Int32");
163 pEntityFoundation
->UseNamespace("Types::UInt32");
164 pEntityFoundation
->UseNamespace("Types::Float");
165 pEntityFoundation
->UseNamespace("Types::Vector2");
166 pEntityFoundation
->UseNamespace("Types::Vector3");
167 pEntityFoundation
->UseNamespace("Types::Angle2");
168 pEntityFoundation
->UseNamespace("Types::QRotation");
169 pEntityFoundation
->UseNamespace("Types::String");
171 pEntityFoundation
->AddExtension
<Schematyc2::IFoundationPreviewExtension
>(CEntityFoundationPreviewExtensionPtr(std::make_shared
<CEntityFoundationPreviewExtension
>()));
175 CEntityClassRegistrar::SEntityClass::SEntityClass()
177 // N.B. This is a quick work around for the problem of entities without script tables not triggering areas.
178 desc
.pScriptTable
= gEnv
->pScriptSystem
->CreateTable();
179 desc
.pScriptTable
->AddRef();
182 CEntityClassRegistrar::SEntityClass::SEntityClass(const SEntityClass
& rhs
)
183 : editorCategory(rhs
.editorCategory
)
187 desc
.pScriptTable
->AddRef();
190 CEntityClassRegistrar::SEntityClass::~SEntityClass()
192 desc
.pScriptTable
->Release();
195 void CEntityClassRegistrar::RegisterEntityClass(const Schematyc2::ILibClass
& libClass
, SEntityClass
& entityClass
, bool bNewEntityClass
)
197 Schematyc2::IPropertiesConstPtr pFoundationProperties
= libClass
.GetFoundationProperties();
198 CRY_ASSERT(pFoundationProperties
);
199 if(pFoundationProperties
)
201 const SEntityFoundationProperties
& foundationProperties
= *pFoundationProperties
->ToPtr
<SEntityFoundationProperties
>();
203 entityClass
.libClassGUID
= libClass
.GetGUID();
205 entityClass
.editorCategory
= "Schematyc";
206 entityClass
.editorCategory
.append("/");
207 //entityClass.editorCategory.append(libClass.GetLib().GetName());
208 entityClass
.editorCategory
.append(libClass
.GetName());
209 string::size_type fileNamePos
= entityClass
.editorCategory
.find_last_of("/");
210 if(fileNamePos
!= string::npos
)
212 entityClass
.editorCategory
.erase(fileNamePos
);
214 entityClass
.editorCategory
.replace("::", "/");
216 entityClass
.icon
= foundationProperties
.icon
;
217 const string::size_type iconFileNamePos
= entityClass
.icon
.find_last_of("/\\");
218 if(iconFileNamePos
!= string::npos
)
220 entityClass
.icon
.erase(0, iconFileNamePos
+ 1);
223 entityClass
.desc
.flags
= ECLF_BBOX_SELECTION
;
224 if(foundationProperties
.bHideInEditor
)
226 entityClass
.desc
.flags
|= ECLF_INVISIBLE
;
230 entityClass
.desc
.flags
|= ECLF_MODIFY_EXISTING
;
233 entityClass
.desc
.sName
= libClass
.GetName();
234 entityClass
.desc
.editorClassInfo
.sCategory
= entityClass
.editorCategory
.c_str();
235 entityClass
.desc
.editorClassInfo
.sIcon
= entityClass
.icon
.c_str();
236 entityClass
.desc
.pUserProxyCreateFunc
= &CreateGameObjectEntityProxy
;
238 // NOTE pavloi 2016.11.25: CEntityGameObjectExtension::Init expects to find this pointer to SEntityClass in the pUserProxyData
239 entityClass
.desc
.pUserProxyData
= &entityClass
;
241 gEnv
->pEntitySystem
->GetClassRegistry()->RegisterStdClass(entityClass
.desc
);
245 void CEntityClassRegistrar::OnClassRegistration(const Schematyc2::ILibClassConstPtr
& pLibClass
)
247 const Schematyc2::SGUID foundationGUID
= pLibClass
->GetFoundationGUID();
248 if(foundationGUID
== s_entityFoundationGUID
)
250 const char* szEntityClassName
= pLibClass
->GetName();
251 EntityClasses::iterator itEntityClass
= m_entityClasses
.find(szEntityClassName
);
252 if(itEntityClass
== m_entityClasses
.end())
254 RegisterEntityClass(*pLibClass
, m_entityClasses
[szEntityClassName
], true);
258 RegisterEntityClass(*pLibClass
, itEntityClass
->second
, false);