File: CommonConvert.h

package info (click to toggle)
0ad 0.0.23.1-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 78,292 kB
  • sloc: cpp: 245,166; ansic: 200,249; python: 13,754; sh: 6,104; perl: 4,620; makefile: 977; xml: 810; java: 533; ruby: 229; erlang: 46; pascal: 30; sql: 21; tcl: 4
file content (181 lines) | stat: -rw-r--r-- 5,586 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
/* Copyright (C) 2015 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 ~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::unique_ptr<FCDocument> document;
	std::unique_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