89 using ::Aurora::GFF4File;
90 using ::Aurora::GFF4Struct;
99 static const GFF4Struct *
getChild(
const GFF4Struct &children,
size_t i) {
101 GFF4Struct::FieldType type = children.getFieldType(i, isList);
102 if ((type != GFF4Struct::kFieldTypeStruct) || isList)
105 return children.getStruct(i);
109 return strct && (strct->getLabel() == type);
113 return isType(&strct, type);
118 for (GFF4List::const_iterator c = chunks.begin(); c != chunks.end(); ++c) {
122 if ((*c)->getString(
kGFF4Name).equalsIgnoreCase(name))
132 mmh(0), msh(0), mmhTop(0), mshTop(0), state(0) {
142 e.
add(
"Failed to load model \"%s\"", name.
c_str());
156 mmhTop = &mmh->getTopLevel();
165 if (!mshFile.empty()) {
171 mshTop = &msh->getTopLevel();
184 for (std::list<ModelNode_DragonAge *>::iterator n = nodes.begin(); n != nodes.end(); ++n)
224 for (
size_t i = 0; i < rootNodes->getFieldCount(); i++) {
225 const GFF4Struct *nodeGFF =
getChild(*rootNodes, i);
230 ctx.
nodes.push_back(rootNode);
232 rootNode->
load(ctx, *nodeGFF);
250 for (std::list<ModelNode_DragonAge *>::iterator n = ctx.
nodes.begin(); n != ctx.
nodes.end(); ++n) {
252 ctx.
state->
nodeMap.insert(std::make_pair((*n)->getName(), *n));
254 if (!(*n)->getParent())
374 *f++ = (
uint16) ((data >> 22) & 0x3FFF);
375 *f++ = (
uint16) ((data >> 12) & 0x3FFF);
376 *f++ = (
uint16) ((data >> 2) & 0x3FFF);
384 *f++ = (
uint16) ((data >> 22) & 0x3FFF) / 511.0f;
385 *f++ = (
uint16) ((data >> 12) & 0x3FFF) / 511.0f;
386 *f++ = (
uint16) ((data >> 2) & 0x3FFF) / 511.0f;
463 *f++ = (
uint16) ((data >> 22) & 0x3FFF);
464 *f++ = (
uint16) ((data >> 12) & 0x3FFF);
465 *f++ = (
uint16) ((data >> 2) & 0x3FFF);
466 *f++ = (
uint16) ( data & 0x0002);
474 *f++ = (
uint16) ((data >> 22) & 0x3FFF) / 511.0f;
475 *f++ = (
uint16) ((data >> 12) & 0x3FFF) / 511.0f;
476 *f++ = (
uint16) ((data >> 2) & 0x3FFF) / 511.0f;
477 *f++ = (
uint16) ( data & 0x0002) / 4.0f;
506 if (ctx.
state->name.size() != 0) {
507 meshName += ctx.
state->name;
509 meshName +=
"xoreos.default";
516 if (
MeshMan.getMesh(meshName)) {
517 warning(
"Warning: probable mesh duplication of: %s", meshName.
c_str());
528 if (
GfxMan.isRendererExperimental())
537 for (
size_t i = 0; i < children->getFieldCount(); i++) {
538 const GFF4Struct *childGFF =
getChild(*children, i);
543 double x = 0.0, y = 0.0, z = 0.0, w = 1.0;
553 double x = 0.0, y = 0.0, z = 0.0, w = 1.0;
569 for (
size_t i = 0; i < children->getFieldCount(); i++) {
570 const GFF4Struct *childGFF =
getChild(*children, i);
575 ctx.
nodes.push_back(childNode);
579 childNode->
load(ctx, *childGFF);
585 if (primitiveType != 0)
589 if (indexFormat != 0)
593 if (baseVertexIndex != 0)
604 for (GFF4List::const_iterator d = chunkDecl.begin(); d != chunkDecl.end(); ++d) {
611 if (streamIndex == -1)
616 if (streamIndex != 0)
620 if (streamIndex != 0)
648 indexData.
skip(startIndex * 2);
651 while (indexCount-- > 0)
658 const size_t vertexPos = vertexData.
pos();
665 size_t textureCount = 0;
666 for (MeshDeclarations::const_iterator d = meshDecl.begin(); d != meshDecl.end(); ++d) {
692 for (
uint32 v = 0; v < vertexCount; v++) {
694 for (MeshDeclarations::const_iterator d = meshDecl.begin(); d != meshDecl.end(); ++d) {
695 vertexData.
seek(vertexPos + vertexOffset + v * vertexSize + d->offset);
720 e.
add(
"While reading mesh declaration with usage %u", d->use);
730 GFF4File mao(maoStream,
kMAOID);
732 const GFF4Struct &maoTop = mao.getTopLevel();
741 for (GFF4List::const_iterator f = floats.begin(); f != floats.end(); ++f) {
752 for (GFF4List::const_iterator v = vectors.begin(); v != vectors.end(); ++v) {
756 double v1 = 0.0, v2 = 0.0, v3 = 0.0, v4 = 1.0;
766 for (GFF4List::const_iterator t = textures.begin(); t != textures.end(); ++t) {
780 XMLParser mao(*maoStream,
true, fileName);
783 if (maoRoot.
getName() !=
"materialobject")
787 for (XMLNode::Children::const_iterator n = maoNodes.begin(); n != maoNodes.end(); ++n) {
788 if ((*n)->getName() ==
"material") {
790 material.
material = (*n)->getProperty(
"name");
792 }
else if ((*n)->getName() ==
"defaultsemantic") {
796 }
else if ((*n)->getName() ==
"float") {
799 std::sscanf((*n)->getProperty(
"value").c_str(),
"%f", &value);
801 material.
floats[(*n)->getProperty(
"name")] = value;
803 }
else if ((*n)->getName() ==
"vector4f") {
805 float v1 = 0.0f, v2 = 0.0f, v3 = 0.0f, v4 = 0.0f;
806 std::sscanf((*n)->getProperty(
"value").c_str(),
"%f %f %f %f", &v1, &v2, &v3, &v4);
808 material.
vectors[(*n)->getProperty(
"name")] = glm::vec4(v1, v2, v3, v4);
810 }
else if ((*n)->getName() ==
"texture") {
812 material.
textures[(*n)->getProperty(
"name")] = (*n)->getProperty(
"resname");
846 e.
add(
"Failed to load MAO \"%s\"", materialName.
c_str());
871 std::vector<TextureHandle> handles;
873 for (std::vector<Common::UString>::const_iterator t = textures.begin(); t != textures.end(); ++t) {
874 if (t->empty() || (*t ==
"NULL") ||
TextureMan.hasTexture(*t))
888 if ((mipMap.
size % 4) != 0)
891 for (
size_t p = 0; p < mipMap.
size; p += 4) {
892 mipMap.
data[p + 3] = 0xFF;
911 std::vector<TextureHandle> handles;
913 for (std::vector<Common::UString>::const_iterator t = textures.begin(); t != textures.end(); ++t) {
914 if (t->empty() || (*t ==
"NULL") ||
TextureMan.hasTexture(*t))
928 if ((mipMap.
size % 4) != 0)
931 for (
size_t p = 0; p < mipMap.
size; p += 4) {
932 mipMap.
data[p + 0] = mipMap.
data[p + 3];
933 mipMap.
data[p + 1] = mipMap.
data[p + 3];
934 mipMap.
data[p + 2] = mipMap.
data[p + 3];
935 mipMap.
data[p + 3] = 0xFF;
959 if (meshGroupName.
empty() || materialName.
empty())
972 if (meshDecl.empty())
997 readMAO(materialName, materialObject);
999 std::vector<Common::UString> textures;
1000 textures.push_back(materialObject.
textures[
"mml_tDiffuse"]);
1001 if (textures.back().empty())
1002 textures.back() = materialObject.
textures[
"mml_tPackedTexture"];
1003 if (textures.back().empty())
1004 textures.back() = materialObject.
textures[
"LowLodMap"];
1006 while (!textures.empty() && textures.back().empty())
1007 textures.pop_back();
static const uint32 kTEXID
#define ResMan
Shortcut for accessing the sound manager.
GLvoid * getData()
Access buffer data.
static const uint32 kCHNKID
#define MKTAG(a0, a1, a2, a3)
A wrapper macro used around four character constants, like 'DATA', to ensure portability.
void addState(ParserContext &ctx)
uint16 readUint16LE()
Read an unsigned 16-bit word stored in little endian (LSB first) order from the stream and return it...
Generic image decoder interface.
ParserContext(const Common::UString &name)
static const uint32 kMMHID
static const uint32 kMSHHID
NodeMap nodeMap
The nodes within the state, indexed by name.
std::list< MeshDeclaration > MeshDeclarations
static const uint32 kTRSLID
void add(const char *s,...) GCC_PRINTF(2
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...
void readMAO(const Common::UString &materialName, MaterialObject &material)
Read a material object MAO, which can be encoded in either XML or GFF.
static void read2Float32(Common::ReadStream &stream, MeshDeclType type, float *&f)
Generic interface for a readable data stream.
#define TypeMan
Shortcut for accessing the file type manager.
friend class ModelNode_DragonAge
const ::Aurora::GFF4Struct * mshTop
static const GFF4Struct * getChild(const GFF4Struct &children, size_t i)
A class holding an UTF-8 string.
Class to parse a ReadStream into a simple XML tree.
#define TextureMan
Shortcut for accessing the texture manager.
virtual size_t seek(ptrdiff_t offset, Origin whence=kOriginBegin)=0
Sets the stream position indicator for the stream.
VertexBuffer * getVertexBuffer()
2 normalized signed 16-bit integers.
const UString & getName() const
std::map< Common::UString, glm::vec4 > vectors
void loadTextures(const std::vector< Common::UString > &textures)
static Texture * create(const Common::UString &name, bool deswizzle=false)
Create a texture from this image resource.
void init()
General mesh initialisation, queuing the mesh for GL resource creation.
The Aurora texture manager.
void readMAOGFF(Common::SeekableReadStream *maoStream, MaterialObject &material)
Read a MAO encoded in a GFF file.
bool render
Render this mesh?
Model_DragonAge(const Common::UString &name, ModelType type=kModelTypeObject)
static const uint32 kXMLID
Common::ScopedArray< byte > data
The mip map's data.
Common::UString name
The state's name.
const Children & getChildren() const
Return a list of children.
Common::UString defaultSemantic
4 unsigned integers of 10-bit, 10-bit, 10-bit, 2-bit.
NodeList rootNodes
The nodes in the state without a parent.
bool equalsIgnoreCase(const UString &str) const
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.
Utility functions to handle files used in BioWare's Aurora engine.
bool _render
Render the node?
static const uint32 kVersion01
const GFF4Struct * getGeneric(uint32 field) const
static const uint32 kCRSTID
Common::UString _fileName
The model's file name.
static const uint32 kMAOID
std::vector< VertexAttrib > VertexDecl
Vertex data layout.
#define IGNORE_UNUSED_VARIABLES
Utility templates and functions for working with strings and streams.
Exception that provides a stack of explanations.
void readTransformation(const ::Aurora::GFF4Struct &nodeGFF)
void decompress()
Manually decompress the texture image data.
Model * _model
The model this node belongs to.
Common::UString _name
The model's name.
static void read4Float32(Common::ReadStream &stream, MeshDeclType type, float *&f)
std::vector< const GFF4Struct * > GFF4List
Handling version V4.0/V4.1 of BioWare's GFFs (generic file format).
static const uint32 kROTAID
Basic exceptions to throw.
4 normalized unsigned 16-bit integers.
Common::SeekableReadStream * getData(uint32 field) const
Return the raw data of the field as a Seekable(Sub)ReadStream.
const char * c_str() const
Return the (utf8 encoded) string data.
4 normalized signed 16-bit integers.
4 normalized unsigned 8-bit integers.
ModelType
The display type of a model.
Utility templates and functions.
static ImageDecoder * loadImage(const Common::UString &name, bool deswizzle=false)
Load an image in any of the common texture formats.
4 signed 16-bit integers.
void loadTextures(const std::vector< Common::UString > &textures, const MaterialObject &material)
std::map< Common::UString, Common::UString > textures
virtual void buildMaterial()
Base for BioWare's Aurora engine files.
void sanityCheckMeshChunk(const ::Aurora::GFF4Struct &meshChunk)
static void read3Float32(Common::ReadStream &stream, MeshDeclType type, float *&f)
static const uint32 kVersion10
PixelFormatRaw getFormatRaw() const
Return the image data's raw format.
virtual size_t skip(ptrdiff_t offset)
Skip the specified number of bytes, adding that offset to the current position in the stream...
const MipMap & getMipMap(size_t mipMap, size_t layer=0) const
Return a mip map.
Utility functions for working with differing string encodings.
XML parsing helpers, using libxml2.
bool empty() const
Is the string empty?
static const GFF4Struct * findMeshChunk(const GFF4Struct &mshTop, const Common::UString &name)
MeshDeclUse
Usage information for a mesh declaration part.
float _position[3]
Position of the node.
NodeList nodeList
The nodes within the state.
static const uint32 kGFFID
void warning(const char *s,...)
Loading MMH+MSH files found in Dragon Age: Origins and Dragon Age 2.
void readMeshDecl(const ::Aurora::GFF4Struct &meshChunk, MeshDeclarations &meshDecl)
StateMap _stateMap
All states within this model, index by name.
Basic reading stream interfaces.
virtual size_t pos() const =0
Obtains the current value of the stream position indicator of the stream.
ModelNode_DragonAge(Model &model)
MeshDeclType
Type information for a mesh declaration part.
FORCEINLINE float readIEEEFloatLE()
Read a 32-bit IEEE float stored in little endian (LSB first) order from the stream and return it...
static const uint32 kMSHID
#define MeshMan
Shortcut for accessing the shader manager.
UString toLower() const
Return a lowercased copy of the string.
void newState(ParserContext &ctx)
Graphics::Mesh::Mesh * rawMesh
Node raw mesh data.
Common::UString _name
The node's name.
void fixTexturesAlpha(const std::vector< Common::UString > &textures)
A texture as used in the Aurora engines.
void readChildren(Model_DragonAge::ParserContext &ctx, const ::Aurora::GFF4Struct &nodeGFF)
UString debugTag(uint32 tag, bool trim)
Create an elaborate string from an integer tag, for debugging purposes.
void createVertexBuffer(const ::Aurora::GFF4Struct &meshChunk, Common::SeekableReadStream &vertexData, const MeshDeclarations &meshDecl)
An internal material object.
GLvoid * getData()
Access buffer data.
float _orientation[4]
Orientation of the node.
static const uint32 kDECLID
void fixTexturesHair(const std::vector< Common::UString > &textures)
const XMLNode & getRoot() const
Return the XML root node.
const ::Aurora::GFF4Struct * mmhTop
A generic interface for image decoders.
static float rad2deg(float rad)
static uint32 readHeaderID(Common::ReadStream &stream)
Read the ID out of a stream.
void finalize()
Finalize the loading procedure.
2 normalized unsigned 16-bit integers.
4 unsigned 8-bit integers.
static const uint32 kFLT4ID
void open(const Common::UString &name)
std::map< Common::UString, float > floats
void setName(const Common::UString &name)
float readIEEEFloat16(uint16 value)
Read a half-precision 16-bit IEEE float, converting it into a 32-bit iEEE float.
void createIndexBuffer(const ::Aurora::GFF4Struct &meshChunk, Common::SeekableReadStream &indexData)
size_t getMipMapCount() const
Return the number of mip maps contained in the image.
void readMesh(Model_DragonAge::ParserContext &ctx, const ::Aurora::GFF4Struct &meshGFF)
void readMAOXML(Common::SeekableReadStream *maoStream, MaterialObject &material, const Common::UString &fileName)
Read a MAO encoded in an XML file.
StateList _stateList
All states within this model.
std::list< ModelNode_DragonAge * > nodes
uint32 size
The mip map's size in bytes.
Generic vertex attribute data.
Interface for a seekable & readable data stream.
An internal mesh declaration part.
static const uint32 kFLOTID
byte readByte()
Read an unsigned byte from the stream and return it.
IndexBuffer * getIndexBuffer()
4 normalized unsigned integers of 10-bit, 10-bit, 10-bit, 2-bit.
bool isCompressed() const
Is the image data compressed?
#define GfxMan
Shortcut for accessing the graphics manager.
void setSize(uint32 indexCount, uint32 indexSize, GLenum indexType)
Change buffer size.
The global resource manager for Aurora resources.
Utility class for manipulating file paths.
void load(Model_DragonAge::ParserContext &ctx, const ::Aurora::GFF4Struct &nodeGFF)
void load(ParserContext &ctx)
static const uint32 kNODEID
2 signed 16-bit integers.
static UString changeExtension(const UString &p, const UString &ext="")
Change a file name's extension.
static bool isType(const GFF4Struct *strct, uint32 type)