- first draft of the Collada importer. Compiles and runs fine, but not functional yet.
- added a "rotation around arbitrary axis" function to the matrix class git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@238 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
04ca1a72f7
commit
1083d85b2c
|
@ -0,0 +1,116 @@
|
||||||
|
/** Implementation of the Collada loader */
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
#include "../include/aiAnim.h"
|
||||||
|
#include "ColladaLoader.h"
|
||||||
|
#include "ColladaParser.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Constructor to be privately used by Importer
|
||||||
|
ColladaLoader::ColladaLoader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Destructor, private as well
|
||||||
|
ColladaLoader::~ColladaLoader()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Returns whether the class can handle the format of the given file.
|
||||||
|
bool ColladaLoader::CanRead( const std::string& pFile, IOSystem* pIOHandler) const
|
||||||
|
{
|
||||||
|
// check file extension
|
||||||
|
std::string::size_type pos = pFile.find_last_of('.');
|
||||||
|
// no file extension - can't read
|
||||||
|
if( pos == std::string::npos)
|
||||||
|
return false;
|
||||||
|
std::string extension = pFile.substr( pos);
|
||||||
|
for( std::string::iterator it = extension.begin(); it != extension.end(); ++it)
|
||||||
|
*it = tolower( *it);
|
||||||
|
|
||||||
|
if( extension == ".dae")
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Imports the given file into the given scene structure.
|
||||||
|
void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler)
|
||||||
|
{
|
||||||
|
mFileName = pFile;
|
||||||
|
|
||||||
|
// parse the input file
|
||||||
|
ColladaParser parser( pFile);
|
||||||
|
|
||||||
|
// build the node hierarchy from it
|
||||||
|
pScene->mRootNode = BuildHierarchy( parser, parser.mRootNode);
|
||||||
|
|
||||||
|
pScene->mFlags = AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Recursively constructs a scene node for the given parser node and returns it.
|
||||||
|
aiNode* ColladaLoader::BuildHierarchy( const ColladaParser& pParser, const ColladaParser::Node* pNode)
|
||||||
|
{
|
||||||
|
// create a node for it
|
||||||
|
aiNode* node = new aiNode( pNode->mName);
|
||||||
|
|
||||||
|
// calculate the transformation matrix for it
|
||||||
|
node->mTransformation = pParser.CalculateResultTransform( pNode->mTransforms);
|
||||||
|
|
||||||
|
// add children
|
||||||
|
node->mNumChildren = pNode->mChildren.size();
|
||||||
|
node->mChildren = new aiNode*[node->mNumChildren];
|
||||||
|
for( unsigned int a = 0; a < pNode->mChildren.size(); a++)
|
||||||
|
{
|
||||||
|
node->mChildren[a] = BuildHierarchy( pParser, pNode->mChildren[a]);
|
||||||
|
node->mChildren[a]->mParent = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
|
@ -0,0 +1,95 @@
|
||||||
|
/** Defines the collada loader class */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AI_COLLADALOADER_H_INC
|
||||||
|
#define AI_COLLADALOADER_H_INC
|
||||||
|
|
||||||
|
#include "BaseImporter.h"
|
||||||
|
#include "ColladaParser.h"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Loader class to read Collada scenes. Collada is over-engineered to death, with every new iteration bringing
|
||||||
|
* more useless stuff, so I limited the data to what I think is useful for games.
|
||||||
|
*/
|
||||||
|
class ColladaLoader : public BaseImporter
|
||||||
|
{
|
||||||
|
friend class Importer;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Constructor to be privately used by Importer */
|
||||||
|
ColladaLoader();
|
||||||
|
|
||||||
|
/** Destructor, private as well */
|
||||||
|
~ColladaLoader();
|
||||||
|
|
||||||
|
public:
|
||||||
|
/** Returns whether the class can handle the format of the given file.
|
||||||
|
* See BaseImporter::CanRead() for details. */
|
||||||
|
bool CanRead( const std::string& pFile, IOSystem* pIOHandler) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Called by Importer::GetExtensionList() for each loaded importer.
|
||||||
|
* See BaseImporter::GetExtensionList() for details
|
||||||
|
*/
|
||||||
|
void GetExtensionList( std::string& append)
|
||||||
|
{
|
||||||
|
append.append("*.dae");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Imports the given file into the given scene structure.
|
||||||
|
* See BaseImporter::InternReadFile() for details
|
||||||
|
*/
|
||||||
|
void InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler);
|
||||||
|
|
||||||
|
/** Recursively constructs a scene node for the given parser node and returns it. */
|
||||||
|
aiNode* BuildHierarchy( const ColladaParser& pParser, const ColladaParser::Node* pNode);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Filename, for a verbose error message */
|
||||||
|
std::string mFileName;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // AI_COLLADALOADER_H_INC
|
|
@ -0,0 +1,484 @@
|
||||||
|
/** Implementation of the Collada parser helper*/
|
||||||
|
/*
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the following
|
||||||
|
conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
---------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "AssimpPCH.h"
|
||||||
|
#include "ColladaParser.h"
|
||||||
|
#include "fast_atof.h"
|
||||||
|
#include "ParsingUtils.h"
|
||||||
|
|
||||||
|
using namespace Assimp;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Constructor to be privately used by Importer
|
||||||
|
ColladaParser::ColladaParser( const std::string& pFile)
|
||||||
|
: mFileName( pFile)
|
||||||
|
{
|
||||||
|
mRootNode = NULL;
|
||||||
|
mUnitSize = 1.0f;
|
||||||
|
mUpDirection = UP_Z;
|
||||||
|
|
||||||
|
// generate a XML reader for it
|
||||||
|
mReader = irr::io::createIrrXMLReader( pFile.c_str());
|
||||||
|
if( !mReader)
|
||||||
|
ThrowException( "Unable to open file.");
|
||||||
|
|
||||||
|
// start reading
|
||||||
|
ReadContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Destructor, private as well
|
||||||
|
ColladaParser::~ColladaParser()
|
||||||
|
{
|
||||||
|
delete mReader;
|
||||||
|
for( NodeLibrary::iterator it = mNodeLibrary.begin(); it != mNodeLibrary.end(); ++it)
|
||||||
|
delete it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads the contents of the file
|
||||||
|
void ColladaParser::ReadContents()
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
// handle the root element "COLLADA"
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "COLLADA"))
|
||||||
|
{
|
||||||
|
ReadStructure();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
DefaultLogger::get()->debug( boost::str( boost::format( "Ignoring global element \"%s\".") % mReader->getNodeName()));
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// skip everything else silently
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads the structure of the file
|
||||||
|
void ColladaParser::ReadStructure()
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
// beginning of elements
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "asset"))
|
||||||
|
ReadAssetInfo();
|
||||||
|
else if( IsElement( "library_geometries"))
|
||||||
|
ReadGeometryLibrary();
|
||||||
|
else if( IsElement( "library_visual_scenes"))
|
||||||
|
ReadSceneLibrary();
|
||||||
|
else if( IsElement( "scene"))
|
||||||
|
ReadScene();
|
||||||
|
else
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads asset informations such as coordinate system informations and legal blah
|
||||||
|
void ColladaParser::ReadAssetInfo()
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "unit"))
|
||||||
|
{
|
||||||
|
// read unit data from the element's attributes
|
||||||
|
int attrIndex = GetAttribute( "meter");
|
||||||
|
mUnitSize = mReader->getAttributeValueAsFloat( attrIndex);
|
||||||
|
|
||||||
|
// consume the trailing stuff
|
||||||
|
if( !mReader->isEmptyElement())
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
else if( IsElement( "up_axis"))
|
||||||
|
{
|
||||||
|
// read content, strip whitespace, compare
|
||||||
|
const char* content = GetTextContent();
|
||||||
|
if( strncmp( content, "X_UP", 4) == 0)
|
||||||
|
mUpDirection = UP_X;
|
||||||
|
else if( strncmp( content, "Y_UP", 4) == 0)
|
||||||
|
mUpDirection = UP_Y;
|
||||||
|
else
|
||||||
|
mUpDirection = UP_Z;
|
||||||
|
|
||||||
|
// check element end
|
||||||
|
TestClosing( "up_axis");
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads the geometry library contents
|
||||||
|
void ColladaParser::ReadGeometryLibrary()
|
||||||
|
{
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads the library of node hierarchies and scene parts
|
||||||
|
void ColladaParser::ReadSceneLibrary()
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
// a visual scene - generate root node under its ID and let ReadNode() do the recursive work
|
||||||
|
if( IsElement( "visual_scene"))
|
||||||
|
{
|
||||||
|
// read ID. Is optional according to the spec, but how on earth should a scene_instance refer to it then?
|
||||||
|
int indexID = GetAttribute( "id");
|
||||||
|
const char* attrID = mReader->getAttributeValue( indexID);
|
||||||
|
|
||||||
|
// read name if given.
|
||||||
|
int indexName = TestAttribute( "name");
|
||||||
|
const char* attrName = "unnamed";
|
||||||
|
if( indexName > -1)
|
||||||
|
attrName = mReader->getAttributeValue( indexName);
|
||||||
|
|
||||||
|
// TODO: (thom) support SIDs
|
||||||
|
assert( TestAttribute( "sid") == -1);
|
||||||
|
|
||||||
|
// create a node and store it in the library under its ID
|
||||||
|
Node* node = new Node;
|
||||||
|
node->mID = attrID;
|
||||||
|
node->mName = attrName;
|
||||||
|
mNodeLibrary[node->mID] = node;
|
||||||
|
|
||||||
|
ReadSceneNode( node);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// ignore the rest
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads a scene node's contents including children and stores it in the given node
|
||||||
|
void ColladaParser::ReadSceneNode( Node* pNode)
|
||||||
|
{
|
||||||
|
// quit immediately on <bla/> elements
|
||||||
|
if( mReader->isEmptyElement())
|
||||||
|
return;
|
||||||
|
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "lookat"))
|
||||||
|
ReadNodeTransformation( pNode, TF_LOOKAT);
|
||||||
|
else if( IsElement( "matrix"))
|
||||||
|
ReadNodeTransformation( pNode, TF_MATRIX);
|
||||||
|
else if( IsElement( "rotate"))
|
||||||
|
ReadNodeTransformation( pNode, TF_ROTATE);
|
||||||
|
else if( IsElement( "scale"))
|
||||||
|
ReadNodeTransformation( pNode, TF_SCALE);
|
||||||
|
else if( IsElement( "skew"))
|
||||||
|
ReadNodeTransformation( pNode, TF_SKEW);
|
||||||
|
else if( IsElement( "translate"))
|
||||||
|
ReadNodeTransformation( pNode, TF_TRANSLATE);
|
||||||
|
else if( IsElement( "node"))
|
||||||
|
{
|
||||||
|
Node* child = new Node;
|
||||||
|
int attrID = TestAttribute( "id");
|
||||||
|
if( attrID > -1)
|
||||||
|
child->mID = mReader->getAttributeValue( attrID);
|
||||||
|
|
||||||
|
int attrName = TestAttribute( "name");
|
||||||
|
if( attrName > -1)
|
||||||
|
child->mName = mReader->getAttributeValue( attrName);
|
||||||
|
|
||||||
|
// TODO: (thom) support SIDs
|
||||||
|
assert( TestAttribute( "sid") == -1);
|
||||||
|
|
||||||
|
pNode->mChildren.push_back( child);
|
||||||
|
child->mParent = pNode;
|
||||||
|
|
||||||
|
// read on recursively from there
|
||||||
|
ReadSceneNode( child);
|
||||||
|
} else if( IsElement( "instance_node"))
|
||||||
|
{
|
||||||
|
// test for it, in case we need to implement it
|
||||||
|
assert( false);
|
||||||
|
SkipElement();
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// skip everything else for the moment
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads a node transformation entry of the given type and adds it to the given node's transformation list.
|
||||||
|
void ColladaParser::ReadNodeTransformation( Node* pNode, TransformType pType)
|
||||||
|
{
|
||||||
|
std::string tagName = mReader->getNodeName();
|
||||||
|
|
||||||
|
// how many parameters to read per transformation type
|
||||||
|
static const unsigned int sNumParameters[] = { 9, 4, 3, 3, 7, 16 };
|
||||||
|
const char* content = GetTextContent();
|
||||||
|
|
||||||
|
// read as many parameters and store in the transformation
|
||||||
|
Transform tf;
|
||||||
|
tf.mType = pType;
|
||||||
|
for( unsigned int a = 0; a < sNumParameters[pType]; a++)
|
||||||
|
{
|
||||||
|
// read a number
|
||||||
|
content = fast_atof_move( content, tf.f[a]);
|
||||||
|
// skip whitespace after it
|
||||||
|
SkipSpacesAndLineEnd( &content);
|
||||||
|
}
|
||||||
|
|
||||||
|
// place the transformation at the queue of the node
|
||||||
|
pNode->mTransforms.push_back( tf);
|
||||||
|
|
||||||
|
// and consum the closing tag
|
||||||
|
TestClosing( tagName.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads the collada scene
|
||||||
|
void ColladaParser::ReadScene()
|
||||||
|
{
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT)
|
||||||
|
{
|
||||||
|
if( IsElement( "instance_visual_scene"))
|
||||||
|
{
|
||||||
|
// should be the first and only occurence
|
||||||
|
if( mRootNode)
|
||||||
|
ThrowException( "Invalid scene containing multiple root nodes");
|
||||||
|
|
||||||
|
// read the url of the scene to instance. Should be of format "#some_name"
|
||||||
|
int urlIndex = GetAttribute( "url");
|
||||||
|
const char* url = mReader->getAttributeValue( urlIndex);
|
||||||
|
if( url[0] != '#')
|
||||||
|
ThrowException( "Unknown reference format");
|
||||||
|
|
||||||
|
// find the referred scene, skip the leading #
|
||||||
|
NodeLibrary::const_iterator sit = mNodeLibrary.find( url+1);
|
||||||
|
if( sit == mNodeLibrary.end())
|
||||||
|
ThrowException( boost::str( boost::format( "Unable to resolve visual_scene reference \"%s\".") % url));
|
||||||
|
mRootNode = sit->second;
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
SkipElement();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Aborts the file reading with an exception
|
||||||
|
void ColladaParser::ThrowException( const std::string& pError) const
|
||||||
|
{
|
||||||
|
throw new ImportErrorException( boost::str( boost::format( "%s - %s") % mFileName % pError));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Skips all data until the end node of the current element
|
||||||
|
void ColladaParser::SkipElement()
|
||||||
|
{
|
||||||
|
// nothing to skip if it's an <element />
|
||||||
|
if( mReader->isEmptyElement())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// copy the current node's name because it'a pointer to the reader's internal buffer,
|
||||||
|
// which is going to change with the upcoming parsing
|
||||||
|
std::string element = mReader->getNodeName();
|
||||||
|
while( mReader->read())
|
||||||
|
{
|
||||||
|
if( mReader->getNodeType() == irr::io::EXN_ELEMENT_END)
|
||||||
|
if( mReader->getNodeName() == element)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Tests for the closing tag of the given element, throws an exception if not found
|
||||||
|
void ColladaParser::TestClosing( const char* pName)
|
||||||
|
{
|
||||||
|
// read closing tag
|
||||||
|
if( !mReader->read())
|
||||||
|
ThrowException( boost::str( boost::format( "Unexpected end of file while reading end of \"%s\" element.") % pName));
|
||||||
|
if( mReader->getNodeType() != irr::io::EXN_ELEMENT_END || strcmp( mReader->getNodeName(), pName) != 0)
|
||||||
|
ThrowException( boost::str( boost::format( "Expected end of \"%s\" element.") % pName));
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes
|
||||||
|
int ColladaParser::GetAttribute( const char* pAttr) const
|
||||||
|
{
|
||||||
|
int index = TestAttribute( pAttr);
|
||||||
|
if( index != -1)
|
||||||
|
return index;
|
||||||
|
|
||||||
|
// attribute not found -> throw an exception
|
||||||
|
ThrowException( boost::str( boost::format( "Expected attribute \"%s\" at element \"%s\".") % pAttr % mReader->getNodeName()));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Tests the present element for the presence of one attribute, returns its index or throws an exception if not found
|
||||||
|
int ColladaParser::TestAttribute( const char* pAttr) const
|
||||||
|
{
|
||||||
|
for( int a = 0; a < mReader->getAttributeCount(); a++)
|
||||||
|
if( strcmp( mReader->getAttributeName( a), pAttr) == 0)
|
||||||
|
return a;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Reads the text contents of an element, throws an exception if not given. Skips leading whitespace.
|
||||||
|
const char* ColladaParser::GetTextContent()
|
||||||
|
{
|
||||||
|
// present node should be the beginning of an element
|
||||||
|
if( mReader->getNodeType() != irr::io::EXN_ELEMENT || mReader->isEmptyElement())
|
||||||
|
ThrowException( "Expected opening element");
|
||||||
|
|
||||||
|
// read contents of the element
|
||||||
|
if( !mReader->read())
|
||||||
|
ThrowException( "Unexpected end of file while reading asset up_axis element.");
|
||||||
|
if( mReader->getNodeType() != irr::io::EXN_TEXT)
|
||||||
|
ThrowException( "Invalid contents in element \"up_axis\".");
|
||||||
|
|
||||||
|
// skip leading whitespace
|
||||||
|
const char* text = mReader->getNodeData();
|
||||||
|
SkipSpacesAndLineEnd( &text);
|
||||||
|
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
// Calculates the resulting transformation fromm all the given transform steps
|
||||||
|
aiMatrix4x4 ColladaParser::CalculateResultTransform( const std::vector<Transform>& pTransforms) const
|
||||||
|
{
|
||||||
|
aiMatrix4x4 res;
|
||||||
|
|
||||||
|
for( std::vector<Transform>::const_iterator it = pTransforms.begin(); it != pTransforms.end(); ++it)
|
||||||
|
{
|
||||||
|
const Transform& tf = *it;
|
||||||
|
switch( tf.mType)
|
||||||
|
{
|
||||||
|
case TF_LOOKAT:
|
||||||
|
// TODO: (thom)
|
||||||
|
assert( false);
|
||||||
|
break;
|
||||||
|
case TF_ROTATE:
|
||||||
|
{
|
||||||
|
aiMatrix4x4 rot;
|
||||||
|
aiMatrix4x4::Rotation( tf.f[3], aiVector3D( tf.f[0], tf.f[1], tf.f[2]), rot);
|
||||||
|
res *= rot;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TF_TRANSLATE:
|
||||||
|
{
|
||||||
|
aiMatrix4x4 trans;
|
||||||
|
aiMatrix4x4::Translation( aiVector3D( tf.f[0], tf.f[1], tf.f[2]), trans);
|
||||||
|
res *= trans;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TF_SCALE:
|
||||||
|
{
|
||||||
|
aiMatrix4x4 scale( tf.f[0], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[1], 0.0f, 0.0f, 0.0f, 0.0f, tf.f[2], 0.0f,
|
||||||
|
0.0f, 0.0f, 0.0f, 1.0f);
|
||||||
|
res *= scale;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TF_SKEW:
|
||||||
|
// TODO: (thom)
|
||||||
|
assert( false);
|
||||||
|
break;
|
||||||
|
case TF_MATRIX:
|
||||||
|
{
|
||||||
|
aiMatrix4x4 mat( tf.f[0], tf.f[1], tf.f[2], tf.f[3], tf.f[4], tf.f[5], tf.f[6], tf.f[7],
|
||||||
|
tf.f[8], tf.f[9], tf.f[10], tf.f[11], tf.f[12], tf.f[13], tf.f[14], tf.f[15]);
|
||||||
|
res *= mat;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert( false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
|
@ -0,0 +1,194 @@
|
||||||
|
/** Defines the parser helper class for the collada loader */
|
||||||
|
|
||||||
|
/*
|
||||||
|
Open Asset Import Library (ASSIMP)
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
Copyright (c) 2006-2008, ASSIMP Development Team
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use of this software in source and binary forms,
|
||||||
|
with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
copyright notice, this list of conditions and the
|
||||||
|
following disclaimer in the documentation and/or other
|
||||||
|
materials provided with the distribution.
|
||||||
|
|
||||||
|
* Neither the name of the ASSIMP team, nor the names of its
|
||||||
|
contributors may be used to endorse or promote products
|
||||||
|
derived from this software without specific prior
|
||||||
|
written permission of the ASSIMP Development Team.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AI_COLLADAPARSER_H_INC
|
||||||
|
#define AI_COLLADAPARSER_H_INC
|
||||||
|
|
||||||
|
#include "./irrXML/irrXMLWrapper.h"
|
||||||
|
|
||||||
|
namespace Assimp
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Parser helper class for the Collada loader. Does all the XML reading and builds internal data structures from it,
|
||||||
|
* but leaves the resolving of all the references to the loader.
|
||||||
|
*/
|
||||||
|
class ColladaParser
|
||||||
|
{
|
||||||
|
friend class ColladaLoader;
|
||||||
|
public:
|
||||||
|
/** Transformation types that can be applied to a node */
|
||||||
|
enum TransformType
|
||||||
|
{
|
||||||
|
TF_LOOKAT,
|
||||||
|
TF_ROTATE,
|
||||||
|
TF_TRANSLATE,
|
||||||
|
TF_SCALE,
|
||||||
|
TF_SKEW,
|
||||||
|
TF_MATRIX
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Contains all data for one of the different transformation types */
|
||||||
|
struct Transform
|
||||||
|
{
|
||||||
|
TransformType mType;
|
||||||
|
float f[16]; ///< Interpretation of data depends on the type of the transformation
|
||||||
|
};
|
||||||
|
|
||||||
|
/** A node in a scene hierarchy */
|
||||||
|
struct Node
|
||||||
|
{
|
||||||
|
std::string mName;
|
||||||
|
std::string mID;
|
||||||
|
Node* mParent;
|
||||||
|
std::vector<Node*> mChildren;
|
||||||
|
|
||||||
|
/** Operations in order to calculate the resulting transformation to parent. */
|
||||||
|
std::vector<Transform> mTransforms;
|
||||||
|
|
||||||
|
Node() { mParent = NULL; }
|
||||||
|
~Node() { for( std::vector<Node*>::iterator it = mChildren.begin(); it != mChildren.end(); ++it) delete *it; }
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Data source array */
|
||||||
|
struct Data
|
||||||
|
{
|
||||||
|
std::vector<float> mValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Accessor to a data array */
|
||||||
|
struct Accessor
|
||||||
|
{
|
||||||
|
unsigned int mCount; // in number of objects
|
||||||
|
unsigned int mOffset; // in number of values
|
||||||
|
unsigned int mStride; // Stride in number of values
|
||||||
|
std::string mSource; // URL of the source array
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Contains data for a single mesh */
|
||||||
|
struct Mesh
|
||||||
|
{
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Constructor from XML file */
|
||||||
|
ColladaParser( const std::string& pFile);
|
||||||
|
|
||||||
|
/** Destructor */
|
||||||
|
~ColladaParser();
|
||||||
|
|
||||||
|
/** Reads the contents of the file */
|
||||||
|
void ReadContents();
|
||||||
|
|
||||||
|
/** Reads the structure of the file */
|
||||||
|
void ReadStructure();
|
||||||
|
|
||||||
|
/** Reads asset informations such as coordinate system informations and legal blah */
|
||||||
|
void ReadAssetInfo();
|
||||||
|
|
||||||
|
/** Reads the geometry library contents */
|
||||||
|
void ReadGeometryLibrary();
|
||||||
|
|
||||||
|
/** Reads a mesh from the geometry library */
|
||||||
|
void ReadGeometry();
|
||||||
|
|
||||||
|
/** Reads the library of node hierarchies and scene parts */
|
||||||
|
void ReadSceneLibrary();
|
||||||
|
|
||||||
|
/** Reads a scene node's contents including children and stores it in the given node */
|
||||||
|
void ReadSceneNode( Node* pNode);
|
||||||
|
|
||||||
|
/** Reads a node transformation entry of the given type and adds it to the given node's transformation list. */
|
||||||
|
void ReadNodeTransformation( Node* pNode, TransformType pType);
|
||||||
|
|
||||||
|
/** Reads the collada scene */
|
||||||
|
void ReadScene();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Aborts the file reading with an exception */
|
||||||
|
void ThrowException( const std::string& pError) const;
|
||||||
|
|
||||||
|
/** Skips all data until the end node of the current element */
|
||||||
|
void SkipElement();
|
||||||
|
|
||||||
|
/** Compares the current xml element name to the given string and returns true if equal */
|
||||||
|
bool IsElement( const char* pName) const { assert( mReader->getNodeType() == irr::io::EXN_ELEMENT); return strcmp( mReader->getNodeName(), pName) == 0; }
|
||||||
|
|
||||||
|
/** Tests for the closing tag of the given element, throws an exception if not found */
|
||||||
|
void TestClosing( const char* pName);
|
||||||
|
|
||||||
|
/** Checks the present element for the presence of the attribute, returns its index or throws an exception if not found */
|
||||||
|
int GetAttribute( const char* pAttr) const;
|
||||||
|
|
||||||
|
/** Returns the index of the named attribute or -1 if not found. Does not throw, therefore useful for optional attributes */
|
||||||
|
int TestAttribute( const char* pAttr) const;
|
||||||
|
|
||||||
|
/** Reads the text contents of an element, throws an exception if not given. Skips leading whitespace. */
|
||||||
|
const char* GetTextContent();
|
||||||
|
|
||||||
|
/** Calculates the resulting transformation fromm all the given transform steps */
|
||||||
|
aiMatrix4x4 CalculateResultTransform( const std::vector<Transform>& pTransforms) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/** Filename, for a verbose error message */
|
||||||
|
std::string mFileName;
|
||||||
|
|
||||||
|
/** XML reader */
|
||||||
|
irr::io::IrrXMLReader* mReader;
|
||||||
|
|
||||||
|
/** node library: root node of the hierarchy part by ID */
|
||||||
|
typedef std::map<std::string, Node*> NodeLibrary;
|
||||||
|
NodeLibrary mNodeLibrary;
|
||||||
|
|
||||||
|
/** Pointer to the root node. Don't delete, it just points to one of the nodes in the node library. */
|
||||||
|
Node* mRootNode;
|
||||||
|
|
||||||
|
/** Size unit: how large compared to a meter */
|
||||||
|
float mUnitSize;
|
||||||
|
|
||||||
|
/** Which is the up vector */
|
||||||
|
enum { UP_X, UP_Y, UP_Z } mUpDirection;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end of namespace Assimp
|
||||||
|
|
||||||
|
#endif // AI_COLLADAPARSER_H_INC
|
|
@ -129,6 +129,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#ifndef AI_BUILD_NO_B3D_IMPORTER
|
#ifndef AI_BUILD_NO_B3D_IMPORTER
|
||||||
# include "B3DImporter.h"
|
# include "B3DImporter.h"
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef AI_BUILD_NO_COLLADA_IMPORTER
|
||||||
|
# include "ColladaLoader.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
// PostProcess-Steps
|
// PostProcess-Steps
|
||||||
|
@ -283,6 +286,9 @@ Importer::Importer() :
|
||||||
#if (!defined AI_BUILD_NO_B3D_IMPORTER)
|
#if (!defined AI_BUILD_NO_B3D_IMPORTER)
|
||||||
mImporter.push_back( new B3DImporter());
|
mImporter.push_back( new B3DImporter());
|
||||||
#endif
|
#endif
|
||||||
|
#if (!defined AI_BUILD_NO_COLLADA_IMPORTER)
|
||||||
|
mImporter.push_back( new ColladaLoader());
|
||||||
|
#endif
|
||||||
|
|
||||||
// add an instance of each post processing step here in the order
|
// add an instance of each post processing step here in the order
|
||||||
// of sequence it is executed. steps that are added here are not validated -
|
// of sequence it is executed. steps that are added here are not validated -
|
||||||
|
|
|
@ -142,6 +142,14 @@ struct aiMatrix4x4
|
||||||
*/
|
*/
|
||||||
static aiMatrix4x4& RotationZ(float a, aiMatrix4x4& out);
|
static aiMatrix4x4& RotationZ(float a, aiMatrix4x4& out);
|
||||||
|
|
||||||
|
/** Returns a rotation matrix for a rotation around an arbitrary axis.
|
||||||
|
* @param a Rotation angle, in radians
|
||||||
|
* @param axis Rotation axis, should be a normalized vector.
|
||||||
|
* @param out Receives the output matrix
|
||||||
|
* \return Reference to the output matrix
|
||||||
|
*/
|
||||||
|
static aiMatrix4x4& Rotation(float a, const aiVector3D& axis, aiMatrix4x4& out);
|
||||||
|
|
||||||
/** \brief Returns a translation matrix
|
/** \brief Returns a translation matrix
|
||||||
* \param v Translation vector
|
* \param v Translation vector
|
||||||
* \param out Receives the output matrix
|
* \param out Receives the output matrix
|
||||||
|
|
|
@ -282,6 +282,25 @@ inline aiMatrix4x4& aiMatrix4x4::RotationZ(float a, aiMatrix4x4& out)
|
||||||
out.a2 = -(out.b1 = sin(a));
|
out.a2 = -(out.b1 = sin(a));
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------
|
||||||
|
// Returns a rotation matrix for a rotation around an arbitrary axis.
|
||||||
|
inline aiMatrix4x4& aiMatrix4x4::Rotation( float a, const aiVector3D& axis, aiMatrix4x4& out)
|
||||||
|
{
|
||||||
|
float c = cos( a), s = sin( a), t = 1 - c;
|
||||||
|
float x = axis.x, y = axis.y, z = axis.z;
|
||||||
|
|
||||||
|
// Many thanks to MathWorld and Wikipedia
|
||||||
|
out.a1 = t*x*x + c; out.a2 = t*x*y - s*z; out.a3 = t*x*z + s*y;
|
||||||
|
out.b1 = t*x*y + s*z; out.b2 = t*y*y + c; out.b3 = t*y*z - s*x;
|
||||||
|
out.c1 = t*x*z - s*y; out.c2 = t*y*z + s*x; out.c3 = t*z*z + c;
|
||||||
|
out.a4 = out.b4 = out.c4 = 0.0f;
|
||||||
|
out.d1 = out.d2 = out.d3 = 0.0f;
|
||||||
|
out.d4 = 1.0f;
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
inline aiMatrix4x4& aiMatrix4x4::Translation( const aiVector3D& v, aiMatrix4x4& out)
|
inline aiMatrix4x4& aiMatrix4x4::Translation( const aiVector3D& v, aiMatrix4x4& out)
|
||||||
{
|
{
|
||||||
|
|
|
@ -76,30 +76,21 @@ Global
|
||||||
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|x64.ActiveCfg = Release|x64
|
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|x64.ActiveCfg = Release|x64
|
||||||
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|x64.Build.0 = Release|x64
|
{5691E159-2D9B-407F-971F-EA5C592DC524}.Release|x64.Build.0 = Release|x64
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|Win32.ActiveCfg = Debug_DLL|Win32
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|Win32.ActiveCfg = Debug_DLL|Win32
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|Win32.Build.0 = Debug_DLL|Win32
|
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|x64.ActiveCfg = Debug_DLL|x64
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|x64.ActiveCfg = Debug_DLL|x64
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug_DLL|x64.Build.0 = Debug_DLL|x64
|
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|Win32.ActiveCfg = Debug|Win32
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|x64.ActiveCfg = Debug|x64
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|Win32.ActiveCfg = Release_DLL|Win32
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|Win32.ActiveCfg = Release_DLL|Win32
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|Win32.Build.0 = Release_DLL|Win32
|
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|x64.ActiveCfg = Release_DLL|x64
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|x64.ActiveCfg = Release_DLL|x64
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release_DLL|x64.Build.0 = Release_DLL|x64
|
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|Win32.ActiveCfg = Release|Win32
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|Win32.Build.0 = Release|Win32
|
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.ActiveCfg = Release|x64
|
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.ActiveCfg = Release|x64
|
||||||
{9B9D1C90-8A03-409A-B547-AE7B48B90F1A}.Release|x64.Build.0 = Release|x64
|
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|Win32.ActiveCfg = Debug|Win32
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|Win32.ActiveCfg = Debug|Win32
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|x64.ActiveCfg = Debug|x64
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug_DLL|x64.ActiveCfg = Debug|x64
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|Win32.ActiveCfg = Debug|Win32
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.ActiveCfg = Debug|x64
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|Win32.ActiveCfg = Release|Win32
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|Win32.ActiveCfg = Release|Win32
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|x64.ActiveCfg = Release|x64
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release_DLL|x64.ActiveCfg = Release|x64
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|Win32.ActiveCfg = Release|Win32
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|Win32.ActiveCfg = Release|Win32
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|x64.ActiveCfg = Release|x64
|
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|x64.ActiveCfg = Release|x64
|
||||||
{FE78BFBA-4BA5-457D-8602-B800D498102D}.Release|x64.Build.0 = Release|x64
|
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -1422,6 +1422,26 @@
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="Collada"
|
||||||
|
>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\ColladaLoader.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\ColladaLoader.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\ColladaParser.cpp"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\code\ColladaParser.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="PostProcess"
|
Name="PostProcess"
|
||||||
|
|
Loading…
Reference in New Issue