From c40b7670166952bf813577044d2954f2125a8ef5 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 15 Feb 2012 18:28:08 +0100 Subject: [PATCH 1/2] Matrix to Quaternion conversion precision fix. See below links for reasoning, but in short, avoid sqrt and division of small values. It's also possible to normalize the quaternion after the conversion, but better precision is preferable. http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/ethan.htm --- include/assimp/quaternion.inl | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/assimp/quaternion.inl b/include/assimp/quaternion.inl index b6394b8a3..9113848b8 100644 --- a/include/assimp/quaternion.inl +++ b/include/assimp/quaternion.inl @@ -69,12 +69,12 @@ bool aiQuaterniont::operator!= (const aiQuaterniont& o) const template inline aiQuaterniont::aiQuaterniont( const aiMatrix3x3t &pRotMatrix) { - TReal t = 1 + pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3; + TReal t = pRotMatrix.a1 + pRotMatrix.b2 + pRotMatrix.c3; // large enough - if( t > static_cast(0.001)) + if( t > static_cast(0)) { - TReal s = sqrt( t) * static_cast(2.0); + TReal s = sqrt(1 + t) * static_cast(2.0); x = (pRotMatrix.c2 - pRotMatrix.b3) / s; y = (pRotMatrix.a3 - pRotMatrix.c1) / s; z = (pRotMatrix.b1 - pRotMatrix.a2) / s; From 771d804c46783da8427c557e7f4c6e48284768e4 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Fri, 16 Mar 2012 12:02:53 +0100 Subject: [PATCH 2/2] ColladaParser: Tolerate empty data arrays and controller weights. --- code/ColladaParser.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/code/ColladaParser.cpp b/code/ColladaParser.cpp index 41aaee320..2f7787b62 100644 --- a/code/ColladaParser.cpp +++ b/code/ColladaParser.cpp @@ -599,7 +599,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) if( mReader->getNodeType() == irr::io::EXN_ELEMENT) { // Input channels for weight data. Two possible semantics: "JOINT" and "WEIGHT" - if( IsElement( "input")) + if( IsElement( "input") && vertexCount > 0 ) { InputChannel channel; @@ -628,7 +628,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) if( !mReader->isEmptyElement()) SkipElement(); } - else if( IsElement( "vcount")) + else if( IsElement( "vcount") && vertexCount > 0 ) { // read weight count per vertex const char* text = GetTextContent(); @@ -648,7 +648,7 @@ void ColladaParser::ReadControllerWeights( Collada::Controller& pController) // reserve weight count pController.mWeights.resize( numWeights); } - else if( IsElement( "v")) + else if( IsElement( "v") && vertexCount > 0 ) { // read JointIndex - WeightIndex pairs const char* text = GetTextContent(); @@ -1656,6 +1656,7 @@ void ColladaParser::ReadDataArray() std::string id = mReader->getAttributeValue( indexID); int indexCount = GetAttribute( "count"); unsigned int count = (unsigned int) mReader->getAttributeValueAsInt( indexCount); + if (count == 0) { return; } // some exporters write empty data arrays with count="0" const char* content = TestTextContent(); // read values and store inside an array in the data library