xoreos  0.0.5
model_jade.cpp
Go to the documentation of this file.
1 /* xoreos - A reimplementation of BioWare's Aurora engine
2  *
3  * xoreos is the legal property of its developers, whose names
4  * can be found in the AUTHORS file distributed with this source
5  * distribution.
6  *
7  * xoreos is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 3
10  * of the License, or (at your option) any later version.
11  *
12  * xoreos is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with xoreos. If not, see <http://www.gnu.org/licenses/>.
19  */
20 
25 /* Based in parts on cchargin's KotOR model specs
26  * (<https://home.comcast.net/~cchargin/kotor/mdl_info.html>).
27  */
28 
29 #include <cstring>
30 
31 #include "src/common/error.h"
32 #include "src/common/maths.h"
33 #include "src/common/readstream.h"
34 #include "src/common/encoding.h"
35 
36 #include "src/aurora/types.h"
37 #include "src/aurora/resman.h"
38 
42 
45 
47 
49 
50 // This is included if a mesh wants a unique name.
51 #include "src/common/uuid.h"
52 
53 // Disable the "unused variable" warnings while most stuff is still stubbed
55 
56 enum NodeType {
57  kNodeTypeNode = 0x00000001,
58  kNodeTypeLight = 0x00000003,
59  kNodeTypeEmitter = 0x00000005,
60  kNodeTypeCamera = 0x00000009,
61  kNodeTypeReference = 0x00000011,
62  kNodeTypeTrimesh = 0x00000021,
63  kNodeTypeSkin = 0x00000061,
64  kNodeTypeAABB = 0x00000221,
65  kNodeTypeWeaponTrail = 0x00000821,
66  kNodeTypeGob = 0x00001001,
67  kNodeTypeCloth = 0x00004021,
70  kNodeTypeDanglyBone = 0x00020001,
72  kNodeTypeUnknown = 0x00040001
73 };
74 
76  kNodeTypeHasHeader = 0x00000001,
77  kNodeTypeHasMesh = 0x00000020,
78  kNodeTypeHasSkin = 0x00000040,
79  kNodeTypeHasAABB = 0x00000200
80 };
81 
82 enum NodeFlag {
88 };
89 
90 namespace Graphics {
91 
92 namespace Aurora {
93 
95  const Common::UString &t) :
96  mdl(0), mdx(0), state(0), texture(t) {
97 
98  try {
99 
100  if (!(mdl = ResMan.getResource(name, ::Aurora::kFileTypeMDL)))
101  throw Common::Exception("No such MDL \"%s\"", name.c_str());
102  if (!(mdx = ResMan.getResource(name, ::Aurora::kFileTypeMDX)))
103  throw Common::Exception("No such MDX \"%s\"", name.c_str());
104 
105  } catch (...) {
106  delete mdl;
107  delete mdx;
108  throw;
109  }
110 }
111 
113  delete mdl;
114  delete mdx;
115 
116  clear();
117 }
118 
120  for (std::list<ModelNode_Jade *>::iterator n = nodes.begin(); n != nodes.end(); ++n)
121  delete *n;
122  nodes.clear();
123 
124  delete state;
125  state = 0;
126 
127  newNode();
128 }
129 
131  vertices.clear();
132  indices.clear();
133 
134  textures.clear();
135 
136  texCoords.clear();
137 }
138 
139 
141  Model(type) {
142 
143  _fileName = name;
144 
145  ParserContext ctx(name, texture);
146 
147  load(ctx);
148 
149  finalize();
150 }
151 
153 }
154 
156  /* Magic and version number:
157  *
158  * - First byte must be 0x00
159  * - Third byte version:
160  * - Upper bit PC (1) / Xbox (0)
161  * - Lower 7 bits version number
162  *
163  * We only support version 7 of the PC version.
164  */
165  uint32 version = ctx.mdl->readUint32BE();
166  if (version != 0x00008700)
167  throw Common::Exception("Unsupported MDL: 0x%08X", version);
168 
169  ctx.offModelData = 20;
170 
171  // Size of the MDL file, without the 20 byte header
172  ctx.mdlSize = ctx.mdl->readUint32LE();
173 
174  // Size of the vertices part of the MDX file
175  ctx.mdxSizeVertices = ctx.mdl->readUint32LE();
176  // Size of the faces part of the MDX file
177  ctx.mdxSizeFaces = ctx.mdl->readUint32LE();
178  // Size of a third part of the MDX file, always 0?
179  ctx.mdxSize3 = ctx.mdl->readUint32LE();
180 
181  if (ctx.mdxSize3 != 0)
182  warning("Model_Jade: Model \"%s\" mdxSize3 == %d", _fileName.c_str(), ctx.mdxSize3);
183 
184  ctx.mdl->skip(8); // Function pointers
185 
187  ctx.mdlName = _name;
188 
189  uint32 nodeHeadPointer = ctx.mdl->readUint32LE();
190  uint32 nodeCount = ctx.mdl->readUint32LE();
191 
192  ctx.mdl->skip(24); // Unknown
193  ctx.mdl->skip( 4); // Pointer to the MDL file
194 
195  uint8 type = ctx.mdl->readByte();
196 
197  ctx.mdl->skip(3); // Padding
198  ctx.mdl->skip(4); // Unknown
199  ctx.mdl->skip(4); // Reference count
200 
201  ctx.mdl->skip(12); // TODO: Animation Header Pointer Array
202 
203  ctx.mdl->skip(4); // Pointer to the super model
204 
205  float boundingMin[3], boundingMax[3];
206 
207  boundingMin[0] = ctx.mdl->readIEEEFloatLE();
208  boundingMin[1] = ctx.mdl->readIEEEFloatLE();
209  boundingMin[2] = ctx.mdl->readIEEEFloatLE();
210 
211  boundingMax[0] = ctx.mdl->readIEEEFloatLE();
212  boundingMax[1] = ctx.mdl->readIEEEFloatLE();
213  boundingMax[2] = ctx.mdl->readIEEEFloatLE();
214 
215  float radius = ctx.mdl->readIEEEFloatLE();
216 
217  ctx.mdl->skip(4); // Unknown
218 
219  float modelScale = ctx.mdl->readIEEEFloatLE();
220 
222 
223  ctx.mdl->skip( 4); // Pointer to some node
224  ctx.mdl->skip(12); // Unknown
225  ctx.mdl->skip( 4); // Pointer to the MDX file
226 
227  uint32 nameOffset, nameCount;
228  readArrayDef(*ctx.mdl, nameOffset, nameCount);
229 
230  std::vector<uint32> nameOffsets;
231  readArray(*ctx.mdl, ctx.offModelData + nameOffset, nameCount, nameOffsets);
232 
233  readStrings(*ctx.mdl, nameOffsets, ctx.offModelData, ctx.names);
234 
235  newState(ctx);
236 
237  ModelNode_Jade *rootNode = new ModelNode_Jade(*this);
238  ctx.nodes.push_back(rootNode);
239 
240  ctx.mdl->seek(ctx.offModelData + nodeHeadPointer);
241  rootNode->load(ctx);
242 
243  addState(ctx);
244 }
245 
247  const std::vector<uint32> &offsets, uint32 offset,
248  std::vector<Common::UString> &strings) {
249 
250  size_t pos = mdl.pos();
251 
252  strings.reserve(offsets.size());
253  for (std::vector<uint32>::const_iterator o = offsets.begin(); o != offsets.end(); ++o) {
254  mdl.seek(offset + *o);
255 
256  strings.push_back(Common::readString(mdl, Common::kEncodingASCII));
257  }
258 
259  mdl.seek(pos);
260 }
261 
263  ctx.clear();
264 
265  ctx.state = new State;
266 }
267 
269  if (!ctx.state || ctx.nodes.empty()) {
270  ctx.clear();
271  return;
272  }
273 
274  for (std::list<ModelNode_Jade *>::iterator n = ctx.nodes.begin();
275  n != ctx.nodes.end(); ++n) {
276 
277  ctx.state->nodeList.push_back(*n);
278  ctx.state->nodeMap.insert(std::make_pair((*n)->getName(), *n));
279 
280  if (!(*n)->getParent())
281  ctx.state->rootNodes.push_back(*n);
282  }
283 
284  _stateList.push_back(ctx.state);
285  _stateMap.insert(std::make_pair(ctx.state->name, ctx.state));
286 
287  if (!_currentState)
288  _currentState = ctx.state;
289 
290  ctx.state = 0;
291 
292  ctx.nodes.clear();
293 }
294 
295 
297 }
298 
300 }
301 
303  uint32 type = ctx.mdl->readUint32LE();
304 
305  // Node number in tree order
306  uint16 nodeNumber1 = ctx.mdl->readUint16LE();
307 
308  // Sequentially node number as found in the file
309  uint16 nodeNumber2 = ctx.mdl->readUint16LE();
310 
311  if (nodeNumber2 < ctx.names.size())
312  _name = ctx.names[nodeNumber2];
313 
314  ctx.mdl->skip(4); // Pointer to the MDL file
315  ctx.mdl->skip(4); // Pointer to the parent Model
316 
317  _position [0] = ctx.mdl->readIEEEFloatLE();
318  _position [1] = ctx.mdl->readIEEEFloatLE();
319  _position [2] = ctx.mdl->readIEEEFloatLE();
320  _orientation[3] = Common::rad2deg(acos(ctx.mdl->readIEEEFloatLE()) * 2.0f);
321  _orientation[0] = ctx.mdl->readIEEEFloatLE();
322  _orientation[1] = ctx.mdl->readIEEEFloatLE();
323  _orientation[2] = ctx.mdl->readIEEEFloatLE();
324 
325  uint32 childrenOffset = ctx.mdl->readUint32LE();
326  uint32 childrenCount = ctx.mdl->readUint32LE();
327 
328  float nodeScale = ctx.mdl->readIEEEFloatLE();
329  float maxAnimDistance = ctx.mdl->readIEEEFloatLE();
330 
331  std::vector<uint32> children;
332  Model::readArray(*ctx.mdl, ctx.offModelData + childrenOffset, childrenCount, children);
333 
334  if (type & kNodeTypeHasMesh) {
335  readMesh(ctx);
336  createMesh(ctx);
337  }
338 
339  for (std::vector<uint32>::const_iterator child = children.begin(); child != children.end(); ++child) {
340  ModelNode_Jade *childNode = new ModelNode_Jade(*_model);
341  ctx.nodes.push_back(childNode);
342  ctx.newNode();
343 
344  childNode->setParent(this);
345 
346  ctx.mdl->seek(ctx.offModelData + *child);
347  childNode->load(ctx);
348  }
349 
350  Common::UString meshName = ctx.mdlName;
351  meshName += ".";
352  if (ctx.state->name.size() != 0) {
353  meshName += ctx.state->name;
354  } else {
355  meshName += "xoreos.default";
356  }
357  meshName += ".";
358  meshName += _name;
359 
360  if (!_mesh) {
361  return;
362  }
363 
364  if (!_mesh->data) {
365  return;
366  }
367 
368  if (!_mesh->data->rawMesh) {
369  return;
370  }
371 
372  _mesh->data->rawMesh->init();
373  if (MeshMan.getMesh(meshName)) {
374  warning("Warning: probable mesh duplication of: %s", meshName.c_str());
375 
376  // TODO: figure out the right thing to handle mesh duplication.
377  meshName += "#" + Common::generateIDRandomString();
378  }
379  _mesh->data->rawMesh->setName(meshName);
380  MeshMan.addMesh(_mesh->data->rawMesh);
381 
382  if (GfxMan.isRendererExperimental())
383  buildMaterial();
384 }
385 
388 }
389 
391  ctx.mdl->skip(12); // Unknown
392 
393  float boundingMin[3], boundingMax[3];
394 
395  boundingMin[0] = ctx.mdl->readIEEEFloatLE();
396  boundingMin[1] = ctx.mdl->readIEEEFloatLE();
397  boundingMin[2] = ctx.mdl->readIEEEFloatLE();
398 
399  boundingMax[0] = ctx.mdl->readIEEEFloatLE();
400  boundingMax[1] = ctx.mdl->readIEEEFloatLE();
401  boundingMax[2] = ctx.mdl->readIEEEFloatLE();
402 
403  float radius = ctx.mdl->readIEEEFloatLE();
404 
405  float pointsAverage[3];
406  pointsAverage[0] = ctx.mdl->readIEEEFloatLE();
407  pointsAverage[1] = ctx.mdl->readIEEEFloatLE();
408  pointsAverage[2] = ctx.mdl->readIEEEFloatLE();
409 
410  _mesh = new Mesh();
411 
412  uint32 transparencyHint = ctx.mdl->readUint32LE();
413  uint16 flags = ctx.mdl->readUint16LE();
414 
415  _mesh->shadow = ctx.mdl->readUint16LE() != 0;
416 
417  _mesh->render = (flags & kNodeFlagsRender) != 0;
418  _mesh->beaming = (flags & kNodeFlagsBeaming) != 0;
420 
421  _mesh->hasTransparencyHint = true;
422  _mesh->transparencyHint = (transparencyHint == 1);
423  _mesh->transparencyHintFull = transparencyHint;
424 
426 
427  uint32 indexCount = ctx.mdl->readUint32LE();
428 
429  // Offset of the face indices into the MDL. If 0, use faceOffsetMDX.
430  uint32 faceOffsetMDL = ctx.mdl->readUint32LE();
431 
432  ctx.mdl->skip(4); // Unknown
433 
434  // Type of the mesh:
435  // - 0: Point list?
436  // - 1: Line list?
437  // - 2: Line strip?
438  // - 3: Triangle list
439  // - 4: Triangle strip
440  // - 5: Triangle fan
441  // - 6: ???
442  uint32 meshType = ctx.mdl->readUint32LE();
443 
444  ctx.mdl->skip(12); // Unknown
445 
446  uint32 mdxStructSize = ctx.mdl->readUint32LE();
447 
448  ctx.mdl->skip(8); // Unknown
449 
450  uint32 offNormals = ctx.mdl->readUint32LE();
451 
452  ctx.mdl->skip(4); // Unknown
453 
454  uint32 offUV[4];
455  offUV[0] = ctx.mdl->readUint32LE();
456  offUV[1] = ctx.mdl->readUint32LE();
457  offUV[2] = ctx.mdl->readUint32LE();
458  offUV[3] = ctx.mdl->readUint32LE();
459 
460  ctx.mdl->skip(20); // Unknown
461 
462  uint16 vertexCount = ctx.mdl->readUint16LE();
463  uint16 textureCount = MIN<uint16>(ctx.mdl->readUint16LE(), 4);
464 
465  uint32 vertexOffset = ctx.mdl->readUint32LE();
466  ctx.mdl->skip(4); // Unknown
467 
468  uint32 materialID = ctx.mdl->readUint32LE();
469 
470  // Group id is likely used to select an appropriate shader.
471  uint32 materialGroupID = ctx.mdl->readUint32LE();
472 
473  _mesh->selfIllum[0] = ctx.mdl->readIEEEFloatLE();
474  _mesh->selfIllum[1] = ctx.mdl->readIEEEFloatLE();
475  _mesh->selfIllum[2] = ctx.mdl->readIEEEFloatLE();
476 
477  _mesh->alpha = ctx.mdl->readIEEEFloatLE();
478 
479  float textureWCoords = ctx.mdl->readIEEEFloatLE();
480 
481  ctx.mdl->skip(4); // Unknown
482 
483  // Offset of the face indices into the MDX. If 0, use faceOffsetMDL.
484  uint32 faceOffsetMDX = ctx.mdl->readUint32LE();
485 
486  ctx.mdl->skip(4); // Unknown
487 
488 
489  // Load textures
490 
491  /* If we were given a valid materialID, load textures from that material.
492  * Otherwise, try the texture that was given directly.
493  */
494  if (materialID != 0xFFFFFFFF)
495  readMaterialTextures(materialID, ctx.textures);
496  else if (!texture.empty())
497  ctx.textures.push_back(texture);
498 
499  textureCount = ctx.textures.size();
500 
501 
502  // Read vertices
503 
504  ctx.vertices.resize(vertexCount * 3);
505 
506  ctx.texCoords.resize(textureCount);
507  for (uint32 i = 0; i < textureCount; i++)
508  ctx.texCoords[i].resize(vertexCount * 2);
509 
510  // TODO: Figure out the correct layout of the vertex struct
511  for (uint32 i = 0; i < vertexCount; i++) {
512  ctx.mdx->seek(vertexOffset + i * mdxStructSize);
513 
514  ctx.vertices[i * 3 + 0] = ctx.mdx->readIEEEFloatLE();
515  ctx.vertices[i * 3 + 1] = ctx.mdx->readIEEEFloatLE();
516  ctx.vertices[i * 3 + 2] = ctx.mdx->readIEEEFloatLE();
517 
518  for (uint32 t = 0; t < textureCount; t++) {
519  if ((offUV[t] != 0xFFFFFFFF) && ((offUV[t] + 8) <= mdxStructSize)) {
520  ctx.mdx->seek(vertexOffset + i * mdxStructSize + offUV[t]);
521 
522  ctx.texCoords[t][i * 2 + 0] = ctx.mdx->readIEEEFloatLE();
523  ctx.texCoords[t][i * 2 + 1] = ctx.mdx->readIEEEFloatLE();
524  } else {
525  ctx.texCoords[t][i * 2 + 0] = 0.0f;
526  ctx.texCoords[t][i * 2 + 1] = 0.0f;
527  }
528  }
529  }
530 
531 
532  // Read face indices
533 
534  if (faceOffsetMDL != 0)
535  readPlainIndices (*ctx.mdl, ctx.indices, faceOffsetMDL + ctx.offModelData, indexCount);
536  else if (faceOffsetMDX != 0)
537  readChunkedIndices(*ctx.mdx, ctx.indices, faceOffsetMDX, indexCount);
538 
539  unfoldFaces(ctx.indices, meshType);
540 }
541 
542 void ModelNode_Jade::readPlainIndices(Common::SeekableReadStream &stream, std::vector<uint16> &indices,
543  uint32 offset, uint32 count) {
544 
545  size_t pos = stream.pos();
546 
547  stream.seek(offset);
548 
549  indices.resize(count);
550  for (std::vector<uint16>::iterator i = indices.begin(); i != indices.end(); ++i)
551  *i = stream.readUint16LE();
552 
553  stream.seek(pos);
554 }
555 
556 void ModelNode_Jade::readChunkedIndices(Common::SeekableReadStream &stream, std::vector<uint16> &indices,
557  uint32 offset, uint32 count) {
558 
559  size_t pos = stream.pos();
560 
561  stream.seek(offset);
562 
563  uint32 stopValue = stream.readUint32LE();
564  stream.skip(4); // Unknown
565 
566  indices.reserve(count);
567 
568  while (count > 0) {
569  uint32 chunk = stream.readUint32LE();
570  if (chunk == stopValue)
571  break;
572 
573  uint32 chunkLength = ((chunk >> 16) & 0x1FFF) / 2;
574  uint32 toRead = MIN(chunkLength, count);
575 
576  for (uint32 i = 0; i < toRead; i++)
577  indices.push_back(stream.readUint16LE());
578 
579  count -= toRead;
580  }
581 
582  stream.seek(pos);
583 }
584 
586 void ModelNode_Jade::unfoldFaces(std::vector<uint16> &indices, uint32 meshType) {
587  switch (meshType) {
588  case 0: // Point list?
589  case 1: // Line list?
590  case 2: // Line strip?
591  case 6: // ???
592  default:
593  warning("ModelNode_Jade \"%s\".\"%s\": Unsupported mesh type %d",
594  _model->getName().c_str(), _name.c_str(), meshType);
595  indices.clear();
596  break;
597 
598  case 3: // Triangle list
599  break;
600 
601  case 4: // Triangle strip
602  unfoldTriangleStrip(indices);
603  break;
604 
605  case 5: // Triangle fan
606  unfoldTriangleFan(indices);
607  break;
608  }
609 }
610 
611 void ModelNode_Jade::unfoldTriangleStrip(std::vector<uint16> &indices) {
612  if (indices.size() < 3) {
613  indices.clear();
614  return;
615  }
616 
617  std::vector<uint16> unfolded;
618  unfolded.reserve((indices.size() - 2) * 3);
619 
620  for (size_t i = 0; i < indices.size() - 2; i++) {
621  if (i & 1) {
622  unfolded.push_back(indices[i]);
623  unfolded.push_back(indices[i + 2]);
624  unfolded.push_back(indices[i + 1]);
625  } else {
626  unfolded.push_back(indices[i]);
627  unfolded.push_back(indices[i + 1]);
628  unfolded.push_back(indices[i + 2]);
629  }
630  }
631 
632  indices.swap(unfolded);
633 }
634 
635 void ModelNode_Jade::unfoldTriangleFan(std::vector<uint16> &indices) {
636  if (indices.size() < 3) {
637  indices.clear();
638  return;
639  }
640 
641  std::vector<uint16> unfolded;
642  unfolded.reserve((indices.size() - 2) * 3);
643 
644  for (size_t i = 1; i < indices.size() - 1; i++) {
645  unfolded.push_back(indices[0]);
646  unfolded.push_back(indices[i]);
647  unfolded.push_back(indices[i + 1]);
648  }
649 
650  indices.swap(unfolded);
651 }
652 
654  const uint32 vertexCount = ctx.vertices.size() / 3;
655  const uint32 indexCount = ctx.indices.size();
656  const uint32 textureCount = ctx.texCoords.size();
657  if ((vertexCount == 0) || (indexCount == 0))
658  return;
659 
660  _render = _mesh->render;
661  _mesh->data = new MeshData();
663 
664  loadTextures(ctx.textures);
665 
666  // Create the VertexBuffer / IndexBuffer
667 
668  VertexDecl vertexDecl;
669 
670  vertexDecl.push_back(VertexAttrib(VPOSITION, 3, GL_FLOAT));
671  for (uint t = 0; t < textureCount; t++)
672  vertexDecl.push_back(VertexAttrib(VTCOORD + t , 2, GL_FLOAT));
673 
674  _mesh->data->rawMesh->getVertexBuffer()->setVertexDeclInterleave(vertexCount, vertexDecl);
675 
676  float *v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData());
677  for (uint32 i = 0; i < vertexCount; i++) {
678  // Position
679  *v++ = ctx.vertices[i * 3 + 0];
680  *v++ = ctx.vertices[i * 3 + 1];
681  *v++ = ctx.vertices[i * 3 + 2];
682 
683  // Texture coordinates
684  for (uint t = 0; t < textureCount; t++) {
685  *v++ = ctx.texCoords[t][i * 2 + 0];
686  *v++ = ctx.texCoords[t][i * 2 + 1];
687  }
688  }
689 
690  _mesh->data->rawMesh->getIndexBuffer()->setSize(indexCount, sizeof(uint16), GL_UNSIGNED_SHORT);
691 
692  uint16 *f = reinterpret_cast<uint16 *>(_mesh->data->rawMesh->getIndexBuffer()->getData());
693  memcpy(f, &ctx.indices[0], indexCount * sizeof(uint16));
694 
695  createBound();
696 }
697 
702 void ModelNode_Jade::readMaterialTextures(uint32 materialID, std::vector<Common::UString> &textures) {
703  if (materialID == 0xFFFFFFFF) {
704  textures.clear();
705  return;
706  }
707 
708  Common::UString mabFile = Common::UString::format("%d", materialID);
709  Common::SeekableReadStream *mab = ResMan.getResource(mabFile, ::Aurora::kFileTypeMAB);
710  if (!mab) {
711  textures.clear();
712  return;
713  }
714 
715  textures.reserve(4);
716 
717  try {
718  uint32 size = mab->readUint32LE();
719  if (size != 292)
720  throw Common::Exception("Invalid size in binary material %s.mab", mabFile.c_str());
721 
723 
726 
730 
732 
734 
737 
738  mab->skip(2); // Unknown, padding?
739 
746 
747  mab->skip(24); // Unknown
748 
751 
752  mab->skip(4); // Unknown
753 
754  for (int i = 0; i < 4; i++) {
755  textures.push_back(Common::readStringFixed(*mab, Common::kEncodingASCII, 32));
756 
757  if (textures.back() == "NULL")
758  textures.back().clear();
759  }
760 
761  } catch (...) {
762  delete mab;
763  textures.clear();
764 
766  return;
767  }
768 
769  delete mab;
770 
771  while (!textures.empty() && textures.back().empty())
772  textures.pop_back();
773 }
774 
775 } // End of namespace Aurora
776 
777 } // End of namespace Graphics
NodeType
Definition: model_jade.cpp:56
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
GLvoid * getData()
Access buffer data.
Definition: indexbuffer.cpp:78
void unfoldFaces(std::vector< uint16 > &indices, uint32 meshType)
Unfolds triangle strips / fans into triangle lists.
Definition: model_jade.cpp:586
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:122
Generic image decoder interface.
NodeMap nodeMap
The nodes within the state, indexed by name.
Definition: model.h:207
Vertex texture coordinates, VTCOORDi = VTCOORD + i.
Definition: vertexbuffer.h:39
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:133
Common::SeekableReadStream * mdl
Definition: model_jade.h:50
NodeFlag
Definition: model_jade.cpp:82
A class holding an UTF-8 string.
Definition: ustring.h:48
Geometry, BioWare model.
Definition: types.h:73
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
Common::SeekableReadStream * mdx
Definition: model_jade.h:51
Vertex position.
Definition: vertexbuffer.h:36
VertexBuffer * getVertexBuffer()
Definition: mesh.cpp:39
void readMesh(Model_Jade::ParserContext &ctx)
Definition: model_jade.cpp:390
void loadTextures(const std::vector< Common::UString > &textures)
Definition: modelnode.cpp:340
void readPlainIndices(Common::SeekableReadStream &stream, std::vector< uint16 > &indices, uint32 offset, uint32 count)
Definition: model_jade.cpp:542
uint8_t uint8
Definition: types.h:200
void readStrings(Common::SeekableReadStream &mdl, const std::vector< uint32 > &offsets, uint32 offset, std::vector< Common::UString > &strings)
Definition: model_jade.cpp:246
void init()
General mesh initialisation, queuing the mesh for GL resource creation.
Definition: mesh.cpp:71
The Aurora texture manager.
bool render
Render this mesh?
Definition: modelnode.h:183
Common::UString name
The state&#39;s name.
Definition: model.h:204
Mathematical helpers.
void readChunkedIndices(Common::SeekableReadStream &stream, std::vector< uint16 > &indices, uint32 offset, uint32 count)
Definition: model_jade.cpp:556
NodeList rootNodes
The nodes in the state without a parent.
Definition: model.h:209
void setParent(ModelNode *parent)
Set the node&#39;s parent.
Definition: modelnode.cpp:143
void setVertexDeclInterleave(uint32 vertCount, VertexDecl &decl)
Set the interleaved vertex declaration for this buffer.
State * _currentState
The current state.
Definition: model.h:227
Utility functions for generating unique IDs.
JadeMaterialData _jadeMaterialData
Definition: model_jade.h:144
bool _render
Render the node?
Definition: modelnode.h:235
const Common::UString & getName() const
Get the model&#39;s name.
Definition: model.cpp:125
Geometry, model mesh data.
Definition: types.h:184
Common::UString _fileName
The model&#39;s file name.
Definition: model.h:218
std::vector< VertexAttrib > VertexDecl
Vertex data layout.
Definition: vertexbuffer.h:63
#define IGNORE_UNUSED_VARIABLES
Definition: system.h:423
ParserContext(const Common::UString &name, const Common::UString &t)
Definition: model_jade.cpp:94
void unfoldTriangleStrip(std::vector< uint16 > &indices)
Definition: model_jade.cpp:611
std::vector< Common::UString > textures
Definition: model_jade.h:74
Model * _model
The model this node belongs to.
Definition: modelnode.h:207
void exceptionDispatcherWarning(const char *s,...)
Exception dispatcher that prints the exception as a warning, and adds another reason on top...
Definition: error.cpp:158
Common::UString _name
The model&#39;s name.
Definition: model.h:220
Model_Jade(const Common::UString &name, ModelType type=kModelTypeObject, const Common::UString &texture="")
Definition: model_jade.cpp:140
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
static UString format(const char *s,...) GCC_PRINTF(1
Print formatted data into an UString object, similar to sprintf().
Definition: ustring.cpp:718
ModelType
The display type of a model.
Definition: types.h:51
uint16_t uint16
Definition: types.h:202
float selfIllum[3]
Self illumination color.
Definition: modelnode.h:176
Material, binary.
Definition: types.h:187
void createMesh(Model_Jade::ParserContext &ctx)
Definition: model_jade.cpp:653
virtual void buildMaterial()
Definition: modelnode.cpp:1008
static void readArray(Common::SeekableReadStream &stream, uint32 offset, uint32 count, std::vector< T > &values)
Definition: model.cpp:902
std::vector< std::vector< float > > texCoords
Definition: model_jade.h:76
T MIN(T a, T b)
Definition: util.h:70
void load(Model_Jade::ParserContext &ctx)
Definition: model_jade.cpp:302
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
Definition: readstream.h:317
void readMaterialTextures(uint32 materialID, std::vector< Common::UString > &textures)
Opens the resource for the materialID and parses it to return the 4 normal textures.
Definition: model_jade.cpp:702
Utility functions for working with differing string encodings.
The global shader material manager.
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
The global shader surface manager.
StackException Exception
Definition: error.h:59
float _position[3]
Position of the node.
Definition: modelnode.h:221
NodeList nodeList
The nodes within the state.
Definition: model.h:206
void warning(const char *s,...)
Definition: util.cpp:33
StateMap _stateMap
All states within this model, index by name.
Definition: model.h:226
Basic reading stream interfaces.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
std::vector< Common::UString > names
Definition: model_jade.h:69
void load(ParserContext &ctx)
Definition: model_jade.cpp:155
uint32 readUint32BE()
Read an unsigned 32-bit word stored in big endian (MSB first) order from the stream and return it...
Definition: readstream.h:166
Render queue manager.
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
Definition: readstream.h:230
#define MeshMan
Shortcut for accessing the shader manager.
Definition: meshman.h:74
Basic type definitions to handle files used in BioWare&#39;s Aurora engine.
Plain, unextended ASCII (7bit clean).
Definition: encoding.h:40
NodeTypeFeature
Definition: model_jade.cpp:75
Graphics::Mesh::Mesh * rawMesh
Node raw mesh data.
Definition: modelnode.h:159
Common::UString _name
The node&#39;s name.
Definition: modelnode.h:216
A texture as used in the Aurora engines.
bool shadow
Does the node have a shadow?
Definition: modelnode.h:184
uint32_t uint32
Definition: types.h:204
static void readArrayDef(Common::SeekableReadStream &stream, uint32 &offset, uint32 &count)
Definition: model.cpp:886
GLvoid * getData()
Access buffer data.
float _orientation[4]
Orientation of the node.
Definition: modelnode.h:223
UString readString(SeekableReadStream &stream, Encoding encoding)
Read a string with the given encoding of a stream.
Definition: encoding.cpp:287
static float rad2deg(float rad)
Definition: maths.h:93
void finalize()
Finalize the loading procedure.
Definition: model.cpp:807
Loading MDL/MDX files found in Jade Empire.
std::list< ModelNode_Jade * > nodes
Definition: model_jade.h:57
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
Definition: encoding.cpp:297
void unfoldTriangleFan(std::vector< uint16 > &indices)
Definition: model_jade.cpp:635
void setName(const Common::UString &name)
Definition: mesh.cpp:47
UString generateIDRandomString()
Definition: uuid.cpp:37
void newState(ParserContext &ctx)
Definition: model_jade.cpp:262
StateList _stateList
All states within this model.
Definition: model.h:225
Generic vertex attribute data.
Definition: vertexbuffer.h:43
Interface for a seekable & readable data stream.
Definition: readstream.h:265
byte readByte()
Read an unsigned byte from the stream and return it.
Definition: readstream.h:92
IndexBuffer * getIndexBuffer()
Definition: mesh.cpp:43
#define GfxMan
Shortcut for accessing the graphics manager.
Definition: graphics.h:299
void setSize(uint32 indexCount, uint32 indexSize, GLenum indexType)
Change buffer size.
Definition: indexbuffer.cpp:65
The global resource manager for Aurora resources.
unsigned int uint
Definition: types.h:211
void addState(ParserContext &ctx)
Definition: model_jade.cpp:268