1 /* Copyright (C) 2021 Wildfire Games.
2 * This file is part of 0 A.D.
4 * 0 A.D. is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * 0 A.D. is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
18 #ifndef INCLUDED_COMMONCONVERT
19 #define INCLUDED_COMMONCONVERT
26 class FCDEntityInstance
;
28 class FCDSkinController
;
33 class ColladaException
: public std::exception
36 ColladaException(const std::string
& msg
) : msg(msg
) { }
37 ~ColladaException() throw() { }
38 virtual const char* what() const throw() { return msg
.c_str(); }
45 virtual ~OutputCB() { }
46 virtual void operator() (const char* data
, unsigned int length
)=0;
50 * Standard error handler - logs FCollada messages using Log(), and also
51 * maintains a list of XML parser errors.
53 class FColladaErrorHandler
56 FColladaErrorHandler(std::string
& xmlErrors
);
57 ~FColladaErrorHandler();
60 void OnError(FUError::Level errorLevel
, uint32 errorCode
, uint32 lineNumber
);
61 std::string
& xmlErrors
;
63 void operator=(FColladaErrorHandler
);
67 * Standard document loader. Based on FCDocument::LoadFromText, but allows
68 * access to \<extra\> nodes at the document level (i.e. directly in \<COLLADA\>).
70 class FColladaDocument
74 * Loads the document from the given XML string. Should be the first function
75 * called on this object, and should only be called once.
76 * @throws ColladaException if unable to load.
78 void LoadFromText(const char* text
);
80 /** Returns the FCDocument that was loaded. */
81 FCDocument
* GetDocument() const { return document
.get(); }
83 /** Returns the \<extra\> data from the \<COLLADA\> element. */
84 FCDExtra
* GetExtra() const { return extra
.get(); }
87 void ReadExtras(xmlNode
* colladaNode
);
88 std::unique_ptr
<FCDocument
> document
;
89 std::unique_ptr
<FCDExtra
> extra
;
93 * Wrapper for code shared between the PMD and PSA converters. Loads the document
94 * and provides access to the relevant objects and values.
99 CommonConvert(const char* text
, std::string
& xmlErrors
);
101 const FColladaDocument
& GetDocument() const { return m_Doc
; }
102 FCDSceneNode
& GetRoot() { return *m_Doc
.GetDocument()->GetVisualSceneRoot(); }
103 FCDEntityInstance
& GetInstance() { return *m_Instance
; }
104 const FMMatrix44
& GetEntityTransform() const { return m_EntityTransform
; }
105 bool IsYUp() const { return m_YUp
; }
106 bool IsXSI() const { return m_IsXSI
; }
109 FColladaErrorHandler m_Err
;
110 FColladaDocument m_Doc
;
111 FCDEntityInstance
* m_Instance
;
112 FMMatrix44 m_EntityTransform
;
117 /** Throws a ColladaException unless the value is true. */
118 #define REQUIRE(value, message) require_(__LINE__, value, "Assertion not satisfied", "failed requirement \"" message "\"")
120 /** Throws a ColladaException unless the status is successful. */
121 #define REQUIRE_SUCCESS(status) require_(__LINE__, status, "FCollada error", "Line " STRINGIFY(__LINE__))
122 #define STRINGIFY(x) #x
124 void require_(int line
, bool value
, const char* type
, const char* message
);
126 /** Outputs a structure, using sizeof to get the size. */
127 template<typename T
> void write(OutputCB
& output
, const T
& data
)
129 output((char*)&data
, sizeof(T
));
133 * Tries to find a single suitable entity instance in the scene. Fails if there
134 * are none, or if there are too many and it's not clear which one should
137 * @param node root scene node to search under
138 * @param instance output - the found entity instance (if any)
139 * @param transform - the world-space transform of the found entity
141 * @return true if one was found
143 bool FindSingleInstance(FCDSceneNode
* node
, FCDEntityInstance
*& instance
, FMMatrix44
& transform
);
146 * Like FCDSkinController::ReduceInfluences but works correctly.
147 * Additionally, multiple influences for the same joint-vertex pair are
148 * collapsed into a single influence.
150 void SkinReduceInfluences(FCDSkinController
* skin
, size_t maxInfluenceCount
, float minimumWeight
);
153 * Fixes some occasional problems with the skeleton root definitions in a
154 * controller. (In particular, it's needed for models exported from XSI.)
155 * Should be called before extracting any joint information from the controller.
157 void FixSkeletonRoots(FCDControllerInstance
& controllerInstance
);
160 * Finds the skeleton definition which best matches the given controller.
161 * @throws ColladaException if none is found.
163 const Skeleton
& FindSkeleton(const FCDControllerInstance
& controllerInstance
);
165 /** Bone pose data */
168 float translation
[3];
169 float orientation
[4];
173 * Performs the standard transformations on bones, applying a scale matrix and
174 * moving them into the game's coordinate space.
176 void TransformBones(std::vector
<BoneTransform
>& bones
, const FMMatrix44
& scaleTransform
, bool yUp
);
178 extern FMMatrix44 FMMatrix44_Identity
;
180 #endif // INCLUDED_COMMONCONVERT