diff --git a/source/collada/PMDConvert.cpp.orig b/source/collada/PMDConvert.cpp.orig
deleted file mode 100644
index 52f9061518..0000000000
--- a/source/collada/PMDConvert.cpp.orig
+++ /dev/null
@@ -1,722 +0,0 @@
-/* Copyright (C) 2012 Wildfire Games.
- * This file is part of 0 A.D.
- *
- * 0 A.D. is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * 0 A.D. is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with 0 A.D. If not, see .
- */
-
-#include "precompiled.h"
-
-#include "PMDConvert.h"
-#include "CommonConvert.h"
-
-#include "FCollada.h"
-#include "FCDocument/FCDAsset.h"
-#include "FCDocument/FCDocument.h"
-#include "FCDocument/FCDocumentTools.h"
-#include "FCDocument/FCDController.h"
-#include "FCDocument/FCDControllerInstance.h"
-#include "FCDocument/FCDGeometry.h"
-#include "FCDocument/FCDGeometryMesh.h"
-#include "FCDocument/FCDGeometryPolygons.h"
-#include "FCDocument/FCDGeometryPolygonsInput.h"
-#include "FCDocument/FCDGeometryPolygonsTools.h"
-#include "FCDocument/FCDGeometrySource.h"
-#include "FCDocument/FCDSceneNode.h"
-#include "FCDocument/FCDSkinController.h"
-
-#include "StdSkeletons.h"
-#include "Decompose.h"
-#include "Maths.h"
-#include "GeomReindex.h"
-
-#include
-#include
-
-const size_t maxInfluences = 4;
-struct VertexBlend
-{
- uint8 bones[maxInfluences];
- float weights[maxInfluences];
-};
-VertexBlend defaultInfluences = { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0, 0, 0, 0 } };
-
-struct PropPoint
-{
- std::string name;
- float translation[3];
- float orientation[4];
- uint8 bone;
-};
-
-// Based on FMVector3::Normalize, but that function uses a static member
-// FMVector3::XAxis which causes irritating linker errors. Rather than trying
-// to make that XAxis work in a cross-platform way, just reimplement Normalize:
-static FMVector3 FMVector3_Normalize(const FMVector3& vec)
-{
- float l = vec.Length();
- if (l > 0.0f)
- return FMVector3(vec.x/l, vec.y/l, vec.z/l);
- else
- return FMVector3(1.0f, 0.0f, 0.0f);
-}
-
-static void AddStaticPropPoints(std::vector &propPoints, const FMMatrix44& upAxisTransform, FCDSceneNode* node)
-{
- if (node->GetName().find("prop-") == 0 || node->GetName().find("prop_") == 0)
- {
- // Strip off the "prop-" from the name
- std::string propPointName (node->GetName().substr(5));
-
- Log(LOG_INFO, "Adding prop point %s", propPointName.c_str());
-
- // CalculateWorldTransform applies transformations recursively for all parents of this node
- // upAxisTransform transforms this node to right-handed Z_UP coordinates
-
- FMMatrix44 transform = upAxisTransform * node->CalculateWorldTransform();
-
- HMatrix matrix;
- memcpy(matrix, transform.Transposed().m, sizeof(matrix));
-
- AffineParts parts;
- decomp_affine(matrix, &parts);
-
- // Add prop point in game coordinates
-
- PropPoint p = {
- propPointName,
-
- // Flip translation across the x-axis by swapping y and z
- { parts.t.x, parts.t.z, parts.t.y },
-
- // To convert the quaternions: imagine you're using the axis/angle
- // representation, then swap the y,z basis vectors and change the
- // direction of rotation by negating the angle ( => negating sin(angle)
- // => negating x,y,z => changing (x,y,z,w) to (-x,-z,-y,w)
- // but then (-x,-z,-y,w) == (x,z,y,-w) so do that instead)
- { parts.q.x, parts.q.z, parts.q.y, -parts.q.w },
-
- 0xff
- };
- propPoints.push_back(p);
- }
-
- // Search children for prop points
- for (size_t i = 0; i < node->GetChildrenCount(); ++i)
- AddStaticPropPoints(propPoints, upAxisTransform, node->GetChild(i));
-}
-
-class PMDConvert
-{
-public:
- /**
- * Converts a COLLADA XML document into the PMD mesh format.
- *
- * @param input XML document to parse
- * @param output callback for writing the PMD data; called lots of times
- * with small strings
- * @param xmlErrors output - errors reported by the XML parser
- * @throws ColladaException on failure
- */
- static void ColladaToPMD(const char* input, OutputCB& output, std::string& xmlErrors)
- {
- CommonConvert converter(input, xmlErrors);
-
- if (converter.GetInstance().GetEntity()->GetType() == FCDEntity::GEOMETRY)
- {
- Log(LOG_INFO, "Found static geometry");
-
- FCDGeometryPolygons* polys = GetPolysFromGeometry((FCDGeometry*)converter.GetInstance().GetEntity());
-
- // Convert the geometry into a suitable form for the game
- ReindexGeometry(polys);
-
- std::vector boneWeights; // unused
- std::vector boneTransforms; // unused
- std::vector propPoints;
-
- // Get the raw vertex data
-
- FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION);
- FCDGeometryPolygonsInput* inputNormal = polys->FindInput(FUDaeGeometryInput::NORMAL);
-
- const uint32* indicesCombined = inputPosition->GetIndices();
- size_t indicesCombinedCount = inputPosition->GetIndexCount();
- // (ReindexGeometry guarantees position/normal/texcoord have the same indexes)
-
- FCDGeometrySource* sourcePosition = inputPosition->GetSource();
- FCDGeometrySource* sourceNormal = inputNormal ->GetSource();
-
- FCDGeometrySourceList texcoordSources;
- polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources);
-
- float* dataPosition = sourcePosition->GetData();
- float* dataNormal = sourceNormal ->GetData();
- size_t vertexCount = sourcePosition->GetDataCount() / 3;
- assert(sourcePosition->GetDataCount() == vertexCount*3);
- assert(sourceNormal ->GetDataCount() == vertexCount*3);
-
- std::vector dataTexcoords;
- for (size_t i = 0; i < texcoordSources.size(); ++i)
- {
- dataTexcoords.push_back(texcoordSources[i]->GetData());
- assert(texcoordSources[i]->GetDataCount() == vertexCount*2);
- }
-
- // Transform mesh coordinate system to game coordinates
- // (doesn't modify prop points)
-
- TransformStaticModel(dataPosition, dataNormal, vertexCount, converter.GetEntityTransform(), converter.IsYUp());
-
- // Add static prop points
- // which are empty child nodes of the main parent
-
- // Default prop points are already given in game coordinates
- AddDefaultPropPoints(propPoints);
-
- // Calculate transform to convert from COLLADA-defined up_axis to Z-up because
- // it's relatively straightforward to convert that to game coordinates
- FMMatrix44 upAxisTransform = FMMatrix44_Identity;
- if (converter.IsYUp())
- {
- // Prop points are rotated -90 degrees about the X-axis, reverse that rotation
- // (do this once now because it's easier than messing with quaternions later)
- upAxisTransform = FMMatrix44::XAxisRotationMatrix(1.57f);
- }
-
- AddStaticPropPoints(propPoints, upAxisTransform, converter.GetInstance().GetParent());
-
- WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoords, vertexCount, boneWeights, boneTransforms, propPoints);
- }
- else if (converter.GetInstance().GetType() == FCDEntityInstance::CONTROLLER)
- {
- Log(LOG_INFO, "Found skinned geometry");
-
- FCDControllerInstance& controllerInstance = static_cast(converter.GetInstance());
-
- // (NB: GetType is deprecated and should be replaced with HasType,
- // except that has irritating linker errors when using a DLL, so don't
- // bother)
-
- assert(converter.GetInstance().GetEntity()->GetType() == FCDEntity::CONTROLLER); // assume this is always true?
- FCDController* controller = static_cast(converter.GetInstance().GetEntity());
-
- FCDSkinController* skin = controller->GetSkinController();
- REQUIRE(skin != NULL, "is skin controller");
-
- FixSkeletonRoots(controllerInstance);
-
- // Data for joints is stored in two places - avoid overflows by limiting
- // to the minimum of the two sizes, and warn if they're different (which
- // happens in practice for slightly-broken meshes)
- size_t jointCount = std::min(skin->GetJointCount(), controllerInstance.GetJointCount());
- if (skin->GetJointCount() != controllerInstance.GetJointCount())
- {
- Log(LOG_WARNING, "Mismatched bone counts (skin has %d, skeleton has %d)",
- skin->GetJointCount(), controllerInstance.GetJointCount());
- for (size_t i = 0; i < skin->GetJointCount(); ++i)
- Log(LOG_INFO, "Skin joint %d: %s", i, skin->GetJoint(i)->GetId().c_str());
- for (size_t i = 0; i < controllerInstance.GetJointCount(); ++i)
- Log(LOG_INFO, "Skeleton joint %d: %s", i, controllerInstance.GetJoint(i)->GetName().c_str());
- }
-
- // Get the skinned mesh for this entity
- FCDGeometry* baseGeometry = controller->GetBaseGeometry();
- REQUIRE(baseGeometry != NULL, "controller has base geometry");
- FCDGeometryPolygons* polys = GetPolysFromGeometry(baseGeometry);
-
- // Make sure it doesn't use more bones per vertex than the game can handle
- SkinReduceInfluences(skin, maxInfluences, 0.001f);
-
- // Convert the geometry into a suitable form for the game
- ReindexGeometry(polys, skin);
-
- const Skeleton& skeleton = FindSkeleton(controllerInstance);
-
- // Convert the bone influences into VertexBlend structures for the PMD:
-
- bool hasComplainedAboutNonexistentJoints = false; // because we want to emit a warning only once
-
- std::vector boneWeights; // one per vertex
-
- const FCDSkinControllerVertex* vertexInfluences = skin->GetVertexInfluences();
- for (size_t i = 0; i < skin->GetInfluenceCount(); ++i)
- {
- VertexBlend influences = defaultInfluences;
-
- assert(vertexInfluences[i].GetPairCount() <= maxInfluences);
- // guaranteed by ReduceInfluences; necessary for avoiding
- // out-of-bounds writes to the VertexBlend
-
- if (vertexInfluences[i].GetPairCount() == 0)
- {
- // Blender exports some models with vertices that have no influences,
- // which I've not found details about in the COLLADA spec, however,
- // it seems to work OK to treat these vertices the same as if they
- // were only influenced by the bind-shape matrix (see comment below),
- // so we use the same special case here.
- influences.bones[0] = (uint8)jointCount;
- influences.weights[0] = 1.0f;
- }
-
- for (size_t j = 0; j < vertexInfluences[i].GetPairCount(); ++j)
- {
- if (vertexInfluences[i].GetPair(j)->jointIndex == -1)
- {
- // This is a special case we must handle, according to the COLLADA spec:
- // "An index of -1 into the array of joints refers to the bind shape"
- //
- // which basically means when skinning the vertex it's relative to the
- // bind-shape transform instead of an animated bone. Since our skinning
- // is in world space, we will have already applied the bind-shape transform,
- // so we don't have to worry about that, though we DO have to apply the
- // world space transform of the model for the indicated vertex.
- //
- // To indicate this special case, we use a bone ID set to the total number
- // of bones in the model, which will have a special "bone matrix" reserved
- // that contains the world space transform of the model during skinning.
- // (see http://trac.wildfiregames.com/ticket/1012)
- influences.bones[j] = (uint8)jointCount;
- influences.weights[j] = vertexInfluences[i].GetPair(j)->weight;
- }
- else
- {
- // Check for less than 254 joints because we store them in a u8,
- // 0xFF is a reserved value (no influence), and we reserve one slot
- // for the above special case.
- uint32 jointIdx = vertexInfluences[i].GetPair(j)->jointIndex;
- REQUIRE(jointIdx < 0xFE, "sensible number of joints (<254)");
-
- // Find the joint on the skeleton, after checking it really exists
- FCDSceneNode* joint = NULL;
- if (jointIdx < controllerInstance.GetJointCount())
- joint = controllerInstance.GetJoint(jointIdx);
-
- // Complain on error
- if (! joint)
- {
- if (! hasComplainedAboutNonexistentJoints)
- {
- Log(LOG_WARNING, "Vertexes influenced by nonexistent joint");
- hasComplainedAboutNonexistentJoints = true;
- }
- continue;
- }
-
- // Store into the VertexBlend
- int boneId = skeleton.GetBoneID(joint->GetName().c_str());
- if (boneId < 0)
- {
- // The relevant joint does exist, but it's not a recognised
- // bone in our chosen skeleton structure
- Log(LOG_ERROR, "Vertex influenced by unrecognised bone '%s'", joint->GetName().c_str());
- continue;
- }
-
- influences.bones[j] = (uint8)boneId;
- influences.weights[j] = vertexInfluences[i].GetPair(j)->weight;
- }
- }
-
- boneWeights.push_back(influences);
- }
-
- // Convert the bind pose into BoneTransform structures for the PMD:
-
- BoneTransform boneDefault = { { 0, 0, 0 }, { 0, 0, 0, 1 } }; // identity transform
- std::vector boneTransforms (skeleton.GetBoneCount(), boneDefault);
-
- for (size_t i = 0; i < jointCount; ++i)
- {
- FCDSceneNode* joint = controllerInstance.GetJoint(i);
-
- int boneId = skeleton.GetRealBoneID(joint->GetName().c_str());
- if (boneId < 0)
- {
- // unrecognised joint - it's probably just a prop point
- // or something, so ignore it
- continue;
- }
-
- FMMatrix44 bindPose = skin->GetJoint(i)->GetBindPoseInverse().Inverted();
-
- HMatrix matrix;
- memcpy(matrix, bindPose.Transposed().m, sizeof(matrix));
- // set matrix = bindPose^T, to match what decomp_affine wants
-
- AffineParts parts;
- decomp_affine(matrix, &parts);
-
- BoneTransform b = {
- { parts.t.x, parts.t.y, parts.t.z },
- { parts.q.x, parts.q.y, parts.q.z, parts.q.w }
- };
-
- boneTransforms[boneId] = b;
- }
-
- // Construct the list of prop points.
- // Currently takes all objects that are directly attached to a
- // standard bone, and whose name begins with "prop-" or "prop_".
-
- std::vector propPoints;
- AddDefaultPropPoints(propPoints);
-
- for (size_t i = 0; i < jointCount; ++i)
- {
- FCDSceneNode* joint = controllerInstance.GetJoint(i);
-
- int boneId = skeleton.GetBoneID(joint->GetName().c_str());
- if (boneId < 0)
- {
- // unrecognised joint name - ignore, same as before
- continue;
- }
-
- // Check all the objects attached to this bone
- for (size_t j = 0; j < joint->GetChildrenCount(); ++j)
- {
- FCDSceneNode* child = joint->GetChild(j);
- if (child->GetName().find("prop-") != 0 && child->GetName().find("prop_") != 0)
- {
- // doesn't begin with "prop-", so skip it
- continue;
- }
- // Strip off the "prop-" from the name
- std::string propPointName (child->GetName().substr(5));
-
- Log(LOG_INFO, "Adding prop point %s", propPointName.c_str());
-
- // Get translation and orientation of local transform
-
- FMMatrix44 localTransform = child->ToMatrix();
-
- HMatrix matrix;
- memcpy(matrix, localTransform.Transposed().m, sizeof(matrix));
-
- AffineParts parts;
- decomp_affine(matrix, &parts);
-
- // Add prop point to list
-
- PropPoint p = {
- propPointName,
- { parts.t.x, parts.t.y, parts.t.z },
- { parts.q.x, parts.q.y, parts.q.z, parts.q.w },
- (uint8)boneId
- };
- propPoints.push_back(p);
- }
- }
-
- // Get the raw vertex data
-
- FCDGeometryPolygonsInput* inputPosition = polys->FindInput(FUDaeGeometryInput::POSITION);
- FCDGeometryPolygonsInput* inputNormal = polys->FindInput(FUDaeGeometryInput::NORMAL);
-
- const uint32* indicesCombined = inputPosition->GetIndices();
- size_t indicesCombinedCount = inputPosition->GetIndexCount();
- // (ReindexGeometry guarantees position/normal/texcoord have the same indexes)
-
- FCDGeometrySource* sourcePosition = inputPosition->GetSource();
- FCDGeometrySource* sourceNormal = inputNormal ->GetSource();
-
- FCDGeometrySourceList texcoordSources;
- polys->GetParent()->FindSourcesByType(FUDaeGeometryInput::TEXCOORD, texcoordSources);
-
- float* dataPosition = sourcePosition->GetData();
- float* dataNormal = sourceNormal ->GetData();
- size_t vertexCount = sourcePosition->GetDataCount() / 3;
- assert(sourcePosition->GetDataCount() == vertexCount*3);
- assert(sourceNormal ->GetDataCount() == vertexCount*3);
-
- std::vector dataTexcoords;
- for (size_t i = 0; i < texcoordSources.size(); ++i)
- {
- dataTexcoords.push_back(texcoordSources[i]->GetData());
- assert(texcoordSources[i]->GetDataCount() == vertexCount*2);
- }
-
- // Transform model coordinate system to game coordinates
-
- TransformSkinnedModel(dataPosition, dataNormal, vertexCount, boneTransforms, propPoints,
- converter.GetEntityTransform(), skin->GetBindShapeTransform(),
- converter.IsYUp(), converter.IsXSI());
-
- WritePMD(output, indicesCombined, indicesCombinedCount, dataPosition, dataNormal, dataTexcoords, vertexCount, boneWeights, boneTransforms, propPoints);
- }
- else
- {
- throw ColladaException("Unrecognised object type");
- }
-
- }
-
- /**
- * Adds the default "root" prop-point.
- */
- static void AddDefaultPropPoints(std::vector& propPoints)
- {
- PropPoint root;
- root.name = "root";
- root.translation[0] = root.translation[1] = root.translation[2] = 0.0f;
- root.orientation[0] = root.orientation[1] = root.orientation[2] = 0.0f;
- root.orientation[3] = 1.0f;
- root.bone = 0xFF;
- propPoints.push_back(root);
- }
-
- /**
- * Writes the model data in the PMD format.
- */
- static void WritePMD(OutputCB& output,
- const uint32* indices, size_t indexCount,
- const float* position, const float* normal,
- const std::vector& texcoords,
- size_t vertexCount,
- const std::vector& boneWeights, const std::vector& boneTransforms,
- const std::vector& propPoints)
- {
- static const VertexBlend noBlend = { { 0xFF, 0xFF, 0xFF, 0xFF }, { 0, 0, 0, 0 } };
-
- size_t faceCount = indexCount/3;
- size_t boneCount = boneTransforms.size();
- if (boneCount)
- assert(boneWeights.size() == vertexCount);
-
- size_t propPointsSize = 0; // can't calculate this statically, so loop over all the prop points
- for (size_t i = 0; i < propPoints.size(); ++i)
- {
- propPointsSize += 4 + propPoints[i].name.length();
- propPointsSize += 3*4 + 4*4 + 1;
- }
-
- output("PSMD", 4); // magic number
- write(output, (uint32)4); // version number
- write(output, (uint32)(
- // for UVs, we add one uint32 (i.e. 4 bytes) per model that gives the number of
- // texcoord sets in the model, plus 2 floats per new UV
- // pair per vertex (i.e. 8 bytes * number of pairs * vertex count)
- 4 + 11*4*vertexCount + 4 + 8*texcoords.size()*vertexCount + // vertices
- 4 + 6*faceCount + // faces
- 4 + 7*4*boneCount + // bones
- 4 + propPointsSize // props
- )); // data size
-
- // Vertex data
- write(output, (uint32)vertexCount);
- write(output, (uint32)texcoords.size()); // UV pairs per vertex
- for (size_t i = 0; i < vertexCount; ++i)
- {
- output((char*)&position[i*3], 12);
- output((char*)&normal [i*3], 12);
-
- for (size_t s = 0; s < texcoords.size(); ++s)
- {
- output((char*)&texcoords[s][i*2], 8);
- }
-
- if (boneCount)
- write(output, boneWeights[i]);
- else
- write(output, noBlend);
- }
-
- // Face data
- write(output, (uint32)faceCount);
- for (size_t i = 0; i < indexCount; ++i)
- {
- write(output, (uint16)indices[i]);
- }
-
- // Bones data
- write(output, (uint32)boneCount);
- for (size_t i = 0; i < boneCount; ++i)
- {
- output((char*)&boneTransforms[i], 7*4);
- }
-
- // Prop points data
- write(output, (uint32)propPoints.size());
- for (size_t i = 0; i < propPoints.size(); ++i)
- {
- uint32 nameLen = (uint32)propPoints[i].name.length();
- write(output, nameLen);
- output(propPoints[i].name.c_str(), nameLen);
- write(output, propPoints[i].translation);
- write(output, propPoints[i].orientation);
- write(output, propPoints[i].bone);
- }
- }
-
- static FCDGeometryPolygons* GetPolysFromGeometry(FCDGeometry* geom)
- {
- REQUIRE(geom->IsMesh(), "geometry is mesh");
- FCDGeometryMesh* mesh = geom->GetMesh();
-
- if (! mesh->IsTriangles())
- FCDGeometryPolygonsTools::Triangulate(mesh);
-
- REQUIRE(mesh->IsTriangles(), "mesh is made of triangles");
- REQUIRE(mesh->GetPolygonsCount() == 1, "mesh has single set of polygons");
- FCDGeometryPolygons* polys = mesh->GetPolygons(0);
- REQUIRE(polys->FindInput(FUDaeGeometryInput::POSITION) != NULL, "mesh has vertex positions");
- REQUIRE(polys->FindInput(FUDaeGeometryInput::NORMAL) != NULL, "mesh has vertex normals");
- REQUIRE(polys->FindInput(FUDaeGeometryInput::TEXCOORD) != NULL, "mesh has vertex tex coords");
- return polys;
- }
-
- /**
- * Applies world-space transform to vertex data and transforms Collada's right-handed
- * Y-up / Z-up coordinates to the game's left-handed Y-up coordinate system
- *
- * TODO: Maybe we should use FCDocumentTools::StandardizeUpAxisAndLength in addition
- * to this, so we'd only have one up-axis case to worry about, but it doesn't seem to
- * correctly adjust the prop points in Y_UP models.
- */
- static void TransformStaticModel(float* position, float* normal, size_t vertexCount,
- const FMMatrix44& transform, bool yUp)
- {
- for (size_t i = 0; i < vertexCount; ++i)
- {
- FMVector3 pos (&position[i*3], 0);
- FMVector3 norm (&normal[i*3], 0);
-
- // Apply the scene-node transforms
- pos = transform.TransformCoordinate(pos);
- norm = FMVector3_Normalize(transform.TransformVector(norm));
-
- // Convert from right-handed Y_UP or Z_UP to the game's coordinate system (left-handed Y-up)
-
- if (yUp)
- {
- pos.z = -pos.z;
- norm.z = -norm.z;
- }
- else
- {
- std::swap(pos.y, pos.z);
- std::swap(norm.y, norm.z);
- }
-
- // Copy back to array
-
- position[i*3] = pos.x;
- position[i*3+1] = pos.y;
- position[i*3+2] = pos.z;
-
- normal[i*3] = norm.x;
- normal[i*3+1] = norm.y;
- normal[i*3+2] = norm.z;
- }
- }
-
- /**
- * Applies world-space transform to vertex data and transforms Collada's right-handed
- * Y-up / Z-up coordinates to the game's left-handed Y-up coordinate system
- *
- * TODO: Maybe we should use FCDocumentTools::StandardizeUpAxisAndLength in addition
- * to this, so we'd only have one up-axis case to worry about, but it doesn't seem to
- * correctly adjust the prop points in Y_UP models.
- */
- static void TransformSkinnedModel(float* position, float* normal, size_t vertexCount,
- std::vector& bones, std::vector& propPoints,
- const FMMatrix44& transform, const FMMatrix44& bindTransform, bool yUp, bool isXSI)
- {
- FMMatrix44 scaledTransform; // for vertexes
- FMMatrix44 scaleMatrix; // for bones
-
- // HACK: see comment in PSAConvert::TransformVertices
- if (isXSI)
- {
- scaleMatrix = DecomposeToScaleMatrix(transform);
- scaledTransform = DecomposeToScaleMatrix(bindTransform) * transform;
- }
- else
- {
- scaleMatrix = FMMatrix44_Identity;
- scaledTransform = bindTransform;
- }
-
- // Update the vertex positions and normals
- for (size_t i = 0; i < vertexCount; ++i)
- {
- FMVector3 pos (&position[i*3], 0);
- FMVector3 norm (&normal[i*3], 0);
-
- // Apply the scene-node transforms
- pos = scaledTransform.TransformCoordinate(pos);
- norm = FMVector3_Normalize(scaledTransform.TransformVector(norm));
-
- // Convert from right-handed Y_UP or Z_UP to the game's coordinate system (left-handed Y-up)
-
- if (yUp)
- {
- pos.z = -pos.z;
- norm.z = -norm.z;
- }
- else
- {
- std::swap(pos.y, pos.z);
- std::swap(norm.y, norm.z);
- }
-
- // and copy back into the original array
-
- position[i*3] = pos.x;
- position[i*3+1] = pos.y;
- position[i*3+2] = pos.z;
-
- normal[i*3] = norm.x;
- normal[i*3+1] = norm.y;
- normal[i*3+2] = norm.z;
- }
-
- TransformBones(bones, scaleMatrix, yUp);
-
- // And do the same for prop points
- for (size_t i = 0; i < propPoints.size(); ++i)
- {
- if (yUp)
- {
- propPoints[i].translation[0] = -propPoints[i].translation[0];
- propPoints[i].orientation[0] = -propPoints[i].orientation[0];
- propPoints[i].orientation[3] = -propPoints[i].orientation[3];
- }
- else
- {
- // Flip translation across the x-axis by swapping y and z
- std::swap(propPoints[i].translation[1], propPoints[i].translation[2]);
-
- // To convert the quaternions: imagine you're using the axis/angle
- // representation, then swap the y,z basis vectors and change the
- // direction of rotation by negating the angle ( => negating sin(angle)
- // => negating x,y,z => changing (x,y,z,w) to (-x,-z,-y,w)
- // but then (-x,-z,-y,w) == (x,z,y,-w) so do that instead)
- std::swap(propPoints[i].orientation[1], propPoints[i].orientation[2]);
- propPoints[i].orientation[3] = -propPoints[i].orientation[3];
- }
- }
-
- }
-};
-
-
-// The above stuff is just in a class since I don't like having to bother
-// with forward declarations of functions - but provide the plain function
-// interface here:
-
-void ColladaToPMD(const char* input, OutputCB& output, std::string& xmlErrors)
-{
- PMDConvert::ColladaToPMD(input, output, xmlErrors);
-}