Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
SCR_GenericPreviewEntity.c
Go to the documentation of this file.
1[EntityEditorProps(category: "GameScripted/Preview", color: "0 0 0 0", dynamicBox: true)]
5
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
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 Animation anim = parent.GetAnimation();
146 if (anim)
147 {
148 array<string> boneNames = {};
149 anim.GetBoneNames(boneNames);
150 for (int i = 0, count = boneNames.Count(); i < count; i++)
151 {
152 if (anim.GetBoneIndex(boneNames[i]) == pivotIndex)
153 return boneNames[i];
154 }
155 }
156 return string.Empty;
157 }
158 protected static bool GetMesh(IEntity entity, EPreviewEntityFlag flags, SCR_BasePreviewEntry entry, out notnull array<ref SCR_BasePreviewEntry> outEntries)
159 {
160 SCR_BaseAreaMeshComponent areaMeshComponent = SCR_BaseAreaMeshComponent.Cast(entity.FindComponent(SCR_BaseAreaMeshComponent));
161 if (areaMeshComponent)
162 {
163 EAreaMeshShape areaMeshShape = areaMeshComponent.GetShape();
164 if (areaMeshShape == EAreaMeshShape.ELLIPSE)
165 entry.m_Shape = EPreviewEntityShape.ELLIPSE;
166 else if (areaMeshShape == EAreaMeshShape.RECTANGLE)
167 entry.m_Shape = EPreviewEntityShape.RECTANGLE;
168 else
169 return false;
170
171 areaMeshComponent.GetDimensions3D(entry.m_vScale);
172 return false;
173 }
174
175 if (!SCR_Enum.HasFlag(flags, EPreviewEntityFlag.IGNORE_PREFAB))
176 {
177 SCR_PreviewEntityComponent previewComponent = SCR_PreviewEntityComponent.Cast(entity.FindComponent(SCR_PreviewEntityComponent));
178 if (previewComponent && previewComponent.IsRuntime())
179 {
180 //--- Entries pre-defined in the component, use them instead of scanning entity children dynamically
181 if (previewComponent.GetPreviewEntries(outEntries, entry) != 0)
182 return true;
183
184 //--- Preview defined as a prefab, use that one
185 entry.m_Mesh = previewComponent.GetPreviewPrefab();
186 entry.m_Shape = EPreviewEntityShape.PREFAB;
187 return false;
188 }
189 }
190
191 VObject meshObject = entity.GetVObject();
192 if (meshObject)
193 {
194 entry.m_Mesh = meshObject.GetResourceName();
195 entry.m_Shape = EPreviewEntityShape.MESH;
196 }
197
198 return false;
199 }
200 protected static void SaveTerrainTransform(IEntity entity, SCR_BasePreviewEntry entry, bool isUnderwater = false, TraceParam trace = null)
201 {
202 vector worldTransform[4], terrainTransform[4], surfaceBasis[4];
203
204 //--- Get world transform
205 entity.GetWorldTransform(worldTransform);
206
207 //--- Get surface basis
208 if (!SCR_TerrainHelper.GetTerrainBasis(worldTransform[3], surfaceBasis, entity.GetWorld(), !isUnderwater, trace))
209 return;
210
211 //--- Get identity matrix rotated according to the entity
212 vector angles = Math3D.MatrixToAngles(worldTransform);
213 Math3D.AnglesToMatrix(Vector(angles[0], 0, 0), terrainTransform);
214
215 //--- Rotate surface basis
216 Math3D.MatrixMultiply3(surfaceBasis, terrainTransform, terrainTransform);
217
218 //--- Get local transformation relative to terrain
219 Math3D.MatrixInvMultiply3(terrainTransform, worldTransform, terrainTransform);
220 entry.m_vAnglesTerrain = Math3D.MatrixToAngles(terrainTransform);
221 entry.m_fHeightTerrain = worldTransform[3][1] - surfaceBasis[3][1];
222 }
223 protected static void SaveRootTransform(out vector transform[4], out vector rootTransform[4])
224 {
225 if (SCR_Math3D.IsMatrixIdentity(rootTransform))
226 {
227 //--- When pivot is undefined, transformation of the first entity is used as pivot
228 Math3D.MatrixCopy(transform, rootTransform);
229 Math3D.MatrixIdentity4(transform);
230
231 //--- Correct the matrix when pointing straight up or down (ToDo: More robust solution?)
232 vector angles = Math3D.MatrixToAngles(rootTransform);
233 if (float.AlmostEqual(Math.AbsFloat(angles[1]), 90))
234 {
235 if (angles[1] > 0) angles[2] = angles[2] - 90;
236 Math3D.AnglesToMatrix(Vector(angles[2] + 180, 0, 0), rootTransform);
237 }
238 }
239 else
240 {
241 //--- Relative transformation to pivot
242 Math3D.MatrixInvMultiply4(rootTransform, transform, transform);
243 }
244 }
245};
SCR_EAIThreatSectorFlags flags
vector scale
EPreviewEntityFlag
EPreviewEntityShape
ref array< string > angles
void SpawnPreview()
Create a preview if it does not exist.
enum SCR_ECompassType EntityEditorProps(category:"GameScripted/Gadgets", description:"Compass", color:"0 0 255 255")
Prefab data class for compass component.
proto external EntityFlags GetFlags()
void IEntity(IEntitySource src, IEntity parent)
protected script Constructor
proto external Managed FindComponent(typename typeName)
proto external float GetScale()
proto external IEntity GetChildren()
proto external void GetWorldTransform(out vector mat[])
See IEntity::GetTransform.
proto external Animation GetAnimation()
proto external BaseWorld GetWorld()
proto external IEntity GetParent()
proto external TNodeId GetPivot()
Returns pivot ID from hierarchy component.
proto external IEntity GetSibling()
proto external VObject GetVObject()
Returns visual object set to this Entity. No reference is added.
proto external void GetLocalTransform(out vector mat[])
See IEntity::GetTransform.
Definition Math.c:13
void SCR_BasePreviewEntity(IEntitySource src, IEntity parent)
static string GetPivotName(IEntity entity)
static float GetLocalScale(IEntity entity)
static bool GetMesh(IEntity entity, EPreviewEntityFlag flags, SCR_BasePreviewEntry entry, out notnull array< ref SCR_BasePreviewEntry > outEntries)
static void SaveTerrainTransform(IEntity entity, SCR_BasePreviewEntry entry, bool isUnderwater=false, TraceParam trace=null)
static void SaveRootTransform(out vector transform[4], out vector rootTransform[4])
Contains various scripted 3D math functions.
Definition SCR_Math3D.c:3
Entity composition which is supposed to fit into a slot.
static bool GetTerrainBasis(vector pos, out vector result[4], BaseWorld world=null, bool noUnderwater=false, TraceParam trace=null)
Visual object.
Definition VObject.c:14
void EntitySpawnParams()
Definition gameLib.c:130
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
EntityFlags
Various entity flags.
Definition EntityFlags.c:14
int TNodeId
Node global id is a hash of name of the node.
Definition EnEntity.c:18
proto native vector Vector(float x, float y, float z)