xoreos  0.0.5
model_witcher.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 the binary MDL specs by Torlack
26  * (<https://github.com/xoreos/xoreos-docs/tree/master/specs/torlack>)
27  * and the code of Michael_DarkAngel's twMax importer script
28  * (<http://www.tbotr.net/modules.php?mod=Downloads&op=download&sid=3&ssid=3&dlid=19>).
29  */
30 
31 #include <cassert>
32 
33 #include "src/common/error.h"
34 #include "src/common/maths.h"
35 #include "src/common/readstream.h"
36 #include "src/common/encoding.h"
37 
38 #include "src/aurora/types.h"
39 #include "src/aurora/resman.h"
40 
42 
45 
48 
50 
51 #include "src/common/uuid.h"
52 
53 // Disable the "unused variable" warnings while most stuff is still stubbed
55 
56 namespace Graphics {
57 
58 namespace Aurora {
59 
60 enum NodeType {
61  kNodeTypeNode = 0x00000001,
62  kNodeTypeLight = 0x00000003,
63  kNodeTypeEmitter = 0x00000005,
64  kNodeTypeCamera = 0x00000009,
65  kNodeTypeReference = 0x00000011,
66  kNodeTypeTrimesh = 0x00000021,
67  kNodeTypeSkin = 0x00000061,
68  kNodeTypeAABB = 0x00000221,
69  kNodeTypeTrigger = 0x00000421,
70  kNodeTypeSectorInfo = 0x00001001,
71  kNodeTypeWalkmesh = 0x00002001,
72  kNodeTypeDanglyNode = 0x00004001,
73  kNodeTypeTexturePaint = 0x00008001,
74  kNodeTypeSpeedTree = 0x00010001,
75  kNodeTypeChain = 0x00020001,
76  kNodeTypeCloth = 0x00040001
77 };
78 
83 };
84 
88 };
89 
90 
92  mdb = ResMan.getResource(name, ::Aurora::kFileTypeMDB);
93  if (!mdb)
94  throw Common::Exception("No such MDB \"%s\"", name.c_str());
95 }
96 
98  delete mdb;
99 
100  clear();
101 }
102 
104  for (std::list<ModelNode_Witcher *>::iterator n = nodes.begin(); n != nodes.end(); ++n)
105  delete *n;
106  nodes.clear();
107 
108  delete state;
109  state = 0;
110 }
111 
112 
114  _fileName = name;
115 
116  ParserContext ctx(name);
117 
118  load(ctx);
119 
120  finalize();
121 }
122 
124 }
125 
127  if (ctx.mdb->readByte() != 0) {
128  ctx.mdb->seek(0);
129 
131  if (type.beginsWith("binarycompositemodel"))
132  throw Common::Exception("TODO: binarycompositemodel");
133 
134  throw Common::Exception("Not a The Witcher MDB file");
135  }
136 
137  ctx.mdb->seek(4);
138 
139  ctx.fileVersion = ctx.mdb->readUint32LE() & 0x0FFFFFFF;
140  if ((ctx.fileVersion != 136) && (ctx.fileVersion != 133))
141  throw Common::Exception("Unknown The Witcher MDB version %d", ctx.fileVersion);
142 
143  uint32 modelCount = ctx.mdb->readUint32LE();
144  if (modelCount != 1)
145  throw Common::Exception("Unsupported model count %d in The Witcher MDB", modelCount);
146 
147  ctx.mdb->skip(4);
148 
149  ctx.modelDataSize = ctx.mdb->readUint32LE();
150 
151  ctx.mdb->skip(4);
152 
153  ctx.offModelData = 32;
154 
155  if (ctx.fileVersion == 133) {
156  ctx.offRawData = ctx.mdb->readUint32LE() + ctx.offModelData;
157  ctx.rawDataSize = ctx.mdb->readUint32LE();
158  ctx.offTexData = ctx.offModelData;
159  ctx.texDatasize = 0;
160  } else {
161  ctx.offRawData = ctx.offModelData;
162  ctx.rawDataSize = 0;
163  ctx.offTexData = ctx.mdb->readUint32LE() + ctx.offModelData;
164  ctx.texDatasize = ctx.mdb->readUint32LE();
165  }
166 
167  ctx.mdb->skip(8);
168 
170  ctx.mdlName = _name;
171 
172  uint32 offsetRootNode = ctx.mdb->readUint32LE();
173 
174  ctx.mdb->skip(32);
175 
176  byte type = ctx.mdb->readByte();
177 
178  ctx.mdb->skip(3);
179 
180  ctx.mdb->skip(48);
181 
182  float firstLOD = ctx.mdb->readIEEEFloatLE();
183  float lastLOD = ctx.mdb->readIEEEFloatLE();
184 
185  ctx.mdb->skip(16);
186 
188 
189  ctx.mdb->skip(4);
190 
191  float modelScale = ctx.mdb->readIEEEFloatLE();
192 
194 
195  ctx.mdb->skip(16);
196 
197  newState(ctx);
198 
199  ModelNode_Witcher *rootNode = new ModelNode_Witcher(*this);
200  ctx.nodes.push_back(rootNode);
201 
202  ctx.mdb->seek(ctx.offModelData + offsetRootNode);
203  rootNode->load(ctx);
204 
205  addState(ctx);
206 }
207 
209  ctx.clear();
210 
211  ctx.state = new State;
212 }
213 
215  if (!ctx.state || ctx.nodes.empty()) {
216  ctx.clear();
217  return;
218  }
219 
220  for (std::list<ModelNode_Witcher *>::iterator n = ctx.nodes.begin();
221  n != ctx.nodes.end(); ++n) {
222 
223  ctx.state->nodeList.push_back(*n);
224  ctx.state->nodeMap.insert(std::make_pair((*n)->getName(), *n));
225 
226  if (!(*n)->getParent())
227  ctx.state->rootNodes.push_back(*n);
228  }
229 
230  _stateList.push_back(ctx.state);
231  _stateMap.insert(std::make_pair(ctx.state->name, ctx.state));
232 
233  if (!_currentState)
234  _currentState = ctx.state;
235 
236  ctx.state = 0;
237 
238  ctx.nodes.clear();
239 }
240 
241 
243 }
244 
246 }
247 
249  ctx.mdb->skip(24); // Function pointers
250 
251  uint32 inheritColor = ctx.mdb->readUint32LE();
252  uint32 nodeNumber = ctx.mdb->readUint32LE();
253 
255 
256  ctx.mdb->skip(8); // Parent pointers
257 
258  uint32 childrenOffset, childrenCount;
259  Model::readArrayDef(*ctx.mdb, childrenOffset, childrenCount);
260 
261  std::vector<uint32> children;
262  Model::readArray(*ctx.mdb, ctx.offModelData + childrenOffset, childrenCount, children);
263 
264  uint32 controllerKeyOffset, controllerKeyCount;
265  Model::readArrayDef(*ctx.mdb, controllerKeyOffset, controllerKeyCount);
266 
267  uint32 controllerDataOffset, controllerDataCount;
268  Model::readArrayDef(*ctx.mdb, controllerDataOffset, controllerDataCount);
269 
270  std::vector<float> controllerData;
271  Model::readArray(*ctx.mdb, ctx.offModelData + controllerDataOffset,
272  controllerDataCount, controllerData);
273 
274  readNodeControllers(ctx, ctx.offModelData + controllerKeyOffset,
275  controllerKeyCount, controllerData);
276 
277  ctx.mdb->skip(4); // Unknown
278 
279  uint32 imposterGroup = ctx.mdb->readUint32LE();
280  uint32 fixedRot = ctx.mdb->readUint32LE();
281 
282  int32 minLOD = ctx.mdb->readUint32LE();
283  int32 maxLOD = ctx.mdb->readUint32LE();
284 
285  NodeType type = (NodeType) ctx.mdb->readUint32LE();
286  switch (type) {
287  case kNodeTypeTrimesh:
288  readMesh(ctx);
289  break;
290 
292  readTexturePaint(ctx);
293  break;
294 
295  default:
296  break;
297  }
298 
299  if (_mesh && _mesh->data && _mesh->data->rawMesh) {
300  Common::UString meshName = ctx.mdlName;
301  meshName += ".";
302  if (ctx.state->name.size() != 0) {
303  meshName += ctx.state->name;
304  } else {
305  meshName += "xoreos.default";
306  }
307  meshName += ".";
308  meshName += _name;
309 
320  Graphics::Mesh::Mesh *mystery_mesh = MeshMan.getMesh(meshName);
321  if (ctx.state->name.size() == 0) {
322  while (mystery_mesh) {
323  meshName += "_";
324  mystery_mesh = MeshMan.getMesh(meshName);
325  }
326  }
327 
328  if (!mystery_mesh) {
329  Graphics::Mesh::Mesh *checkMesh = MeshMan.getMesh(meshName);
330  if (checkMesh) {
331  warning("Warning: probable mesh duplication of: %s, attempting to correct", meshName.c_str());
332  delete _mesh->data->rawMesh;
333  _mesh->data->rawMesh = checkMesh;
334  } else {
335  _mesh->data->rawMesh->setName(meshName);
336  _mesh->data->rawMesh->init();
337  MeshMan.addMesh(_mesh->data->rawMesh);
338  }
339  } else {
340  delete _mesh->data->rawMesh;
341  _mesh->data->rawMesh = mystery_mesh;
342  }
343  }
344 
345  // Only render the highest LOD (0), or if the node is not LODing (-1)
346  if ((minLOD != -1) && (maxLOD != -1) && (minLOD > 0))
347  _render = false;
348 
349  for (std::vector<uint32>::const_iterator child = children.begin(); child != children.end(); ++child) {
350  ModelNode_Witcher *childNode = new ModelNode_Witcher(*_model);
351  ctx.nodes.push_back(childNode);
352 
353  childNode->setParent(this);
354 
355  ctx.mdb->seek(ctx.offModelData + *child);
356  childNode->load(ctx);
357  }
358 }
359 
361  ctx.mdb->skip(4); // Function pointer
362  ctx.mdb->skip(4); // Unknown
363 
364  uint32 offMeshArrays = ctx.mdb->readUint32LE();
365 
366  ctx.mdb->skip(4); // Unknown
367 
368  float boundingMin[3], boundingMax[3];
369 
370  boundingMin[0] = ctx.mdb->readIEEEFloatLE();
371  boundingMin[1] = ctx.mdb->readIEEEFloatLE();
372  boundingMin[2] = ctx.mdb->readIEEEFloatLE();
373 
374  boundingMax[0] = ctx.mdb->readIEEEFloatLE();
375  boundingMax[1] = ctx.mdb->readIEEEFloatLE();
376  boundingMax[2] = ctx.mdb->readIEEEFloatLE();
377 
378  ctx.mdb->skip(28); // Unknown
379 
380  float volFogScale = ctx.mdb->readIEEEFloatLE();
381 
382  ctx.mdb->skip(16); // Unknown
383 
384  _mesh = new Mesh();
385 
386  _mesh->diffuse[0] = ctx.mdb->readIEEEFloatLE();
387  _mesh->diffuse[1] = ctx.mdb->readIEEEFloatLE();
388  _mesh->diffuse[2] = ctx.mdb->readIEEEFloatLE();
389  _mesh->ambient[0] = ctx.mdb->readIEEEFloatLE();
390  _mesh->ambient[1] = ctx.mdb->readIEEEFloatLE();
391  _mesh->ambient[2] = ctx.mdb->readIEEEFloatLE();
392 
393  float textureTransRot[3];
394  textureTransRot[0] = ctx.mdb->readIEEEFloatLE();
395  textureTransRot[1] = ctx.mdb->readIEEEFloatLE();
396  textureTransRot[2] = ctx.mdb->readIEEEFloatLE();
397 
399 
400  _mesh->shadow = ctx.mdb->readUint32LE() == 1;
401  _mesh->beaming = ctx.mdb->readUint32LE() == 1;
402  _mesh->render = ctx.mdb->readUint32LE() == 1;
403 
404  _mesh->hasTransparencyHint = true;
405  _mesh->transparencyHint = ctx.mdb->readUint32LE() == 1;
406 
407  ctx.mdb->skip(4); // Unknown
408 
409  Common::UString texture[4];
410  for (int t = 0; t < 4; t++) {
411  texture[t] = Common::readStringFixed(*ctx.mdb, Common::kEncodingASCII, 64);
412 
413  if (texture[t] == "NULL")
414  texture[t].clear();
415  }
416 
417  bool tileFade = ctx.mdb->readUint32LE() == 1;
418 
419  bool controlFade = ctx.mdb->readByte() == 1;
420  bool lightMapped = ctx.mdb->readByte() == 1;
421  bool rotateTexture = ctx.mdb->readByte() == 1;
422 
423  ctx.mdb->skip(1); // Unknown
424 
425  float transparencyShift = ctx.mdb->readIEEEFloatLE();
426 
427  uint32 defaultRenderList = ctx.mdb->readUint32LE();
428  uint32 preserveVColors = ctx.mdb->readUint32LE();
429 
430  uint32 fourCC = ctx.mdb->readUint32BE();
431 
432  ctx.mdb->skip(4); // Unknown
433 
434  float depthOffset = ctx.mdb->readIEEEFloatLE();
435  float coronaCenterMult = ctx.mdb->readIEEEFloatLE();
436  float fadeStartDistance = ctx.mdb->readIEEEFloatLE();
437 
438  bool distFromScreenCenterFace = ctx.mdb->readByte() == 1;
439  ctx.mdb->skip(3); // Unknown
440 
441  float enlargeStartDistance = ctx.mdb->readIEEEFloatLE();
442 
443  bool affectedByWind = ctx.mdb->readByte() == 1;
444  ctx.mdb->skip(3); // Unknown
445 
446  float dampFactor = ctx.mdb->readIEEEFloatLE();
447 
448  uint32 blendGroup = ctx.mdb->readUint32LE();
449 
450  bool dayNightLightMaps = ctx.mdb->readByte() == 1;
451 
452  Common::UString dayNightTransition = Common::readStringFixed(*ctx.mdb, Common::kEncodingASCII, 200);
453 
454  bool ignoreHitCheck = ctx.mdb->readByte() == 1;
455  bool needsReflection = ctx.mdb->readByte() == 1;
456  ctx.mdb->skip(1); // Unknown
457 
458  float reflectionPlaneNormal[3];
459  reflectionPlaneNormal[0] = ctx.mdb->readIEEEFloatLE();
460  reflectionPlaneNormal[1] = ctx.mdb->readIEEEFloatLE();
461  reflectionPlaneNormal[2] = ctx.mdb->readIEEEFloatLE();
462 
463  float reflectionPlaneDistance = ctx.mdb->readIEEEFloatLE();
464 
465  bool fadeOnCameraCollision = ctx.mdb->readByte() == 1;
466  bool noSelfShadow = ctx.mdb->readByte() == 1;
467  bool isReflected = ctx.mdb->readByte() == 1;
468  bool onlyReflected = ctx.mdb->readByte() == 1;
469 
471 
472  bool canDecal = ctx.mdb->readByte() == 1;
473  bool multiBillBoard = ctx.mdb->readByte() == 1;
474  bool ignoreLODReflection = ctx.mdb->readByte() == 1;
475  ctx.mdb->skip(1); // Unknown
476 
477  float detailMapScape = ctx.mdb->readIEEEFloatLE();
478 
479  ctx.offTextureInfo = ctx.mdb->readUint32LE();
480 
481  uint32 endPos = ctx.mdb->seek(ctx.offRawData + offMeshArrays);
482 
483  ctx.mdb->skip(4);
484 
485  uint32 vertexOffset, vertexCount;
486  Model::readArrayDef(*ctx.mdb, vertexOffset, vertexCount);
487 
488  uint32 normalsOffset, normalsCount;
489  Model::readArrayDef(*ctx.mdb, normalsOffset, normalsCount);
490 
491  uint32 tangentsOffset, tangentsCount;
492  Model::readArrayDef(*ctx.mdb, tangentsOffset, tangentsCount);
493 
494  uint32 biNormalsOffset, biNormalsCount;
495  Model::readArrayDef(*ctx.mdb, biNormalsOffset, biNormalsCount);
496 
497  uint32 tVertsOffset[4], tVertsCount[4];
498  for (uint t = 0; t < 4; t++)
499  Model::readArrayDef(*ctx.mdb, tVertsOffset[t], tVertsCount[t]);
500 
501  uint32 unknownOffset, unknownCount;
502  Model::readArrayDef(*ctx.mdb, unknownOffset, unknownCount);
503 
504  uint32 facesOffset, facesCount;
505  Model::readArrayDef(*ctx.mdb, facesOffset, facesCount);
506 
507  if (ctx.fileVersion == 133)
508  ctx.offTexData = ctx.mdb->readUint32LE();
509 
510 
511  if ((vertexCount == 0) || (facesCount == 0)) {
512  ctx.mdb->seek(endPos);
513  return;
514  }
515 
516  _render = _mesh->render;
517  _mesh->data = new MeshData();
519 
520  std::vector<Common::UString> textures;
521  readTextures(ctx, textures);
522 
523  evaluateTextures(4, textures, texture, tVertsCount, dayNightLightMaps, lightMapName);
524 
525  loadTextures(textures);
526 
527  size_t texCount = textures.size();
528 
529  // Read vertices
530 
531  VertexDecl vertexDecl;
532 
533  vertexDecl.push_back(VertexAttrib(VPOSITION, 3, GL_FLOAT));
534  vertexDecl.push_back(VertexAttrib(VNORMAL , 3, GL_FLOAT));
535  for (uint t = 0; t < texCount; t++)
536  vertexDecl.push_back(VertexAttrib(VTCOORD + t, 2, GL_FLOAT));
537 
538  _mesh->data->rawMesh->getVertexBuffer()->setVertexDeclLinear(vertexCount, vertexDecl);
539 
540  // Read vertex position
541  ctx.mdb->seek(ctx.offRawData + vertexOffset);
542  float *v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData(0));
543  for (uint32 i = 0; i < vertexCount; i++) {
544  *v++ = ctx.mdb->readIEEEFloatLE();
545  *v++ = ctx.mdb->readIEEEFloatLE();
546  *v++ = ctx.mdb->readIEEEFloatLE();
547  }
548 
549  // Read vertex normals
550  assert(normalsCount == vertexCount);
551  ctx.mdb->seek(ctx.offRawData + normalsOffset);
552  v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData(1));
553  for (uint32 i = 0; i < normalsCount; i++) {
554  *v++ = ctx.mdb->readIEEEFloatLE();
555  *v++ = ctx.mdb->readIEEEFloatLE();
556  *v++ = ctx.mdb->readIEEEFloatLE();
557  }
558 
559  // Read texture coordinates
560  for (uint t = 0; t < texCount; t++) {
561 
562  ctx.mdb->seek(ctx.offRawData + tVertsOffset[t]);
563  v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData(2 + t));
564  for (uint32 i = 0; i < tVertsCount[t]; i++) {
565  if (i < tVertsCount[t]) {
566  *v++ = ctx.mdb->readIEEEFloatLE();
567  *v++ = ctx.mdb->readIEEEFloatLE();
568  } else {
569  *v++ = 0.0f;
570  *v++ = 0.0f;
571  }
572  }
573  }
574 
575 
576  // Read faces
577 
578  _mesh->data->rawMesh->getIndexBuffer()->setSize(facesCount * 3, sizeof(uint32), GL_UNSIGNED_INT);
579 
580  ctx.mdb->seek(ctx.offRawData + facesOffset);
581  uint32 *f = reinterpret_cast<uint32 *>(_mesh->data->rawMesh->getIndexBuffer()->getData());
582  for (uint32 i = 0; i < facesCount; i++) {
583  ctx.mdb->skip(4 * 4 + 4);
584 
585  if (ctx.fileVersion == 133)
586  ctx.mdb->skip(3 * 4);
587 
588  // Vertex indices
589  *f++ = ctx.mdb->readUint32LE();
590  *f++ = ctx.mdb->readUint32LE();
591  *f++ = ctx.mdb->readUint32LE();
592 
593  if (ctx.fileVersion == 133)
594  ctx.mdb->skip(4);
595  }
596 
597  createBound();
598 
599  ctx.mdb->seek(endPos);
600 }
601 
603  uint32 layersOffset, layersCount;
604  Model::readArrayDef(*ctx.mdb, layersOffset, layersCount);
605 
606  ctx.mdb->skip(28); // Unknown
607 
608  uint32 offMeshArrays = ctx.mdb->readUint32LE();
609 
610  uint32 sectorID0 = ctx.mdb->readUint32LE();
611  uint32 sectorID1 = ctx.mdb->readUint32LE();
612  uint32 sectorID2 = ctx.mdb->readUint32LE();
613  uint32 sectorID3 = ctx.mdb->readUint32LE();
614 
615  float boundingMin[3], boundingMax[3];
616 
617  boundingMin[0] = ctx.mdb->readIEEEFloatLE();
618  boundingMin[1] = ctx.mdb->readIEEEFloatLE();
619  boundingMin[2] = ctx.mdb->readIEEEFloatLE();
620 
621  boundingMax[0] = ctx.mdb->readIEEEFloatLE();
622  boundingMax[1] = ctx.mdb->readIEEEFloatLE();
623  boundingMax[2] = ctx.mdb->readIEEEFloatLE();
624 
625  _mesh = new Mesh();
626 
627  _mesh->diffuse[0] = ctx.mdb->readIEEEFloatLE();
628  _mesh->diffuse[1] = ctx.mdb->readIEEEFloatLE();
629  _mesh->diffuse[2] = ctx.mdb->readIEEEFloatLE();
630  _mesh->ambient[0] = ctx.mdb->readIEEEFloatLE();
631  _mesh->ambient[1] = ctx.mdb->readIEEEFloatLE();
632  _mesh->ambient[2] = ctx.mdb->readIEEEFloatLE();
633 
634  float textureTransRot[3];
635  textureTransRot[0] = ctx.mdb->readIEEEFloatLE();
636  textureTransRot[1] = ctx.mdb->readIEEEFloatLE();
637  textureTransRot[2] = ctx.mdb->readIEEEFloatLE();
638 
639  _mesh->shadow = ctx.mdb->readUint32LE() == 1;
640  _mesh->render = ctx.mdb->readUint32LE() == 1;
641 
642  bool tileFade = ctx.mdb->readUint32LE() == 1;
643 
644  bool controlFade = ctx.mdb->readByte() == 1;
645  bool lightMapped = ctx.mdb->readByte() == 1;
646  bool rotateTexture = ctx.mdb->readByte() == 1;
647  ctx.mdb->skip(1); // Unknown
648 
649  float transparencyShift = ctx.mdb->readIEEEFloatLE();
650 
651  uint32 defaultRenderList = ctx.mdb->readUint32LE();
652  uint32 fourCC = ctx.mdb->readUint32BE();
653 
654  ctx.mdb->skip(4); // Unknown
655 
656  float depthOffset = ctx.mdb->readIEEEFloatLE();
657 
658  uint32 blendGroup = ctx.mdb->readUint32LE();
659 
660  bool dayNightLightMaps = ctx.mdb->readByte() == 1;
661 
662  Common::UString dayNightTransition = Common::readStringFixed(*ctx.mdb, Common::kEncodingASCII, 200);
663 
664  bool ignoreHitCheck = ctx.mdb->readByte() == 1;
665  bool needsReflection = ctx.mdb->readByte() == 1;
666  ctx.mdb->skip(1); // Unknown
667 
668  float reflectionPlaneNormal[3];
669  reflectionPlaneNormal[0] = ctx.mdb->readIEEEFloatLE();
670  reflectionPlaneNormal[1] = ctx.mdb->readIEEEFloatLE();
671  reflectionPlaneNormal[2] = ctx.mdb->readIEEEFloatLE();
672 
673  float reflectionPlaneDistance = ctx.mdb->readIEEEFloatLE();
674 
675  bool fadeOnCameraCollision = ctx.mdb->readByte() == 1;
676  bool noSelfShadow = ctx.mdb->readByte() == 1;
677  bool isReflected = ctx.mdb->readByte() == 1;
678  ctx.mdb->skip(1); // Unknown
679 
680  float detailMapScape = ctx.mdb->readIEEEFloatLE();
681 
682  bool onlyReflected = ctx.mdb->readByte() == 1;
683 
685 
686  bool canDecal = ctx.mdb->readByte() == 1;
687  bool ignoreLODReflection = ctx.mdb->readByte() == 1;
688  bool enableSpecular = ctx.mdb->readByte() == 1;
689 
690 
691  uint32 endPos = ctx.mdb->seek(ctx.offRawData + offMeshArrays);
692 
693  ctx.mdb->skip(4);
694 
695  uint32 vertexOffset, vertexCount;
696  Model::readArrayDef(*ctx.mdb, vertexOffset, vertexCount);
697 
698  uint32 normalsOffset, normalsCount;
699  Model::readArrayDef(*ctx.mdb, normalsOffset, normalsCount);
700 
701  uint32 tangentsOffset, tangentsCount;
702  Model::readArrayDef(*ctx.mdb, tangentsOffset, tangentsCount);
703 
704  uint32 biNormalsOffset, biNormalsCount;
705  Model::readArrayDef(*ctx.mdb, biNormalsOffset, biNormalsCount);
706 
707  uint32 tVertsOffset[4], tVertsCount[4];
708  for (uint t = 0; t < 4; t++)
709  Model::readArrayDef(*ctx.mdb, tVertsOffset[t], tVertsCount[t]);
710 
711  uint32 unknownOffset, unknownCount;
712  Model::readArrayDef(*ctx.mdb, unknownOffset, unknownCount);
713 
714  uint32 facesOffset, facesCount;
715  Model::readArrayDef(*ctx.mdb, facesOffset, facesCount);
716 
717  if ((vertexCount == 0) || (facesCount == 0)) {
718  ctx.mdb->seek(endPos);
719  return;
720  }
721 
722  _render = _mesh->render;
723  _mesh->data = new MeshData();
725 
726  std::vector<TexturePaintLayer> layers;
727  layers.resize(layersCount);
728 
729  for (uint32 l = 0; l < layersCount; l++) {
730  ctx.mdb->seek(ctx.offRawData + layersOffset + l * 52);
731 
732  layers[l].hasTexture = ctx.mdb->readByte() == 1;
733  if (!layers[l].hasTexture)
734  continue;
735 
736  ctx.mdb->skip(3); // Unknown
737  ctx.mdb->skip(4); // Offset to material
738 
739  layers[l].texture = Common::readStringFixed(*ctx.mdb, Common::kEncodingASCII, 32);
740 
741  uint32 weightsOffset, weightsCount;
742  Model::readArrayDef(*ctx.mdb, weightsOffset, weightsCount);
743 
744  ctx.mdb->seek(ctx.offRawData + weightsOffset);
745  layers[l].weights.resize(weightsCount);
746 
747  for (std::vector<float>::iterator w = layers[l].weights.begin(); w != layers[l].weights.end(); ++w)
748  *w = ctx.mdb->readIEEEFloatLE();
749  }
750 
751  std::vector<Common::UString> textures;
752  textures.push_back(lightMapName);
753 
754  evaluateTextures(1, textures, 0, tVertsCount, dayNightLightMaps, lightMapName);
755 
756  loadTextures(textures);
757 
758  size_t texCount = textures.size();
759 
760  // Read vertices
761 
762  VertexDecl vertexDecl;
763 
764  vertexDecl.push_back(VertexAttrib(VPOSITION, 3, GL_FLOAT));
765  vertexDecl.push_back(VertexAttrib(VNORMAL , 3, GL_FLOAT));
766  for (uint t = 0; t < texCount; t++)
767  vertexDecl.push_back(VertexAttrib(VTCOORD + t, 2, GL_FLOAT));
768 
769  _mesh->data->rawMesh->getVertexBuffer()->setVertexDeclLinear(vertexCount, vertexDecl);
770 
771  // Read vertex position
772  ctx.mdb->seek(ctx.offRawData + vertexOffset);
773  float *v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData(0));
774  for (uint32 i = 0; i < vertexCount; i++) {
775  *v++ = ctx.mdb->readIEEEFloatLE();
776  *v++ = ctx.mdb->readIEEEFloatLE();
777  *v++ = ctx.mdb->readIEEEFloatLE();
778  }
779 
780  // Read vertex normals
781  assert(normalsCount == vertexCount);
782  ctx.mdb->seek(ctx.offRawData + normalsOffset);
783  v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData(1));
784  for (uint32 i = 0; i < normalsCount; i++) {
785  *v++ = ctx.mdb->readIEEEFloatLE();
786  *v++ = ctx.mdb->readIEEEFloatLE();
787  *v++ = ctx.mdb->readIEEEFloatLE();
788  }
789 
790  // Read texture coordinates
791  for (uint t = 0; t < texCount; t++) {
792 
793  ctx.mdb->seek(ctx.offRawData + tVertsOffset[t]);
794  v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData(2 + t));
795  for (uint32 i = 0; i < tVertsCount[t]; i++) {
796  if (i < tVertsCount[t]) {
797  *v++ = ctx.mdb->readIEEEFloatLE();
798  *v++ = ctx.mdb->readIEEEFloatLE();
799  } else {
800  *v++ = 0.0f;
801  *v++ = 0.0f;
802  }
803  }
804  }
805 
806 
807  // Read faces
808 
809  _mesh->data->rawMesh->getIndexBuffer()->setSize(facesCount * 3, sizeof(uint32), GL_UNSIGNED_INT);
810 
811  ctx.mdb->seek(ctx.offRawData + facesOffset);
812  uint32 *f = reinterpret_cast<uint32 *>(_mesh->data->rawMesh->getIndexBuffer()->getData());
813  for (uint32 i = 0; i < facesCount; i++) {
814  // Vertex indices
815  *f++ = ctx.mdb->readUint32LE();
816  *f++ = ctx.mdb->readUint32LE();
817  *f++ = ctx.mdb->readUint32LE();
818 
819  ctx.mdb->skip(68); // Unknown
820  }
821 
822  _mesh->data->rawMesh->init();
823 
824  createBound();
825 
826  ctx.mdb->seek(endPos);
827 
828  if (GfxMan.isRendererExperimental())
829  buildMaterial();
830 }
831 
833  std::vector<Common::UString> &textures) {
834 
835  uint32 offset;
836  if (ctx.fileVersion == 133)
837  offset = ctx.offRawData + ctx.offTexData;
838  else
839  offset = ctx.offTexData + ctx.offTextureInfo;
840 
841  ctx.mdb->seek(offset);
842 
843  uint32 textureCount = ctx.mdb->readUint32LE();
844  uint32 offTexture = ctx.mdb->readUint32LE();
845 
846  std::vector<Common::UString> textureLine;
847  textureLine.resize(textureCount);
848  for (std::vector<Common::UString>::iterator line = textureLine.begin(); line != textureLine.end(); ++line) {
850  ctx.mdb->skip(1);
851 
852  line->trim();
853  }
854 
855  textures.resize(4);
856 
857  int hasShaderTex = false;
858 
859  for (std::vector<Common::UString>::const_iterator line = textureLine.begin(); line != textureLine.end(); ++line) {
860  int s = -1;
861  int n = 0;
862 
863  if (line->beginsWith("texture texture0 ")) {
864  s = 17;
865  n = 0 + (hasShaderTex ? 1 : 0);
866  } else if (line->beginsWith("texture texture1 ")) {
867  s = 17;
868  n = 1 + (hasShaderTex ? 1 : 0);
869  } else if (line->beginsWith("texture texture2 ")) {
870  s = 17;
871  n = 2 + (hasShaderTex ? 1 : 0);
872  } else if (line->beginsWith("texture texture3 ")) {
873  s = 17;
874  n = 3;
875  } else if (line->beginsWith("texture tex ")) {
876  s = 12;
877  n = 0 + (hasShaderTex ? 1 : 0);
878  } else if (line->beginsWith("shader ")) {
879  hasShaderTex = true;
880 
881  Common::UString shader = line->substr(line->getPosition(7), line->end());
882  if ((shader == "dadd_al_mul_alp") ||
883  (shader == "corona") ||
884  (shader == "normalmap") ||
885  (shader == "norm_env_rim_ao") ||
886  (shader == "transparency_2ps") ||
887  (shader == "skin_n_rim_ao"))
888  hasShaderTex = false;
889  }
890 
891  if (s != -1)
892  textures[n] = line->substr(line->getPosition(s), line->end());
893  }
894 
895 }
896 
897 void ModelNode_Witcher::evaluateTextures(int n, std::vector<Common::UString> &textures,
898  const Common::UString *staticTextures, const uint32 *tVertsCount,
899  bool lightMapDayNight, const Common::UString &lightMapName) {
900 
901  textures.resize(n);
902 
903  for (int t = 0; t < n; t++) {
904  if (textures[t].empty() && staticTextures)
905  textures[t] = staticTextures[t];
906 
907  if (tVertsCount[t] == 0)
908  textures[t].clear();
909 
910  if (textures[t].empty())
911  continue;
912 
913  if (lightMapDayNight && (textures[t] == lightMapName)) {
914  // Day (dzie&#324;)
915  if (ResMan.hasResource(textures[t] + "!d", ::Aurora::kResourceImage))
916  textures[t] += "!d";
917  // Morning (rano)
918  else if (ResMan.hasResource(textures[t] + "!r", ::Aurora::kResourceImage))
919  textures[t] += "!r";
920  // Noon (po&#322;udnie)
921  else if (ResMan.hasResource(textures[t] + "!p", ::Aurora::kResourceImage))
922  textures[t] += "!p";
923  // Evening (wiecz&#211;r)
924  else if (ResMan.hasResource(textures[t] + "!w", ::Aurora::kResourceImage))
925  textures[t] += "!w";
926  // Night (noc)
927  else if (ResMan.hasResource(textures[t] + "!n", ::Aurora::kResourceImage))
928  textures[t] += "!n";
929  else
930  textures[t].clear();
931  }
932  }
933 
934  while (!textures.empty() && textures.back().empty())
935  textures.pop_back();
936 }
937 
939  uint32 offset, uint32 count, std::vector<float> &data) {
940 
941  uint32 pos = ctx.mdb->seek(offset);
942 
943  // TODO: readNodeControllers: Implement this properly :P
944 
945  for (uint32 i = 0; i < count; i++) {
946  uint32 type = ctx.mdb->readUint32LE();
947  uint16 rowCount = ctx.mdb->readUint16LE();
948  uint16 timeIndex = ctx.mdb->readUint16LE();
949  uint16 dataIndex = ctx.mdb->readUint16LE();
950  uint8 columnCount = ctx.mdb->readByte();
951  ctx.mdb->skip(1);
952 
953  if (rowCount == 0xFFFF)
954  // TODO: Controller row count = 0xFFFF
955  continue;
956 
957  if (type == kNodeControllerTypePosition) {
958  if (columnCount != 3)
959  throw Common::Exception("Position controller with %d values", columnCount);
960 
961  _position[0] = data[dataIndex + 0];
962  _position[1] = data[dataIndex + 1];
963  _position[2] = data[dataIndex + 2];
964 
965  } else if (type == kNodeControllerTypeOrientation) {
966  if (columnCount != 4)
967  throw Common::Exception("Orientation controller with %d values", columnCount);
968 
969  _orientation[0] = data[dataIndex + 0];
970  _orientation[1] = data[dataIndex + 1];
971  _orientation[2] = data[dataIndex + 2];
972  _orientation[3] = Common::rad2deg(acos(data[dataIndex + 3]) * 2.0);
973  }
974 
975  }
976 
977  ctx.mdb->seek(pos);
978 }
979 
981  ModelNode::Mesh *pmesh = 0; // TODO: if anything is changed in here, ensure there's a local copy instead that shares the root data.
982  TextureHandle *phandles = 0; // Take from self first, or root state, if there is one, otherwise.
983  TextureHandle *penvmap = 0; // Maybe it's only the environment map that's overriden.
984  EnvironmentMapMode envmapmode;
985 
986  uint32 textureCount = 0;
987 
988  _renderableArray.clear();
989 
998  pmesh = _mesh;
999 
1000  if (!_model->getState().empty() && !pmesh) {
1002  if (_rootStateNode == this) {
1003  _rootStateNode = 0;
1004  }
1005  if (_rootStateNode) {
1006  pmesh = _rootStateNode->getMesh();
1007  }
1008  } else {
1009  _rootStateNode = 0;
1010  }
1011 
1012  _dirtyRender = false;
1013 
1014  if (!pmesh) {
1015  return;
1016  }
1017 
1018  if (!pmesh->data) {
1019  return;
1020  }
1021 
1022  if (pmesh->data->textures.size() == 0 && pmesh->data->envMap.empty() && !pmesh->data->rawMesh) {
1023  return;
1024  }
1032  phandles = getTextures(textureCount);
1033  penvmap = getEnvironmentMap(envmapmode);
1034 
1035  if (textureCount == 0) {
1036  return;
1037  }
1038 
1039  if (!_render) {
1040  return;
1041  }
1042 
1043  if (!pmesh->data->rawMesh) {
1044  return;
1045  }
1046 
1047  Common::UString vertexShaderName;
1048  Common::UString fragmentShaderName;
1049  Common::UString materialName = "xoreos.";
1051 
1052  Shader::ShaderMaterial *material;
1053  Shader::ShaderSampler *sampler;
1054  Shader::ShaderSurface *surface;
1055 
1056  uint32 materialFlags = 0;
1057 
1058  _renderableArray.clear();
1059 
1060  const VertexDecl &decl = pmesh->data->rawMesh->getVertexBuffer()->getVertexDecl();
1061  for (uint32 i = 0; i < decl.size(); ++i) {
1062  switch (decl[i].index) {
1063  case 0:
1065  break;
1066  case 1:
1068  break;
1069  case 2:
1070  break;
1071  case 3:
1073  break;
1074  case 4:
1076  break;
1077  default: break;
1078  }
1079  }
1080 
1081  if (penvmap) {
1082  if (penvmap->getTexture().getImage().isCubeMap()) {
1089  } else {
1096  }
1097 
1098  if (envmapmode == kModeEnvironmentBlendedUnder) {
1099  materialName += penvmap->getName();
1100  // Figure out if a cube or sphere map is used.
1101  if (penvmap->getTexture().getImage().isCubeMap()) {
1102  if (!pmesh->isTransparent) {
1103  materialFlags |= Shader::ShaderMaterial::MATERIAL_OPAQUE;
1104  }
1107  } else {
1113  materialFlags |= Shader::ShaderMaterial::MATERIAL_OPAQUE;
1116  }
1117  }
1118  }
1119 
1120  if (pmesh->isTransparent && !(materialFlags & Shader::ShaderMaterial::MATERIAL_OPAQUE)) {
1122  }
1123 
1129  if (textureCount >= 1) {
1130  if (!phandles[0].empty()) {
1131  materialName += phandles[0].getName();
1137  if (textureCount >= 2) {
1139  }
1140  cripter.declareSampler(sid,
1142  cripter.connect(sid,
1145 
1146  if (phandles[0].getTexture().getTXI().getFeatures().blending) {
1148  }
1149  // Check to see if it's actually a decal texture.
1150  if (phandles[0].getTexture().getTXI().getFeatures().decal) {
1151  materialFlags |= Shader::ShaderMaterial::MATERIAL_DECAL;
1152  }
1153  if (penvmap && envmapmode == kModeEnvironmentBlendedUnder) {
1156  } else {
1159  }
1160  } else {
1170  }
1171  }
1172 
1173  if (textureCount >= 2) {
1174  if (!phandles[1].empty()) {
1175  materialName += ".";
1176  materialName += phandles[1].getName();
1184  }
1185  }
1186 
1187  if (textureCount >= 3) {
1188  if (!phandles[2].empty()) {
1189  materialName += ".";
1190  materialName += phandles[2].getName();
1193  }
1194  }
1195 
1196  if (textureCount >= 4) {
1197  // Don't know yet what this extra texture is supposed to be.
1198  if (!phandles[3].empty()) {
1199  materialName += ".";
1200  materialName += phandles[3].getName();
1203  }
1204  }
1205 
1206  if (penvmap) {
1207  if (envmapmode == kModeEnvironmentBlendedOver) {
1208  materialName += penvmap->getName();
1209  // Figure out if a cube or sphere map is used.
1210  if (penvmap->getTexture().getImage().isCubeMap()) {
1213  } else {
1216  }
1217  }
1218  }
1219 
1220  material = MaterialMan.getMaterial(materialName);
1221  if (material) {
1222  surface = SurfaceMan.getSurface(materialName);
1223  _renderableArray.push_back(Shader::ShaderRenderable(surface, material, pmesh->data->rawMesh));
1224  return;
1225  }
1226 
1227  if (_mesh->alpha < 1.0f) {
1228  materialFlags &= ~Shader::ShaderMaterial::MATERIAL_OPAQUE; // Make sure it's not actually opaque.
1230  }
1231 
1232  cripter.genName(vertexShaderName);
1233  fragmentShaderName = vertexShaderName + ".frag";
1234  vertexShaderName += ".vert";
1235 
1236  // Ok, material doesn't exist. Check on the shaders.
1237  Shader::ShaderObject *vertexObject = ShaderMan.getShaderObject(vertexShaderName, Shader::SHADER_VERTEX);
1238  Shader::ShaderObject *fragmentObject = ShaderMan.getShaderObject(fragmentShaderName, Shader::SHADER_FRAGMENT);
1239 
1240  // Should be checking vert and frag shader separately, but they really should exist together anyway.
1241  if (!vertexObject) {
1242  // No object found. Generate a shader then.
1243  bool isGL3 = GfxMan.isGL3();
1244 
1245  Common::UString vertexStringFinal;
1246  Common::UString fragmentStringFinal;
1247 
1248  cripter.build(isGL3, vertexStringFinal, fragmentStringFinal);
1249 
1250  vertexObject = ShaderMan.getShaderObject(vertexShaderName, vertexStringFinal, Shader::SHADER_VERTEX);
1251  fragmentObject = ShaderMan.getShaderObject(fragmentShaderName, fragmentStringFinal, Shader::SHADER_FRAGMENT);
1252  }
1253 
1254  // Shader objects should now exist, so go ahead and make the material and surface.
1255  surface = new Shader::ShaderSurface(vertexObject, materialName);
1256  material = new Shader::ShaderMaterial(fragmentObject, materialName);
1257  material->setFlags(materialFlags);
1258  MaterialMan.addMaterial(material);
1259  SurfaceMan.addSurface(surface);
1260 
1261  if (penvmap) {
1262  sampler = (Shader::ShaderSampler *)(material->getVariableData("sampler_7_id"));
1263  sampler->handle = *penvmap;
1264  }
1265 
1266  if (textureCount >= 1) {
1267  if (!phandles[0].empty()) {
1268  if (textureCount >= 2) {
1269  sampler = (Shader::ShaderSampler *)(material->getVariableData("sampler_1_id"));
1270  } else {
1271  sampler = (Shader::ShaderSampler *)(material->getVariableData("sampler_0_id"));
1272  }
1273  sampler->handle = phandles[0];
1274  }
1275  }
1276 
1277  if (textureCount >= 2) {
1278  if (!phandles[1].empty()) {
1279  sampler = (Shader::ShaderSampler *)(material->getVariableData("sampler_0_id"));
1280  sampler->handle = phandles[1];
1281  }
1282  }
1283 
1284  _renderableArray.push_back(Shader::ShaderRenderable(surface, material, pmesh->data->rawMesh));
1285 }
1286 
1287 } // End of namespace Aurora
1288 
1289 } // End of namespace Graphics
#define ResMan
Shortcut for accessing the sound manager.
Definition: resman.h:557
GLvoid * getData()
Access buffer data.
Definition: indexbuffer.cpp:78
const Common::UString & getState() const
Return the name of the current state.
Definition: model.cpp:361
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
EnvironmentMapMode
The way the environment map is applied to a model node.
Definition: modelnode.h:129
void build(bool isGL3, Common::UString &v_string, Common::UString &f_string)
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
ParserContext(const Common::UString &name)
Not strictly speaking an input, but generated for an output.
Definition: shaderbuilder.h:63
A class holding an UTF-8 string.
Definition: ustring.h:48
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
Vertex position.
Definition: vertexbuffer.h:36
VertexBuffer * getVertexBuffer()
Definition: mesh.cpp:39
Model_Witcher(const Common::UString &name, ModelType type=kModelTypeObject)
#define SurfaceMan
Shortcut for accessing the shader manager.
Definition: surfaceman.h:74
void loadTextures(const std::vector< Common::UString > &textures)
Definition: modelnode.cpp:340
void addState(ParserContext &ctx)
uint8_t uint8
Definition: types.h:200
void * getVariableData(uint32 index) const
bool beginsWith(const UString &with) const
Definition: ustring.cpp:295
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.
NodeList rootNodes
The nodes in the state without a parent.
Definition: model.h:209
void readMesh(Model_Witcher::ParserContext &ctx)
void setParent(ModelNode *parent)
Set the node&#39;s parent.
Definition: modelnode.cpp:143
State * _currentState
The current state.
Definition: model.h:227
Render hint; material has no transparency.
Utility functions for generating unique IDs.
Diffuse textures first, then blend the environment map in.
Definition: modelnode.h:131
bool _render
Render the node?
Definition: modelnode.h:235
void load(ParserContext &ctx)
Different to default blending. Maybe this should be extended one day.
TextureHandle * getEnvironmentMap(EnvironmentMapMode &mode)
Definition: modelnode.cpp:988
void declareSampler(ShaderDescriptor::Sampler sampler, ShaderDescriptor::SamplerType type)
bool isCubeMap() const
Is this image a cube map?
Definition: decoder.cpp:198
Common::UString _fileName
The model&#39;s file name.
Definition: model.h:218
TextureHandle * getTextures(uint32 &count)
Definition: modelnode.cpp:967
std::vector< VertexAttrib > VertexDecl
Vertex data layout.
Definition: vertexbuffer.h:63
#define IGNORE_UNUSED_VARIABLES
Definition: system.h:423
void connect(ShaderDescriptor::Sampler sampler, ShaderDescriptor::Input input, ShaderDescriptor::Action action)
Connect an input to a sampler and an action.
Exception that provides a stack of explanations.
Definition: error.h:36
const VertexDecl & getVertexDecl() const
Access vertex declaration.
Environment map first, then blend the diffuse textures in.
Definition: modelnode.h:130
Model * _model
The model this node belongs to.
Definition: modelnode.h:207
Common::UString _name
The model&#39;s name.
Definition: model.h:220
Vertex normal.
Definition: vertexbuffer.h:37
const ImageDecoder & getImage() const
Return the image.
Definition: texture.cpp:106
bool _dirtyRender
Rendering information needs updating.
Definition: modelnode.h:236
Basic exceptions to throw.
UString substr(iterator from, iterator to) const
Definition: ustring.cpp:706
UString readStringLine(SeekableReadStream &stream, Encoding encoding)
Read a line with the given encoding out of a stream.
Definition: encoding.cpp:310
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
Not strictly speaking an input, but generated for an output.
Definition: shaderbuilder.h:64
Graphics::Aurora::TextureHandle handle
Definition: shader.h:176
void readNodeControllers(Model_Witcher::ParserContext &ctx, uint32 offset, uint32 count, std::vector< float > &data)
ModelType
The display type of a model.
Definition: types.h:51
uint16_t uint16
Definition: types.h:202
TextureHandle envMap
The environment map texture.
Definition: modelnode.h:165
An image resource.
Definition: types.h:408
Not really blending, but component-wise multiply.
static void readArray(Common::SeekableReadStream &stream, uint32 offset, uint32 count, std::vector< T > &values)
Definition: model.cpp:902
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
Material definitely has transparency.
void readTextures(Model_Witcher::ParserContext &ctx, std::vector< Common::UString > &textures)
void setVertexDeclLinear(uint32 vertCount, VertexDecl &decl)
Set the linear vertex declaration for this buffer.
float ambient[3]
Ambient color.
Definition: modelnode.h:173
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.
Geometry, BioWare model.
Definition: types.h:136
#define MaterialMan
Shortcut for accessing the shader material manager.
Definition: materialman.h:74
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
std::vector< TextureHandle > textures
Textures.
Definition: modelnode.h:163
Basic reading stream interfaces.
void evaluateTextures(int n, std::vector< Common::UString > &textures, const Common::UString *staticTextures, const uint32 *tVertsCount, bool lightMapDayNight, const Common::UString &lightMapName)
void load(Model_Witcher::ParserContext &ctx)
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
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
Shader sampler is used to bind a texture to a texture unit.
Definition: shader.h:174
Loading MDB files found in The Witcher.
Graphics::Mesh::Mesh * rawMesh
Node raw mesh data.
Definition: modelnode.h:159
Common::UString _name
The node&#39;s name.
Definition: modelnode.h:216
Uniform variable colour information.
std::vector< Shader::ShaderRenderable > _renderableArray
Damn you bioware.
Definition: modelnode.h:218
A texture as used in the Aurora engines.
bool shadow
Does the node have a shadow?
Definition: modelnode.h:184
#define ShaderMan
Shortcut for accessing the shader manager.
Definition: shader.h:293
uint32_t uint32
Definition: types.h:204
void genName(Common::UString &n_string)
Generate a name to asscoiate with the current description.
static void readArrayDef(Common::SeekableReadStream &stream, uint32 &offset, uint32 &count)
Definition: model.cpp:886
GLvoid * getData()
Access buffer data.
float diffuse[3]
Diffuse color.
Definition: modelnode.h:174
float _orientation[4]
Orientation of the node.
Definition: modelnode.h:223
void addPass(ShaderDescriptor::Action action, ShaderDescriptor::Blend blend)
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
void readTexturePaint(Model_Witcher::ParserContext &ctx)
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
const Common::UString & getName() const
void newState(ParserContext &ctx)
void setName(const Common::UString &name)
Definition: mesh.cpp:47
void declareInput(ShaderDescriptor::Input input)
std::list< ModelNode_Witcher * > nodes
Definition: model_witcher.h:55
ModelNode * getNode(const Common::UString &node)
Get the specified node, from the current state.
Definition: model.cpp:379
A handle to a texture.
Definition: texturehandle.h:51
StateList _stateList
All states within this model.
Definition: model.h:225
void clear()
Clear the string&#39;s contents.
Definition: ustring.cpp:236
Generic vertex attribute data.
Definition: vertexbuffer.h:43
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.
uint8 byte
Definition: types.h:209
unsigned int uint
Definition: types.h:211
int32_t int32
Definition: types.h:203