BrawlCrate v0.41
Wii File Editor
Loading...
Searching...
No Matches
Static Public Member Functions | List of all members
BrawlLib.Wii.Models.ModelEncoder Class Reference

Static Public Member Functions

static void AssignNodeIndices (ModelLinker linker)
 
static int CalcSize (ModelLinker linker)
 
static int CalcSize (Collada form, ModelLinker linker)
 

Member Function Documentation

◆ AssignNodeIndices()

static void BrawlLib.Wii.Models.ModelEncoder.AssignNodeIndices ( ModelLinker  linker)
inlinestatic
18 {
19 MDL0Node model = linker.Model;
20 int index = 0;
21
22 int count = model._influences.Count + linker.BoneCache.Length;
23
24 linker._nodeCount = count;
25 linker.Model._numNodes = count;
26 linker.NodeCache = new IMatrixNode[count];
27
28 //Add referenced primaries
29 foreach (MDL0BoneNode bone in linker.BoneCache)
30 {
31 if (bone.Users.Count > 0 || bone._singleBindObjects.Count > 0)
32 {
33 linker.NodeCache[bone._nodeIndex = index++] = bone;
34 }
35 else
36 {
37 bone._nodeIndex = -1;
38 }
39
40 bone._weightCount = 0;
41 }
42
43 //Add weight groups
44 foreach (Influence i in model._influences._influences)
45 {
46 linker.NodeCache[i._index = index++] = i;
47 foreach (BoneWeight b in i.Weights)
48 {
49 if (b.Bone != null)
50 {
51 b.Bone.WeightCount++;
52 }
53 }
54 }
55
56 //Add remaining bones
57 foreach (MDL0BoneNode bone in linker.BoneCache)
58 {
59 if (bone._nodeIndex == -1)
60 {
61 linker.NodeCache[bone._nodeIndex = index++] = bone;
62 }
63 }
64 }
Definition: MDL0BoneNode.cs:17
List< IMatrixNodeUser > Users
Definition: MDL0BoneNode.cs:150
List< MDL0ObjectNode > _singleBindObjects
Definition: MDL0BoneNode.cs:52
int WeightCount
Definition: MDL0BoneNode.cs:96
int _nodeIndex
Definition: MDL0BoneNode.cs:60
Definition: MDL0Node.cs:24
IBoneNode[] BoneCache
Definition: MDL0Node.cs:2916
InfluenceManager _influences
Definition: MDL0Node.cs:50
Definition: IMatrixNode.cs:9

◆ CalcSize() [1/2]

static int BrawlLib.Wii.Models.ModelEncoder.CalcSize ( Collada  form,
ModelLinker  linker 
)
inlinestatic
72 {
73 MDL0Node model = linker.Model;
74 model._needsNrmMtxArray = model._needsTexMtxArray = false;
75 model._numFacepoints = model._numTriangles = 0;
76
77 int headerLen,
78 groupLen = 0,
79 tableLen = 0,
80 texLen = 0,
81 boneLen = 0,
82 dataLen = 0,
83 defLen = 0,
84 assetLen = 0,
85 treeLen = 0,
86 mixLen = 0,
87 opaLen = 0,
88 xluLen = 0;
89
90 int aInd, aLen;
91
92 //Get header length
93 switch (linker.Version)
94 {
95 case 0x08:
96 case 0x09:
97 headerLen = 0x80;
98 break;
99 case 0x0A:
100 headerLen = 0x88;
101 break;
102 case 0x0B:
103 headerLen = 0x8C;
104 break;
105 default:
106 headerLen = 0x80;
107 //Unsupported version. Change to 9 as default.
108 linker.Version = 9;
109 break;
110 }
111
112 //Assign node indices
113 AssignNodeIndices(linker);
114
115 //Get table length
116 tableLen = (linker._nodeCount + 1) << 2;
117
118 //Get group/data length
119 List<MDLResourceType> iList = ModelLinker.IndexBank[linker.Version];
120 foreach (MDLResourceType resType in iList)
121 {
122 IEnumerable entryList = null;
123 int entries = 0;
124
125 switch (resType)
126 {
127 case MDLResourceType.Definitions:
128
129 //NodeTree
130 treeLen = linker.BoneCache.Length * 5;
131
132 //NodeMix
133 foreach (Influence i in model._influences._influences)
134 {
135 mixLen += 4;
136 foreach (BoneWeight w in i.Weights)
137 {
138 MDL0BoneNode bone = w.Bone as MDL0BoneNode;
139 if (bone != null && w.Weight != 0 && bone._nodeIndex < linker.NodeCache.Length &&
140 bone._nodeIndex >= 0 && linker.NodeCache[bone._nodeIndex] is MDL0BoneNode)
141 {
142 mixLen += 6;
143 }
144 }
145 }
146
147 foreach (MDL0BoneNode b in linker.BoneCache)
148 {
149 if (b._weightCount > 0)
150 {
151 mixLen += 5;
152 }
153 }
154
155 //DrawOpa and DrawXlu
156 //Get assigned materials and categorize
157 if (model._objList != null)
158 {
159 for (int i = 0; i < model._objList.Count; i++)
160 {
161 //Entries are ordered by material, not by polygon.
162 //Using the material's attached polygon list is untrustable if the definitions were corrupt on parse.
163 MDL0ObjectNode poly = model._objList[i] as MDL0ObjectNode;
164
165 model._numTriangles += poly._numFaces;
166 model._numFacepoints += poly._numFacepoints;
167
168 foreach (DrawCall c in poly._drawCalls)
169 {
170 if (c.DrawPass == DrawCall.DrawPassType.Opaque)
171 {
172 opaLen += 8;
173 }
174 else
175 {
176 xluLen += 8;
177 }
178 }
179 }
180 }
181
182 //Add terminate byte and set model def flags
183 if (model._hasTree = treeLen > 0)
184 {
185 treeLen++;
186 entries++;
187 }
188
189 if (model._hasMix = mixLen > 0)
190 {
191 mixLen++;
192 entries++;
193 }
194
195 if (model._hasOpa = opaLen > 0)
196 {
197 opaLen++;
198 entries++;
199 }
200
201 if (model._hasXlu = xluLen > 0)
202 {
203 xluLen++;
204 entries++;
205 }
206
207 //Align data
208 defLen += (treeLen + mixLen + opaLen + xluLen).Align(4);
209
210 break;
211
212 case MDLResourceType.Vertices:
213 if (model._vertList != null)
214 {
215 entryList = model._vertList;
216 break;
217 }
218 else
219 {
220 aInd = 0; //Set the ID
221 aLen = 1; //Offset count
222 }
223
224 EvalAssets:
225
226 List<ResourceNode> polyList = model._objList;
227 if (polyList == null)
228 {
229 break;
230 }
231
232 string str = "";
233
234 bool direct = linker._forceDirectAssets[aInd];
235
236 //Create asset lists
237 IList aList;
238 switch (aInd) //Switch by the set ID
239 {
240 case 0:
241 aList = linker._vertices = new List<VertexCodec>(polyList.Count);
242 str = "Vertices ";
243 break;
244 case 1:
245 aList = linker._normals = new List<VertexCodec>(polyList.Count);
246 str = "Normals ";
247 break;
248 case 2:
249 aList = linker._colors = new List<ColorCodec>(polyList.Count);
250 str = "Colors ";
251 break;
252 default:
253 aList = linker._uvs = new List<VertexCodec>(polyList.Count);
254 str = "UVs ";
255 break;
256 }
257
258 aLen += aInd;
259 for (int i = 0; i < polyList.Count; i++)
260 {
261 MDL0ObjectNode obj = polyList[i] as MDL0ObjectNode;
262 for (int x = aInd; x < aLen; x++)
263 {
264 if (obj._manager._faceData[x] != null)
265 {
266 //Remap color nodes
267 if (x == 2 || x == 3)
268 {
270 {
271 obj._elementIndices[x] = -1;
272 foreach (MDL0ObjectNode thatObj in polyList.OrderBy(c =>
273 -((MDL0ObjectNode) c)._manager.GetColors(x - 2, false).Length))
274 {
275 //Only compare up to the current object
276 if (thatObj == obj)
277 {
278 break;
279 }
280
281 RGBAPixel[] thatArr = thatObj._manager.GetColors(x - 2, false);
282 RGBAPixel[] thisArr = obj._manager.GetColors(x - 2, false);
283 bool equals = true;
284 if (thisArr.Length == thatArr.Length)
285 {
286 for (int n = 0; n < thisArr.Length; n++)
287 {
288 if (thisArr[n] != thatArr[n])
289 {
290 equals = false;
291 break;
292 }
293 }
294 }
295 else
296 {
297 foreach (RGBAPixel px in thisArr)
298 {
299 if (Array.IndexOf(thatArr, px) < 0)
300 {
301 equals = false;
302 break;
303 }
304 }
305 }
306
307 if (equals)
308 {
309 //Found a match
310 obj._elementIndices[x] = thatObj._elementIndices[x];
311 obj._manager._newClrObj[x - 2] = thatObj.Index;
312 break;
313 }
314 }
315
316 if (obj._elementIndices[x] != -1)
317 {
318 continue;
319 }
320 }
321 else
322 {
323 obj._manager._newClrObj[x - 2] = i;
324 }
325 }
326
327 obj._elementIndices[x] = (short) aList.Count;
328
329 form?.Say("Encoding " + str + (x - aInd) + " for Object " + i + ": " + obj.Name);
330
331 VertexCodec vert;
332 switch (aInd)
333 {
334 case 0:
335 vert = new VertexCodec(obj._manager.GetVertices(false), false,
337 aList.Add(vert);
338 if (!direct)
339 {
340 assetLen += vert._dataLen.Align(0x20) + 0x40;
341 }
342
343 break;
344 case 1:
345 vert = new VertexCodec(obj._manager.GetNormals(false), false,
347 aList.Add(vert);
348 if (!direct)
349 {
350 assetLen += vert._dataLen.Align(0x20) + 0x20;
351 }
352
353 break;
354 case 2:
355 ColorCodec col = new ColorCodec(obj._manager.GetColors(x - 2, false));
356 aList.Add(col);
357 if (!direct)
358 {
359 assetLen += col._dataLen.Align(0x20) + 0x20;
360 }
361
362 break;
363 default:
364 vert = new VertexCodec(obj._manager.GetUVs(x - 4, false),
366 aList.Add(vert);
367 if (!direct)
368 {
369 assetLen += vert._dataLen.Align(0x20) + 0x40;
370 }
371
372 break;
373 }
374 }
375 else
376 {
377 obj._elementIndices[x] = -1;
378 }
379 }
380 }
381
382 if (!direct)
383 {
384 entries = aList.Count;
385 }
386
387 break;
388 case MDLResourceType.Normals:
389 if (model._normList != null)
390 {
391 entryList = model._normList;
392 }
393 else
394 {
395 aInd = 1; //Set the ID
396 aLen = 1; //Offset count
397 goto EvalAssets;
398 }
399
400 break;
401 case MDLResourceType.Colors:
402 if (model._colorList != null)
403 {
404 entryList = model._colorList;
405 }
406 else
407 {
409 {
410 HashSet<RGBAPixel> pixels = new HashSet<RGBAPixel>();
411 if (model._objList != null)
412 {
413 foreach (MDL0ObjectNode obj in model._objList)
414 {
415 for (int i = 0; i < 2; i++)
416 {
417 RGBAPixel[] arr = obj._manager.GetColors(i, false);
418 if (arr.Length > 0)
419 {
420 obj._elementIndices[i + 2] = 0;
421 foreach (RGBAPixel p in arr)
422 {
423 pixels.Add(p);
424 }
425 }
426 else
427 {
428 obj._elementIndices[i + 2] = -1;
429 }
430 }
431 }
432 }
433
434 List<RGBAPixel> le = pixels.ToList();
435 le.Sort();
436
437 if (le.Count == 0)
438 {
439 break;
440 }
441
442 Collada._importOptions._singleColorNodeEntries = le.ToArray();
443
444 ColorCodec col = new ColorCodec(Collada._importOptions._singleColorNodeEntries);
445 linker._colors = new List<ColorCodec> {col};
446 assetLen += col._dataLen.Align(0x20) + 0x20;
447 entries = 1;
448 }
449 else
450 {
451 aInd = 2; //Set the ID
452 aLen = 2; //Offset count
453 goto EvalAssets;
454 }
455 }
456
457 break;
458 case MDLResourceType.UVs:
459 if (model._uvList != null)
460 {
461 entryList = model._uvList;
462 }
463 else
464 {
465 aInd = 4; //Set the ID
466 aLen = 8; //Offset count
467 goto EvalAssets;
468 }
469
470 break;
471
472 case MDLResourceType.Bones:
473 int index = 0;
474 foreach (MDL0BoneNode b in linker.BoneCache)
475 {
476 form?.Say("Calculating the size of the Bones - " + b.Name);
477
478 b._entryIndex = index++;
479 boneLen += b.CalculateSize(true);
480 }
481
482 entries = linker.BoneCache.Length;
483 break;
484
485 case MDLResourceType.Materials:
486 if (model._matList != null)
487 {
488 entries = model._matList.Count;
489 }
490
491 break;
492
493 case MDLResourceType.Objects:
494 if (model._objList != null)
495 {
496 entryList = model._objList;
497 foreach (MDL0ObjectNode n in model._objList)
498 {
499 if (n.NormalNode != null || n._manager._faceData[1] != null)
500 {
501 model._needsNrmMtxArray = true;
502 }
503
504 if (n.HasTexMtx)
505 {
506 model._needsTexMtxArray = true;
507 }
508 }
509 }
510
511 break;
512
513 case MDLResourceType.Shaders:
514 if (model._matList != null && (entryList = model.GetUsedShaders()) != null)
515 {
516 entries = model._matList.Count;
517 }
518
519 break;
520
521 case MDLResourceType.Textures:
522 if (model._texList != null)
523 {
524 List<MDL0TextureNode> texNodes = new List<MDL0TextureNode>();
525 foreach (MDL0TextureNode tex in model._texList)
526 {
527 texNodes.Add(tex);
528 texLen += tex._references.Count * 8 + 4;
529 }
530
531 entries = (linker._texList = texNodes).Count;
532 }
533
534 break;
535
536 case MDLResourceType.Palettes:
537 if (model._pltList != null)
538 {
539 List<MDL0TextureNode> pltNodes = new List<MDL0TextureNode>();
540 foreach (MDL0TextureNode plt in model._pltList)
541 {
542 pltNodes.Add(plt);
543 texLen += plt._references.Count * 8 + 4;
544 }
545
546 entries = (linker._pltList = pltNodes).Count;
547 }
548
549 break;
550 }
551
552 if (entryList != null)
553 {
554 int index = 0;
555 foreach (MDL0EntryNode e in entryList)
556 {
557 if (form != null)
558 {
559 if (resType == MDLResourceType.Objects)
560 {
561 form.Say("Encoding the " + resType + " - " + e.Name);
562 }
563 else
564 {
565 form.Say("Calculating the size of the " + resType + " - " + e.Name);
566 }
567 }
568
569 e._entryIndex = index++;
570 dataLen += e.CalculateSize(true);
571 }
572
573 if (entries == 0)
574 {
575 entries = index;
576 }
577 }
578
579 if (entries > 0)
580 {
581 groupLen += entries * 0x10 + 0x18;
582 }
583 }
584
585 //Align the materials perfectly using the data length
586 int temp = 0;
587 if (model._matList != null && iList.IndexOf(MDLResourceType.Materials) != -1)
588 {
589 int index = 0;
590 MDL0MaterialNode prev = null;
591 foreach (MDL0MaterialNode e in model._matList)
592 {
593 form?.Say("Calculating the size of the Materials - " + e.Name);
594
595 if (index != 0)
596 {
597 e._mdlOffset = (prev = (MDL0MaterialNode) model._matList[index - 1])._mdlOffset +
598 prev._calcSize;
599 }
600 else if ((temp =
601 (e._mdlOffset = headerLen + tableLen + groupLen + texLen + defLen + boneLen).Align(
602 0x10)) != e._mdlOffset)
603 {
604 e._dataAlign = temp - e._mdlOffset;
605 }
606
607 e._entryIndex = index++;
608 dataLen += e.CalculateSize(true);
609 }
610 }
611
612 if (model._isImport && model._objList != null)
613 {
614 foreach (MDL0ObjectNode obj1 in model._objList)
615 {
616 if (obj1?._drawCalls == null || obj1._drawCalls.Count == 0)
617 {
618 continue;
619 }
620
621 MDL0MaterialNode p = obj1._drawCalls[0].MaterialNode;
622 if (p == null)
623 {
624 continue;
625 }
626
627 //Set materials to use register color if option set
629 linker._colors != null &&
630 linker._colors.Count > 0)
631 {
632 p.C1AlphaMaterialSource = GXColorSrc.Vertex;
633 p.C1ColorMaterialSource = GXColorSrc.Vertex;
634 }
635 else
636 {
637 p.C1MaterialColor = Collada._importOptions._dfltClr;
638 p.C1ColorMaterialSource = GXColorSrc.Register;
639 p.C1AlphaMaterialSource = GXColorSrc.Register;
640 }
641 }
642 }
643
644 return
645 (linker._headerLen = headerLen) +
646 (linker._tableLen = tableLen) +
647 (linker._groupLen = groupLen) +
648 (linker._texLen = texLen) +
649 (linker._defLen = defLen) +
650 (linker._boneLen = boneLen) +
651 (linker._assetLen = assetLen) +
652 (linker._dataLen = dataLen) +
653 (linker.Version > 9 ? model._userEntries.GetSize() : 0);
654 }
bool _useReg
Definition: ColladaImporter.cs:1208
RGBAPixel _dfltClr
Definition: ColladaImporter.cs:1211
bool _rmpClrs
Definition: ColladaImporter.cs:1205
bool _fltUVs
Definition: ColladaImporter.cs:1203
bool _fltVerts
Definition: ColladaImporter.cs:1201
bool _useOneNode
Definition: ColladaImporter.cs:1220
bool _fltNrms
Definition: ColladaImporter.cs:1202
Definition: ColladaAssetDecoder.cs:10
void Say(string text)
Definition: ColladaImportDialog.cs:30
static ImportOptions _importOptions
Definition: ColladaImporter.cs:949
Vector3[] GetVertices(bool force)
Returns vertex positions from each vertex.
Definition: PrimitiveManager.cs:178
Vector3[] GetNormals(bool force)
Retrieves normals from raw facedata in a remapped array.
Definition: PrimitiveManager.cs:202
Vector2[] GetUVs(int index, bool force)
Retrieves texture coordinates from raw facedata in a remapped array.
Definition: PrimitiveManager.cs:233
RGBAPixel[] GetColors(int index, bool force)
Retrieves color values from raw facedata in a remapped array.
Definition: PrimitiveManager.cs:266
UnsafeBuffer[] _faceData
Definition: PrimitiveManager.cs:59
Definition: MDL0ObjectNode.cs:2040
DrawPassType
Definition: MDL0ObjectNode.cs:2089
DrawPassType DrawPass
Definition: MDL0ObjectNode.cs:2096
int _weightCount
Definition: MDL0BoneNode.cs:60
Definition: MDL0GroupNode.cs:16
Definition: MDL0MaterialNode.cs:22
List< ResourceNode > GetUsedShaders()
Definition: MDL0Node.cs:437
List< ResourceNode > _colorList
Definition: MDL0Node.cs:313
List< ResourceNode > _vertList
Definition: MDL0Node.cs:309
List< ResourceNode > _objList
Definition: MDL0Node.cs:306
List< ResourceNode > _pltList
Definition: MDL0Node.cs:308
List< ResourceNode > _matList
Definition: MDL0Node.cs:304
List< ResourceNode > _normList
Definition: MDL0Node.cs:310
bool _hasXlu
Definition: MDL0Node.cs:47
bool _hasMix
Definition: MDL0Node.cs:47
bool _hasOpa
Definition: MDL0Node.cs:47
bool _hasTree
Definition: MDL0Node.cs:47
bool _isImport
Definition: MDL0Node.cs:47
List< ResourceNode > _texList
Definition: MDL0Node.cs:307
List< ResourceNode > _uvList
Definition: MDL0Node.cs:311
Definition: MDL0ObjectNode.cs:21
BindingList< DrawCall > _drawCalls
Definition: MDL0ObjectNode.cs:626
PrimitiveManager _manager
Definition: MDL0ObjectNode.cs:710
int _numFacepoints
Definition: MDL0ObjectNode.cs:613
string?? NormalNode
Definition: MDL0ObjectNode.cs:266
int _numFaces
Definition: MDL0ObjectNode.cs:614
Definition: MDL0TextureNode.cs:17
int _calcSize
Definition: ResourceNode.cs:145
int Index
Definition: ResourceNode.cs:301
virtual string Name
Definition: ResourceNode.cs:223
virtual int CalculateSize(bool force)
Definition: ResourceNode.cs:1161
static void AssignNodeIndices(ModelLinker linker)
Definition: ModelEncoder.cs:17
string Name
Definition: IBoneNode.cs:11
GXColorSrc
Definition: MDL0MaterialNode.cs:2882
MDLResourceType
Definition: ModelLinker.cs:15
Definition: PixelTypes.cs:327

◆ CalcSize() [2/2]

static int BrawlLib.Wii.Models.ModelEncoder.CalcSize ( ModelLinker  linker)
inlinestatic
67 {
68 return CalcSize(null, linker);
69 }
static int CalcSize(ModelLinker linker)
Definition: ModelEncoder.cs:66

The documentation for this class was generated from the following file: