33 #include <boost/unordered_set.hpp> 35 #include "glm/glm.hpp" 128 mdl(0), state(0), texture(t) {
155 for (std::list<ModelNode *>::iterator n = nodes.begin(); n != nodes.end(); ++n)
168 if (name.
empty() || (name ==
"NULL"))
171 for (std::list<ModelNode *>::const_iterator n = nodes.begin();
172 n != nodes.end(); ++n) {
174 if ((*n)->getName() == name) {
244 uint32 animOffset, animCount;
249 float boundingMin[3], boundingMax[3];
268 ctx.
nodes.push_back(rootNode);
275 std::vector<uint32> animOffsets;
278 for (std::vector<uint32>::const_iterator offset = animOffsets.begin(); offset != animOffsets.end(); ++offset) {
293 std::vector<Common::UString> line;
300 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
305 if (line[0] ==
"newmodel") {
307 warning(
"Model_NWN_ASCII::load(): More than one model definition");
314 }
else if (line[0] ==
"setsupermodel") {
315 if (line[1] !=
_name)
316 warning(
"Model_NWN_ASCII::load(): setsupermodel: \"%s\" != \"%s\"",
319 if (!line[2].empty() && (line[2] !=
"NULL"))
322 }
else if (line[0] ==
"beginmodelgeom") {
323 if (line[1] !=
_name)
324 warning(
"Model_NWN_ASCII::load(): beginmodelgeom: \"%s\" != \"%s\"",
326 }
else if (line[0] ==
"setanimationscale") {
328 }
else if (line[0] ==
"node") {
331 ctx.
nodes.push_back(newNode);
333 newNode->
load(ctx, line[1], line[2]);
335 }
else if (line[0] ==
"newanim") {
338 }
else if (line[0] ==
"donemodel") {
347 for (std::vector<uint32>::iterator a = ctx.
anims.begin(); a != ctx.
anims.end(); ++a) {
364 std::vector<Common::UString> line;
371 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
376 if (line[0] ==
"doneanim") {
402 for (std::list<ModelNode *>::iterator n = ctx.
nodes.begin();
403 n != ctx.
nodes.end(); ++n) {
406 ctx.
state->
nodeMap.insert(std::make_pair((*n)->getName(), *n));
408 if (!(*n)->getParent())
444 uint32 eventOffset, eventCount;
450 for (
uint32 i = 0; i < eventCount; i++) {
457 ctx.
nodes.push_back(rootNode);
472 for (std::list<ModelNode *>::iterator n = ctx.
nodes.begin();
473 n != ctx.
nodes.end(); ++n) {
482 bool foundInCache =
false;
486 if (super != modelCache->end()) {
496 if (modelCache && !foundInCache)
536 size_t pos = ctx.
mdl->
pos();
561 uint32 childrenOffset, childrenCount;
564 std::vector<uint32> children;
567 uint32 controllerKeyOffset, controllerKeyCount;
570 uint32 controllerDataOffset, controllerDataCount;
573 std::vector<float> controllerData;
575 controllerDataCount, controllerData);
579 if ((flags & 0xFFFFFC00) != 0)
621 controllerKeyCount, controllerData);
637 for (std::vector<uint32>::const_iterator child = children.begin(); child != children.end(); ++child) {
644 ctx.
nodes.push_back(childNode);
650 childNode->
load(ctx);
660 for (std::list<ModelNode *>::iterator n = ctx.
nodes.begin(); n != ctx.
nodes.end(); ++n) {
661 if ((*n)->getName().equalsIgnoreCase(name)) {
673 warning(
"Duplicate node \"%s\" in state \"%s\" in model \"%s\"",
676 for (std::list<ModelNode *>::const_iterator c = oldChildNode->
getChildren().begin();
679 (*c)->setParent(newNode);
685 ctx.
nodes.remove(oldChildNode);
698 return fabs(a[0] - b[0]) < 1E-4 &&
699 fabs(a[1] - b[1]) < 1E-4 &&
700 fabs(a[2] - b[2]) < 1E-4;
706 uint32 facesOffset, facesCount;
711 float boundingMin[3], boundingMax[3];
723 float pointsAverage[3];
751 std::vector<Common::UString> textures;
775 uint32 textureVertexOffset[4];
784 uint32 textureAnimOffset[6];
785 for (
uint32 i = 0; i < 6; i++)
798 if ((vertexCount == 0) || (facesCount == 0) || (facesOffset == 0))
801 if (textureCount > 4) {
802 warning(
"ModelNode_NWN_Binary::readMesh(): textureCount > 4 (%d)", textureCount);
813 textures.resize(textureCount);
816 size_t endPos = ctx.
mdl->
pos();
821 std::vector<float> vertices;
822 vertices.resize(vertexCount * 3);
824 assert (vertexOffset != 0xFFFFFFFF);
826 for (std::vector<float>::iterator v = vertices.begin(); v != vertices.end(); ++v)
831 std::vector<Face> faces;
832 faces.resize(facesCount);
834 std::vector< std::list<Face *> > vFaces;
835 vFaces.resize(vertexCount);
837 assert (facesOffset != 0xFFFFFFFF);
839 for (std::vector<Face>::iterator f = faces.begin(); f != faces.end(); ++f) {
855 for (
int i = 0; i < 3; i++) {
856 assert((
size_t)(f->index[i] * 3) < vertices.size());
858 const float *fV = &vertices[f->index[i] * 3];
860 for (
uint32 j = 0; j < vertices.size() / 3; j++)
862 vFaces[j].push_back(&*f);
868 std::vector<float> texCoords;
869 texCoords.resize(textureCount * vertexCount * 2);
871 for (
uint16 t = 0; t < textureCount; t++) {
872 const bool hasTexture = textureVertexOffset[t] != 0xFFFFFFFF;
876 float *v = &texCoords[t * vertexCount * 2];
877 for (
uint32 i = 0; i < vertexCount; i++) {
889 for (
uint t = 0; t < textureCount; t++)
895 for (
uint32 i = 0; i < facesCount; i++) {
896 const Face &face = faces[i];
898 for (
uint32 j = 0; j < 3; j++) {
900 assert((
size_t)(index * 3) < vertices.size());
903 *v++ = vertices[index * 3 + 0];
904 *v++ = vertices[index * 3 + 1];
905 *v++ = vertices[index * 3 + 2];
908 glm::vec3 normal(0.0f, 0.0f, 0.0f);
911 for (std::list<Face *>::const_iterator vF = vFaces[index].begin(); vF != vFaces[index].end(); ++vF) {
912 if (face.
smooth != (*vF)->smooth)
915 normal += glm::vec3((*vF)->normal[0], (*vF)->normal[1], (*vF)->normal[2]);
921 normal = glm::normalize(normal);
929 for (
uint32 t = 0; t < textureCount; t++) {
930 *v++ = texCoords[t * vertexCount * 2 + index * 2 + 0];
931 *v++ = texCoords[t * vertexCount * 2 + index * 2 + 1];
941 for (
uint16 i = 0; i < facesCount * 3; i++)
953 meshName +=
"xoreos.default";
968 if (
GfxMan.isRendererExperimental())
992 uint32 offset,
uint32 count, std::vector<float> &data) {
998 for (
uint32 i = 0; i < count; i++) {
1006 if (rowCount == 0xFFFF)
1011 if (columnCount != 3)
1013 for (
int r = 0; r < rowCount; r++) {
1015 p.
time = data[timeIndex + r];
1016 p.
x = data[dataIndex + (r * columnCount) + 0];
1017 p.
y = data[dataIndex + (r * columnCount) + 1];
1018 p.
z = data[dataIndex + (r * columnCount) + 2];
1022 if (p.
time == 0.0f) {
1034 if (columnCount != 4)
1037 for (
int r = 0; r < rowCount; r++) {
1039 q.
time = data[timeIndex + r];
1040 q.
x = data[dataIndex + (r * columnCount) + 0];
1041 q.
y = data[dataIndex + (r * columnCount) + 1];
1042 q.
z = data[dataIndex + (r * columnCount) + 2];
1043 q.
q = data[dataIndex + (r * columnCount) + 3];
1047 if (data[timeIndex + 0] == 0.0f) {
1062 if (columnCount != 1)
1066 if (data[timeIndex + 0] == 0.0f)
1067 if (data[dataIndex + 0] == 0.0f)
1092 bool skipNode =
false;
1099 if ((type ==
"trimesh") || (type ==
"danglymesh") || (type ==
"skin")) {
1101 _mesh->hasTransparencyHint =
true;
1102 _mesh->render =
true;
1103 if (type ==
"danglymesh")
1107 if ((type ==
"emitter") || (type ==
"reference") || (type ==
"aabb")) {
1114 while (!ctx.
mdl->
eos()) {
1115 std::vector<Common::UString> line;
1122 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
1125 line[0].makeLower();
1127 if (line[0] ==
"endnode") {
1130 }
else if (skipNode) {
1132 }
else if (line[0] ==
"parent") {
1135 if (!ctx.
findNode(line[1], parent))
1136 warning(
"ModelNode_NWN_ASCII::load(): Non-existent parent node \"%s\"",
1141 }
else if (line[0] ==
"position") {
1143 }
else if (line[0] ==
"orientation") {
1147 }
else if (line[0] ==
"render") {
1149 }
else if (line[0] ==
"transparencyhint") {
1151 }
else if (line[0] ==
"danglymesh") {
1152 }
else if (line[0] ==
"constraints") {
1157 }
else if (line[0] ==
"weights") {
1162 }
else if (line[0] ==
"bitmap") {
1164 }
else if (line[0] ==
"verts") {
1168 }
else if (line[0] ==
"tverts") {
1170 warning(
"ModelNode_NWN_ASCII::load(): Multiple texture coordinates!");
1175 }
else if (line[0] ==
"faces") {
1197 meshName +=
"xoreos.default";
1210 if (!
_mesh->data->rawMesh) {
1214 _mesh->data->rawMesh->setName(meshName);
1215 _mesh->data->rawMesh->init();
1216 if (
MeshMan.getMesh(meshName)) {
1217 warning(
"Warning: probable mesh duplication of: %s", meshName.
c_str());
1221 if (
GfxMan.isRendererExperimental())
1226 for (
uint32 i = 0; i < n; ) {
1227 std::vector<Common::UString> line;
1234 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
1242 for (
uint32 i = 0; i < n; ) {
1243 std::vector<Common::UString> line;
1250 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
1260 if (strings.size() < (start + n))
1263 for (
uint32 i = 0; i < n; i++)
1273 std::vector<Common::UString> line;
1280 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
1296 std::vector<Common::UString> line;
1303 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
1326 std::vector<Common::UString> line;
1333 if ((count == 0) || line[0].empty() || (*line[0].begin() ==
'#'))
1365 std::size_t seed = 0;
1366 boost::hash_combine(seed, b.
p);
1367 boost::hash_combine(seed, b.
t);
1368 boost::hash_combine(seed,
uint32(b.
n[0] * 1E4));
1369 boost::hash_combine(seed,
uint32(b.
n[1] * 1E4));
1370 boost::hash_combine(seed,
uint32(b.
n[2] * 1E4));
1384 const size_t textureCount = mesh.
textures.size();
1385 if (textureCount > 1)
1386 warning(
"ModelNode_NWN_ASCII::processMesh(): textureCount == %u", (
uint)textureCount);
1392 _mesh->data->rawMesh->getIndexBuffer()->setSize(facesCount * 3,
sizeof(
uint32), GL_UNSIGNED_INT);
1394 boost::unordered_set<FaceVert> verts;
1395 typedef boost::unordered_set<FaceVert>::iterator verts_set_it;
1398 uint32 *f =
reinterpret_cast<uint32 *
>(
_mesh->data->rawMesh->getIndexBuffer()->getData());
1399 for (
uint32 i = 0; i < facesCount; i++) {
1404 const Vec3 p1(mesh.
vX[v[0]], mesh.
vY[v[0]], mesh.
vZ[v[0]]);
1405 const Vec3 p2(mesh.
vX[v[1]], mesh.
vY[v[1]], mesh.
vZ[v[1]]);
1406 const Vec3 p3(mesh.
vX[v[2]], mesh.
vY[v[2]], mesh.
vZ[v[2]]);
1407 const Vec3 n = glm::normalize(glm::cross(p2 - p1, p3 - p2));
1409 for (
uint32 j = 0; j < 3; j++) {
1416 std::pair<verts_set_it, bool> it = verts.insert(fv);
1431 for (
uint t = 0; t < textureCount; t++)
1434 _mesh->data->rawMesh->getVertexBuffer()->setVertexDeclInterleave(vertexCount, vertexDecl);
1436 for (verts_set_it i = verts.begin(); i != verts.end(); ++i) {
1437 byte *vData =
reinterpret_cast<byte *
>(
_mesh->data->rawMesh->getVertexBuffer()->getData()) + i->i *
_mesh->data->rawMesh->getVertexBuffer()->getSize();
1438 float *v =
reinterpret_cast<float *
>(vData);
1441 *v++ = mesh.
vX[i->p];
1442 *v++ = mesh.
vY[i->p];
1443 *v++ = mesh.
vZ[i->p];
1451 if (i->t < mesh.
tCount) {
1452 *v++ = mesh.
tX[i->t];
1453 *v++ = mesh.
tY[i->t];
1458 for (
uint16 t = 1; t < textureCount; t++) {
static const uint16 kControllerTypeSelfIllumColor
Model_NWN(const Common::UString &name, ModelType type=kModelTypeObject, const Common::UString &texture="", ModelCache *modelCache=0)
#define ResMan
Shortcut for accessing the sound manager.
GLvoid * getData()
Access buffer data.
bool operator==(const FaceVert &a, const FaceVert &b)
A node within an animation.
static const uint16 kControllerTypeColorMid
static const uint16 kControllerTypeSizeEnd_Y
void loadSuperModel(ModelCache *modelCache)
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
NodeMap nodeMap
The nodes within the state, indexed by name.
std::vector< uint32 > vIB
void loadBinary(ParserContext &ctx)
std::vector< uint32 > vIC
std::vector< uint32 > smooth
Vertex texture coordinates, VTCOORDi = VTCOORD + i.
uint32 readUint32LE()
Read an unsigned 32-bit word stored in little endian (LSB first) order from the stream and return it...
static const int kNodeFlagHasDangly
An element of the front GUI.
void debugC(Common::DebugChannel channel, uint32 level, const char *s,...)
static const uint16 kControllerTypeLifeExp
friend class ModelNode_NWN_Binary
A class holding an UTF-8 string.
static const uint16 kControllerTypeP2P_Bezier3
static const uint16 kControllerTypeVelocity
void setLength(float length)
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
void readFaces(Model_NWN::ParserContext &ctx, Mesh &mesh)
An animation to be applied to a model.
VertexBuffer * getVertexBuffer()
Utility functions for debug output.
static const uint16 kControllerTypeDrag
std::vector< Common::UString > textures
static const uint16 kControllerTypeThreshold
static const int kNodeFlagHasSkin
void loadTextures(const std::vector< Common::UString > &textures)
virtual bool eos() const =0
Returns true if a read failed because the stream has been reached.
void init()
General mesh initialisation, queuing the mesh for GL resource creation.
static const uint16 kControllerTypeRadius
static const uint16 kControllerTypeDetonate
std::list< ModelNode * > & getChildren()
Get the node's children.
bool render
Render this mesh?
Common::UString name
The state's name.
static const uint16 kControllerTypeLightningRadius
NodeList rootNodes
The nodes in the state without a parent.
static const uint16 kControllerTypeXSize
void readWeights(Model_NWN::ParserContext &ctx, uint32 n)
void setParent(ModelNode *parent)
Set the node's parent.
void setVertexDeclInterleave(uint32 vertCount, VertexDecl &decl)
Set the interleaved vertex declaration for this buffer.
State * _currentState
The current state.
void addChunkEnd(uint32 c)
Add a character marking the end of a chunk.
static const uint16 kControllerTypeSizeStart
#define ARRAYSIZE(x)
Macro which determines the number of entries in a fixed size array.
bool _render
Render the node?
void readConstraints(Model_NWN::ParserContext &ctx, uint32 n)
static const uint16 kControllerTypeSizeMid
const Common::UString & getName() const
Get the model's name.
void readAnimBinary(ParserContext &ctx, uint32 offset)
static const uint16 kControllerTypeBounce_Co
Common::UString _fileName
The model's file name.
static bool fuzzyEqual(const float *a, const float *b)
std::vector< VertexAttrib > VertexDecl
Vertex data layout.
static const int kNodeFlagHasMesh
#define IGNORE_UNUSED_VARIABLES
static const uint16 kControllerTypeAlphaEnd
static const uint16 kControllerTypeFrameEnd
Utility templates and functions for working with strings and streams.
static const uint16 kControllerTypeParticleRot
void processMesh(ModelNode_NWN_ASCII::Mesh &mesh)
static const int kNodeFlagHasAnim
void populateDefaultAnimations()
static const uint16 kControllerTypeColorEnd
Model * _model
The model this node belongs to.
void readNodeControllers(Model_NWN::ParserContext &ctx, uint32 offset, uint32 count, std::vector< float > &data)
static const int kNodeFlagHasAABB
std::vector< uint32 > tIC
void load(Model_NWN::ParserContext &ctx, const Common::UString &type, const Common::UString &name)
void readTCoords(Model_NWN::ParserContext &ctx, Mesh &mesh)
Common::UString _name
The model's name.
void addState(ParserContext &ctx)
Basic exceptions to throw.
const char * c_str() const
Return the (utf8 encoded) string data.
AnimationMap _animationMap
Map of all animations in this model.
ModelType
The display type of a model.
ModelType _type
The model's type.
static const uint16 kControllerTypeScale
static const uint16 kControllerTypeVerticalDisplacement
void setTransTime(float transtime)
static const uint16 kControllerTypeColor
void newState(ParserContext &ctx)
static const int kNodeFlagHasReference
static const uint16 kControllerTypeBlurLength
"GGraphics", global, non-engine graphics.
virtual void buildMaterial()
void readAnim(Model_NWN::ParserContext &ctx)
static const DefaultAnim kDefaultAnims[]
static void readArray(Common::SeekableReadStream &stream, uint32 offset, uint32 count, std::vector< T > &values)
std::vector< uint32 > vIA
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
void load(Model_NWN::ParserContext &ctx)
static const uint16 kControllerTypePosition
Loading MDL files found in Neverwinter Nights.
float ambient[3]
Ambient color.
Utility functions for working with differing string encodings.
The global shader material manager.
bool empty() const
Is the string empty?
The global shader surface manager.
static const uint16 kControllerTypeMass
float specular[3]
Specular color.
static const uint16 kControllerTypeColorStart
void checkDuplicateNode(Model_NWN::ParserContext &ctx, ModelNode_NWN_Binary *newNode)
std::size_t hash_value(const FaceVert &b)
std::vector< QuaternionKeyFrame > _orientationFrames
Keyframes for orientation animation.
static const uint16 kControllerTypePercentMid
static const uint16 kControllerTypeYSize
void addIgnore(uint32 c)
Add a character to ignore.
float _position[3]
Position of the node.
NodeList nodeList
The nodes within the state.
static Common::UString loadName(Model_NWN::ParserContext &ctx)
void warning(const char *s,...)
std::vector< uint32 > tIA
StateMap _stateMap
All states within this model, index by name.
std::list< ModelNode * > nodes
Basic reading stream interfaces.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
Common::StreamTokenizer * tokenize
ParserContext(const Common::UString &name, const Common::UString &t)
void readMesh(Model_NWN::ParserContext &ctx)
float _scale[3]
Model's scale.
static const uint16 kControllerTypeLightningDelay
static const uint16 kControllerTypeSizeMid_Y
void readVCoords(Model_NWN::ParserContext &ctx, Mesh &mesh)
bool findNode(const Common::UString &name, ModelNode *&node) const
void skipAnimASCII(ParserContext &ctx)
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
#define MeshMan
Shortcut for accessing the shader manager.
static const uint16 kControllerTypePercentEnd
Basic type definitions to handle files used in BioWare's Aurora engine.
Plain, unextended ASCII (7bit clean).
static const uint16 kControllerTypeMultiplier
static const uint16 kControllerTypeCombineTime
static const int kNodeFlagHasLight
size_t getTokens(SeekableReadStream &stream, std::vector< UString > &list, size_t min=0, size_t max=SIZE_MAX, const UString &def="")
Parse tokens out of the stream.
Graphics::Mesh::Mesh * rawMesh
Node raw mesh data.
void inheritPosition(ModelNode &node) const
Common::UString _name
The node's name.
std::vector< uint32 > anims
size_t size() const
Return the size of the string, in characters.
static const int kNodeFlagHasHeader
void loadASCII(ParserContext &ctx)
static const uint16 kControllerTypeRandVel
bool shadow
Does the node have a shadow?
static const uint16 kControllerTypeAlpha
static const uint16 kControllerTypeBirthRate
Parse tokens out of a stream.
static void readArrayDef(Common::SeekableReadStream &stream, uint32 &offset, uint32 &count)
GLvoid * getData()
Access buffer data.
void nextChunk(SeekableReadStream &stream)
Skip past end of chunk characters.
Ignore all repeated separators.
friend class ModelNode_NWN_ASCII
Low-level detection of architecture/system properties.
float diffuse[3]
Diffuse color.
void setName(Common::UString &name)
float _orientation[4]
Orientation of the node.
float _orientationBuffer[4]
Model * _superModel
The actual super model.
static const uint16 kControllerTypeGrav
static const uint16 kControllerTypeAlphaMid
void addAnimNode(AnimNode *node)
static const uint16 kControllerTypeSpread
static float rad2deg(float rad)
std::vector< uint32 > mat
void finalize()
Finalize the loading procedure.
void addDefaultAnimation(const Common::UString &anim, uint8 probability)
UString readStringFixed(SeekableReadStream &stream, Encoding encoding, size_t length)
Read length bytes as a string with the given encoding out of a stream.
void setName(const Common::UString &name)
Animation * getAnimation(const Common::UString &anim)
Get the animation from its name.
static const uint16 kControllerTypeOrientation
static const int kNodeFlagHasEmitter
std::vector< PositionKeyFrame > _positionFrames
Keyframes for position animation.
void addSeparator(uint32 c)
Add a character on where to split tokens.
void readFloats(const std::vector< Common::UString > &strings, float *floats, uint32 n, uint32 start)
ModelNode * getParent()
Get the node's parent.
static const uint16 kControllerTypeAlphaStart
std::vector< uint32 > tIB
ModelNode * getNode(const Common::UString &node)
Get the specified node, from the current state.
StateList _stateList
All states within this model.
static const uint16 kControllerTypePercentStart
float _animationScale
The scale of the animation.
void readAnimASCII(ParserContext &ctx)
Common::UString _superModelName
Name of the super model.
Generic vertex attribute data.
static const uint16 kControllerTypeFPS
static const uint16 kControllerTypeLightningScale
byte readByte()
Read an unsigned byte from the stream and return it.
IndexBuffer * getIndexBuffer()
static const uint16 kControllerTypeP2P_Bezier2
static const uint16 kControllerTypeFrameStart
void parseString(const UString &str, T &value, bool allowEmpty)
Parse a string into any POD integer, float/double or bool type.
#define GfxMan
Shortcut for accessing the graphics manager.
static const uint16 kControllerTypeSizeStart_Y
void setSize(uint32 indexCount, uint32 indexSize, GLenum indexType)
Change buffer size.
ModelNode_NWN_ASCII(Model &model)
ModelNode_NWN_Binary(Model &model)
The global resource manager for Aurora resources.
static const uint16 kControllerTypeShadowRadius
void inheritOrientation(ModelNode &node) const
Common::SeekableReadStream * mdl
static const uint16 kControllerTypeSizeEnd