11 protected ResourceName m_SourcePrefab;
13 [
Attribute(
"{58F07022C12D0CF5}Assets/Editor/PlacingPreview/Preview.emat", UIWidgets.ResourcePickerThumbnail,
"Material used when regenerating the preview.",
category:
"Preview",
params:
"emat")]
14 private ResourceName m_PreviewMaterial;
25 static SCR_BasePreviewEntity SpawnPreviewFromPrefab(Resource prefabResource, ResourceName previewPrefab, BaseWorld world =
null, EntitySpawnParams spawnParams =
null, ResourceName material = ResourceName.Empty,
EPreviewEntityFlag flags = 0)
27 return SpawnPreview(GetPreviewEntriesFromPrefab(prefabResource), previewPrefab, world, spawnParams, material, flags);
35 static array<ref SCR_BasePreviewEntry> GetPreviewEntriesFromPrefab(Resource prefabResource)
38 array<ref SCR_BasePreviewEntry> entries = {};
39 GetPreviewEntries(entitySource, entries);
48 static void GetPreviewEntries(IEntitySource entitySource, out notnull array<ref SCR_BasePreviewEntry> outEntries,
int parentID = -1,
SCR_BasePreviewEntry entry =
null,
EPreviewEntityFlag flags = 0)
50 EntityFlags entityFlags;
51 entitySource.Get(
"Flags", entityFlags);
52 if (entityFlags & EntityFlags.EDITOR_ONLY)
62 entitySource.Get(
"coords", entryLocal.m_vPosition);
66 entitySource.Get(
"scale", scale);
67 entryLocal.SetScale(scale);
72 float angleX, angleY, angleZ;
73 entitySource.Get(
"angleX", angleX);
74 entitySource.Get(
"angleY", angleY);
75 entitySource.Get(
"angleZ", angleZ);
76 entryLocal.m_vAngles = Vector(angleX, angleY, angleZ);
79 entryLocal.m_EntitySource = entitySource;
80 entryLocal.m_iParentID = parentID;
81 entryLocal.m_vAnglesTerrain = Vector(0, entryLocal.m_vAngles[0], entryLocal.m_vAngles[2]);
82 entryLocal.m_vHeightTerrain = entryLocal.m_vPosition[1];
83 parentID = outEntries.Insert(entryLocal);
86 int componentCount = entitySource.GetComponentCount();
87 IEntityComponentSource componentSource;
88 bool componentEnabled;
91 for (
int i = 0; i < componentCount; i++)
93 componentSource = entitySource.GetComponent(i);
94 componentSource.Get(
"Enabled", componentEnabled);
95 if (!componentEnabled)
98 if (componentSource.GetClassName().ToType().IsInherited(SCR_PreviewEntityComponent) && !
SCR_Enum.HasFlag(flags,
EPreviewEntityFlag.IGNORE_PREFAB))
101 BaseContainerList entryList = componentSource.GetObjectArray(
"m_aEntries");
102 int entryCount = entryList.Count();
107 for (
int e = entryCount - 1; e >= 0; e--)
110 if (entryList.Get(e).Get(
"m_iParentID", itemParentID) && itemParentID == -1)
119 for (
int e = indexStart; e < entryCount; e++)
121 listEntry =
SCR_BasePreviewEntry.Cast(BaseContainerTools.CreateInstanceFromContainer(entryList.Get(e)));
122 if (listEntry.m_iParentID == -1)
126 entryLocal.m_vPosition == listEntry.m_vPosition;
128 entryLocal.m_Mesh = listEntry.m_Mesh;
129 entryLocal.m_Shape = listEntry.m_Shape;
130 entryLocal.m_Flags = listEntry.m_Flags;
134 outEntries.Insert(listEntry);
135 listEntry.m_iParentID += parentID;
136 listEntry.m_vAnglesTerrain = Vector(0, listEntry.m_vAngles[0], listEntry.m_vAngles[2]);
137 listEntry.m_vHeightTerrain = listEntry.m_vPosition[1];
146 componentSource.Get(
"m_PreviewPrefab", entryLocal.m_Mesh);
154 string componentClassName;
155 typename componentType;
157 for (
int i = 0; i < componentCount; i++)
159 componentSource = entitySource.GetComponent(i);
160 componentSource.Get(
"Enabled", componentEnabled);
161 if (!componentEnabled)
164 componentClassName = componentSource.GetClassName();
165 componentType = componentClassName.ToType();
168 case (componentClassName ==
"Hierarchy" && !entryLocal.m_iPivotID):
170 componentSource.Get(
"PivotID", entryLocal.m_iPivotID);
173 case (componentClassName ==
"MeshObject"):
175 componentSource.Get(
"Object", entryLocal.m_Mesh);
179 case (componentType.IsInherited(SlotManagerComponent)):
181 BaseContainerList slots = componentSource.GetObjectArray(
"Slots");
182 for (
int s = 0, slotCount = slots.Count(); s < slotCount; s++)
184 GetPreviewEntriesFromSlot(slots.Get(s), outEntries, parentID);
188 case (componentType.IsInherited(BaseSlotComponent) || componentType.IsInherited(
WeaponSlotComponent)):
190 BaseContainer attachType = componentSource.GetObject(
"AttachType");
194 ResourceName slotPrefab;
195 componentSource.Get(
"EntityPrefab", slotPrefab);
197 componentSource.Get(
"WeaponTemplate", slotPrefab);
199 GetPreviewEntriesFromSlot(attachType, outEntries, parentID, slotPrefab);
202 case (componentType.IsInherited(SCR_EditorLinkComponent)):
204 BaseContainerList entries = componentSource.GetObjectArray(
"m_aEntries");
206 for (
int e = 0, linkCount = entries.Count(); e < linkCount; e++)
208 link =
SCR_EditorLinkEntry.Cast(BaseContainerTools.CreateInstanceFromContainer(entries.Get(e)));
209 GetPreviewEntriesFromLink(link, outEntries, parentID, entryLocal.GetScale());
226 componentSource.Get(
"m_vIconPos", iconPos);
227 if (iconPos != vector.Zero)
228 entryLocal.m_vPosition -= iconPos;
235 componentSource.Get(
"m_bOrientChildrenToTerrain", orientChildren);
241 case (componentType.IsInherited(SCR_HorizontalAlignComponent)):
247 case (componentType.IsInherited(SCR_BaseAreaMeshComponent)):
257 case (componentType.IsInherited(SCR_TriggerAreaMeshComponent)):
260 componentSource.Get(
"m_eShape", areaMeshShape);
268 float radius, height;
269 entitySource.Get(
"SphereRadius", radius);
270 componentSource.Get(
"m_fHeight", height);
272 entryLocal.m_vScale = Vector(radius, height, radius);
276 case (componentType.IsInherited(SCR_WaypointAreaMeshComponent)):
279 componentSource.Get(
"m_eShape", areaMeshShape);
287 float radius, height;
288 entitySource.Get(
"CompletionRadius", radius);
289 componentSource.Get(
"m_fHeight", height);
291 entryLocal.m_vScale = Vector(radius, height, radius);
295 case (componentType.IsInherited(SCR_SpawnPointAreaMeshComponent)):
298 componentSource.Get(
"m_eShape", areaMeshShape);
306 float radius, height;
307 entitySource.Get(
"m_fSpawnRadius", radius);
308 componentSource.Get(
"m_fHeight", height);
310 entryLocal.m_vScale = Vector(radius, height, radius);
314 case (componentType.IsInherited(SCR_CustomAreaMeshComponent)):
317 componentSource.Get(
"m_eShape", areaMeshShape);
325 float radius, height;
326 componentSource.Get(
"m_fRadius", radius);
327 componentSource.Get(
"m_fHeight", height);
329 entryLocal.m_vScale = Vector(radius, height, radius);
333 case (componentType.IsInherited(SCR_ZoneRestrictionAreaMeshComponent)):
336 componentSource.Get(
"m_eShape", areaMeshShape);
344 float radius, height;
345 entitySource.Get(
"m_fZoneRadius", radius);
346 componentSource.Get(
"m_fHeight", height);
348 entryLocal.m_vScale = Vector(radius, height, radius);
352 case (componentType.IsInherited(SCR_SupportStationAreaMeshComponent)):
355 componentSource.Get(
"m_eShape", areaMeshShape);
364 for (
int c = 0; c < componentCount; c++)
366 IEntityComponentSource supportStation_componentSource = entitySource.GetComponent(c);
368 bool supportStation_componentEnabled;
369 supportStation_componentSource.Get(
"Enabled", supportStation_componentEnabled);
370 if (!supportStation_componentEnabled)
373 string supportStation_componentClassName = supportStation_componentSource.GetClassName();
374 if (!supportStation_componentClassName.ToType().IsInherited(SCR_BaseSupportStationComponent))
377 float radius, height;
378 supportStation_componentSource.Get(
"m_fRange", radius);
379 componentSource.Get(
"m_fHeight", height);
381 entryLocal.m_vScale = Vector(radius, height, radius);
386 float radius, height;
387 componentSource.Get(
"m_fRadius", radius);
388 componentSource.Get(
"m_fHeight", height);
389 entryLocal.m_vScale = Vector(radius, height, radius);
401 array<ResourceName> groupPrefabs =
new array<ResourceName>;
402 array<vector> groupOffsets =
new array<vector>;
403 int groupSize =
SCR_AIGroupClass.GetMembers(entitySource, groupPrefabs, groupOffsets);
407 IEntitySource groupMemberSource;
408 for (
int i = 0; i < groupSize; i++)
410 Resource resource = Resource.Load(groupPrefabs[i]);
413 groupMemberEntry.m_vPosition = groupOffsets[i];
414 GetPreviewEntries(groupMemberSource, outEntries, parentID, groupMemberEntry);
419 for (
int i = 0, count = entitySource.GetNumChildren(); i < count; i++)
421 GetPreviewEntries(entitySource.GetChild(i), outEntries, parentID);
425 protected static void GetPreviewEntriesFromSlot(BaseContainer slotSource, out notnull array<ref SCR_BasePreviewEntry> outEntries,
int parentID = -1, ResourceName slotPrefab = ResourceName.Empty)
428 slotSource.Get(
"Prefab", slotPrefab);
434 if (slotSource.GetName().Contains(
"SupplyStorage"))
437 Resource resource = Resource.Load(slotPrefab);
443 slotSource.Get(
"Offset", entry.m_vPosition);
444 slotSource.Get(
"Angles", entry.m_vAngles);
445 slotSource.Get(
"PivotID", entry.m_iPivotID);
447 GetPreviewEntries(entitySource, outEntries, parentID, entry);
449 protected static void GetPreviewEntriesFromLink(
SCR_EditorLinkEntry link, out notnull array<ref SCR_BasePreviewEntry> outEntries,
int parentID = -1,
float parentScale = 1)
451 Resource resource = Resource.Load(link.m_Prefab);
457 entry.m_vPosition = link.m_vPosition;
458 entry.m_vAngles = link.m_vAngles;
459 entry.SetScale(link.m_fScale);
461 GetPreviewEntries(entitySource, outEntries, parentID, entry);
466 void CreatePrefabFromSource(WorldEditorAPI api, ResourceName basePrefab)
468 Resource baseResource = Resource.Load(basePrefab);
469 if (!baseResource.IsValid())
472 IEntitySource baseSource = baseResource.GetResource().ToEntitySource();
476 array<ref SCR_BasePreviewEntry> entries = {};
480 IEntitySource child, parent;
481 IEntityComponentSource component;
482 array<ref IEntitySource> children = {};
483 string className =
"SCR_PrefabPreviewEntity";
486 if (entry.m_iParentID == -1)
489 parent = children[entry.m_iParentID];
491 child = api.CreateEntity(className,
"", 0, parent, entry.m_vPosition, entry.m_vAngles);
492 children.Insert(child);
494 child.Set(
"scale", entry.GetScale());
495 child.Set(
"m_Flags", entry.m_Flags);
499 className =
"SCR_BasePreviewEntity";
503 api.CreateComponent(child,
"Hierarchy");
505 if (!entry.m_iPivotID.IsEmpty())
506 api.SetVariableValue(child, {ContainerIdPathEntry(
"Hierarchy")},
"PivotID", entry.m_iPivotID);
515 component = api.CreateComponent(child,
"MeshObject");
516 api.SetVariableValue(child, {ContainerIdPathEntry(
"MeshObject")},
"Object", entry.m_Mesh);
518 Resource resource = Resource.Load(entry.m_Mesh);
519 if (!resource.IsValid())
521 Print(
"Cannot load " + entry.m_Mesh +
" | " + FilePath.StripPath(__FILE__) +
":" + __LINE__, LogLevel.WARNING);
525 VObject mesh = resource.GetResource().ToVObject();
526 string materials[256];
527 for (
int m = 0, materialsCount = mesh.GetMaterials(materials); m < materialsCount; m++)
529 api.CreateObjectArrayVariableMember(child, {ContainerIdPathEntry(
"MeshObject")},
"Materials",
"MaterialAssignClass", m);
530 api.SetVariableValue(child, {ContainerIdPathEntry(
"MeshObject"), ContainerIdPathEntry(
"Materials", m)},
"SourceMaterial", materials[m]);
531 api.SetVariableValue(child, {ContainerIdPathEntry(
"MeshObject"), ContainerIdPathEntry(
"Materials", m)},
"AssignedMaterial", m_PreviewMaterial);
536 IEntitySource previewSource = children[0];
537 api.SetVariableValue(previewSource,
null,
"m_SourcePrefab", basePrefab);
542 Workbench.GetAbsolutePath(prefab.GetPath(), absolutePath);
543 api.CreateEntityTemplate(previewSource, absolutePath);
545 api.DeleteEntity(previewSource);
548 override void _WB_OnContextMenu(
int id)
550 WorldEditorAPI api = _WB_GetEditorAPI();
551 IEntitySource entitySource = api.EntityToSource(
this);
553 ResourceName basePrefab;
554 entitySource.Get(
"m_SourcePrefab", basePrefab);
558 Debug.Error2(Type().ToString(),
"m_SourcePrefab is empty!");
562 api.BeginEntityAction();
563 CreatePrefabFromSource(api, basePrefab);
564 api.EndEntityAction();
566 override array<ref WB_UIMenuItem> _WB_GetContextMenuItems()
568 return {
new WB_UIMenuItem(
"Generate preview prefab", 0) };