Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
PrefabImporter.c
Go to the documentation of this file.
1class PrefabImporterRequest : JsonApiStruct
2{
3 string absPath;
4 int start;
5
6 void PrefabImporterRequest()
7 {
8 RegV("absPath");
9 RegV("start");
10 }
11}
12
13
15{
16 string status;
17 string message;
18 // absolute fbx path
19 ref array<string> fbx = new array<string>;
20 // transformation
21 ref array<string> coords = new array<string>;
22 ref array<string> angles = new array<string>;
23 ref array<string> scales = new array<string>;
24 // socket names
25 ref array<string> pivots = new array<string>;
26 // scoket ids
27 ref array<string> ids = new array<string>;
28 // material name
29 ref array<string> sourceMat = new array<string>;
30 // path to rewritten emat
31 ref array<string> ematPath = new array<string>;
32 // index of a object in a fbx array on which the current object is parented
33 ref array<int> parents = new array<int>;
35 int size;
36
38 {
39 RegV("status");
40 RegV("message");
41 RegV("fbx");
42 RegV("coords");
43 RegV("angles");
44 RegV("scales");
45 RegV("pivots");
46 RegV("ids");
47 RegV("sourceMat");
48 RegV("ematPath");
49 RegV("stopped");
50 RegV("size");
51 RegV("parents");
52 }
53}
54
55
57{
58
59 // in prefab it's impossible to get index of component
60 // this function loops through all the components and returns "i" when the component is the same as the input
61 int GetPrefabParamIndex(BaseContainer prefab, string name)
62 {
63 BaseContainerList srcList = prefab.GetObjectArray(EBTContainerFields.components);
64 for (int i = 0; i < srcList.Count(); i++)
65 {
66 prefab = srcList.Get(i);
67 if (prefab.GetClassName() == name)
68 {
69 return i;
70 }
71 }
72 return -1;
73 }
74
75
76 // getting paramaters from the prefab file
77 void GetPrefabParams(IEntitySource prefab, PrefabImporterResponse response)
78 {
79 BaseContainer empty;
80 BaseContainer ancestorSource = prefab.GetAncestor();
81 // edge-case for null prefab
82 if (!ancestorSource)
83 {
84 return;
85 }
86 ResourceName ancestor = ancestorSource.GetResourceName();
87 IEntitySource parent = prefab.GetParent();
88 string pivotID = "";
89
90
91
92 // get hierarchy
93 int hierarchy = GetPrefabParamIndex(prefab, EBTContainerFields.hierarchy);
94 if (hierarchy != -1)
95 {
96 // set pivot/socket ID and Name
97 BaseContainerList srcList = prefab.GetObjectArray(EBTContainerFields.components);
98 BaseContainer prefabSocket = srcList.Get(hierarchy);
99 ResourceName id = prefabSocket.GetResourceName();
100 prefabSocket.Get(EBTContainerFields.pivot, pivotID);
101 pivotID.ToLower();
102 response.ids.Insert(prefab.GetID().ToString());
103 response.pivots.Insert(pivotID);
104 }
105 else
106 {
107 // if not fill with garbage
108 response.pivots.Insert("xxx");
109 }
110
111
112 //<-----------------Getting params----------------->\\
113 string coords;
114 string scale;
115
116 // getting coords in local space
117 if (prefab.IsVariableSet(EBTContainerFields.coords))
118 {
119 prefab.Get(EBTContainerFields.coords, coords);
120 }
121 else
122 {
123 coords = "0 0 0";
124 }
125 // getting scale
126 if (prefab.IsVariableSet(EBTContainerFields.scale))
127 {
128 prefab.Get(EBTContainerFields.scale, scale);
129 }
130 else
131 {
132 scale = "1";
133 }
134 // getting angles as one string (EBT formatting)
135 string angles = "0 0 0";
136 // getting coords in local space
137 if (prefab.IsVariableSet(EBTContainerFields.angles))
138 {
139 prefab.Get(EBTContainerFields.angles, angles);
140 }
141
142
143 // check if this fbx is parented to something in the prefab
144 if (parent != empty)
145 {
146 int parentObjectID = GetPrefabParamIndex(parent, EBTContainerFields.meshObject);
147 if (parentObjectID != -1)
148 {
149 // get parentFBX and check if the FBX already was processed
150 string parentFbx = GetFBXPath(parent, parentObjectID, EBTContainerFields.object, response, false);
151 for (int i = response.fbx.Count() - 1; i > 0; i--)
152 {
153 // if it was processed then we know its index and we add the index to this prefabs "parent" array since this prefab is parented to it
154 if (response.fbx.Count() > 1 && parentFbx == response.fbx[i])
155 {
156 response.parents.Insert(i);
157 break;
158 }
159 }
160 }
161 }
162
163 // insert data
164 response.coords.Insert(coords);
165 response.scales.Insert(scale);
166 response.angles.Insert(angles);
167
168 // check if fbx paths is the same count as coords
169 // if not add -1 as a parent since that means its the heighest prefab with no parents
170 if (response.parents.Count() != response.coords.Count())
171 {
172 response.parents.Insert(-1);
173 }
174
175 // now get the absolute fbx path of the prefab we got parameters from
176 int meshObjectID = GetPrefabParamIndex(prefab, EBTContainerFields.meshObject);
177
178 // only if the meshObject exists
179 // and read its ancestor
180 if (meshObjectID != -1)
181 {
182 string fbxPath = GetFBXPath(prefab, meshObjectID, EBTContainerFields.object, response, true);
183 // If filepath does not contain FBX, do not send it
184 if (fbxPath.Contains(".fbx"))
185 {
186 response.fbx.Insert(fbxPath);
187 ReadAncestor(ancestorSource, response, true);
188 }
189 }
190
191 // if not then add a collection
192 else
193 {
194 response.fbx.Insert("Collection-" + FilePath.StripExtension(FilePath.StripPath(prefab.GetResourceName())));
195 ReadAncestor(ancestorSource, response, true);
196 }
197 return;
198 }
199
200
201 string GetFBXPath(IEntitySource prefab, int meshObjectID, string meshVarName, PrefabImporterResponse response, bool getEmat)
202 {
203 // get meshObjectID from the prefab file
204 ResourceName absPath, output, relXob;
205 array<string> sourceMat = new array<string>;
206 Workbench.GetAbsolutePath(prefab.GetResourceName().GetPath(), absPath);
207 BaseContainerList srcList = prefab.GetObjectArray(EBTContainerFields.components);
208 IEntitySource prefabMesh = srcList.Get(meshObjectID);
209 // if prefab has its own emat
210 if (getEmat)
211 {
212 GetPrefabEmat(prefabMesh, response);
213 }
214 // get the fbx absolute path
215 prefabMesh.Get(meshVarName, relXob);
216 Workbench.GetAbsolutePath(relXob.GetPath(), output);
217 output.Replace("xob","fbx");
218 if (!FileIO.FileExists(output)){
219 output = "";
220 }
221 return output;
222 }
223
224 // get materials that are overitten in prefab file
225 void GetPrefabEmat(IEntitySource prefab, PrefabImporterResponse response)
226 {
227 ResourceName ematPath, absPathEmat;
228 string matName;
229 array<string> sourceMat = new array<string>;
230 prefab.Get("Materials", ematPath);
231 if (ematPath != "")
232 {
233 // format the material output
234 ematPath.Split(";", sourceMat, false);
235 for (int i = 0; i < sourceMat.Count(); i++)
236 {
237 //Material name
238 matName = sourceMat[i].Substring(0, sourceMat[i].IndexOf(","));
239 //Relative Path
240 ematPath = sourceMat[i].Substring(sourceMat[i].IndexOf("{"), sourceMat[i].IndexOf(".emat") + 5 - sourceMat[i].IndexOf("{"));
241 //Absolute Path
242 Workbench.GetAbsolutePath(ematPath.GetPath(), absPathEmat);
243
244 // insert data
245 response.sourceMat.Insert(response.fbx.Count().ToString() + "|" + matName);
246 response.ematPath.Insert(ematPath);
247 }
248 }
249 }
250
251
252
253 void ReadAncestor(IEntitySource prefab, PrefabImporterResponse response, bool getMeshObject)
254 {
255
256 // check if Ancestor of main prefab is null if yes then its a BasePrefab and we can return
257 BaseContainer empty;
258 BaseContainer ancestorMain = prefab.GetAncestor();
259 if (ancestorMain == empty)
260 {
261 return;
262 }
263
264 // if not get its child
265 ReadChild(prefab, response);
266 // and then his ancestor
267 ReadAncestor(ancestorMain, response, getMeshObject);
268 return;
269 }
270
271
272 // get child params if the child is one of the predefined entity types
273 void ReadChild(IEntitySource prefab, PrefabImporterResponse response)
274 {
275 for (int i = 0; i < prefab.GetNumChildren(); i++)
276 {
277 IEntitySource child = prefab.GetChild(i).ToEntitySource();
278 if(EBTContainerFields.supportedTypes.Contains(child.GetClassName()))
279 {
280 GetPrefabParams(child, response);
281 }
282 }
283 }
284
285 void ReadFirst(ResourceName path, PrefabImporterResponse response)
286 {
287 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
288 //Get MetaFile from AbsPath of prefab (.et)
289 MetaFile meta = resourceManager.GetMetaFile(path);
290 Resource resource = Resource.Load(meta.GetResourceID());
291 BaseContainer prefab = resource.GetResource().ToEntitySource();
292
293 BaseContainer ancestorPrefab = prefab.GetAncestor();
294 if(!ancestorPrefab)
295 {
296 return;
297 }
298
299 // get its paramas and read the child
300 GetPrefabParams(prefab, response);
301 ReadChild(prefab, response);
302 }
303
304 // JSONStructAPI has limitation what can be sent through
305 // removing prefabs that were already sent or will cause the overload
306 int RemoveOverloadedPrefabs(PrefabImporterResponse response, int startIndex)
307 {
308 const int DATA_CAP = 60000;
309 // remove already sent prefabs
310 for (int i = 0; i < startIndex; i++)
311 {
312 response.fbx.RemoveOrdered(0);
313 response.scales.RemoveOrdered(0);
314 response.angles.RemoveOrdered(0);
315 response.coords.RemoveOrdered(0);
316 response.pivots.RemoveOrdered(0);
317 response.parents.RemoveOrdered(0);
318 }
319
320 // remove all other from last that will overload JSON
321 while (response.GetSizeOf() > DATA_CAP)
322 {
323 response.fbx.RemoveOrdered(response.fbx.Count()-1);
324 response.scales.RemoveOrdered(response.scales.Count()-1);
325 response.angles.RemoveOrdered(response.angles.Count()-1);
326 response.coords.RemoveOrdered(response.coords.Count()-1);
327 response.pivots.RemoveOrdered(response.pivots.Count()-1);
328 response.parents.RemoveOrdered(response.parents.Count()-1);
329 }
330 int stopIndex = response.fbx.Count() + startIndex;
331 return stopIndex;
332
333 }
334}
335
336class PrefabImporter : NetApiHandler
337{
338 override JsonApiStruct GetRequest()
339 {
340 return new PrefabImporterRequest();
341 }
344 {
348
349
350 ResourceManager resourceManager = Workbench.GetModule(ResourceManager);
351 MetaFile meta = resourceManager.GetMetaFile(req.absPath);
352
353 if (!meta)
354 {
355 response.status = "ERROR";
356 response.message = string.Format("Prefab Resource with path \"%1\" is missing!", req.absPath);
357 return response;
359
360 response.status = "OK";
361
362 // get prefabs with params
363 utils.ReadFirst(req.absPath, response);
364
365 // the size of the data
366 response.size = response.fbx.Count();
367
368 // removing overloaded data
369 response.stopped = utils.RemoveOverloadedPrefabs(response, req.start);
370 return response;
371 }
372}
string path
override JsonApiStruct GetResponse(JsonApiStruct request)
vector scale
ref array< string > ematPath
ref array< string > fbx
int size
void PrefabImporterResponse()
int stopped
ref array< string > ids
ref array< string > coords
ref array< string > scales
ref array< int > parents
ref array< string > angles
ref array< string > sourceMat
ref array< string > pivots
SCR_AICombatMoveRequestBase GetRequest()
base classes for filtering in server browser
Object holding reference to resource. In destructor release the resource.
Definition Resource.c:25