Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_GenericPreviewEntity.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameScripted/Preview", color: "0 0 0 0", dynamicBox: true)]
3 {
4 };
9 {
19  static SCR_BasePreviewEntity SpawnPreviewFromEntity(IEntity entity, ResourceName previewPrefab, BaseWorld world = null, EntitySpawnParams spawnParams = null, ResourceName material = ResourceName.Empty, EPreviewEntityFlag flags = 0)
20  {
21  if (!entity)
22  {
23  Print("No entity defined", LogLevel.WARNING);
24  return null;
25  }
26 
27  array<ref SCR_BasePreviewEntry> entries = GetPreviewEntriesFromEntity(entity, spawnParams, flags);
28  return SpawnPreview(entries, previewPrefab, world, spawnParams, material, flags);
29  }
30 
38  static array<ref SCR_BasePreviewEntry> GetPreviewEntriesFromEntity(IEntity entity, out EntitySpawnParams spawnParams = null, EPreviewEntityFlag flags = 0)
39  {
40  if (!spawnParams)
41  spawnParams = new EntitySpawnParams();
42 
43  TraceParam trace;
44  if (SCR_Enum.HasFlag(flags, EPreviewEntityFlag.GEOMETRY))
45  {
46  trace = new TraceParam();
47  SCR_EntityHelper.GetHierarchyEntityList(entity, trace.ExcludeArray);
48  }
49 
50  array<ref SCR_BasePreviewEntry> entries = {};
51  GetPreviewEntries(entity, entries, spawnParams.Transform, -1, flags, trace);
52  return entries;
53  }
54 
61  static void GetPreviewEntries(IEntity entity, out notnull array<ref SCR_BasePreviewEntry> outEntries, out vector rootTransform[4], int parentID = -1, EPreviewEntityFlag flags = 0, TraceParam trace = null)
62  {
63  vector transform[4];
64  if (parentID == -1)
65  {
66  entity.GetWorldTransform(transform);
67  SaveRootTransform(transform, rootTransform);
68  }
69  else
70  {
71  //--- Ignore vehicle crew, wouldn't have correct animations
72  if (entity.IsInherited(ChimeraCharacter))
73  return;
74 
75  //--- Skip the entity if...
76  if (
77  //--- ... it has an object (e.g., not a composition folder)...
78  entity.GetVObject()
79  &&
80  (
81  //--- ... but the object does not have a mesh (e.g., particle effect)...
82  (!entity.GetVObject().ToMeshObject())
83  ||
84  //--- ... or the object is not visible or is not intended for play mode
85  (!(entity.GetFlags() & EntityFlags.VISIBLE) || (entity.GetFlags() & EntityFlags.EDITOR_ONLY))
86  )
87  )
88  return;
89 
90  entity.GetLocalTransform(transform);
91  }
92 
94  entry.m_iParentID = parentID;
95  parentID = outEntries.Insert(entry);
96 
97  entry.m_Entity = entity;
98  entry.SaveTransform(transform);
99  entry.SetScale(GetLocalScale(entity));
100  entry.m_iPivotID = GetPivotName(entity);
101 
102  if (GetMesh(entity, flags, entry, outEntries))
103  return;
104 
105  SCR_SlotCompositionComponent compositionComponent = SCR_SlotCompositionComponent.Cast(entity.FindComponent(SCR_SlotCompositionComponent));
106  if (compositionComponent && compositionComponent.CanOrientChildrenToTerrain())
107  entry.m_Flags |= EPreviewEntityFlag.ORIENT_CHILDREN;
108 
109  SCR_HorizontalAlignComponent horizontalComponent = SCR_HorizontalAlignComponent.Cast(entity.FindComponent(SCR_HorizontalAlignComponent));
110  if (horizontalComponent)
111  entry.m_Flags |= EPreviewEntityFlag.HORIZONTAL;
112 
113  if (!SCR_Enum.HasFlag(flags, EPreviewEntityFlag.IGNORE_TERRAIN) && (entry.m_iParentID == -1 || SCR_Enum.HasFlag(entry.m_Flags, EPreviewEntityFlag.ORIENT_CHILDREN)))
114  SaveTerrainTransform(entity, entry, SCR_Enum.HasFlag(flags, EPreviewEntityFlag.UNDERWATER), trace);
115 
116  if (entry.m_Shape != EPreviewEntityShape.PREFAB)
117  {
118  IEntity child = entity.GetChildren();
119  while (child)
120  {
121  GetPreviewEntries(child, outEntries, rootTransform, parentID, flags, trace);
122  child = child.GetSibling();
123  }
124  }
125  }
126 
127  protected static float GetLocalScale(IEntity entity)
128  {
129  float scale = entity.GetScale();
130  if (entity.GetParent())
131  scale /= entity.GetParent().GetScale();
132 
133  return scale;
134  }
135  protected static string GetPivotName(IEntity entity)
136  {
137  IEntity parent = entity.GetParent();
138  if (!parent)
139  return string.Empty;
140 
141  TNodeId pivotIndex = entity.GetPivot();
142  if (pivotIndex == -1)
143  return string.Empty;
144 
145  array<string> boneNames = {};
146  Animation anim = parent.GetAnimation();
147  anim.GetBoneNames(boneNames);
148  for (int i = 0, count = boneNames.Count(); i < count; i++)
149  {
150  if (anim.GetBoneIndex(boneNames[i]) == pivotIndex)
151  return boneNames[i];
152  }
153  return string.Empty;
154  }
155  protected static bool GetMesh(IEntity entity, EPreviewEntityFlag flags, SCR_BasePreviewEntry entry, out notnull array<ref SCR_BasePreviewEntry> outEntries)
156  {
157  SCR_BaseAreaMeshComponent areaMeshComponent = SCR_BaseAreaMeshComponent.Cast(entity.FindComponent(SCR_BaseAreaMeshComponent));
158  if (areaMeshComponent)
159  {
160  EAreaMeshShape areaMeshShape = areaMeshComponent.GetShape();
161  if (areaMeshShape == EAreaMeshShape.ELLIPSE)
162  entry.m_Shape = EPreviewEntityShape.ELLIPSE;
163  else if (areaMeshShape == EAreaMeshShape.RECTANGLE)
164  entry.m_Shape = EPreviewEntityShape.RECTANGLE;
165  else
166  return false;
167 
168  areaMeshComponent.GetDimensions3D(entry.m_vScale);
169  return false;
170  }
171 
172  if (!SCR_Enum.HasFlag(flags, EPreviewEntityFlag.IGNORE_PREFAB))
173  {
174  SCR_PreviewEntityComponent previewComponent = SCR_PreviewEntityComponent.Cast(entity.FindComponent(SCR_PreviewEntityComponent));
175  if (previewComponent && previewComponent.IsRuntime())
176  {
177  //--- Entries pre-defined in the component, use them instead of scanning entity children dynamically
178  if (previewComponent.GetPreviewEntries(outEntries, entry) != 0)
179  return true;
180 
181  //--- Preview defined as a prefab, use that one
182  entry.m_Mesh = previewComponent.GetPreviewPrefab();
183  entry.m_Shape = EPreviewEntityShape.PREFAB;
184  return false;
185  }
186  }
187 
188  VObject meshObject = entity.GetVObject();
189  if (meshObject)
190  {
191  entry.m_Mesh = meshObject.GetResourceName();
192  entry.m_Shape = EPreviewEntityShape.MESH;
193  }
194 
195  return false;
196  }
197  protected static void SaveTerrainTransform(IEntity entity, SCR_BasePreviewEntry entry, bool isUnderwater = false, TraceParam trace = null)
198  {
199  vector worldTransform[4], terrainTransform[4], surfaceBasis[4];
200 
201  //--- Get world transform
202  entity.GetWorldTransform(worldTransform);
203 
204  //--- Get surface basis
205  if (!SCR_TerrainHelper.GetTerrainBasis(worldTransform[3], surfaceBasis, entity.GetWorld(), !isUnderwater, trace))
206  return;
207 
208  //--- Get identity matrix rotated according to the entity
209  vector angles = Math3D.MatrixToAngles(worldTransform);
210  Math3D.AnglesToMatrix(Vector(angles[0], 0, 0), terrainTransform);
211 
212  //--- Rotate surface basis
213  Math3D.MatrixMultiply3(surfaceBasis, terrainTransform, terrainTransform);
214 
215  //--- Get local transformation relative to terrain
216  Math3D.MatrixInvMultiply3(terrainTransform, worldTransform, terrainTransform);
217  entry.m_vAnglesTerrain = Math3D.MatrixToAngles(terrainTransform);
218  entry.m_vHeightTerrain = worldTransform[3][1] - surfaceBasis[3][1];
219  }
220  protected static void SaveRootTransform(out vector transform[4], out vector rootTransform[4])
221  {
222  if (SCR_Math3D.IsMatrixIdentity(rootTransform))
223  {
224  //--- When pivot is undefined, transformation of the first entity is used as pivot
225  Math3D.MatrixCopy(transform, rootTransform);
226  Math3D.MatrixIdentity4(transform);
227 
228  //--- Correct the matrix when pointing straight up or down (ToDo: More robust solution?)
229  vector angles = Math3D.MatrixToAngles(rootTransform);
230  if (float.AlmostEqual(Math.AbsFloat(angles[1]), 90))
231  {
232  if (angles[1] > 0) angles[2] = angles[2] - 90;
233  Math3D.AnglesToMatrix(Vector(angles[2] + 180, 0, 0), rootTransform);
234  }
235  }
236  else
237  {
238  //--- Relative transformation to pivot
239  Math3D.MatrixInvMultiply4(rootTransform, transform, transform);
240  }
241  }
242 };
SCR_TerrainHelper
Definition: SCR_TerrainHelper.c:1
SCR_EntityHelper
Definition: SCR_EntityHelper.c:1
SCR_Enum
Definition: SCR_Enum.c:1
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
SCR_BasePreviewEntry
Definition: SCR_BasePreviewEntry.c:2
SCR_BasePreviewEntityClass
Definition: SCR_BasePreviewEntity.c:2
EAreaMeshShape
EAreaMeshShape
Definition: SCR_BaseAreaMeshComponent.c:255
EPreviewEntityShape
EPreviewEntityShape
Definition: EPreviewEntityMesh.c:1
SCR_BasePreviewEntity
Definition: SCR_BasePreviewEntity.c:9
SCR_GenericPreviewEntity
Definition: SCR_GenericPreviewEntity.c:8
SCR_Math3D
Contains various scripted 3D math functions.
Definition: SCR_Math3D.c:2
EPreviewEntityFlag
EPreviewEntityFlag
Definition: EPreviewEntityFlag.c:1
SpawnPreview
void SpawnPreview()
Create a preview if it does not exist.
Definition: SCR_CampaignBuildingLayoutComponent.c:244
SCR_GenericPreviewEntityClass
Definition: SCR_GenericPreviewEntity.c:2
SCR_SlotCompositionComponent
Entity composition which is supposed to fit into a slot.
Definition: SCR_SlotCompositionComponent.c:44
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180