forked from 0ad/0ad
181 lines
5.4 KiB
C++
181 lines
5.4 KiB
C++
/* Copyright (C) 2009 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef INCLUDED_COMMONCONVERT
|
|
#define INCLUDED_COMMONCONVERT
|
|
|
|
#include <exception>
|
|
#include <string>
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
class FCDEntityInstance;
|
|
class FCDSceneNode;
|
|
class FCDSkinController;
|
|
class FMMatrix44;
|
|
class FUStatus;
|
|
|
|
class Skeleton;
|
|
|
|
class ColladaException : public std::exception
|
|
{
|
|
public:
|
|
ColladaException(const std::string& msg) : msg(msg) { }
|
|
~ColladaException() throw() { }
|
|
virtual const char* what() const throw() { return msg.c_str(); }
|
|
private:
|
|
std::string msg;
|
|
};
|
|
|
|
struct OutputCB
|
|
{
|
|
virtual void operator() (const char* data, unsigned int length)=0;
|
|
};
|
|
|
|
/**
|
|
* Standard error handler - logs FCollada messages using Log(), and also
|
|
* maintains a list of XML parser errors.
|
|
*/
|
|
class FColladaErrorHandler
|
|
{
|
|
public:
|
|
FColladaErrorHandler(std::string& xmlErrors);
|
|
~FColladaErrorHandler();
|
|
|
|
private:
|
|
void OnError(FUError::Level errorLevel, uint32 errorCode, uint32 lineNumber);
|
|
std::string& xmlErrors;
|
|
|
|
void operator=(FColladaErrorHandler);
|
|
};
|
|
|
|
/**
|
|
* Standard document loader. Based on FCDocument::LoadFromText, but allows
|
|
* access to <extra> nodes at the document level (i.e. directly in <COLLADA>).
|
|
*/
|
|
class FColladaDocument
|
|
{
|
|
public:
|
|
/**
|
|
* Loads the document from the given XML string. Should be the first function
|
|
* called on this object, and should only be called once.
|
|
* @throws ColladaException if unable to load.
|
|
*/
|
|
void LoadFromText(const char* text);
|
|
|
|
/** Returns the FCDocument that was loaded. */
|
|
FCDocument* GetDocument() const { return document.get(); }
|
|
|
|
/** Returns the <extra> data from the <COLLADA> element. */
|
|
FCDExtra* GetExtra() const { return extra.get(); }
|
|
|
|
private:
|
|
void ReadExtras(xmlNode* colladaNode);
|
|
std::auto_ptr<FCDocument> document;
|
|
std::auto_ptr<FCDExtra> extra;
|
|
};
|
|
|
|
/**
|
|
* Wrapper for code shared between the PMD and PSA converters. Loads the document
|
|
* and provides access to the relevant objects and values.
|
|
*/
|
|
class CommonConvert
|
|
{
|
|
public:
|
|
CommonConvert(const char* text, std::string& xmlErrors);
|
|
~CommonConvert();
|
|
const FColladaDocument& GetDocument() const { return m_Doc; }
|
|
FCDSceneNode& GetRoot() { return *m_Doc.GetDocument()->GetVisualSceneRoot(); }
|
|
FCDEntityInstance& GetInstance() { return *m_Instance; }
|
|
const FMMatrix44& GetEntityTransform() const { return m_EntityTransform; }
|
|
bool IsYUp() const { return m_YUp; }
|
|
bool IsXSI() const { return m_IsXSI; }
|
|
|
|
private:
|
|
FColladaErrorHandler m_Err;
|
|
FColladaDocument m_Doc;
|
|
FCDEntityInstance* m_Instance;
|
|
FMMatrix44 m_EntityTransform;
|
|
bool m_YUp;
|
|
bool m_IsXSI;
|
|
};
|
|
|
|
/** Throws a ColladaException unless the value is true. */
|
|
#define REQUIRE(value, message) require_(__LINE__, value, "Assertion not satisfied", "failed requirement \"" message "\"")
|
|
|
|
/** Throws a ColladaException unless the status is successful. */
|
|
#define REQUIRE_SUCCESS(status) require_(__LINE__, status, "FCollada error", "Line " STRINGIFY(__LINE__))
|
|
#define STRINGIFY(x) #x
|
|
|
|
void require_(int line, bool value, const char* type, const char* message);
|
|
|
|
/** Outputs a structure, using sizeof to get the size. */
|
|
template<typename T> void write(OutputCB& output, const T& data)
|
|
{
|
|
output((char*)&data, sizeof(T));
|
|
}
|
|
|
|
/**
|
|
* Tries to find a single suitable entity instance in the scene. Fails if there
|
|
* are none, or if there are too many and it's not clear which one should
|
|
* be converted.
|
|
*
|
|
* @param node root scene node to search under
|
|
* @param instance output - the found entity instance (if any)
|
|
* @param transform - the world-space transform of the found entity
|
|
*
|
|
* @return true if one was found
|
|
*/
|
|
bool FindSingleInstance(FCDSceneNode* node, FCDEntityInstance*& instance, FMMatrix44& transform);
|
|
|
|
/**
|
|
* Like FCDSkinController::ReduceInfluences but works correctly.
|
|
* Additionally, multiple influences for the same joint-vertex pair are
|
|
* collapsed into a single influence.
|
|
*/
|
|
void SkinReduceInfluences(FCDSkinController* skin, size_t maxInfluenceCount, float minimumWeight);
|
|
|
|
/**
|
|
* Fixes some occasional problems with the skeleton root definitions in a
|
|
* controller. (In particular, it's needed for models exported from XSI.)
|
|
* Should be called before extracting any joint information from the controller.
|
|
*/
|
|
void FixSkeletonRoots(FCDControllerInstance& controllerInstance);
|
|
|
|
/**
|
|
* Finds the skeleton definition which best matches the given controller.
|
|
* @throws ColladaException if none is found.
|
|
*/
|
|
const Skeleton& FindSkeleton(const FCDControllerInstance& controllerInstance);
|
|
|
|
/** Bone pose data */
|
|
struct BoneTransform
|
|
{
|
|
float translation[3];
|
|
float orientation[4];
|
|
};
|
|
|
|
/**
|
|
* Performs the standard transformations on bones, applying a scale matrix and
|
|
* moving them into the game's coordinate space.
|
|
*/
|
|
void TransformBones(std::vector<BoneTransform>& bones, const FMMatrix44& scaleTransform, bool yUp);
|
|
|
|
extern FMMatrix44 FMMatrix44_Identity;
|
|
|
|
#endif // INCLUDED_COMMONCONVERT
|