xoreos  0.0.5
model_nwn2.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 on Tazpn's MDB specs found in the NWN2Wiki
26  * (<http://nwn2.wikia.com/wiki/MDB_Format>).
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 #include "src/common/strutil.h"
36 
37 #include "src/aurora/types.h"
38 #include "src/aurora/resman.h"
39 
42 
46 
47 // Disable the "unused variable" warnings while most stuff is still stubbed
49 
50 
51 static const uint32 kMDBID = MKTAG('N', 'W', 'N', '2');
52 
53 static const uint32 kRigidID = MKTAG('R', 'I', 'G', 'D');
54 static const uint32 kSkinID = MKTAG('S', 'K', 'I', 'N');
55 
56 namespace Graphics {
57 
58 namespace Aurora {
59 
61  mdb = ResMan.getResource(name, ::Aurora::kFileTypeMDB);
62  if (!mdb)
63  throw Common::Exception("No such MDB \"%s\"", name.c_str());
64  this->mdlName = name;
65 }
66 
68  delete mdb;
69 
70  clear();
71 }
72 
74  for (std::list<ModelNode_NWN2 *>::iterator n = nodes.begin(); n != nodes.end(); ++n)
75  delete *n;
76  nodes.clear();
77 
78  delete state;
79  state = 0;
80 }
81 
82 
84  _fileName = name;
85 
86  ParserContext ctx(name);
87 
88  load(ctx);
89 
90  finalize();
91 }
92 
94 }
95 
96 void Model_NWN2::setTint(const float tint[3][4]) {
97  for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s)
98  for (NodeList::iterator n = (*s)->nodeList.begin(); n != (*s)->nodeList.end(); ++n)
99  dynamic_cast<ModelNode_NWN2 &>(**n).setTint(tint);
100 }
101 
102 void Model_NWN2::setTintFloor(const float tint[3][4]) {
103  // Tileset model floor node names are of the form TL_XX_YYYY_##_F
104 
105  for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s)
106  for (NodeList::iterator n = (*s)->nodeList.begin(); n != (*s)->nodeList.end(); ++n)
107  if ((*n)->getName().beginsWith("TL_"))
108  if ((*n)->getName().endsWith("_F"))
109  dynamic_cast<ModelNode_NWN2 &>(**n).setTint(tint);
110 }
111 
112 void Model_NWN2::setTintWalls(const float tint[3][4]) {
113  // Tileset model wall node names are of the form TL_XX_YYYY_##.
114  // Exclude floors (TL_XX_YYYY_##_F), roof (TL_XX_YYYY_##_R),
115  // walk meshes (TL_XX_YYYY_##_W) and collision meshes (TL_XX_YYYY_##_C3)
116 
117  for (StateList::iterator s = _stateList.begin(); s != _stateList.end(); ++s)
118  for (NodeList::iterator n = (*s)->nodeList.begin(); n != (*s)->nodeList.end(); ++n)
119  if ((*n)->getName().beginsWith("TL_"))
120  if (!(*n)->getName().endsWith("_F") && !(*n)->getName().endsWith("_R") &&
121  !(*n)->getName().endsWith("_W") && !(*n)->getName().endsWith("_C3"))
122  dynamic_cast<ModelNode_NWN2 &>(**n).setTint(tint);
123 }
124 
126  uint32 tag = ctx.mdb->readUint32BE();
127  if (tag != kMDBID)
128  throw Common::Exception("Not a NWN2 MDB file (%s)", Common::debugTag(tag).c_str());
129 
130  uint16 verMajor = ctx.mdb->readUint16LE();
131  uint16 verMinor = ctx.mdb->readUint16LE();
132 
133  uint32 packetCount = ctx.mdb->readUint32LE();
134 
135  std::vector<PacketKey> packetKeys;
136  packetKeys.resize(packetCount);
137  for (std::vector<PacketKey>::iterator packetKey = packetKeys.begin();
138  packetKey != packetKeys.end(); ++packetKey) {
139 
140  packetKey->signature = ctx.mdb->readUint32BE();
141  packetKey->offset = ctx.mdb->readUint32LE();
142  }
143 
144  newState(ctx);
145 
146  for (std::vector<PacketKey>::const_iterator packetKey = packetKeys.begin();
147  packetKey != packetKeys.end(); ++packetKey) {
148 
149  ctx.mdb->seek(packetKey->offset);
150 
151  ModelNode_NWN2 *newNode = new ModelNode_NWN2(*this);
152  bool success = false;
153 
154  if (packetKey->signature == kRigidID)
155  success = newNode->loadRigid(ctx);
156  else if (packetKey->signature == kSkinID)
157  success = newNode->loadSkin (ctx);
158 
159  if (success)
160  ctx.nodes.push_back(newNode);
161  else
162  delete newNode;
163  }
164 
165  addState(ctx);
166 }
167 
169  ctx.clear();
170 
171  ctx.state = new State;
172 }
173 
175  if (!ctx.state || ctx.nodes.empty()) {
176  ctx.clear();
177  return;
178  }
179 
180  for (std::list<ModelNode_NWN2 *>::iterator n = ctx.nodes.begin();
181  n != ctx.nodes.end(); ++n) {
182 
183  ctx.state->nodeList.push_back(*n);
184  ctx.state->nodeMap.insert(std::make_pair((*n)->getName(), *n));
185 
186  if (!(*n)->getParent())
187  ctx.state->rootNodes.push_back(*n);
188  }
189 
190  _stateList.push_back(ctx.state);
191  _stateMap.insert(std::make_pair(ctx.state->name, ctx.state));
192 
193  if (!_currentState)
194  _currentState = ctx.state;
195 
196  ctx.state = 0;
197 
198  ctx.nodes.clear();
199 }
200 
201 
202 ModelNode_NWN2::ModelNode_NWN2(Model &model) : ModelNode(model), _tintedMapIndex(-1) {
203 }
204 
206 }
207 
209  uint32 tag = ctx.mdb->readUint32BE();
210  if (tag != kRigidID)
211  throw Common::Exception("Invalid rigid packet signature (%s)", Common::debugTag(tag).c_str());
212 
213  uint32 packetSize = ctx.mdb->readUint32LE();
214 
216 
217  // Skipping lower level of detail models
218  if (_name.endsWith("_L01") || _name.endsWith("_L02"))
219  return false;
220 
225 
226  _mesh = new Mesh();
227 
228  _mesh->diffuse [0] = ctx.mdb->readIEEEFloatLE();
229  _mesh->diffuse [1] = ctx.mdb->readIEEEFloatLE();
230  _mesh->diffuse [2] = ctx.mdb->readIEEEFloatLE();
231  _mesh->specular[0] = ctx.mdb->readIEEEFloatLE();
232  _mesh->specular[1] = ctx.mdb->readIEEEFloatLE();
233  _mesh->specular[2] = ctx.mdb->readIEEEFloatLE();
234 
235  float specularPower = ctx.mdb->readIEEEFloatLE();
236  float specularValue = ctx.mdb->readIEEEFloatLE();
237  uint32 textureFlags = ctx.mdb->readUint32LE();
238 
239  uint32 vertexCount = ctx.mdb->readUint32LE();
240  uint32 facesCount = ctx.mdb->readUint32LE();
241 
242  if ((vertexCount == 0) || (facesCount == 0))
243  return false;
244 
245  _render = _mesh->render = true;
246  _mesh->data = new MeshData();
248 
249  std::vector<Common::UString> textures;
250  textures.push_back(diffuseMap);
251 
252  loadTextures(textures);
253 
254  // Read vertices (interleaved)
255 
256  VertexDecl vertexDecl;
257 
258  vertexDecl.push_back(VertexAttrib(VPOSITION, 3, GL_FLOAT));
259  vertexDecl.push_back(VertexAttrib(VNORMAL , 3, GL_FLOAT));
260  vertexDecl.push_back(VertexAttrib(VTCOORD , 3, GL_FLOAT));
261 
262  if (!_tintMap.empty())
263  vertexDecl.push_back(VertexAttrib(VTCOORD + 1, 3, GL_FLOAT));
264 
265  _mesh->data->rawMesh->getVertexBuffer()->setVertexDeclInterleave(vertexCount, vertexDecl);
266 
267  float *v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData());
268  for (uint32 i = 0; i < vertexCount; i++) {
269  // Position
270  *v++ = ctx.mdb->readIEEEFloatLE();
271  *v++ = ctx.mdb->readIEEEFloatLE();
272  *v++ = ctx.mdb->readIEEEFloatLE();
273 
274  // Normal
275  *v++ = ctx.mdb->readIEEEFloatLE();
276  *v++ = ctx.mdb->readIEEEFloatLE();
277  *v++ = ctx.mdb->readIEEEFloatLE();
278 
279  ctx.mdb->skip(3 * 4); // Tangent
280  ctx.mdb->skip(3 * 4); // Binormal
281 
282  // Texture Coords
283  *v++ = ctx.mdb->readIEEEFloatLE();
284  *v++ = ctx.mdb->readIEEEFloatLE();
285  *v++ = ctx.mdb->readIEEEFloatLE();
286 
287  // TintMap TexCoords
288  if (!_tintMap.empty()) {
289  v[0] = v[-3];
290  v[1] = v[-2];
291  v[2] = v[-1];
292  v += 3;
293  }
294  }
295 
296 
297  // Read faces
298 
299  _mesh->data->rawMesh->getIndexBuffer()->setSize(facesCount * 3, sizeof(uint16), GL_UNSIGNED_SHORT);
300 
301  uint16 *f = reinterpret_cast<uint16 *>(_mesh->data->rawMesh->getIndexBuffer()->getData());
302  for (uint32 i = 0; i < facesCount * 3; i++)
303  f[i] = ctx.mdb->readUint16LE();
304 
305  Common::UString meshName = ctx.mdlName;
306  meshName += ".";
307  if (ctx.state->name.size() != 0) {
308  meshName += ctx.state->name;
309  } else {
310  meshName += "xoreos.default";
311  }
312  meshName += ".";
313  meshName += _name;
314 
315  Graphics::Mesh::Mesh *checkMesh = MeshMan.getMesh(meshName);
316  if (checkMesh) {
317  warning("Warning: probable mesh duplication of: %s, attempting to correct", meshName.c_str());
318  delete _mesh->data->rawMesh;
319  _mesh->data->rawMesh = checkMesh;
320  } else {
321  _mesh->data->rawMesh->setName(meshName);
322  _mesh->data->rawMesh->init();
323  MeshMan.addMesh(_mesh->data->rawMesh);
324  }
325 
326  createBound();
327 
328  return true;
329 }
330 
332  uint32 tag = ctx.mdb->readUint32BE();
333  if (tag != kSkinID)
334  throw Common::Exception("Invalid skin packet signature (%s)", Common::debugTag(tag).c_str());
335 
336  uint32 packetSize = ctx.mdb->readUint32LE();
337 
339 
340  // Skipping lower level of detail models
341  if (_name.endsWith("_L01") || _name.endsWith("_L02"))
342  return false;
343 
345 
350 
351  _mesh = new Mesh();
352 
353  _mesh->diffuse [0] = ctx.mdb->readIEEEFloatLE();
354  _mesh->diffuse [1] = ctx.mdb->readIEEEFloatLE();
355  _mesh->diffuse [2] = ctx.mdb->readIEEEFloatLE();
356  _mesh->specular[0] = ctx.mdb->readIEEEFloatLE();
357  _mesh->specular[1] = ctx.mdb->readIEEEFloatLE();
358  _mesh->specular[2] = ctx.mdb->readIEEEFloatLE();
359 
360  float specularPower = ctx.mdb->readIEEEFloatLE();
361  float specularValue = ctx.mdb->readIEEEFloatLE();
362  uint32 textureFlags = ctx.mdb->readUint32LE();
363 
364  uint32 vertexCount = ctx.mdb->readUint32LE();
365  uint32 facesCount = ctx.mdb->readUint32LE();
366 
367  if ((vertexCount == 0) || (facesCount == 0))
368  return false;
369 
370  _render = _mesh->render = true;
371  _mesh->data = new MeshData();
373 
374  std::vector<Common::UString> textures;
375  textures.push_back(diffuseMap);
376 
377  loadTextures(textures);
378 
379  // Read vertices (interleaved)
380 
381  VertexDecl vertexDecl;
382 
383  vertexDecl.push_back(VertexAttrib(VPOSITION, 3, GL_FLOAT));
384  vertexDecl.push_back(VertexAttrib(VNORMAL , 3, GL_FLOAT));
385  vertexDecl.push_back(VertexAttrib(VTCOORD , 3, GL_FLOAT));
386 
387  if (!_tintMap.empty())
388  vertexDecl.push_back(VertexAttrib(VTCOORD + 1, 3, GL_FLOAT));
389 
390  _mesh->data->rawMesh->getVertexBuffer()->setVertexDeclInterleave(vertexCount, vertexDecl);
391 
392  float *v = reinterpret_cast<float *>(_mesh->data->rawMesh->getVertexBuffer()->getData());
393  for (uint32 i = 0; i < vertexCount; i++) {
394  // Position
395  *v++ = ctx.mdb->readIEEEFloatLE();
396  *v++ = ctx.mdb->readIEEEFloatLE();
397  *v++ = ctx.mdb->readIEEEFloatLE();
398 
399  // Normal
400  *v++ = ctx.mdb->readIEEEFloatLE();
401  *v++ = ctx.mdb->readIEEEFloatLE();
402  *v++ = ctx.mdb->readIEEEFloatLE();
403 
404  ctx.mdb->skip(4 * 4); // Bone weights
405  ctx.mdb->skip(4 * 1); // Bone indices
406  ctx.mdb->skip(3 * 4); // Tangent
407  ctx.mdb->skip(3 * 4); // Binormal
408 
409  // TexCoords
410  *v++ = ctx.mdb->readIEEEFloatLE();
411  *v++ = ctx.mdb->readIEEEFloatLE();
412  *v++ = ctx.mdb->readIEEEFloatLE();
413 
414  // TintMap TexCoords
415  if (!_tintMap.empty()) {
416  v[0] = v[-3];
417  v[1] = v[-2];
418  v[2] = v[-1];
419  v += 3;
420  }
421 
422  ctx.mdb->skip(4); // Bone count
423  }
424 
425 
426  // Read faces
427  _mesh->data->rawMesh->getIndexBuffer()->setSize(facesCount * 3, sizeof(uint16), GL_UNSIGNED_SHORT);
428 
429  uint16 *f = reinterpret_cast<uint16 *>(_mesh->data->rawMesh->getIndexBuffer()->getData());
430  for (uint32 i = 0; i < facesCount * 3; i++)
431  f[i] = ctx.mdb->readUint16LE();
432 
433  createBound();
434 
435  Common::UString meshName = ctx.mdlName;
436  meshName += ".";
437  if (ctx.state->name.size() != 0) {
438  meshName += ctx.state->name;
439  } else {
440  meshName += "xoreos.default";
441  }
442  meshName += ".";
443  meshName += _name;
444 
445  Graphics::Mesh::Mesh *checkMesh = MeshMan.getMesh(meshName);
446  if (checkMesh) {
447  warning("Warning: probable mesh duplication of: %s, attempting to correct", meshName.c_str());
448  delete _mesh->data->rawMesh;
449  _mesh->data->rawMesh = checkMesh;
450  } else {
451  _mesh->data->rawMesh->setName(meshName);
452  _mesh->data->rawMesh->init();
453  MeshMan.addMesh(_mesh->data->rawMesh);
454  }
455 
456  return true;
457 }
458 
459 void ModelNode_NWN2::setTint(const float tint[3][4]) {
460  if (!_mesh || !_mesh->data)
461  return;
462 
464 
465  memcpy(_tint, tint, 3 * 4 * sizeof(float));
466 
467  removeTint();
468  createTint();
469 
471 }
472 
474  if (_tintedMapIndex < 0)
475  return;
476 
477  _mesh->data->textures.erase(_mesh->data->textures.begin() + _tintedMapIndex);
478 
479  _tintedMapIndex = -1;
480 }
481 
482 /* Create a tinted texture by combining the tint map with the tint colors.
483  *
484  * This is currently all done here in software and has several drawbacks:
485  * - Slow
486  * - We're creating lots of uncompressed RBGA texture, so it
487  * takes up a lot of memory, both on the GPU and in system RAM
488  *
489  * TODO: We really need to do this in shaders in the future.
490  */
492  if (_tintMap.empty())
493  return;
494 
495  ImageDecoder *tintMap = 0;
496  Surface *tintedMap = 0;
497  try {
498  // Load and uncompress the texture
499  tintMap = Texture::loadImage(_tintMap);
500  if (tintMap->isCompressed())
501  tintMap->decompress();
502 
503  const ImageDecoder::MipMap &tintImg = tintMap->getMipMap(0);
504 
505  // Create a new target surface with the same dimensions
506  tintedMap = new Surface(tintImg.width, tintImg.height);
507  ImageDecoder::MipMap &tintedImg = tintedMap->getMipMap();
508 
509  // Iterate over all pixels: read values, mix tints, write pixel to target surface
510  for (int n = 0; n < tintImg.width * tintImg.height; n++) {
511  float srcColor[4], dstColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
512  tintImg.getPixel(n, srcColor[0], srcColor[1], srcColor[2], srcColor[3]);
513 
514  if (srcColor[3] != 0.0f) {
515  // Mix using the value and the alpha components as intensities
516  // TODO: Verify how the mixing is actually done in NWN2!
517  for (int i = 0; i < 3; i++) {
518  for (int j = 0; j < 3; j++)
519  dstColor[j] += _tint[i][j] * srcColor[i] * _tint[i][3] * srcColor[3] * _mesh->diffuse[i];
520  }
521  } else
522  // Source alpha is 0.0f: No tinting for this pixel
523  for (int i = 0; i < 3; i++)
524  dstColor[i] = _mesh->diffuse[i] * _tint[i][3];
525 
526  tintedImg.setPixel(n, dstColor[0], dstColor[1], dstColor[2], dstColor[3]);
527  }
528 
529  } catch (...) {
530  delete tintMap;
531  delete tintedMap;
532  return;
533  }
534 
535  delete tintMap;
536 
537  // And add the new texture to the TextureManager
538  TextureHandle tintedTexture = TextureMan.add(Texture::create(tintedMap));
539 
540  _mesh->data->textures.push_back(tintedTexture);
541  _tintedMapIndex = _mesh->data->textures.size() - 1;
542 }
543 
544 } // End of namespace Aurora
545 
546 } // 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
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like &#39;DATA&#39;, to ensure portability.
Definition: endianness.h:140
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
void getPixel(int x, int y, float &r, float &g, float &b, float &a) const
Get the color values of the pixel at this position.
Definition: decoder.cpp:64
A class holding an UTF-8 string.
Definition: ustring.h:48
#define TextureMan
Shortcut for accessing the texture manager.
Definition: textureman.h:127
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
void loadTextures(const std::vector< Common::UString > &textures)
Definition: modelnode.cpp:340
static Texture * create(const Common::UString &name, bool deswizzle=false)
Create a texture from this image resource.
Definition: texture.cpp:323
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
void setTintFloor(const float tint[3][4])
Tint all floor nodes of the model with these tint colors.
Definition: model_nwn2.cpp:102
Mathematical helpers.
NodeList rootNodes
The nodes in the state without a parent.
Definition: model.h:209
void setVertexDeclInterleave(uint32 vertCount, VertexDecl &decl)
Set the interleaved vertex declaration for this buffer.
State * _currentState
The current state.
Definition: model.h:227
bool endsWith(const UString &with) const
Definition: ustring.cpp:315
bool _render
Render the node?
Definition: modelnode.h:235
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
Utility templates and functions for working with strings and streams.
int height
The mip map&#39;s height.
Definition: decoder.h:53
void decompress()
Manually decompress the texture image data.
Definition: decoder.cpp:242
Vertex normal.
Definition: vertexbuffer.h:37
Model_NWN2(const Common::UString &name, ModelType type=kModelTypeObject)
Definition: model_nwn2.cpp:83
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
Definition: ustring.cpp:249
ModelType
The display type of a model.
Definition: types.h:51
uint16_t uint16
Definition: types.h:202
static ImageDecoder * loadImage(const Common::UString &name, bool deswizzle=false)
Load an image in any of the common texture formats.
Definition: texture.cpp:401
void newState(ParserContext &ctx)
Definition: model_nwn2.cpp:168
void setPixel(int x, int y, float r, float g, float b, float a)
Set the color values of the pixel at this position.
Definition: decoder.cpp:97
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
const MipMap & getMipMap(size_t mipMap, size_t layer=0) const
Return a mip map.
Definition: decoder.cpp:204
Utility functions for working with differing string encodings.
bool loadSkin(Model_NWN2::ParserContext &ctx)
Definition: model_nwn2.cpp:331
bool empty() const
Is the string empty?
Definition: ustring.cpp:245
Geometry, BioWare model.
Definition: types.h:136
float specular[3]
Specular color.
Definition: modelnode.h:175
StackException Exception
Definition: error.h:59
NodeList nodeList
The nodes within the state.
Definition: model.h:206
void setTintWalls(const float tint[3][4])
Tint all wall nodes of the model with these tint colors.
Definition: model_nwn2.cpp:112
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.
static IGNORE_UNUSED_VARIABLES const uint32 kMDBID
Definition: model_nwn2.cpp:51
void setTint(const float tint[3][4])
Definition: model_nwn2.cpp:459
bool loadRigid(Model_NWN2::ParserContext &ctx)
Definition: model_nwn2.cpp:208
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
const MipMap & getMipMap(size_t mipMap) const
Return a mip map.
Definition: surface.cpp:85
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
void setTint(const float tint[3][4])
Tint the whole model with these tint colors.
Definition: model_nwn2.cpp:96
#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
int width
The mip map&#39;s width.
Definition: decoder.h:52
An image surface, in BGRA format.
Graphics::Mesh::Mesh * rawMesh
Node raw mesh data.
Definition: modelnode.h:159
Common::UString _name
The node&#39;s name.
Definition: modelnode.h:216
std::list< ModelNode_NWN2 * > nodes
Definition: model_nwn2.h:68
ParserContext(const Common::UString &name)
Definition: model_nwn2.cpp:60
A texture as used in the Aurora engines.
uint32_t uint32
Definition: types.h:204
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
Definition: strutil.cpp:117
GLvoid * getData()
Access buffer data.
float diffuse[3]
Diffuse color.
Definition: modelnode.h:174
Common::SeekableReadStream * mdb
Definition: model_nwn2.h:62
A generic interface for image decoders.
Definition: decoder.h:48
void finalize()
Finalize the loading procedure.
Definition: model.cpp:807
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 setName(const Common::UString &name)
Definition: mesh.cpp:47
Loading MDB files found in Neverwinter Nights 2.
void load(ParserContext &ctx)
Definition: model_nwn2.cpp:125
A handle to a texture.
Definition: texturehandle.h:51
StateList _stateList
All states within this model.
Definition: model.h:225
static const uint32 kRigidID
Definition: model_nwn2.cpp:53
Generic vertex attribute data.
Definition: vertexbuffer.h:43
IndexBuffer * getIndexBuffer()
Definition: mesh.cpp:43
bool isCompressed() const
Is the image data compressed?
Definition: decoder.cpp:168
void setSize(uint32 indexCount, uint32 indexSize, GLenum indexType)
Change buffer size.
Definition: indexbuffer.cpp:65
The global resource manager for Aurora resources.
void addState(ParserContext &ctx)
Definition: model_nwn2.cpp:174
static const uint32 kSkinID
Definition: model_nwn2.cpp:54