next fixed warnings
This commit is contained in:
@@ -53,140 +53,94 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// Define as 1 to get verbose logging.
|
||||
#define OGRE_XML_SERIALIZER_DEBUG 0
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Ogre
|
||||
{
|
||||
namespace Assimp {
|
||||
namespace Ogre {
|
||||
|
||||
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader* reader, const std::string &name, const std::string &error)
|
||||
{
|
||||
if (!error.empty())
|
||||
{
|
||||
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void ThrowAttibuteError(const XmlReader *reader, const std::string &name, const std::string &error) {
|
||||
if (!error.empty()) {
|
||||
throw DeadlyImportError(error + " in node '" + std::string(reader->getNodeName()) + "' and attribute '" + name + "'");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
throw DeadlyImportError("Attribute '" + name + "' does not exist in node '" + std::string(reader->getNodeName()) + "'");
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const
|
||||
{
|
||||
if (HasAttribute(name))
|
||||
{
|
||||
return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name));
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowAttibuteError(m_reader, name);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const
|
||||
{
|
||||
if (HasAttribute(name))
|
||||
{
|
||||
/** @note This is hackish. But we are never expecting unsigned values that go outside the
|
||||
int32_t range. Just monitor for negative numbers and kill the import. */
|
||||
int32_t temp = ReadAttribute<int32_t>(name);
|
||||
if (temp >= 0)
|
||||
{
|
||||
return static_cast<uint32_t>(temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
template <>
|
||||
int32_t OgreXmlSerializer::ReadAttribute<int32_t>(const char *name) const {
|
||||
if (!HasAttribute(name)) {
|
||||
ThrowAttibuteError(m_reader, name);
|
||||
}
|
||||
return 0;
|
||||
|
||||
return static_cast<int32_t>(m_reader->getAttributeValueAsInt(name));
|
||||
}
|
||||
|
||||
template<>
|
||||
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const
|
||||
{
|
||||
if (HasAttribute(name))
|
||||
{
|
||||
return static_cast<uint16_t>(ReadAttribute<uint32_t>(name));
|
||||
}
|
||||
else
|
||||
{
|
||||
template <>
|
||||
uint32_t OgreXmlSerializer::ReadAttribute<uint32_t>(const char *name) const {
|
||||
if (!HasAttribute(name)) {
|
||||
ThrowAttibuteError(m_reader, name);
|
||||
}
|
||||
return 0;
|
||||
// @note This is hackish. But we are never expecting unsigned values that go outside the
|
||||
// int32_t range. Just monitor for negative numbers and kill the import.
|
||||
int32_t temp = ReadAttribute<int32_t>(name);
|
||||
if (temp < 0) {
|
||||
ThrowAttibuteError(m_reader, name, "Found a negative number value where expecting a uint32_t value");
|
||||
}
|
||||
|
||||
return static_cast<uint32_t>(temp);
|
||||
}
|
||||
|
||||
template<>
|
||||
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const
|
||||
{
|
||||
if (HasAttribute(name))
|
||||
{
|
||||
return m_reader->getAttributeValueAsFloat(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
template <>
|
||||
uint16_t OgreXmlSerializer::ReadAttribute<uint16_t>(const char *name) const {
|
||||
if (!HasAttribute(name)) {
|
||||
ThrowAttibuteError(m_reader, name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return static_cast<uint16_t>(ReadAttribute<uint32_t>(name));
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const
|
||||
{
|
||||
const char* value = m_reader->getAttributeValue(name);
|
||||
if (value)
|
||||
{
|
||||
return std::string(value);
|
||||
}
|
||||
else
|
||||
{
|
||||
template <>
|
||||
float OgreXmlSerializer::ReadAttribute<float>(const char *name) const {
|
||||
if (!HasAttribute(name)) {
|
||||
ThrowAttibuteError(m_reader, name);
|
||||
return "";
|
||||
}
|
||||
|
||||
return m_reader->getAttributeValueAsFloat(name);
|
||||
}
|
||||
|
||||
template<>
|
||||
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const
|
||||
{
|
||||
template <>
|
||||
std::string OgreXmlSerializer::ReadAttribute<std::string>(const char *name) const {
|
||||
const char *value = m_reader->getAttributeValue(name);
|
||||
if (nullptr == value) {
|
||||
ThrowAttibuteError(m_reader, name);
|
||||
}
|
||||
|
||||
return std::string(value);
|
||||
}
|
||||
|
||||
template <>
|
||||
bool OgreXmlSerializer::ReadAttribute<bool>(const char *name) const {
|
||||
std::string value = Ogre::ToLower(ReadAttribute<std::string>(name));
|
||||
if (ASSIMP_stricmp(value, "true") == 0)
|
||||
{
|
||||
if (ASSIMP_stricmp(value, "true") == 0) {
|
||||
return true;
|
||||
}
|
||||
else if (ASSIMP_stricmp(value, "false") == 0)
|
||||
{
|
||||
} else if (ASSIMP_stricmp(value, "false") == 0) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
ThrowAttibuteError(m_reader, name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool OgreXmlSerializer::HasAttribute(const char *name) const
|
||||
{
|
||||
bool OgreXmlSerializer::HasAttribute(const char *name) const {
|
||||
return (m_reader->getAttributeValue(name) != 0);
|
||||
}
|
||||
|
||||
std::string &OgreXmlSerializer::NextNode()
|
||||
{
|
||||
do
|
||||
{
|
||||
if (!m_reader->read())
|
||||
{
|
||||
std::string &OgreXmlSerializer::NextNode() {
|
||||
do {
|
||||
if (!m_reader->read()) {
|
||||
m_currentNodeName = "";
|
||||
return m_currentNodeName;
|
||||
}
|
||||
}
|
||||
while(m_reader->getNodeType() != irr::io::EXN_ELEMENT);
|
||||
} while (m_reader->getNodeType() != irr::io::EXN_ELEMENT);
|
||||
|
||||
CurrentNodeName(true);
|
||||
#if (OGRE_XML_SERIALIZER_DEBUG == 1)
|
||||
@@ -195,32 +149,29 @@ std::string &OgreXmlSerializer::NextNode()
|
||||
return m_currentNodeName;
|
||||
}
|
||||
|
||||
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const
|
||||
{
|
||||
bool OgreXmlSerializer::CurrentNodeNameEquals(const std::string &name) const {
|
||||
return (ASSIMP_stricmp(m_currentNodeName, name) == 0);
|
||||
}
|
||||
|
||||
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead)
|
||||
{
|
||||
std::string OgreXmlSerializer::CurrentNodeName(bool forceRead) {
|
||||
if (forceRead)
|
||||
m_currentNodeName = std::string(m_reader->getNodeName());
|
||||
return m_currentNodeName;
|
||||
}
|
||||
|
||||
std::string &OgreXmlSerializer::SkipCurrentNode()
|
||||
{
|
||||
std::string &OgreXmlSerializer::SkipCurrentNode() {
|
||||
#if (OGRE_XML_SERIALIZER_DEBUG == 1)
|
||||
ASSIMP_LOG_DEBUG("Skipping node <" + m_currentNodeName + ">");
|
||||
#endif
|
||||
|
||||
for(;;) {
|
||||
for (;;) {
|
||||
if (!m_reader->read()) {
|
||||
m_currentNodeName = "";
|
||||
return m_currentNodeName;
|
||||
}
|
||||
if ( m_reader->getNodeType() != irr::io::EXN_ELEMENT_END ) {
|
||||
if (m_reader->getNodeType() != irr::io::EXN_ELEMENT_END) {
|
||||
continue;
|
||||
} else if ( std::string( m_reader->getNodeName() ) == m_currentNodeName ) {
|
||||
} else if (std::string(m_reader->getNodeName()) == m_currentNodeName) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -231,38 +182,38 @@ std::string &OgreXmlSerializer::SkipCurrentNode()
|
||||
// Mesh XML constants
|
||||
|
||||
// <mesh>
|
||||
static const char *nnMesh = "mesh";
|
||||
static const char *nnSharedGeometry = "sharedgeometry";
|
||||
static const char *nnSubMeshes = "submeshes";
|
||||
static const char *nnSubMesh = "submesh";
|
||||
static const char *nnSubMeshNames = "submeshnames";
|
||||
static const char *nnSkeletonLink = "skeletonlink";
|
||||
static const char *nnLOD = "levelofdetail";
|
||||
static const char *nnExtremes = "extremes";
|
||||
static const char *nnPoses = "poses";
|
||||
static const char *nnAnimations = "animations";
|
||||
static const char *nnMesh = "mesh";
|
||||
static const char *nnSharedGeometry = "sharedgeometry";
|
||||
static const char *nnSubMeshes = "submeshes";
|
||||
static const char *nnSubMesh = "submesh";
|
||||
static const char *nnSubMeshNames = "submeshnames";
|
||||
static const char *nnSkeletonLink = "skeletonlink";
|
||||
static const char *nnLOD = "levelofdetail";
|
||||
static const char *nnExtremes = "extremes";
|
||||
static const char *nnPoses = "poses";
|
||||
static const char *nnAnimations = "animations";
|
||||
|
||||
// <submesh>
|
||||
static const char *nnFaces = "faces";
|
||||
static const char *nnFace = "face";
|
||||
static const char *nnGeometry = "geometry";
|
||||
static const char *nnTextures = "textures";
|
||||
static const char *nnFaces = "faces";
|
||||
static const char *nnFace = "face";
|
||||
static const char *nnGeometry = "geometry";
|
||||
static const char *nnTextures = "textures";
|
||||
|
||||
// <mesh/submesh>
|
||||
static const char *nnBoneAssignments = "boneassignments";
|
||||
static const char *nnBoneAssignments = "boneassignments";
|
||||
|
||||
// <sharedgeometry/geometry>
|
||||
static const char *nnVertexBuffer = "vertexbuffer";
|
||||
static const char *nnVertexBuffer = "vertexbuffer";
|
||||
|
||||
// <vertexbuffer>
|
||||
static const char *nnVertex = "vertex";
|
||||
static const char *nnPosition = "position";
|
||||
static const char *nnNormal = "normal";
|
||||
static const char *nnTangent = "tangent";
|
||||
static const char *nnBinormal = "binormal";
|
||||
static const char *nnTexCoord = "texcoord";
|
||||
static const char *nnColorDiffuse = "colour_diffuse";
|
||||
static const char *nnColorSpecular = "colour_specular";
|
||||
static const char *nnVertex = "vertex";
|
||||
static const char *nnPosition = "position";
|
||||
static const char *nnNormal = "normal";
|
||||
static const char *nnTangent = "tangent";
|
||||
static const char *nnBinormal = "binormal";
|
||||
static const char *nnTexCoord = "texcoord";
|
||||
static const char *nnColorDiffuse = "colour_diffuse";
|
||||
static const char *nnColorSpecular = "colour_specular";
|
||||
|
||||
// <boneassignments>
|
||||
static const char *nnVertexBoneAssignment = "vertexboneassignment";
|
||||
@@ -270,30 +221,30 @@ static const char *nnVertexBoneAssignment = "vertexboneassignment";
|
||||
// Skeleton XML constants
|
||||
|
||||
// <skeleton>
|
||||
static const char *nnSkeleton = "skeleton";
|
||||
static const char *nnBones = "bones";
|
||||
static const char *nnBoneHierarchy = "bonehierarchy";
|
||||
static const char *nnAnimationLinks = "animationlinks";
|
||||
static const char *nnSkeleton = "skeleton";
|
||||
static const char *nnBones = "bones";
|
||||
static const char *nnBoneHierarchy = "bonehierarchy";
|
||||
static const char *nnAnimationLinks = "animationlinks";
|
||||
|
||||
// <bones>
|
||||
static const char *nnBone = "bone";
|
||||
static const char *nnRotation = "rotation";
|
||||
static const char *nnAxis = "axis";
|
||||
static const char *nnScale = "scale";
|
||||
static const char *nnBone = "bone";
|
||||
static const char *nnRotation = "rotation";
|
||||
static const char *nnAxis = "axis";
|
||||
static const char *nnScale = "scale";
|
||||
|
||||
// <bonehierarchy>
|
||||
static const char *nnBoneParent = "boneparent";
|
||||
static const char *nnBoneParent = "boneparent";
|
||||
|
||||
// <animations>
|
||||
static const char *nnAnimation = "animation";
|
||||
static const char *nnTracks = "tracks";
|
||||
static const char *nnAnimation = "animation";
|
||||
static const char *nnTracks = "tracks";
|
||||
|
||||
// <tracks>
|
||||
static const char *nnTrack = "track";
|
||||
static const char *nnKeyFrames = "keyframes";
|
||||
static const char *nnKeyFrame = "keyframe";
|
||||
static const char *nnTranslate = "translate";
|
||||
static const char *nnRotate = "rotate";
|
||||
static const char *nnTrack = "track";
|
||||
static const char *nnKeyFrames = "keyframes";
|
||||
static const char *nnKeyFrame = "keyframe";
|
||||
static const char *nnTranslate = "translate";
|
||||
static const char *nnRotate = "rotate";
|
||||
|
||||
// Common XML constants
|
||||
|
||||
@@ -322,34 +273,26 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
|
||||
NextNode();
|
||||
|
||||
// Root level nodes
|
||||
while(m_currentNodeName == nnSharedGeometry ||
|
||||
m_currentNodeName == nnSubMeshes ||
|
||||
m_currentNodeName == nnSkeletonLink ||
|
||||
m_currentNodeName == nnBoneAssignments ||
|
||||
m_currentNodeName == nnLOD ||
|
||||
m_currentNodeName == nnSubMeshNames ||
|
||||
m_currentNodeName == nnExtremes ||
|
||||
m_currentNodeName == nnPoses ||
|
||||
m_currentNodeName == nnAnimations)
|
||||
{
|
||||
if (m_currentNodeName == nnSharedGeometry)
|
||||
{
|
||||
while (m_currentNodeName == nnSharedGeometry ||
|
||||
m_currentNodeName == nnSubMeshes ||
|
||||
m_currentNodeName == nnSkeletonLink ||
|
||||
m_currentNodeName == nnBoneAssignments ||
|
||||
m_currentNodeName == nnLOD ||
|
||||
m_currentNodeName == nnSubMeshNames ||
|
||||
m_currentNodeName == nnExtremes ||
|
||||
m_currentNodeName == nnPoses ||
|
||||
m_currentNodeName == nnAnimations) {
|
||||
if (m_currentNodeName == nnSharedGeometry) {
|
||||
mesh->sharedVertexData = new VertexDataXml();
|
||||
ReadGeometry(mesh->sharedVertexData);
|
||||
}
|
||||
else if (m_currentNodeName == nnSubMeshes)
|
||||
{
|
||||
} else if (m_currentNodeName == nnSubMeshes) {
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnSubMesh) {
|
||||
while (m_currentNodeName == nnSubMesh) {
|
||||
ReadSubMesh(mesh);
|
||||
}
|
||||
}
|
||||
else if (m_currentNodeName == nnBoneAssignments)
|
||||
{
|
||||
} else if (m_currentNodeName == nnBoneAssignments) {
|
||||
ReadBoneAssignments(mesh->sharedVertexData);
|
||||
}
|
||||
else if (m_currentNodeName == nnSkeletonLink)
|
||||
{
|
||||
} else if (m_currentNodeName == nnSkeletonLink) {
|
||||
mesh->skeletonRef = ReadAttribute<std::string>("name");
|
||||
ASSIMP_LOG_DEBUG_F("Read skeleton link ", mesh->skeletonRef);
|
||||
NextNode();
|
||||
@@ -360,49 +303,43 @@ void OgreXmlSerializer::ReadMesh(MeshXml *mesh) {
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest)
|
||||
{
|
||||
void OgreXmlSerializer::ReadGeometry(VertexDataXml *dest) {
|
||||
dest->count = ReadAttribute<uint32_t>("vertexcount");
|
||||
ASSIMP_LOG_DEBUG_F( " - Reading geometry of ", dest->count, " vertices");
|
||||
ASSIMP_LOG_DEBUG_F(" - Reading geometry of ", dest->count, " vertices");
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnVertexBuffer) {
|
||||
while (m_currentNodeName == nnVertexBuffer) {
|
||||
ReadGeometryVertexBuffer(dest);
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
|
||||
{
|
||||
void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest) {
|
||||
bool positions = (HasAttribute("positions") && ReadAttribute<bool>("positions"));
|
||||
bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals"));
|
||||
bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents"));
|
||||
uint32_t uvs = (HasAttribute("texture_coords") ? ReadAttribute<uint32_t>("texture_coords") : 0);
|
||||
bool normals = (HasAttribute("normals") && ReadAttribute<bool>("normals"));
|
||||
bool tangents = (HasAttribute("tangents") && ReadAttribute<bool>("tangents"));
|
||||
uint32_t uvs = (HasAttribute("texture_coords") ? ReadAttribute<uint32_t>("texture_coords") : 0);
|
||||
|
||||
// Not having positions is a error only if a previous vertex buffer did not have them.
|
||||
if (!positions && !dest->HasPositions()) {
|
||||
throw DeadlyImportError("Vertex buffer does not contain positions!");
|
||||
}
|
||||
|
||||
if (positions)
|
||||
{
|
||||
if (positions) {
|
||||
ASSIMP_LOG_DEBUG(" - Contains positions");
|
||||
dest->positions.reserve(dest->count);
|
||||
}
|
||||
if (normals)
|
||||
{
|
||||
if (normals) {
|
||||
ASSIMP_LOG_DEBUG(" - Contains normals");
|
||||
dest->normals.reserve(dest->count);
|
||||
}
|
||||
if (tangents)
|
||||
{
|
||||
if (tangents) {
|
||||
ASSIMP_LOG_DEBUG(" - Contains tangents");
|
||||
dest->tangents.reserve(dest->count);
|
||||
}
|
||||
if (uvs > 0)
|
||||
{
|
||||
ASSIMP_LOG_DEBUG_F( " - Contains ", uvs, " texture coords");
|
||||
if (uvs > 0) {
|
||||
ASSIMP_LOG_DEBUG_F(" - Contains ", uvs, " texture coords");
|
||||
dest->uvs.resize(uvs);
|
||||
for(size_t i=0, len=dest->uvs.size(); i<len; ++i) {
|
||||
for (size_t i = 0, len = dest->uvs.size(); i < len; ++i) {
|
||||
dest->uvs[i].reserve(dest->count);
|
||||
}
|
||||
}
|
||||
@@ -413,49 +350,40 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
|
||||
|
||||
NextNode();
|
||||
|
||||
while(m_currentNodeName == nnVertex ||
|
||||
m_currentNodeName == nnPosition ||
|
||||
m_currentNodeName == nnNormal ||
|
||||
m_currentNodeName == nnTangent ||
|
||||
m_currentNodeName == nnBinormal ||
|
||||
m_currentNodeName == nnTexCoord ||
|
||||
m_currentNodeName == nnColorDiffuse ||
|
||||
m_currentNodeName == nnColorSpecular)
|
||||
{
|
||||
while (m_currentNodeName == nnVertex ||
|
||||
m_currentNodeName == nnPosition ||
|
||||
m_currentNodeName == nnNormal ||
|
||||
m_currentNodeName == nnTangent ||
|
||||
m_currentNodeName == nnBinormal ||
|
||||
m_currentNodeName == nnTexCoord ||
|
||||
m_currentNodeName == nnColorDiffuse ||
|
||||
m_currentNodeName == nnColorSpecular) {
|
||||
if (m_currentNodeName == nnVertex) {
|
||||
NextNode();
|
||||
}
|
||||
|
||||
/// @todo Implement nnBinormal, nnColorDiffuse and nnColorSpecular
|
||||
|
||||
if (positions && m_currentNodeName == nnPosition)
|
||||
{
|
||||
if (positions && m_currentNodeName == nnPosition) {
|
||||
aiVector3D pos;
|
||||
pos.x = ReadAttribute<float>(anX);
|
||||
pos.y = ReadAttribute<float>(anY);
|
||||
pos.z = ReadAttribute<float>(anZ);
|
||||
dest->positions.push_back(pos);
|
||||
}
|
||||
else if (normals && m_currentNodeName == nnNormal)
|
||||
{
|
||||
} else if (normals && m_currentNodeName == nnNormal) {
|
||||
aiVector3D normal;
|
||||
normal.x = ReadAttribute<float>(anX);
|
||||
normal.y = ReadAttribute<float>(anY);
|
||||
normal.z = ReadAttribute<float>(anZ);
|
||||
dest->normals.push_back(normal);
|
||||
}
|
||||
else if (tangents && m_currentNodeName == nnTangent)
|
||||
{
|
||||
} else if (tangents && m_currentNodeName == nnTangent) {
|
||||
aiVector3D tangent;
|
||||
tangent.x = ReadAttribute<float>(anX);
|
||||
tangent.y = ReadAttribute<float>(anY);
|
||||
tangent.z = ReadAttribute<float>(anZ);
|
||||
dest->tangents.push_back(tangent);
|
||||
}
|
||||
else if (uvs > 0 && m_currentNodeName == nnTexCoord)
|
||||
{
|
||||
for(auto &uvs : dest->uvs)
|
||||
{
|
||||
} else if (uvs > 0 && m_currentNodeName == nnTexCoord) {
|
||||
for (auto &curUvs : dest->uvs) {
|
||||
if (m_currentNodeName != nnTexCoord) {
|
||||
throw DeadlyImportError("Vertex buffer declared more UVs than can be found in a vertex");
|
||||
}
|
||||
@@ -463,47 +391,31 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
|
||||
aiVector3D uv;
|
||||
uv.x = ReadAttribute<float>("u");
|
||||
uv.y = (ReadAttribute<float>("v") * -1) + 1; // Flip UV from Ogre to Assimp form
|
||||
uvs.push_back(uv);
|
||||
curUvs.push_back(uv);
|
||||
|
||||
NextNode();
|
||||
}
|
||||
// Continue main loop as above already read next node
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/// @todo Remove this stuff once implemented. We only want to log warnings once per element.
|
||||
bool warn = true;
|
||||
if (m_currentNodeName == nnBinormal)
|
||||
{
|
||||
if (warnBinormal)
|
||||
{
|
||||
if (m_currentNodeName == nnBinormal) {
|
||||
if (warnBinormal) {
|
||||
warnBinormal = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
warn = false;
|
||||
}
|
||||
}
|
||||
else if (m_currentNodeName == nnColorDiffuse)
|
||||
{
|
||||
if (warnColorDiffuse)
|
||||
{
|
||||
} else if (m_currentNodeName == nnColorDiffuse) {
|
||||
if (warnColorDiffuse) {
|
||||
warnColorDiffuse = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
warn = false;
|
||||
}
|
||||
}
|
||||
else if (m_currentNodeName == nnColorSpecular)
|
||||
{
|
||||
if (warnColorSpecular)
|
||||
{
|
||||
} else if (m_currentNodeName == nnColorSpecular) {
|
||||
if (warnColorSpecular) {
|
||||
warnColorSpecular = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
warn = false;
|
||||
}
|
||||
}
|
||||
@@ -518,7 +430,7 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
|
||||
|
||||
// Sanity checks
|
||||
if (dest->positions.size() != dest->count) {
|
||||
throw DeadlyImportError(Formatter::format() << "Read only " << dest->positions.size() << " positions when should have read " << dest->count);
|
||||
throw DeadlyImportError(Formatter::format() << "Read only " << dest->positions.size() << " positions when should have read " << dest->count);
|
||||
}
|
||||
if (normals && dest->normals.size() != dest->count) {
|
||||
throw DeadlyImportError(Formatter::format() << "Read only " << dest->normals.size() << " normals when should have read " << dest->count);
|
||||
@@ -526,26 +438,24 @@ void OgreXmlSerializer::ReadGeometryVertexBuffer(VertexDataXml *dest)
|
||||
if (tangents && dest->tangents.size() != dest->count) {
|
||||
throw DeadlyImportError(Formatter::format() << "Read only " << dest->tangents.size() << " tangents when should have read " << dest->count);
|
||||
}
|
||||
for(unsigned int i=0; i<dest->uvs.size(); ++i)
|
||||
{
|
||||
for (unsigned int i = 0; i < dest->uvs.size(); ++i) {
|
||||
if (dest->uvs[i].size() != dest->count) {
|
||||
throw DeadlyImportError(Formatter::format() << "Read only " << dest->uvs[i].size()
|
||||
<< " uvs for uv index " << i << " when should have read " << dest->count);
|
||||
<< " uvs for uv index " << i << " when should have read " << dest->count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
|
||||
{
|
||||
static const char *anMaterial = "material";
|
||||
void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh) {
|
||||
static const char *anMaterial = "material";
|
||||
static const char *anUseSharedVertices = "usesharedvertices";
|
||||
static const char *anCount = "count";
|
||||
static const char *anV1 = "v1";
|
||||
static const char *anV2 = "v2";
|
||||
static const char *anV3 = "v3";
|
||||
static const char *anV4 = "v4";
|
||||
static const char *anCount = "count";
|
||||
static const char *anV1 = "v1";
|
||||
static const char *anV2 = "v2";
|
||||
static const char *anV3 = "v3";
|
||||
static const char *anV4 = "v4";
|
||||
|
||||
SubMeshXml* submesh = new SubMeshXml();
|
||||
SubMeshXml *submesh = new SubMeshXml();
|
||||
|
||||
if (HasAttribute(anMaterial)) {
|
||||
submesh->materialRef = ReadAttribute<std::string>(anMaterial);
|
||||
@@ -554,9 +464,9 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
|
||||
submesh->usesSharedVertexData = ReadAttribute<bool>(anUseSharedVertices);
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG_F( "Reading SubMesh ", mesh->subMeshes.size());
|
||||
ASSIMP_LOG_DEBUG_F( " - Material: '", submesh->materialRef, "'");
|
||||
ASSIMP_LOG_DEBUG_F( " - Uses shared geometry: ", (submesh->usesSharedVertexData ? "true" : "false"));
|
||||
ASSIMP_LOG_DEBUG_F("Reading SubMesh ", mesh->subMeshes.size());
|
||||
ASSIMP_LOG_DEBUG_F(" - Material: '", submesh->materialRef, "'");
|
||||
ASSIMP_LOG_DEBUG_F(" - Uses shared geometry: ", (submesh->usesSharedVertexData ? "true" : "false"));
|
||||
|
||||
// TODO: maybe we have always just 1 faces and 1 geometry and always in this order. this loop will only work correct, when the order
|
||||
// of faces and geometry changed, and not if we have more than one of one
|
||||
@@ -565,19 +475,16 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
|
||||
bool quadWarned = false;
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnFaces ||
|
||||
m_currentNodeName == nnGeometry ||
|
||||
m_currentNodeName == nnTextures ||
|
||||
m_currentNodeName == nnBoneAssignments)
|
||||
{
|
||||
if (m_currentNodeName == nnFaces)
|
||||
{
|
||||
while (m_currentNodeName == nnFaces ||
|
||||
m_currentNodeName == nnGeometry ||
|
||||
m_currentNodeName == nnTextures ||
|
||||
m_currentNodeName == nnBoneAssignments) {
|
||||
if (m_currentNodeName == nnFaces) {
|
||||
submesh->indexData->faceCount = ReadAttribute<uint32_t>(anCount);
|
||||
submesh->indexData->faces.reserve(submesh->indexData->faceCount);
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnFace)
|
||||
{
|
||||
while (m_currentNodeName == nnFace) {
|
||||
aiFace face;
|
||||
face.mNumIndices = 3;
|
||||
face.mIndices = new unsigned int[3];
|
||||
@@ -598,7 +505,7 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
|
||||
}
|
||||
|
||||
if (submesh->indexData->faces.size() == submesh->indexData->faceCount) {
|
||||
ASSIMP_LOG_DEBUG_F( " - Faces ", submesh->indexData->faceCount);
|
||||
ASSIMP_LOG_DEBUG_F(" - Faces ", submesh->indexData->faceCount);
|
||||
} else {
|
||||
throw DeadlyImportError(Formatter::format() << "Read only " << submesh->indexData->faces.size() << " faces when should have read " << submesh->indexData->faceCount);
|
||||
}
|
||||
@@ -622,21 +529,19 @@ void OgreXmlSerializer::ReadSubMesh(MeshXml *mesh)
|
||||
mesh->subMeshes.push_back(submesh);
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
|
||||
{
|
||||
void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest) {
|
||||
if (!dest) {
|
||||
throw DeadlyImportError("Cannot read bone assignments, vertex data is null.");
|
||||
}
|
||||
|
||||
static const char *anVertexIndex = "vertexindex";
|
||||
static const char *anBoneIndex = "boneindex";
|
||||
static const char *anWeight = "weight";
|
||||
static const char *anBoneIndex = "boneindex";
|
||||
static const char *anWeight = "weight";
|
||||
|
||||
std::set<uint32_t> influencedVertices;
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnVertexBoneAssignment)
|
||||
{
|
||||
while (m_currentNodeName == nnVertexBoneAssignment) {
|
||||
VertexBoneAssignment ba;
|
||||
ba.vertexIndex = ReadAttribute<uint32_t>(anVertexIndex);
|
||||
ba.boneIndex = ReadAttribute<uint16_t>(anBoneIndex);
|
||||
@@ -652,38 +557,32 @@ void OgreXmlSerializer::ReadBoneAssignments(VertexDataXml *dest)
|
||||
Some exporters won't care if the sum of all bone weights
|
||||
for a single vertex equals 1 or not, so validate here. */
|
||||
const float epsilon = 0.05f;
|
||||
for (const uint32_t vertexIndex : influencedVertices)
|
||||
{
|
||||
for (const uint32_t vertexIndex : influencedVertices) {
|
||||
float sum = 0.0f;
|
||||
for (VertexBoneAssignmentList::const_iterator baIter=dest->boneAssignments.begin(), baEnd=dest->boneAssignments.end(); baIter != baEnd; ++baIter)
|
||||
{
|
||||
for (VertexBoneAssignmentList::const_iterator baIter = dest->boneAssignments.begin(), baEnd = dest->boneAssignments.end(); baIter != baEnd; ++baIter) {
|
||||
if (baIter->vertexIndex == vertexIndex)
|
||||
sum += baIter->weight;
|
||||
}
|
||||
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon)))
|
||||
{
|
||||
for (auto &boneAssign : dest->boneAssignments)
|
||||
{
|
||||
if ((sum < (1.0f - epsilon)) || (sum > (1.0f + epsilon))) {
|
||||
for (auto &boneAssign : dest->boneAssignments) {
|
||||
if (boneAssign.vertexIndex == vertexIndex)
|
||||
boneAssign.weight /= sum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSIMP_LOG_DEBUG_F( " - ", dest->boneAssignments.size(), " bone assignments");
|
||||
ASSIMP_LOG_DEBUG_F(" - ", dest->boneAssignments.size(), " bone assignments");
|
||||
}
|
||||
|
||||
// Skeleton
|
||||
|
||||
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh)
|
||||
{
|
||||
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *mesh) {
|
||||
if (!mesh || mesh->skeletonRef.empty())
|
||||
return false;
|
||||
|
||||
// Highly unusual to see in read world cases but support
|
||||
// XML mesh referencing a binary skeleton file.
|
||||
if (EndsWith(mesh->skeletonRef, ".skeleton", false))
|
||||
{
|
||||
if (EndsWith(mesh->skeletonRef, ".skeleton", false)) {
|
||||
if (OgreBinarySerializer::ImportSkeleton(pIOHandler, mesh))
|
||||
return true;
|
||||
|
||||
@@ -705,8 +604,7 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, MeshXml *me
|
||||
return true;
|
||||
}
|
||||
|
||||
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
|
||||
{
|
||||
bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh) {
|
||||
if (!mesh || mesh->skeletonRef.empty())
|
||||
return false;
|
||||
|
||||
@@ -721,16 +619,13 @@ bool OgreXmlSerializer::ImportSkeleton(Assimp::IOSystem *pIOHandler, Mesh *mesh)
|
||||
return true;
|
||||
}
|
||||
|
||||
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename)
|
||||
{
|
||||
if (!EndsWith(filename, ".skeleton.xml", false))
|
||||
{
|
||||
XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const std::string &filename) {
|
||||
if (!EndsWith(filename, ".skeleton.xml", false)) {
|
||||
ASSIMP_LOG_ERROR_F("Imported Mesh is referencing to unsupported '", filename, "' skeleton file.");
|
||||
return XmlReaderPtr();
|
||||
}
|
||||
|
||||
if (!pIOHandler->Exists(filename))
|
||||
{
|
||||
if (!pIOHandler->Exists(filename)) {
|
||||
ASSIMP_LOG_ERROR_F("Failed to find skeleton file '", filename, "' that is referenced by imported Mesh.");
|
||||
return XmlReaderPtr();
|
||||
}
|
||||
@@ -748,8 +643,7 @@ XmlReaderPtr OgreXmlSerializer::OpenReader(Assimp::IOSystem *pIOHandler, const s
|
||||
return reader;
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
|
||||
{
|
||||
void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton) {
|
||||
if (NextNode() != nnSkeleton) {
|
||||
throw DeadlyImportError("Root node is <" + m_currentNodeName + "> expecting <skeleton>");
|
||||
}
|
||||
@@ -758,18 +652,16 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
|
||||
|
||||
// Optional blend mode from root node
|
||||
if (HasAttribute("blendmode")) {
|
||||
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative"
|
||||
? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
|
||||
skeleton->blendMode = (ToLower(ReadAttribute<std::string>("blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
|
||||
}
|
||||
|
||||
NextNode();
|
||||
|
||||
// Root level nodes
|
||||
while(m_currentNodeName == nnBones ||
|
||||
m_currentNodeName == nnBoneHierarchy ||
|
||||
m_currentNodeName == nnAnimations ||
|
||||
m_currentNodeName == nnAnimationLinks)
|
||||
{
|
||||
while (m_currentNodeName == nnBones ||
|
||||
m_currentNodeName == nnBoneHierarchy ||
|
||||
m_currentNodeName == nnAnimations ||
|
||||
m_currentNodeName == nnAnimationLinks) {
|
||||
if (m_currentNodeName == nnBones)
|
||||
ReadBones(skeleton);
|
||||
else if (m_currentNodeName == nnBoneHierarchy)
|
||||
@@ -781,8 +673,7 @@ void OgreXmlSerializer::ReadSkeleton(Skeleton *skeleton)
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
|
||||
{
|
||||
void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton) {
|
||||
if (skeleton->bones.empty()) {
|
||||
throw DeadlyImportError("Cannot read <animations> for a Skeleton without bones");
|
||||
}
|
||||
@@ -790,8 +681,7 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
|
||||
ASSIMP_LOG_DEBUG(" - Animations");
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnAnimation)
|
||||
{
|
||||
while (m_currentNodeName == nnAnimation) {
|
||||
Animation *anim = new Animation(skeleton);
|
||||
anim->name = ReadAttribute<std::string>("name");
|
||||
anim->length = ReadAttribute<float>("length");
|
||||
@@ -803,15 +693,13 @@ void OgreXmlSerializer::ReadAnimations(Skeleton *skeleton)
|
||||
ReadAnimationTracks(anim);
|
||||
skeleton->animations.push_back(anim);
|
||||
|
||||
ASSIMP_LOG_DEBUG_F( " ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)");
|
||||
ASSIMP_LOG_DEBUG_F(" ", anim->name, " (", anim->length, " sec, ", anim->tracks.size(), " tracks)");
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
|
||||
{
|
||||
void OgreXmlSerializer::ReadAnimationTracks(Animation *dest) {
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnTrack)
|
||||
{
|
||||
while (m_currentNodeName == nnTrack) {
|
||||
VertexAnimationTrack track;
|
||||
track.type = VertexAnimationTrack::VAT_TRANSFORM;
|
||||
track.boneName = ReadAttribute<std::string>("bone");
|
||||
@@ -826,27 +714,21 @@ void OgreXmlSerializer::ReadAnimationTracks(Animation *dest)
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest)
|
||||
{
|
||||
void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationTrack *dest) {
|
||||
const aiVector3D zeroVec(0.f, 0.f, 0.f);
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnKeyFrame)
|
||||
{
|
||||
while (m_currentNodeName == nnKeyFrame) {
|
||||
TransformKeyFrame keyframe;
|
||||
keyframe.timePos = ReadAttribute<float>("time");
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale)
|
||||
{
|
||||
if (m_currentNodeName == nnTranslate)
|
||||
{
|
||||
while (m_currentNodeName == nnTranslate || m_currentNodeName == nnRotate || m_currentNodeName == nnScale) {
|
||||
if (m_currentNodeName == nnTranslate) {
|
||||
keyframe.position.x = ReadAttribute<float>(anX);
|
||||
keyframe.position.y = ReadAttribute<float>(anY);
|
||||
keyframe.position.z = ReadAttribute<float>(anZ);
|
||||
}
|
||||
else if (m_currentNodeName == nnRotate)
|
||||
{
|
||||
} else if (m_currentNodeName == nnRotate) {
|
||||
float angle = ReadAttribute<float>("angle");
|
||||
|
||||
if (NextNode() != nnAxis) {
|
||||
@@ -857,17 +739,14 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
|
||||
axis.x = ReadAttribute<float>(anX);
|
||||
axis.y = ReadAttribute<float>(anY);
|
||||
axis.z = ReadAttribute<float>(anZ);
|
||||
if (axis.Equal(zeroVec))
|
||||
{
|
||||
if (axis.Equal(zeroVec)) {
|
||||
axis.x = 1.0f;
|
||||
if (angle != 0) {
|
||||
ASSIMP_LOG_WARN_F("Found invalid a key frame with a zero rotation axis in animation: ", anim->name);
|
||||
}
|
||||
}
|
||||
keyframe.rotation = aiQuaternion(axis, angle);
|
||||
}
|
||||
else if (m_currentNodeName == nnScale)
|
||||
{
|
||||
} else if (m_currentNodeName == nnScale) {
|
||||
keyframe.scale.x = ReadAttribute<float>(anX);
|
||||
keyframe.scale.y = ReadAttribute<float>(anY);
|
||||
keyframe.scale.z = ReadAttribute<float>(anZ);
|
||||
@@ -880,14 +759,12 @@ void OgreXmlSerializer::ReadAnimationKeyFrames(Animation *anim, VertexAnimationT
|
||||
}
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
|
||||
{
|
||||
void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton) {
|
||||
if (skeleton->bones.empty()) {
|
||||
throw DeadlyImportError("Cannot read <bonehierarchy> for a Skeleton without bones");
|
||||
}
|
||||
|
||||
while(NextNode() == nnBoneParent)
|
||||
{
|
||||
while (NextNode() == nnBoneParent) {
|
||||
const std::string name = ReadAttribute<std::string>("bone");
|
||||
const std::string parentName = ReadAttribute<std::string>("parent");
|
||||
|
||||
@@ -901,46 +778,38 @@ void OgreXmlSerializer::ReadBoneHierarchy(Skeleton *skeleton)
|
||||
}
|
||||
|
||||
// Calculate bone matrices for root bones. Recursively calculates their children.
|
||||
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
|
||||
{
|
||||
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
|
||||
Bone *bone = skeleton->bones[i];
|
||||
if (!bone->IsParented())
|
||||
bone->CalculateWorldMatrixAndDefaultPose(skeleton);
|
||||
}
|
||||
}
|
||||
|
||||
static bool BoneCompare(Bone *a, Bone *b)
|
||||
{
|
||||
ai_assert( nullptr != a );
|
||||
ai_assert( nullptr != b );
|
||||
|
||||
static bool BoneCompare(Bone *a, Bone *b) {
|
||||
ai_assert(nullptr != a);
|
||||
ai_assert(nullptr != b);
|
||||
|
||||
return (a->id < b->id);
|
||||
}
|
||||
|
||||
void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
|
||||
{
|
||||
void OgreXmlSerializer::ReadBones(Skeleton *skeleton) {
|
||||
ASSIMP_LOG_DEBUG(" - Bones");
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnBone)
|
||||
{
|
||||
while (m_currentNodeName == nnBone) {
|
||||
Bone *bone = new Bone();
|
||||
bone->id = ReadAttribute<uint16_t>("id");
|
||||
bone->name = ReadAttribute<std::string>("name");
|
||||
|
||||
NextNode();
|
||||
while(m_currentNodeName == nnPosition ||
|
||||
m_currentNodeName == nnRotation ||
|
||||
m_currentNodeName == nnScale)
|
||||
{
|
||||
if (m_currentNodeName == nnPosition)
|
||||
{
|
||||
while (m_currentNodeName == nnPosition ||
|
||||
m_currentNodeName == nnRotation ||
|
||||
m_currentNodeName == nnScale) {
|
||||
if (m_currentNodeName == nnPosition) {
|
||||
bone->position.x = ReadAttribute<float>(anX);
|
||||
bone->position.y = ReadAttribute<float>(anY);
|
||||
bone->position.z = ReadAttribute<float>(anZ);
|
||||
}
|
||||
else if (m_currentNodeName == nnRotation)
|
||||
{
|
||||
} else if (m_currentNodeName == nnRotation) {
|
||||
float angle = ReadAttribute<float>("angle");
|
||||
|
||||
if (NextNode() != nnAxis) {
|
||||
@@ -953,17 +822,12 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
|
||||
axis.z = ReadAttribute<float>(anZ);
|
||||
|
||||
bone->rotation = aiQuaternion(axis, angle);
|
||||
}
|
||||
else if (m_currentNodeName == nnScale)
|
||||
{
|
||||
} else if (m_currentNodeName == nnScale) {
|
||||
/// @todo Implement taking scale into account in matrix/pose calculations!
|
||||
if (HasAttribute("factor"))
|
||||
{
|
||||
if (HasAttribute("factor")) {
|
||||
float factor = ReadAttribute<float>("factor");
|
||||
bone->scale.Set(factor, factor, factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
if (HasAttribute(anX))
|
||||
bone->scale.x = ReadAttribute<float>(anX);
|
||||
if (HasAttribute(anY))
|
||||
@@ -985,10 +849,9 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
|
||||
// Validate that bone indexes are not skipped.
|
||||
/** @note Left this from original authors code, but not sure if this is strictly necessary
|
||||
as per the Ogre skeleton spec. It might be more that other (later) code in this imported does not break. */
|
||||
for (size_t i=0, len=skeleton->bones.size(); i<len; ++i)
|
||||
{
|
||||
for (size_t i = 0, len = skeleton->bones.size(); i < len; ++i) {
|
||||
Bone *b = skeleton->bones[i];
|
||||
ASSIMP_LOG_DEBUG_F( " ", b->id, " ", b->name);
|
||||
ASSIMP_LOG_DEBUG_F(" ", b->id, " ", b->name);
|
||||
|
||||
if (b->id != static_cast<uint16_t>(i)) {
|
||||
throw DeadlyImportError(Formatter::format() << "Bone ids are not in sequence starting from 0. Missing index " << i);
|
||||
@@ -996,7 +859,7 @@ void OgreXmlSerializer::ReadBones(Skeleton *skeleton)
|
||||
}
|
||||
}
|
||||
|
||||
} // Ogre
|
||||
} // Assimp
|
||||
} // namespace Ogre
|
||||
} // namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER
|
||||
|
||||
Reference in New Issue
Block a user