1 #include "ofbx.h"
2 #include "miniz.h"
3 #include <cassert>
4 #include <cmath>
5 #include <ctype.h>
6 #include <memory>
7 #include <unordered_map>
8 #include <vector>
9 #include <string>
10 
11 
12 namespace ofbx
13 {
14 
15 
16 struct Error
17 {
Errorofbx::Error18 	Error() {}
Errorofbx::Error19 	Error(const char* msg) { s_message = msg; }
20 
21 	static const char* s_message;
22 };
23 
24 
25 const char* Error::s_message = "";
26 
27 
28 template <typename T> struct OptionalError
29 {
OptionalErrorofbx::OptionalError30 	OptionalError(Error error)
31 		: is_error(true)
32 	{
33 	}
34 
35 
OptionalErrorofbx::OptionalError36 	OptionalError(T _value)
37 		: value(_value)
38 		, is_error(false)
39 	{
40 	}
41 
42 
getValueofbx::OptionalError43 	T getValue() const
44 	{
45 #ifdef _DEBUG
46 		assert(error_checked);
47 #endif
48 		return value;
49 	}
50 
51 
isErrorofbx::OptionalError52 	bool isError()
53 	{
54 #ifdef _DEBUG
55 		error_checked = true;
56 #endif
57 		return is_error;
58 	}
59 
60 
61 private:
62 	T value;
63 	bool is_error;
64 #ifdef _DEBUG
65 	bool error_checked = false;
66 #endif
67 };
68 
69 
70 #pragma pack(1)
71 struct Header
72 {
73 	u8 magic[21];
74 	u8 reserved[2];
75 	u32 version;
76 };
77 #pragma pack()
78 
79 
80 struct Cursor
81 {
82 	const u8* current;
83 	const u8* begin;
84 	const u8* end;
85 };
86 
87 
setTranslation(const Vec3 & t,Matrix * mtx)88 static void setTranslation(const Vec3& t, Matrix* mtx)
89 {
90 	mtx->m[12] = t.x;
91 	mtx->m[13] = t.y;
92 	mtx->m[14] = t.z;
93 }
94 
95 
operator -(const Vec3 & v)96 static Vec3 operator-(const Vec3& v)
97 {
98 	return {-v.x, -v.y, -v.z};
99 }
100 
101 
operator *(const Matrix & lhs,const Matrix & rhs)102 static Matrix operator*(const Matrix& lhs, const Matrix& rhs)
103 {
104 	Matrix res;
105 	for (int j = 0; j < 4; ++j)
106 	{
107 		for (int i = 0; i < 4; ++i)
108 		{
109 			double tmp = 0;
110 			for (int k = 0; k < 4; ++k)
111 			{
112 				tmp += lhs.m[i + k * 4] * rhs.m[k + j * 4];
113 			}
114 			res.m[i + j * 4] = tmp;
115 		}
116 	}
117 	return res;
118 }
119 
120 
makeIdentity()121 static Matrix makeIdentity()
122 {
123 	return {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1};
124 }
125 
126 
rotationX(double angle)127 static Matrix rotationX(double angle)
128 {
129 	Matrix m = makeIdentity();
130 	double c = cos(angle);
131 	double s = sin(angle);
132 
133 	m.m[5] = m.m[10] = c;
134 	m.m[9] = -s;
135 	m.m[6] = s;
136 
137 	return m;
138 }
139 
140 
rotationY(double angle)141 static Matrix rotationY(double angle)
142 {
143 	Matrix m = makeIdentity();
144 	double c = cos(angle);
145 	double s = sin(angle);
146 
147 	m.m[0] = m.m[10] = c;
148 	m.m[8] = s;
149 	m.m[2] = -s;
150 
151 	return m;
152 }
153 
154 
rotationZ(double angle)155 static Matrix rotationZ(double angle)
156 {
157 	Matrix m = makeIdentity();
158 	double c = cos(angle);
159 	double s = sin(angle);
160 
161 	m.m[0] = m.m[5] = c;
162 	m.m[4] = -s;
163 	m.m[1] = s;
164 
165 	return m;
166 }
167 
168 
getRotationMatrix(const Vec3 & euler,RotationOrder order)169 static Matrix getRotationMatrix(const Vec3& euler, RotationOrder order)
170 {
171 	const double TO_RAD = 3.1415926535897932384626433832795028 / 180.0;
172 	Matrix rx = rotationX(euler.x * TO_RAD);
173 	Matrix ry = rotationY(euler.y * TO_RAD);
174 	Matrix rz = rotationZ(euler.z * TO_RAD);
175 	switch (order) {
176 		default:
177 		case RotationOrder::SPHERIC_XYZ:
178 			assert(false);
179 		case RotationOrder::EULER_XYZ:
180 			return rz * ry * rx;
181 		case RotationOrder::EULER_XZY:
182 			return ry * rz * rx;
183 		case RotationOrder::EULER_YXZ:
184 			return rz * rx * ry;
185 		case RotationOrder::EULER_YZX:
186 			return rx * rz * ry;
187 		case RotationOrder::EULER_ZXY:
188 			return ry * rx * rz;
189 		case RotationOrder::EULER_ZYX:
190 			return rx * ry * rz;
191 	}
192 }
193 
194 
fbxTimeToSeconds(i64 value)195 static double fbxTimeToSeconds(i64 value)
196 {
197 	return double(value) / 46186158000L;
198 }
199 
200 
secondsToFbxTime(double value)201 static i64 secondsToFbxTime(double value)
202 {
203 	return i64(value * 46186158000L);
204 }
205 
206 
operator *(const Vec3 & v,float f)207 static Vec3 operator*(const Vec3& v, float f)
208 {
209 	return {v.x * f, v.y * f, v.z * f};
210 }
211 
212 
operator +(const Vec3 & a,const Vec3 & b)213 static Vec3 operator+(const Vec3& a, const Vec3& b)
214 {
215 	return {a.x + b.x, a.y + b.y, a.z + b.z};
216 }
217 
218 
copyString(char (& destination)[SIZE],const char * source)219 template <int SIZE> static bool copyString(char (&destination)[SIZE], const char* source)
220 {
221 	const char* src = source;
222 	char* dest = destination;
223 	int length = SIZE;
224 	if (!src) return false;
225 
226 	while (*src && length > 1)
227 	{
228 		*dest = *src;
229 		--length;
230 		++dest;
231 		++src;
232 	}
233 	*dest = 0;
234 	return *src == '\0';
235 }
236 
237 
toU64() const238 u64 DataView::toU64() const
239 {
240 	if (is_binary)
241 	{
242 		assert(end - begin == sizeof(u64));
243 		return *(u64*)begin;
244 	}
245 	static_assert(sizeof(unsigned long long) >= sizeof(u64), "can't use strtoull");
246 	return strtoull((const char*)begin, nullptr, 10);
247 }
248 
249 
toI64() const250 i64 DataView::toI64() const
251 {
252 	if (is_binary)
253 	{
254 		assert(end - begin == sizeof(i64));
255 		return *(i64*)begin;
256 	}
257 	static_assert(sizeof(long long) >= sizeof(i64), "can't use atoll");
258 	return atoll((const char*)begin);
259 }
260 
261 
toInt() const262 int DataView::toInt() const
263 {
264 	if (is_binary)
265 	{
266 		assert(end - begin == sizeof(int));
267 		return *(int*)begin;
268 	}
269 	return atoi((const char*)begin);
270 }
271 
272 
toU32() const273 u32 DataView::toU32() const
274 {
275 	if (is_binary)
276 	{
277 		assert(end - begin == sizeof(u32));
278 		return *(u32*)begin;
279 	}
280 	return (u32)atoll((const char*)begin);
281 }
282 
283 
toDouble() const284 double DataView::toDouble() const
285 {
286 	if (is_binary)
287 	{
288 		assert(end - begin == sizeof(double));
289 		return *(double*)begin;
290 	}
291 	return atof((const char*)begin);
292 }
293 
294 
toFloat() const295 float DataView::toFloat() const
296 {
297 	if (is_binary)
298 	{
299 		assert(end - begin == sizeof(float));
300 		return *(float*)begin;
301 	}
302 	return (float)atof((const char*)begin);
303 }
304 
305 
operator ==(const char * rhs) const306 bool DataView::operator==(const char* rhs) const
307 {
308 	const char* c = rhs;
309 	const char* c2 = (const char*)begin;
310 	while (*c && c2 != (const char*)end)
311 	{
312 		if (*c != *c2) return 0;
313 		++c;
314 		++c2;
315 	}
316 	return c2 == (const char*)end && *c == '\0';
317 }
318 
319 
320 struct Property;
321 template <typename T> static bool parseArrayRaw(const Property& property, T* out, int max_size);
322 template <typename T> static bool parseBinaryArray(const Property& property, std::vector<T>* out);
323 
324 
325 struct Property : IElementProperty
326 {
~Propertyofbx::Property327 	~Property() { delete next; }
getTypeofbx::Property328 	Type getType() const override { return (Type)type; }
getNextofbx::Property329 	IElementProperty* getNext() const override { return next; }
getValueofbx::Property330 	DataView getValue() const override { return value; }
getCountofbx::Property331 	int getCount() const override
332 	{
333 		assert(type == ARRAY_DOUBLE || type == ARRAY_INT || type == ARRAY_FLOAT || type == ARRAY_LONG);
334 		if (value.is_binary)
335 		{
336 			return int(*(u32*)value.begin);
337 		}
338 		return count;
339 	}
340 
getValuesofbx::Property341 	bool getValues(double* values, int max_size) const override { return parseArrayRaw(*this, values, max_size); }
342 
getValuesofbx::Property343 	bool getValues(float* values, int max_size) const override { return parseArrayRaw(*this, values, max_size); }
344 
getValuesofbx::Property345 	bool getValues(u64* values, int max_size) const override { return parseArrayRaw(*this, values, max_size); }
346 
getValuesofbx::Property347 	bool getValues(i64* values, int max_size) const override { return parseArrayRaw(*this, values, max_size); }
348 
getValuesofbx::Property349 	bool getValues(int* values, int max_size) const override { return parseArrayRaw(*this, values, max_size); }
350 
351 	int count;
352 	u8 type;
353 	DataView value;
354 	Property* next = nullptr;
355 };
356 
357 
358 struct Element final : IElement
359 {
getFirstChildofbx::Element360 	IElement* getFirstChild() const override { return child; }
getSiblingofbx::Element361 	IElement* getSibling() const override { return sibling; }
getIDofbx::Element362 	DataView getID() const override { return id; }
getFirstPropertyofbx::Element363 	IElementProperty* getFirstProperty() const override { return first_property; }
getPropertyofbx::Element364 	IElementProperty* getProperty(int idx) const
365 	{
366 		IElementProperty* prop = first_property;
367 		for (int i = 0; i < idx; ++i)
368 		{
369 			if (prop == nullptr) return nullptr;
370 			prop = prop->getNext();
371 		}
372 		return prop;
373 	}
374 
375 	DataView id;
376 	Element* child = nullptr;
377 	Element* sibling = nullptr;
378 	Property* first_property = nullptr;
379 };
380 
381 
findChild(const Element & element,const char * id)382 static const Element* findChild(const Element& element, const char* id)
383 {
384 	Element* const* iter = &element.child;
385 	while (*iter)
386 	{
387 		if ((*iter)->id == id) return *iter;
388 		iter = &(*iter)->sibling;
389 	}
390 	return nullptr;
391 }
392 
393 
resolveProperty(const Object & obj,const char * name)394 static IElement* resolveProperty(const Object& obj, const char* name)
395 {
396 	const Element* props = findChild((const Element&)obj.element, "Properties70");
397 	if (!props) return nullptr;
398 
399 	Element* prop = props->child;
400 	while (prop)
401 	{
402 		if (prop->first_property && prop->first_property->value == name)
403 		{
404 			return prop;
405 		}
406 		prop = prop->sibling;
407 	}
408 	return nullptr;
409 }
410 
411 
resolveEnumProperty(const Object & object,const char * name,int default_value)412 static int resolveEnumProperty(const Object& object, const char* name, int default_value)
413 {
414 	Element* element = (Element*)resolveProperty(object, name);
415 	if (!element) return default_value;
416 	Property* x = (Property*)element->getProperty(4);
417 	if (!x) return default_value;
418 
419 	return x->value.toInt();
420 }
421 
422 
resolveVec3Property(const Object & object,const char * name,const Vec3 & default_value)423 static Vec3 resolveVec3Property(const Object& object, const char* name, const Vec3& default_value)
424 {
425 	Element* element = (Element*)resolveProperty(object, name);
426 	if (!element) return default_value;
427 	Property* x = (Property*)element->getProperty(4);
428 	if (!x || !x->next || !x->next->next) return default_value;
429 
430 	return {x->value.toDouble(), x->next->value.toDouble(), x->next->next->value.toDouble()};
431 }
432 
433 
Object(const Scene & _scene,const IElement & _element)434 Object::Object(const Scene& _scene, const IElement& _element)
435 	: scene(_scene)
436 	, element(_element)
437 	, is_node(false)
438 	, node_attribute(nullptr)
439 {
440 	auto& e = (Element&)_element;
441 	if (e.first_property && e.first_property->next)
442 	{
443 		e.first_property->next->value.toString(name);
444 	}
445 	else
446 	{
447 		name[0] = '\0';
448 	}
449 }
450 
451 
decompress(const u8 * in,size_t in_size,u8 * out,size_t out_size)452 static bool decompress(const u8* in, size_t in_size, u8* out, size_t out_size)
453 {
454 	mz_stream stream = {};
455 	mz_inflateInit(&stream);
456 
457 	stream.avail_in = (int)in_size;
458 	stream.next_in = in;
459 	stream.avail_out = (int)out_size;
460 	stream.next_out = out;
461 
462 	int status = mz_inflate(&stream, Z_SYNC_FLUSH);
463 
464 	if (status != Z_STREAM_END) return false;
465 
466 	return mz_inflateEnd(&stream) == Z_OK;
467 }
468 
469 
read(Cursor * cursor)470 template <typename T> static OptionalError<T> read(Cursor* cursor)
471 {
472 	if (cursor->current + sizeof(T) > cursor->end) return Error("Reading past the end");
473 	T value = *(const T*)cursor->current;
474 	cursor->current += sizeof(T);
475 	return value;
476 }
477 
478 
readShortString(Cursor * cursor)479 static OptionalError<DataView> readShortString(Cursor* cursor)
480 {
481 	DataView value;
482 	OptionalError<u8> length = read<u8>(cursor);
483 	if (length.isError()) return Error();
484 
485 	if (cursor->current + length.getValue() > cursor->end) return Error("Reading past the end");
486 	value.begin = cursor->current;
487 	cursor->current += length.getValue();
488 
489 	value.end = cursor->current;
490 
491 	return value;
492 }
493 
494 
readLongString(Cursor * cursor)495 static OptionalError<DataView> readLongString(Cursor* cursor)
496 {
497 	DataView value;
498 	OptionalError<u32> length = read<u32>(cursor);
499 	if (length.isError()) return Error();
500 
501 	if (cursor->current + length.getValue() > cursor->end) return Error("Reading past the end");
502 	value.begin = cursor->current;
503 	cursor->current += length.getValue();
504 
505 	value.end = cursor->current;
506 
507 	return value;
508 }
509 
510 
readProperty(Cursor * cursor)511 static OptionalError<Property*> readProperty(Cursor* cursor)
512 {
513 	if (cursor->current == cursor->end) return Error("Reading past the end");
514 
515 	std::unique_ptr<Property> prop(new Property());
516 	prop->next = nullptr;
517 	prop->type = *cursor->current;
518 	++cursor->current;
519 	prop->value.begin = cursor->current;
520 
521 	switch (prop->type)
522 	{
523 		case 'S':
524 		{
525 			OptionalError<DataView> val = readLongString(cursor);
526 			if (val.isError()) return Error();
527 			prop->value = val.getValue();
528 			break;
529 		}
530 		case 'Y': cursor->current += 2; break;
531 		case 'C': cursor->current += 1; break;
532 		case 'I': cursor->current += 4; break;
533 		case 'F': cursor->current += 4; break;
534 		case 'D': cursor->current += 8; break;
535 		case 'L': cursor->current += 8; break;
536 		case 'R':
537 		{
538 			OptionalError<u32> len = read<u32>(cursor);
539 			if (len.isError()) return Error();
540 			if (cursor->current + len.getValue() > cursor->end) return Error("Reading past the end");
541 			cursor->current += len.getValue();
542 			break;
543 		}
544 		case 'b':
545 		case 'f':
546 		case 'd':
547 		case 'l':
548 		case 'i':
549 		{
550 			OptionalError<u32> length = read<u32>(cursor);
551 			OptionalError<u32> encoding = read<u32>(cursor);
552 			OptionalError<u32> comp_len = read<u32>(cursor);
553 			if (length.isError() | encoding.isError() | comp_len.isError()) return Error();
554 			if (cursor->current + comp_len.getValue() > cursor->end) return Error("Reading past the end");
555 			cursor->current += comp_len.getValue();
556 			break;
557 		}
558 		default: return Error("Unknown property type");
559 	}
560 	prop->value.end = cursor->current;
561 	return prop.release();
562 }
563 
564 
deleteElement(Element * el)565 static void deleteElement(Element* el)
566 {
567 	if (!el) return;
568 
569 	Element* iter = el;
570 	// do not use recursion to delete siblings to avoid stack overflow
571 	do
572 	{
573 		Element* next = iter->sibling;
574 		delete iter->first_property;
575 		deleteElement(iter->child);
576 		delete iter;
577 		iter = next;
578 	} while (iter);
579 }
580 
581 
582 
readElementOffset(Cursor * cursor,u16 version)583 static OptionalError<u64> readElementOffset(Cursor* cursor, u16 version)
584 {
585 	if (version >= 7500)
586 	{
587 		OptionalError<u64> tmp = read<u64>(cursor);
588 		if (tmp.isError()) return Error();
589 		return tmp.getValue();
590 	}
591 
592 	OptionalError<u32> tmp = read<u32>(cursor);
593 	if (tmp.isError()) return Error();
594 	return tmp.getValue();
595 }
596 
597 
readElement(Cursor * cursor,u32 version)598 static OptionalError<Element*> readElement(Cursor* cursor, u32 version)
599 {
600 	OptionalError<u64> end_offset = readElementOffset(cursor, version);
601 	if (end_offset.isError()) return Error();
602 	if (end_offset.getValue() == 0) return nullptr;
603 
604 	OptionalError<u64> prop_count = readElementOffset(cursor, version);
605 	OptionalError<u64> prop_length = readElementOffset(cursor, version);
606 	if (prop_count.isError() || prop_length.isError()) return Error();
607 
608 	const char* sbeg = 0;
609 	const char* send = 0;
610 	OptionalError<DataView> id = readShortString(cursor);
611 	if (id.isError()) return Error();
612 
613 	Element* element = new Element();
614 	element->first_property = nullptr;
615 	element->id = id.getValue();
616 
617 	element->child = nullptr;
618 	element->sibling = nullptr;
619 
620 	Property** prop_link = &element->first_property;
621 	for (u32 i = 0; i < prop_count.getValue(); ++i)
622 	{
623 		OptionalError<Property*> prop = readProperty(cursor);
624 		if (prop.isError())
625 		{
626 			deleteElement(element);
627 			return Error();
628 		}
629 
630 		*prop_link = prop.getValue();
631 		prop_link = &(*prop_link)->next;
632 	}
633 
634 	if (cursor->current - cursor->begin >= (ptrdiff_t)end_offset.getValue()) return element;
635 
636 	int BLOCK_SENTINEL_LENGTH = version >= 7500 ? 25 : 13;
637 
638 	Element** link = &element->child;
639 	while (cursor->current - cursor->begin < ((ptrdiff_t)end_offset.getValue() - BLOCK_SENTINEL_LENGTH))
640 	{
641 		OptionalError<Element*> child = readElement(cursor, version);
642 		if (child.isError())
643 		{
644 			deleteElement(element);
645 			return Error();
646 		}
647 
648 		*link = child.getValue();
649 		link = &(*link)->sibling;
650 	}
651 
652 	if (cursor->current + BLOCK_SENTINEL_LENGTH > cursor->end)
653 	{
654 		deleteElement(element);
655 		return Error("Reading past the end");
656 	}
657 
658 	cursor->current += BLOCK_SENTINEL_LENGTH;
659 	return element;
660 }
661 
662 
isEndLine(const Cursor & cursor)663 static bool isEndLine(const Cursor& cursor)
664 {
665 	return *cursor.current == '\n';
666 }
667 
668 
skipInsignificantWhitespaces(Cursor * cursor)669 static void skipInsignificantWhitespaces(Cursor* cursor)
670 {
671 	while (cursor->current < cursor->end && isspace(*cursor->current) && *cursor->current != '\n')
672 	{
673 		++cursor->current;
674 	}
675 }
676 
677 
skipLine(Cursor * cursor)678 static void skipLine(Cursor* cursor)
679 {
680 	while (cursor->current < cursor->end && !isEndLine(*cursor))
681 	{
682 		++cursor->current;
683 	}
684 	if (cursor->current < cursor->end) ++cursor->current;
685 	skipInsignificantWhitespaces(cursor);
686 }
687 
688 
skipWhitespaces(Cursor * cursor)689 static void skipWhitespaces(Cursor* cursor)
690 {
691 	while (cursor->current < cursor->end && isspace(*cursor->current))
692 	{
693 		++cursor->current;
694 	}
695 	while (cursor->current < cursor->end && *cursor->current == ';') skipLine(cursor);
696 }
697 
698 
isTextTokenChar(char c)699 static bool isTextTokenChar(char c)
700 {
701 	return isalnum(c) || c == '_';
702 }
703 
704 
readTextToken(Cursor * cursor)705 static DataView readTextToken(Cursor* cursor)
706 {
707 	DataView ret;
708 	ret.begin = cursor->current;
709 	while (cursor->current < cursor->end && isTextTokenChar(*cursor->current))
710 	{
711 		++cursor->current;
712 	}
713 	ret.end = cursor->current;
714 	return ret;
715 }
716 
717 
readTextProperty(Cursor * cursor)718 static OptionalError<Property*> readTextProperty(Cursor* cursor)
719 {
720 	std::unique_ptr<Property> prop(new Property());
721 	prop->value.is_binary = false;
722 	prop->next = nullptr;
723 	if (*cursor->current == '"')
724 	{
725 		prop->type = 'S';
726 		++cursor->current;
727 		prop->value.begin = cursor->current;
728 		while (cursor->current < cursor->end && *cursor->current != '"')
729 		{
730 			++cursor->current;
731 		}
732 		prop->value.end = cursor->current;
733 		if (cursor->current < cursor->end) ++cursor->current; // skip '"'
734 		return prop.release();
735 	}
736 
737 	if (isdigit(*cursor->current) || *cursor->current == '-')
738 	{
739 		prop->type = 'L';
740 		prop->value.begin = cursor->current;
741 		if (*cursor->current == '-') ++cursor->current;
742 		while (cursor->current < cursor->end && isdigit(*cursor->current))
743 		{
744 			++cursor->current;
745 		}
746 		prop->value.end = cursor->current;
747 
748 		if (cursor->current < cursor->end && *cursor->current == '.')
749 		{
750 			prop->type = 'D';
751 			++cursor->current;
752 			while (cursor->current < cursor->end && isdigit(*cursor->current))
753 			{
754 				++cursor->current;
755 			}
756 			if (cursor->current < cursor->end && (*cursor->current == 'e' || *cursor->current == 'E'))
757 			{
758 				// 10.5e-013
759 				++cursor->current;
760 				if (cursor->current < cursor->end && *cursor->current == '-') ++cursor->current;
761 				while (cursor->current < cursor->end && isdigit(*cursor->current)) ++cursor->current;
762 			}
763 
764 
765 			prop->value.end = cursor->current;
766 		}
767 		return prop.release();
768 	}
769 
770 	if (*cursor->current == 'T' || *cursor->current == 'Y')
771 	{
772 		// WTF is this
773 		prop->type = *cursor->current;
774 		prop->value.begin = cursor->current;
775 		++cursor->current;
776 		prop->value.end = cursor->current;
777 		return prop.release();
778 	}
779 
780 	if (*cursor->current == '*')
781 	{
782 		prop->type = 'l';
783 		++cursor->current;
784 		// Vertices: *10740 { a: 14.2760353088379,... }
785 		while (cursor->current < cursor->end && *cursor->current != ':')
786 		{
787 			++cursor->current;
788 		}
789 		if (cursor->current < cursor->end) ++cursor->current; // skip ':'
790 		skipInsignificantWhitespaces(cursor);
791 		prop->value.begin = cursor->current;
792 		prop->count = 0;
793 		bool is_any = false;
794 		while (cursor->current < cursor->end && *cursor->current != '}')
795 		{
796 			if (*cursor->current == ',')
797 			{
798 				if (is_any) ++prop->count;
799 				is_any = false;
800 			}
801 			else if (!isspace(*cursor->current) && *cursor->current != '\n') is_any = true;
802 			if (*cursor->current == '.') prop->type = 'd';
803 			++cursor->current;
804 		}
805 		if (is_any) ++prop->count;
806 		prop->value.end = cursor->current;
807 		if (cursor->current < cursor->end) ++cursor->current; // skip '}'
808 		return prop.release();
809 	}
810 
811 	assert(false);
812 	return Error("TODO");
813 }
814 
815 
readTextElement(Cursor * cursor)816 static OptionalError<Element*> readTextElement(Cursor* cursor)
817 {
818 	DataView id = readTextToken(cursor);
819 	if (cursor->current == cursor->end) return Error("Unexpected end of file");
820 	if(*cursor->current != ':') return Error("Unexpected end of file");
821 	++cursor->current;
822 
823 	skipWhitespaces(cursor);
824 	if (cursor->current == cursor->end) return Error("Unexpected end of file");
825 
826 	Element* element = new Element;
827 	element->id = id;
828 
829 	Property** prop_link = &element->first_property;
830 	while (cursor->current < cursor->end && *cursor->current != '\n' && *cursor->current != '{')
831 	{
832 		OptionalError<Property*> prop = readTextProperty(cursor);
833 		if (prop.isError())
834 		{
835 			deleteElement(element);
836 			return Error();
837 		}
838 		if (cursor->current < cursor->end && *cursor->current == ',')
839 		{
840 			++cursor->current;
841 			skipWhitespaces(cursor);
842 		}
843 		skipInsignificantWhitespaces(cursor);
844 
845 		*prop_link = prop.getValue();
846 		prop_link = &(*prop_link)->next;
847 	}
848 
849 	Element** link = &element->child;
850 	if (*cursor->current == '{')
851 	{
852 		++cursor->current;
853 		skipWhitespaces(cursor);
854 		while (cursor->current < cursor->end && *cursor->current != '}')
855 		{
856 			OptionalError<Element*> child = readTextElement(cursor);
857 			if (child.isError())
858 			{
859 				deleteElement(element);
860 				return Error();
861 			}
862 			skipWhitespaces(cursor);
863 
864 			*link = child.getValue();
865 			link = &(*link)->sibling;
866 		}
867 		if (cursor->current < cursor->end) ++cursor->current; // skip '}'
868 	}
869 	return element;
870 }
871 
872 
tokenizeText(const u8 * data,size_t size)873 static OptionalError<Element*> tokenizeText(const u8* data, size_t size)
874 {
875 	Cursor cursor;
876 	cursor.begin = data;
877 	cursor.current = data;
878 	cursor.end = data + size;
879 
880 	Element* root = new Element();
881 	root->first_property = nullptr;
882 	root->id.begin = nullptr;
883 	root->id.end = nullptr;
884 	root->child = nullptr;
885 	root->sibling = nullptr;
886 
887 	Element** element = &root->child;
888 	while (cursor.current < cursor.end)
889 	{
890 		if (*cursor.current == ';' || *cursor.current == '\r' || *cursor.current == '\n')
891 		{
892 			skipLine(&cursor);
893 		}
894 		else
895 		{
896 			OptionalError<Element*> child = readTextElement(&cursor);
897 			if (child.isError())
898 			{
899 				deleteElement(root);
900 				return Error();
901 			}
902 			*element = child.getValue();
903 			if (!*element) return root;
904 			element = &(*element)->sibling;
905 		}
906 	}
907 
908 	return root;
909 }
910 
911 
tokenize(const u8 * data,size_t size)912 static OptionalError<Element*> tokenize(const u8* data, size_t size)
913 {
914 	Cursor cursor;
915 	cursor.begin = data;
916 	cursor.current = data;
917 	cursor.end = data + size;
918 
919 	const Header* header = (const Header*)cursor.current;
920 	cursor.current += sizeof(*header);
921 
922 	Element* root = new Element();
923 	root->first_property = nullptr;
924 	root->id.begin = nullptr;
925 	root->id.end = nullptr;
926 	root->child = nullptr;
927 	root->sibling = nullptr;
928 
929 	Element** element = &root->child;
930 	for (;;)
931 	{
932 		OptionalError<Element*> child = readElement(&cursor, header->version);
933 		if (child.isError())
934 		{
935 			deleteElement(root);
936 			return Error();
937 		}
938 		*element = child.getValue();
939 		if (!*element) return root;
940 		element = &(*element)->sibling;
941 	}
942 }
943 
944 
parseTemplates(const Element & root)945 static void parseTemplates(const Element& root)
946 {
947 	const Element* defs = findChild(root, "Definitions");
948 	if (!defs) return;
949 
950 	std::unordered_map<std::string, Element*> templates;
951 	Element* def = defs->child;
952 	while (def)
953 	{
954 		if (def->id == "ObjectType")
955 		{
956 			Element* subdef = def->child;
957 			while (subdef)
958 			{
959 				if (subdef->id == "PropertyTemplate")
960 				{
961 					DataView prop1 = def->first_property->value;
962 					DataView prop2 = subdef->first_property->value;
963 					std::string key((const char*)prop1.begin, prop1.end - prop1.begin);
964 					key += std::string((const char*)prop1.begin, prop1.end - prop1.begin);
965 					templates[key] = subdef;
966 				}
967 				subdef = subdef->sibling;
968 			}
969 		}
970 		def = def->sibling;
971 	}
972 	// TODO
973 }
974 
975 
976 struct Scene;
977 
978 
Mesh(const Scene & _scene,const IElement & _element)979 Mesh::Mesh(const Scene& _scene, const IElement& _element)
980 	: Object(_scene, _element)
981 {
982 }
983 
984 
985 struct MeshImpl : Mesh
986 {
MeshImplofbx::MeshImpl987 	MeshImpl(const Scene& _scene, const IElement& _element)
988 		: Mesh(_scene, _element)
989 		, scene(_scene)
990 	{
991 		is_node = true;
992 	}
993 
994 
getGeometricMatrixofbx::MeshImpl995 	Matrix getGeometricMatrix() const override
996 	{
997 		Vec3 translation = resolveVec3Property(*this, "GeometricTranslation", {0, 0, 0});
998 		Vec3 rotation = resolveVec3Property(*this, "GeometricRotation", {0, 0, 0});
999 		Vec3 scale = resolveVec3Property(*this, "GeometricScaling", {1, 1, 1});
1000 
1001 		Matrix scale_mtx = makeIdentity();
1002 		scale_mtx.m[0] = (float)scale.x;
1003 		scale_mtx.m[5] = (float)scale.y;
1004 		scale_mtx.m[10] = (float)scale.z;
1005 		Matrix mtx = getRotationMatrix(rotation, RotationOrder::EULER_XYZ);
1006 		setTranslation(translation, &mtx);
1007 
1008 		return scale_mtx * mtx;
1009 	}
1010 
1011 
getTypeofbx::MeshImpl1012 	Type getType() const override { return Type::MESH; }
1013 
1014 
getGeometryofbx::MeshImpl1015 	const Geometry* getGeometry() const override { return geometry; }
getMaterialofbx::MeshImpl1016 	const Material* getMaterial(int index) const override { return materials[index]; }
getMaterialCountofbx::MeshImpl1017 	int getMaterialCount() const override { return (int)materials.size(); }
1018 
1019 
1020 	const Geometry* geometry = nullptr;
1021 	const Scene& scene;
1022 	std::vector<const Material*> materials;
1023 };
1024 
1025 
Material(const Scene & _scene,const IElement & _element)1026 Material::Material(const Scene& _scene, const IElement& _element)
1027 	: Object(_scene, _element)
1028 {
1029 }
1030 
1031 
1032 struct MaterialImpl : Material
1033 {
MaterialImplofbx::MaterialImpl1034 	MaterialImpl(const Scene& _scene, const IElement& _element)
1035 		: Material(_scene, _element)
1036 	{
1037 		for (const Texture*& tex : textures) tex = nullptr;
1038 	}
1039 
getTypeofbx::MaterialImpl1040 	Type getType() const override { return Type::MATERIAL; }
1041 
1042 
getTextureofbx::MaterialImpl1043 	const Texture* getTexture(Texture::TextureType type) const override { return textures[type]; }
getDiffuseColorofbx::MaterialImpl1044 	Color getDiffuseColor() const override { return diffuse_color; }
1045 
1046 	const Texture* textures[Texture::TextureType::COUNT];
1047 	Color diffuse_color;
1048 };
1049 
1050 
1051 struct LimbNodeImpl : Object
1052 {
LimbNodeImplofbx::LimbNodeImpl1053 	LimbNodeImpl(const Scene& _scene, const IElement& _element)
1054 		: Object(_scene, _element)
1055 	{
1056 		is_node = true;
1057 	}
getTypeofbx::LimbNodeImpl1058 	Type getType() const override { return Type::LIMB_NODE; }
1059 };
1060 
1061 
1062 struct NullImpl : Object
1063 {
NullImplofbx::NullImpl1064 	NullImpl(const Scene& _scene, const IElement& _element)
1065 		: Object(_scene, _element)
1066 	{
1067 		is_node = true;
1068 	}
getTypeofbx::NullImpl1069 	Type getType() const override { return Type::NULL_NODE; }
1070 };
1071 
1072 
NodeAttribute(const Scene & _scene,const IElement & _element)1073 NodeAttribute::NodeAttribute(const Scene& _scene, const IElement& _element)
1074 	: Object(_scene, _element)
1075 {
1076 }
1077 
1078 
1079 struct NodeAttributeImpl : NodeAttribute
1080 {
NodeAttributeImplofbx::NodeAttributeImpl1081 	NodeAttributeImpl(const Scene& _scene, const IElement& _element)
1082 		: NodeAttribute(_scene, _element)
1083 	{
1084 	}
getTypeofbx::NodeAttributeImpl1085 	Type getType() const override { return Type::NODE_ATTRIBUTE; }
getAttributeTypeofbx::NodeAttributeImpl1086 	DataView getAttributeType() const override { return attribute_type; }
1087 
1088 
1089 	DataView attribute_type;
1090 };
1091 
1092 
Geometry(const Scene & _scene,const IElement & _element)1093 Geometry::Geometry(const Scene& _scene, const IElement& _element)
1094 	: Object(_scene, _element)
1095 {
1096 }
1097 
1098 
1099 struct GeometryImpl : Geometry
1100 {
1101 	enum VertexDataMapping
1102 	{
1103 		BY_POLYGON_VERTEX,
1104 		BY_POLYGON,
1105 		BY_VERTEX
1106 	};
1107 
1108 	struct NewVertex
1109 	{
~NewVertexofbx::GeometryImpl::NewVertex1110 		~NewVertex() { delete next; }
1111 
1112 		int index = -1;
1113 		NewVertex* next = nullptr;
1114 	};
1115 
1116 	std::vector<Vec3> vertices;
1117 	std::vector<Vec3> normals;
1118 	std::vector<Vec2> uvs[s_uvs_max];
1119 	std::vector<Vec4> colors;
1120 	std::vector<Vec3> tangents;
1121 	std::vector<int> materials;
1122 
1123 	const Skin* skin = nullptr;
1124 
1125 	std::vector<int> to_old_vertices;
1126 	std::vector<NewVertex> to_new_vertices;
1127 
GeometryImplofbx::GeometryImpl1128 	GeometryImpl(const Scene& _scene, const IElement& _element)
1129 		: Geometry(_scene, _element)
1130 	{
1131 	}
1132 
1133 
getTypeofbx::GeometryImpl1134 	Type getType() const override { return Type::GEOMETRY; }
getVertexCountofbx::GeometryImpl1135 	int getVertexCount() const override { return (int)vertices.size(); }
getVerticesofbx::GeometryImpl1136 	const Vec3* getVertices() const override { return &vertices[0]; }
getNormalsofbx::GeometryImpl1137 	const Vec3* getNormals() const override { return normals.empty() ? nullptr : &normals[0]; }
getUVsofbx::GeometryImpl1138 	const Vec2* getUVs(int index = 0) const override { return index < 0 || index >= s_uvs_max || uvs[index].empty() ? nullptr : &uvs[index][0]; }
getColorsofbx::GeometryImpl1139 	const Vec4* getColors() const override { return colors.empty() ? nullptr : &colors[0]; }
getTangentsofbx::GeometryImpl1140 	const Vec3* getTangents() const override { return tangents.empty() ? nullptr : &tangents[0]; }
getSkinofbx::GeometryImpl1141 	const Skin* getSkin() const override { return skin; }
getMaterialsofbx::GeometryImpl1142 	const int* getMaterials() const override { return materials.empty() ? nullptr : &materials[0]; }
1143 
1144 
triangulateofbx::GeometryImpl1145 	void triangulate(const std::vector<int>& old_indices, std::vector<int>* indices, std::vector<int>* to_old)
1146 	{
1147 		assert(indices);
1148 		assert(to_old);
1149 
1150 		auto getIdx = [&old_indices](int i) -> int {
1151 			int idx = old_indices[i];
1152 			return idx < 0 ? -idx - 1 : idx;
1153 		};
1154 
1155 		int in_polygon_idx = 0;
1156 		for (int i = 0; i < old_indices.size(); ++i)
1157 		{
1158 			int idx = getIdx(i);
1159 			if (in_polygon_idx <= 2)
1160 			{
1161 				indices->push_back(idx);
1162 				to_old->push_back(i);
1163 			}
1164 			else
1165 			{
1166 				indices->push_back(old_indices[i - in_polygon_idx]);
1167 				to_old->push_back(i - in_polygon_idx);
1168 				indices->push_back(old_indices[i - 1]);
1169 				to_old->push_back(i - 1);
1170 				indices->push_back(idx);
1171 				to_old->push_back(i);
1172 			}
1173 			++in_polygon_idx;
1174 			if (old_indices[i] < 0)
1175 			{
1176 				in_polygon_idx = 0;
1177 			}
1178 		}
1179 	}
1180 };
1181 
1182 
Cluster(const Scene & _scene,const IElement & _element)1183 Cluster::Cluster(const Scene& _scene, const IElement& _element)
1184 	: Object(_scene, _element)
1185 {
1186 }
1187 
1188 
1189 struct ClusterImpl : Cluster
1190 {
ClusterImplofbx::ClusterImpl1191 	ClusterImpl(const Scene& _scene, const IElement& _element)
1192 		: Cluster(_scene, _element)
1193 	{
1194 	}
1195 
getIndicesofbx::ClusterImpl1196 	const int* getIndices() const override { return &indices[0]; }
getIndicesCountofbx::ClusterImpl1197 	int getIndicesCount() const override { return (int)indices.size(); }
getWeightsofbx::ClusterImpl1198 	const double* getWeights() const override { return &weights[0]; }
getWeightsCountofbx::ClusterImpl1199 	int getWeightsCount() const override { return (int)weights.size(); }
getTransformMatrixofbx::ClusterImpl1200 	Matrix getTransformMatrix() const override { return transform_matrix; }
getTransformLinkMatrixofbx::ClusterImpl1201 	Matrix getTransformLinkMatrix() const override { return transform_link_matrix; }
getLinkofbx::ClusterImpl1202 	Object* getLink() const override { return link; }
1203 
1204 
postprocessofbx::ClusterImpl1205 	bool postprocess()
1206 	{
1207 		assert(skin);
1208 
1209 		GeometryImpl* geom = (GeometryImpl*)skin->resolveObjectLinkReverse(Object::Type::GEOMETRY);
1210 		if (!geom) return false;
1211 
1212 		std::vector<int> old_indices;
1213 		const Element* indexes = findChild((const Element&)element, "Indexes");
1214 		if (indexes && indexes->first_property)
1215 		{
1216 			if (!parseBinaryArray(*indexes->first_property, &old_indices)) return false;
1217 		}
1218 
1219 		std::vector<double> old_weights;
1220 		const Element* weights_el = findChild((const Element&)element, "Weights");
1221 		if (weights_el && weights_el->first_property)
1222 		{
1223 			if (!parseBinaryArray(*weights_el->first_property, &old_weights)) return false;
1224 		}
1225 
1226 		if (old_indices.size() != old_weights.size()) return false;
1227 
1228 		indices.reserve(old_indices.size());
1229 		weights.reserve(old_indices.size());
1230 		int* ir = old_indices.empty() ? nullptr : &old_indices[0];
1231 		double* wr = old_weights.empty() ? nullptr : &old_weights[0];
1232 		for (int i = 0, c = (int)old_indices.size(); i < c; ++i)
1233 		{
1234 			int old_idx = ir[i];
1235 			double w = wr[i];
1236 			GeometryImpl::NewVertex* n = &geom->to_new_vertices[old_idx];
1237 			if (n->index == -1) continue; // skip vertices which aren't indexed.
1238 			while (n)
1239 			{
1240 				indices.push_back(n->index);
1241 				weights.push_back(w);
1242 				n = n->next;
1243 			}
1244 		}
1245 
1246 		return true;
1247 	}
1248 
1249 
1250 	Object* link = nullptr;
1251 	Skin* skin = nullptr;
1252 	std::vector<int> indices;
1253 	std::vector<double> weights;
1254 	Matrix transform_matrix;
1255 	Matrix transform_link_matrix;
getTypeofbx::ClusterImpl1256 	Type getType() const override { return Type::CLUSTER; }
1257 };
1258 
1259 
AnimationStack(const Scene & _scene,const IElement & _element)1260 AnimationStack::AnimationStack(const Scene& _scene, const IElement& _element)
1261 	: Object(_scene, _element)
1262 {
1263 }
1264 
1265 
AnimationLayer(const Scene & _scene,const IElement & _element)1266 AnimationLayer::AnimationLayer(const Scene& _scene, const IElement& _element)
1267 	: Object(_scene, _element)
1268 {
1269 }
1270 
1271 
AnimationCurve(const Scene & _scene,const IElement & _element)1272 AnimationCurve::AnimationCurve(const Scene& _scene, const IElement& _element)
1273 	: Object(_scene, _element)
1274 {
1275 }
1276 
1277 
AnimationCurveNode(const Scene & _scene,const IElement & _element)1278 AnimationCurveNode::AnimationCurveNode(const Scene& _scene, const IElement& _element)
1279 	: Object(_scene, _element)
1280 {
1281 }
1282 
1283 
1284 struct AnimationStackImpl : AnimationStack
1285 {
AnimationStackImplofbx::AnimationStackImpl1286 	AnimationStackImpl(const Scene& _scene, const IElement& _element)
1287 		: AnimationStack(_scene, _element)
1288 	{
1289 	}
1290 
1291 
getLayerofbx::AnimationStackImpl1292 	const AnimationLayer* getLayer(int index) const override
1293 	{
1294 		return resolveObjectLink<AnimationLayer>(index);
1295 	}
1296 
1297 
getTypeofbx::AnimationStackImpl1298 	Type getType() const override { return Type::ANIMATION_STACK; }
1299 };
1300 
1301 
1302 struct AnimationCurveImpl : AnimationCurve
1303 {
AnimationCurveImplofbx::AnimationCurveImpl1304 	AnimationCurveImpl(const Scene& _scene, const IElement& _element)
1305 		: AnimationCurve(_scene, _element)
1306 	{
1307 	}
1308 
getKeyCountofbx::AnimationCurveImpl1309 	int getKeyCount() const override { return (int)times.size(); }
getKeyTimeofbx::AnimationCurveImpl1310 	const i64* getKeyTime() const override { return &times[0]; }
getKeyValueofbx::AnimationCurveImpl1311 	const float* getKeyValue() const override { return &values[0]; }
1312 
1313 	std::vector<i64> times;
1314 	std::vector<float> values;
getTypeofbx::AnimationCurveImpl1315 	Type getType() const override { return Type::ANIMATION_CURVE; }
1316 };
1317 
1318 
Skin(const Scene & _scene,const IElement & _element)1319 Skin::Skin(const Scene& _scene, const IElement& _element)
1320 	: Object(_scene, _element)
1321 {
1322 }
1323 
1324 
1325 struct SkinImpl : Skin
1326 {
SkinImplofbx::SkinImpl1327 	SkinImpl(const Scene& _scene, const IElement& _element)
1328 		: Skin(_scene, _element)
1329 	{
1330 	}
1331 
getClusterCountofbx::SkinImpl1332 	int getClusterCount() const override { return (int)clusters.size(); }
getClusterofbx::SkinImpl1333 	const Cluster* getCluster(int idx) const override { return clusters[idx]; }
1334 
getTypeofbx::SkinImpl1335 	Type getType() const override { return Type::SKIN; }
1336 
1337 	std::vector<Cluster*> clusters;
1338 };
1339 
1340 
Texture(const Scene & _scene,const IElement & _element)1341 Texture::Texture(const Scene& _scene, const IElement& _element)
1342 	: Object(_scene, _element)
1343 {
1344 }
1345 
1346 
1347 struct TextureImpl : Texture
1348 {
TextureImplofbx::TextureImpl1349 	TextureImpl(const Scene& _scene, const IElement& _element)
1350 		: Texture(_scene, _element)
1351 	{
1352 	}
1353 
getRelativeFileNameofbx::TextureImpl1354 	DataView getRelativeFileName() const override { return relative_filename; }
getFileNameofbx::TextureImpl1355 	DataView getFileName() const override { return filename; }
1356 
1357 	DataView filename;
1358 	DataView relative_filename;
getTypeofbx::TextureImpl1359 	Type getType() const override { return Type::TEXTURE; }
1360 };
1361 
1362 
1363 struct Root : Object
1364 {
Rootofbx::Root1365 	Root(const Scene& _scene, const IElement& _element)
1366 		: Object(_scene, _element)
1367 	{
1368 		copyString(name, "RootNode");
1369 		is_node = true;
1370 	}
getTypeofbx::Root1371 	Type getType() const override { return Type::ROOT; }
1372 };
1373 
1374 
1375 struct Scene : IScene
1376 {
1377 	struct Connection
1378 	{
1379 		enum Type
1380 		{
1381 			OBJECT_OBJECT,
1382 			OBJECT_PROPERTY
1383 		};
1384 
1385 		Type type;
1386 		u64 from;
1387 		u64 to;
1388 		DataView property;
1389 	};
1390 
1391 	struct ObjectPair
1392 	{
1393 		const Element* element;
1394 		Object* object;
1395 	};
1396 
1397 
getAnimationStackCountofbx::Scene1398 	int getAnimationStackCount() const override { return (int)m_animation_stacks.size(); }
getMeshCountofbx::Scene1399 	int getMeshCount() const override { return (int)m_meshes.size(); }
getSceneFrameRateofbx::Scene1400 	float getSceneFrameRate() const override { return m_scene_frame_rate; }
getGlobalSettingsofbx::Scene1401 	const GlobalSettings* getGlobalSettings() const override { return &m_settings; }
1402 
getAllObjectsofbx::Scene1403 	const Object* const* getAllObjects() const override { return m_all_objects.empty() ? nullptr : &m_all_objects[0]; }
1404 
1405 
getAllObjectCountofbx::Scene1406 	int getAllObjectCount() const override { return (int)m_all_objects.size(); }
1407 
1408 
getAnimationStackofbx::Scene1409 	const AnimationStack* getAnimationStack(int index) const override
1410 	{
1411 		assert(index >= 0);
1412 		assert(index < m_animation_stacks.size());
1413 		return m_animation_stacks[index];
1414 	}
1415 
1416 
getMeshofbx::Scene1417 	const Mesh* getMesh(int index) const override
1418 	{
1419 		assert(index >= 0);
1420 		assert(index < m_meshes.size());
1421 		return m_meshes[index];
1422 	}
1423 
1424 
getTakeInfoofbx::Scene1425 	const TakeInfo* getTakeInfo(const char* name) const override
1426 	{
1427 		for (const TakeInfo& info : m_take_infos)
1428 		{
1429 			if (info.name == name) return &info;
1430 		}
1431 		return nullptr;
1432 	}
1433 
1434 
getRootElementofbx::Scene1435 	const IElement* getRootElement() const override { return m_root_element; }
getRootofbx::Scene1436 	const Object* getRoot() const override { return m_root; }
1437 
1438 
destroyofbx::Scene1439 	void destroy() override { delete this; }
1440 
1441 
~Sceneofbx::Scene1442 	~Scene()
1443 	{
1444 		for (auto iter : m_object_map)
1445 		{
1446 			delete iter.second.object;
1447 		}
1448 
1449 		deleteElement(m_root_element);
1450 	}
1451 
1452 
1453 	Element* m_root_element = nullptr;
1454 	Root* m_root = nullptr;
1455 	float m_scene_frame_rate = -1;
1456 	GlobalSettings m_settings;
1457 	std::unordered_map<u64, ObjectPair> m_object_map;
1458 	std::vector<Object*> m_all_objects;
1459 	std::vector<Mesh*> m_meshes;
1460 	std::vector<AnimationStack*> m_animation_stacks;
1461 	std::vector<Connection> m_connections;
1462 	std::vector<u8> m_data;
1463 	std::vector<TakeInfo> m_take_infos;
1464 };
1465 
1466 
1467 struct AnimationCurveNodeImpl : AnimationCurveNode
1468 {
AnimationCurveNodeImplofbx::AnimationCurveNodeImpl1469 	AnimationCurveNodeImpl(const Scene& _scene, const IElement& _element)
1470 		: AnimationCurveNode(_scene, _element)
1471 	{
1472 	}
1473 
1474 
getBoneofbx::AnimationCurveNodeImpl1475 	const Object* getBone() const override
1476 	{
1477 		return bone;
1478 	}
1479 
1480 
getNodeLocalTransformofbx::AnimationCurveNodeImpl1481 	Vec3 getNodeLocalTransform(double time) const override
1482 	{
1483 		i64 fbx_time = secondsToFbxTime(time);
1484 
1485 		auto getCoord = [](const Curve& curve, i64 fbx_time) {
1486 			if (!curve.curve) return 0.0f;
1487 
1488 			const i64* times = curve.curve->getKeyTime();
1489 			const float* values = curve.curve->getKeyValue();
1490 			int count = curve.curve->getKeyCount();
1491 
1492 			if (fbx_time < times[0]) fbx_time = times[0];
1493 			if (fbx_time > times[count - 1]) fbx_time = times[count - 1];
1494 			for (int i = 1; i < count; ++i)
1495 			{
1496 				if (times[i] >= fbx_time)
1497 				{
1498 					float t = float(double(fbx_time - times[i - 1]) / double(times[i] - times[i - 1]));
1499 					return values[i - 1] * (1 - t) + values[i] * t;
1500 				}
1501 			}
1502 			return values[0];
1503 		};
1504 
1505 		return {getCoord(curves[0], fbx_time), getCoord(curves[1], fbx_time), getCoord(curves[2], fbx_time)};
1506 	}
1507 
1508 
1509 	struct Curve
1510 	{
1511 		const AnimationCurve* curve = nullptr;
1512 		const Scene::Connection* connection = nullptr;
1513 	};
1514 
1515 
1516 	Curve curves[3];
1517 	Object* bone = nullptr;
1518 	DataView bone_link_property;
getTypeofbx::AnimationCurveNodeImpl1519 	Type getType() const override { return Type::ANIMATION_CURVE_NODE; }
1520 	enum Mode
1521 	{
1522 		TRANSLATION,
1523 		ROTATION,
1524 		SCALE
1525 	} mode = TRANSLATION;
1526 };
1527 
1528 
1529 struct AnimationLayerImpl : AnimationLayer
1530 {
AnimationLayerImplofbx::AnimationLayerImpl1531 	AnimationLayerImpl(const Scene& _scene, const IElement& _element)
1532 		: AnimationLayer(_scene, _element)
1533 	{
1534 	}
1535 
1536 
getTypeofbx::AnimationLayerImpl1537 	Type getType() const override { return Type::ANIMATION_LAYER; }
1538 
1539 
getCurveNodeofbx::AnimationLayerImpl1540 	const AnimationCurveNode* getCurveNode(int index) const override
1541 	{
1542 		if (index >= curve_nodes.size() || index < 0) return nullptr;
1543 		return curve_nodes[index];
1544 	}
1545 
1546 
getCurveNodeofbx::AnimationLayerImpl1547 	const AnimationCurveNode* getCurveNode(const Object& bone, const char* prop) const override
1548 	{
1549 		for (const AnimationCurveNodeImpl* node : curve_nodes)
1550 		{
1551 			if (node->bone_link_property == prop && node->bone == &bone) return node;
1552 		}
1553 		return nullptr;
1554 	}
1555 
1556 
1557 	std::vector<AnimationCurveNodeImpl*> curve_nodes;
1558 };
1559 
1560 
parseTexture(const Scene & scene,const Element & element)1561 struct OptionalError<Object*> parseTexture(const Scene& scene, const Element& element)
1562 {
1563 	TextureImpl* texture = new TextureImpl(scene, element);
1564 	const Element* texture_filename = findChild(element, "FileName");
1565 	if (texture_filename && texture_filename->first_property)
1566 	{
1567 		texture->filename = texture_filename->first_property->value;
1568 	}
1569 	const Element* texture_relative_filename = findChild(element, "RelativeFilename");
1570 	if (texture_relative_filename && texture_relative_filename->first_property)
1571 	{
1572 		texture->relative_filename = texture_relative_filename->first_property->value;
1573 	}
1574 	return texture;
1575 }
1576 
1577 
parse(const Scene & scene,const Element & element)1578 template <typename T> static OptionalError<Object*> parse(const Scene& scene, const Element& element)
1579 {
1580 	T* obj = new T(scene, element);
1581 	return obj;
1582 }
1583 
1584 
parseCluster(const Scene & scene,const Element & element)1585 static OptionalError<Object*> parseCluster(const Scene& scene, const Element& element)
1586 {
1587 	std::unique_ptr<ClusterImpl> obj(new ClusterImpl(scene, element));
1588 
1589 	const Element* transform_link = findChild(element, "TransformLink");
1590 	if (transform_link && transform_link->first_property)
1591 	{
1592 		if (!parseArrayRaw(
1593 				*transform_link->first_property, &obj->transform_link_matrix, sizeof(obj->transform_link_matrix)))
1594 		{
1595 			return Error("Failed to parse TransformLink");
1596 		}
1597 	}
1598 	const Element* transform = findChild(element, "Transform");
1599 	if (transform && transform->first_property)
1600 	{
1601 		if (!parseArrayRaw(*transform->first_property, &obj->transform_matrix, sizeof(obj->transform_matrix)))
1602 		{
1603 			return Error("Failed to parse Transform");
1604 
1605 		}
1606 	}
1607 
1608 	return obj.release();
1609 }
1610 
1611 
parseNodeAttribute(const Scene & scene,const Element & element)1612 static OptionalError<Object*> parseNodeAttribute(const Scene& scene, const Element& element)
1613 {
1614 	NodeAttributeImpl* obj = new NodeAttributeImpl(scene, element);
1615 	const Element* type_flags = findChild(element, "TypeFlags");
1616 	if (type_flags && type_flags->first_property)
1617 	{
1618 		obj->attribute_type = type_flags->first_property->value;
1619 	}
1620 	return obj;
1621 }
1622 
1623 
parseLimbNode(const Scene & scene,const Element & element)1624 static OptionalError<Object*> parseLimbNode(const Scene& scene, const Element& element)
1625 {
1626 	if (!element.first_property
1627 		|| !element.first_property->next
1628 		|| !element.first_property->next->next
1629 		|| element.first_property->next->next->value != "LimbNode")
1630 	{
1631 		return Error("Invalid limb node");
1632 	}
1633 
1634 	LimbNodeImpl* obj = new LimbNodeImpl(scene, element);
1635 	return obj;
1636 }
1637 
1638 
parseMesh(const Scene & scene,const Element & element)1639 static OptionalError<Object*> parseMesh(const Scene& scene, const Element& element)
1640 {
1641 	if (!element.first_property
1642 		|| !element.first_property->next
1643 		|| !element.first_property->next->next
1644 		|| element.first_property->next->next->value != "Mesh")
1645 	{
1646 		return Error("Invalid mesh");
1647 	}
1648 
1649 	return new MeshImpl(scene, element);
1650 }
1651 
1652 
parseMaterial(const Scene & scene,const Element & element)1653 static OptionalError<Object*> parseMaterial(const Scene& scene, const Element& element)
1654 {
1655 	MaterialImpl* material = new MaterialImpl(scene, element);
1656 	const Element* prop = findChild(element, "Properties70");
1657 	material->diffuse_color = { 1, 1, 1 };
1658 	if (prop) prop = prop->child;
1659 	while (prop)
1660 	{
1661 		if (prop->id == "P" && prop->first_property)
1662 		{
1663 			if (prop->first_property->value == "DiffuseColor")
1664 			{
1665 				material->diffuse_color.r = (float)prop->getProperty(4)->getValue().toDouble();
1666 				material->diffuse_color.g = (float)prop->getProperty(5)->getValue().toDouble();
1667 				material->diffuse_color.b = (float)prop->getProperty(6)->getValue().toDouble();
1668 			}
1669 		}
1670 		prop = prop->sibling;
1671 	}
1672 	return material;
1673 }
1674 
1675 
1676 template<typename T> static bool parseTextArrayRaw(const Property& property, T* out, int max_size);
1677 
parseArrayRaw(const Property & property,T * out,int max_size)1678 template <typename T> static bool parseArrayRaw(const Property& property, T* out, int max_size)
1679 {
1680 	if (property.value.is_binary)
1681 	{
1682 		assert(out);
1683 
1684 		int elem_size = 1;
1685 		switch (property.type)
1686 		{
1687 			case 'l': elem_size = 8; break;
1688 			case 'd': elem_size = 8; break;
1689 			case 'f': elem_size = 4; break;
1690 			case 'i': elem_size = 4; break;
1691 			default: return false;
1692 		}
1693 
1694 		const u8* data = property.value.begin + sizeof(u32) * 3;
1695 		if (data > property.value.end) return false;
1696 
1697 		u32 count = property.getCount();
1698 		u32 enc = *(const u32*)(property.value.begin + 4);
1699 		u32 len = *(const u32*)(property.value.begin + 8);
1700 
1701 		if (enc == 0)
1702 		{
1703 			if ((int)len > max_size) return false;
1704 			if (data + len > property.value.end) return false;
1705 			memcpy(out, data, len);
1706 			return true;
1707 		}
1708 		else if (enc == 1)
1709 		{
1710 			if (int(elem_size * count) > max_size) return false;
1711 			return decompress(data, len, (u8*)out, elem_size * count);
1712 		}
1713 
1714 		return false;
1715 	}
1716 
1717 	return parseTextArrayRaw(property, out, max_size);
1718 }
1719 
1720 
1721 template <typename T> const char* fromString(const char* str, const char* end, T* val);
fromString(const char * str,const char * end,int * val)1722 template <> const char* fromString<int>(const char* str, const char* end, int* val)
1723 {
1724 	*val = atoi(str);
1725 	const char* iter = str;
1726 	while (iter < end && *iter != ',') ++iter;
1727 	if (iter < end) ++iter; // skip ','
1728 	return (const char*)iter;
1729 }
1730 
1731 
fromString(const char * str,const char * end,u64 * val)1732 template <> const char* fromString<u64>(const char* str, const char* end, u64* val)
1733 {
1734 	*val = strtoull(str, nullptr, 10);
1735 	const char* iter = str;
1736 	while (iter < end && *iter != ',') ++iter;
1737 	if (iter < end) ++iter; // skip ','
1738 	return (const char*)iter;
1739 }
1740 
1741 
fromString(const char * str,const char * end,i64 * val)1742 template <> const char* fromString<i64>(const char* str, const char* end, i64* val)
1743 {
1744 	*val = atoll(str);
1745 	const char* iter = str;
1746 	while (iter < end && *iter != ',') ++iter;
1747 	if (iter < end) ++iter; // skip ','
1748 	return (const char*)iter;
1749 }
1750 
1751 
fromString(const char * str,const char * end,double * val)1752 template <> const char* fromString<double>(const char* str, const char* end, double* val)
1753 {
1754 	*val = atof(str);
1755 	const char* iter = str;
1756 	while (iter < end && *iter != ',') ++iter;
1757 	if (iter < end) ++iter; // skip ','
1758 	return (const char*)iter;
1759 }
1760 
1761 
fromString(const char * str,const char * end,float * val)1762 template <> const char* fromString<float>(const char* str, const char* end, float* val)
1763 {
1764 	*val = (float)atof(str);
1765 	const char* iter = str;
1766 	while (iter < end && *iter != ',') ++iter;
1767 	if (iter < end) ++iter; // skip ','
1768 	return (const char*)iter;
1769 }
1770 
1771 
fromString(const char * str,const char * end,double * val,int count)1772 const char* fromString(const char* str, const char* end, double* val, int count)
1773 {
1774 	const char* iter = str;
1775 	for (int i = 0; i < count; ++i)
1776 	{
1777 		*val = atof(iter);
1778 		++val;
1779 		while (iter < end && *iter != ',') ++iter;
1780 		if (iter < end) ++iter; // skip ','
1781 
1782 		if (iter == end) return iter;
1783 
1784 	}
1785 	return (const char*)iter;
1786 }
1787 
1788 
fromString(const char * str,const char * end,Vec2 * val)1789 template <> const char* fromString<Vec2>(const char* str, const char* end, Vec2* val)
1790 {
1791 	return fromString(str, end, &val->x, 2);
1792 }
1793 
1794 
fromString(const char * str,const char * end,Vec3 * val)1795 template <> const char* fromString<Vec3>(const char* str, const char* end, Vec3* val)
1796 {
1797 	return fromString(str, end, &val->x, 3);
1798 }
1799 
1800 
fromString(const char * str,const char * end,Vec4 * val)1801 template <> const char* fromString<Vec4>(const char* str, const char* end, Vec4* val)
1802 {
1803 	return fromString(str, end, &val->x, 4);
1804 }
1805 
1806 
fromString(const char * str,const char * end,Matrix * val)1807 template <> const char* fromString<Matrix>(const char* str, const char* end, Matrix* val)
1808 {
1809 	return fromString(str, end, &val->m[0], 16);
1810 }
1811 
1812 
parseTextArray(const Property & property,std::vector<T> * out)1813 template<typename T> static void parseTextArray(const Property& property, std::vector<T>* out)
1814 {
1815 	const u8* iter = property.value.begin;
1816 	for(int i = 0; i < property.count; ++i)
1817 	{
1818 		T val;
1819 		iter = (const u8*)fromString<T>((const char*)iter, (const char*)property.value.end, &val);
1820 		out->push_back(val);
1821 	}
1822 }
1823 
1824 
parseTextArrayRaw(const Property & property,T * out_raw,int max_size)1825 template<typename T> static bool parseTextArrayRaw(const Property& property, T* out_raw, int max_size)
1826 {
1827 	const u8* iter = property.value.begin;
1828 
1829 	T* out = out_raw;
1830 	while (iter < property.value.end)
1831 	{
1832 		iter = (const u8*)fromString<T>((const char*)iter, (const char*)property.value.end, out);
1833 		++out;
1834 		if (out - out_raw == max_size / sizeof(T)) return true;
1835 	}
1836 	return out - out_raw == max_size / sizeof(T);
1837 }
1838 
1839 
parseBinaryArray(const Property & property,std::vector<T> * out)1840 template <typename T> static bool parseBinaryArray(const Property& property, std::vector<T>* out)
1841 {
1842 	assert(out);
1843 	if (property.value.is_binary)
1844 	{
1845 		u32 count = property.getCount();
1846 		int elem_size = 1;
1847 		switch (property.type)
1848 		{
1849 			case 'd': elem_size = 8; break;
1850 			case 'f': elem_size = 4; break;
1851 			case 'i': elem_size = 4; break;
1852 			default: return false;
1853 		}
1854 		int elem_count = sizeof(T) / elem_size;
1855 		out->resize(count / elem_count);
1856 
1857 		if (count == 0) return true;
1858 		return parseArrayRaw(property, &(*out)[0], int(sizeof((*out)[0]) * out->size()));
1859 	}
1860 	else
1861 	{
1862 		parseTextArray(property, out);
1863 		return true;
1864 	}
1865 }
1866 
1867 
parseDoubleVecData(Property & property,std::vector<T> * out_vec)1868 template <typename T> static bool parseDoubleVecData(Property& property, std::vector<T>* out_vec)
1869 {
1870 	assert(out_vec);
1871 	if (!property.value.is_binary)
1872 	{
1873 		parseTextArray(property, out_vec);
1874 		return true;
1875 	}
1876 
1877 	if (property.type == 'd')
1878 	{
1879 		return parseBinaryArray(property, out_vec);
1880 	}
1881 
1882 	assert(property.type == 'f');
1883 	assert(sizeof((*out_vec)[0].x) == sizeof(double));
1884 	std::vector<float> tmp;
1885 	if (!parseBinaryArray(property, &tmp)) return false;
1886 	int elem_count = sizeof((*out_vec)[0]) / sizeof((*out_vec)[0].x);
1887 	out_vec->resize(tmp.size() / elem_count);
1888 	double* out = &(*out_vec)[0].x;
1889 	for (int i = 0, c = (int)tmp.size(); i < c; ++i)
1890 	{
1891 		out[i] = tmp[i];
1892 	}
1893 	return true;
1894 }
1895 
1896 
1897 template <typename T>
parseVertexData(const Element & element,const char * name,const char * index_name,std::vector<T> * out,std::vector<int> * out_indices,GeometryImpl::VertexDataMapping * mapping)1898 static bool parseVertexData(const Element& element,
1899 	const char* name,
1900 	const char* index_name,
1901 	std::vector<T>* out,
1902 	std::vector<int>* out_indices,
1903 	GeometryImpl::VertexDataMapping* mapping)
1904 {
1905 	assert(out);
1906 	assert(mapping);
1907 	const Element* data_element = findChild(element, name);
1908 	if (!data_element || !data_element->first_property) 	return false;
1909 
1910 	const Element* mapping_element = findChild(element, "MappingInformationType");
1911 	const Element* reference_element = findChild(element, "ReferenceInformationType");
1912 
1913 	if (mapping_element && mapping_element->first_property)
1914 	{
1915 		if (mapping_element->first_property->value == "ByPolygonVertex")
1916 		{
1917 			*mapping = GeometryImpl::BY_POLYGON_VERTEX;
1918 		}
1919 		else if (mapping_element->first_property->value == "ByPolygon")
1920 		{
1921 			*mapping = GeometryImpl::BY_POLYGON;
1922 		}
1923 		else if (mapping_element->first_property->value == "ByVertice" ||
1924 					mapping_element->first_property->value == "ByVertex")
1925 		{
1926 			*mapping = GeometryImpl::BY_VERTEX;
1927 		}
1928 		else
1929 		{
1930 			return false;
1931 		}
1932 	}
1933 	if (reference_element && reference_element->first_property)
1934 	{
1935 		if (reference_element->first_property->value == "IndexToDirect")
1936 		{
1937 			const Element* indices_element = findChild(element, index_name);
1938 			if (indices_element && indices_element->first_property)
1939 			{
1940 				if (!parseBinaryArray(*indices_element->first_property, out_indices)) return false;
1941 			}
1942 		}
1943 		else if (reference_element->first_property->value != "Direct")
1944 		{
1945 			return false;
1946 		}
1947 	}
1948 	return parseDoubleVecData(*data_element->first_property, out);
1949 }
1950 
1951 
1952 template <typename T>
splat(std::vector<T> * out,GeometryImpl::VertexDataMapping mapping,const std::vector<T> & data,const std::vector<int> & indices,const std::vector<int> & original_indices)1953 static void splat(std::vector<T>* out,
1954 	GeometryImpl::VertexDataMapping mapping,
1955 	const std::vector<T>& data,
1956 	const std::vector<int>& indices,
1957 	const std::vector<int>& original_indices)
1958 {
1959 	assert(out);
1960 	assert(!data.empty());
1961 
1962 	if (mapping == GeometryImpl::BY_POLYGON_VERTEX)
1963 	{
1964 		if (indices.empty())
1965 		{
1966 			out->resize(data.size());
1967 			memcpy(&(*out)[0], &data[0], sizeof(data[0]) * data.size());
1968 		}
1969 		else
1970 		{
1971 			out->resize(indices.size());
1972 			int data_size = (int)data.size();
1973 			for (int i = 0, c = (int)indices.size(); i < c; ++i)
1974 			{
1975 				if(indices[i] < data_size) (*out)[i] = data[indices[i]];
1976 				else (*out)[i] = T();
1977 			}
1978 		}
1979 	}
1980 	else if (mapping == GeometryImpl::BY_VERTEX)
1981 	{
1982 		//  v0  v1 ...
1983 		// uv0 uv1 ...
1984 		assert(indices.empty());
1985 
1986 		out->resize(original_indices.size());
1987 
1988 		int data_size = (int)data.size();
1989 		for (int i = 0, c = (int)original_indices.size(); i < c; ++i)
1990 		{
1991 			int idx = original_indices[i];
1992 			if (idx < 0) idx = -idx - 1;
1993 			if(idx < data_size) (*out)[i] = data[idx];
1994 			else (*out)[i] = T();
1995 		}
1996 	}
1997 	else
1998 	{
1999 		assert(false);
2000 	}
2001 }
2002 
2003 
remap(std::vector<T> * out,const std::vector<int> & map)2004 template <typename T> static void remap(std::vector<T>* out, const std::vector<int>& map)
2005 {
2006 	if (out->empty()) return;
2007 
2008 	std::vector<T> old;
2009 	old.swap(*out);
2010 	int old_size = (int)old.size();
2011 	for (int i = 0, c = (int)map.size(); i < c; ++i)
2012 	{
2013 		if(map[i] < old_size) out->push_back(old[map[i]]);
2014 		else out->push_back(T());
2015 	}
2016 }
2017 
2018 
parseAnimationCurve(const Scene & scene,const Element & element)2019 static OptionalError<Object*> parseAnimationCurve(const Scene& scene, const Element& element)
2020 {
2021 	std::unique_ptr<AnimationCurveImpl> curve(new AnimationCurveImpl(scene, element));
2022 
2023 	const Element* times = findChild(element, "KeyTime");
2024 	const Element* values = findChild(element, "KeyValueFloat");
2025 
2026 	if (times && times->first_property)
2027 	{
2028 		curve->times.resize(times->first_property->getCount());
2029 		if (!times->first_property->getValues(&curve->times[0], (int)curve->times.size() * sizeof(curve->times[0])))
2030 		{
2031 			return Error("Invalid animation curve");
2032 		}
2033 	}
2034 
2035 	if (values && values->first_property)
2036 	{
2037 		curve->values.resize(values->first_property->getCount());
2038 		if (!values->first_property->getValues(&curve->values[0], (int)curve->values.size() * sizeof(curve->values[0])))
2039 		{
2040 			return Error("Invalid animation curve");
2041 		}
2042 	}
2043 
2044 	if (curve->times.size() != curve->values.size()) return Error("Invalid animation curve");
2045 
2046 	return curve.release();
2047 }
2048 
2049 
getTriCountFromPoly(const std::vector<int> & indices,int * idx)2050 static int getTriCountFromPoly(const std::vector<int>& indices, int* idx)
2051 {
2052 	int count = 1;
2053 	while (indices[*idx + 1 + count] >= 0)
2054 	{
2055 		++count;
2056 	}
2057 
2058 	*idx = *idx + 2 + count;
2059 	return count;
2060 }
2061 
2062 
add(GeometryImpl::NewVertex & vtx,int index)2063 static void add(GeometryImpl::NewVertex& vtx, int index)
2064 {
2065 	if (vtx.index == -1)
2066 	{
2067 		vtx.index = index;
2068 	}
2069 	else if (vtx.next)
2070 	{
2071 		add(*vtx.next, index);
2072 	}
2073 	else
2074 	{
2075 		vtx.next = new GeometryImpl::NewVertex;
2076 		vtx.next->index = index;
2077 	}
2078 }
2079 
2080 
parseGeometry(const Scene & scene,const Element & element)2081 static OptionalError<Object*> parseGeometry(const Scene& scene, const Element& element)
2082 {
2083 	assert(element.first_property);
2084 
2085 	const Element* vertices_element = findChild(element, "Vertices");
2086 	if (!vertices_element || !vertices_element->first_property) return Error("Vertices missing");
2087 
2088 	const Element* polys_element = findChild(element, "PolygonVertexIndex");
2089 	if (!polys_element || !polys_element->first_property) return Error("Indices missing");
2090 
2091 	std::unique_ptr<GeometryImpl> geom(new GeometryImpl(scene, element));
2092 
2093 	std::vector<Vec3> vertices;
2094 	if (!parseDoubleVecData(*vertices_element->first_property, &vertices)) return Error("Failed to parse vertices");
2095 	std::vector<int> original_indices;
2096 	if (!parseBinaryArray(*polys_element->first_property, &original_indices)) return Error("Failed to parse indices");
2097 
2098 	std::vector<int> to_old_indices;
2099 	geom->triangulate(original_indices, &geom->to_old_vertices, &to_old_indices);
2100 	geom->vertices.resize(geom->to_old_vertices.size());
2101 
2102 	for (int i = 0, c = (int)geom->to_old_vertices.size(); i < c; ++i)
2103 	{
2104 		geom->vertices[i] = vertices[geom->to_old_vertices[i]];
2105 	}
2106 
2107 	geom->to_new_vertices.resize(vertices.size()); // some vertices can be unused, so this isn't necessarily the same size as to_old_vertices.
2108 	const int* to_old_vertices = geom->to_old_vertices.empty() ? nullptr : &geom->to_old_vertices[0];
2109 	for (int i = 0, c = (int)geom->to_old_vertices.size(); i < c; ++i)
2110 	{
2111 		int old = to_old_vertices[i];
2112 		add(geom->to_new_vertices[old], i);
2113 	}
2114 
2115 	const Element* layer_material_element = findChild(element, "LayerElementMaterial");
2116 	if (layer_material_element)
2117 	{
2118 		const Element* mapping_element = findChild(*layer_material_element, "MappingInformationType");
2119 		const Element* reference_element = findChild(*layer_material_element, "ReferenceInformationType");
2120 
2121 		std::vector<int> tmp;
2122 
2123 		if (!mapping_element || !reference_element) return Error("Invalid LayerElementMaterial");
2124 
2125 		if (mapping_element->first_property->value == "ByPolygon" &&
2126 			reference_element->first_property->value == "IndexToDirect")
2127 		{
2128 			geom->materials.reserve(geom->vertices.size() / 3);
2129 			for (int& i : geom->materials) i = -1;
2130 
2131 			const Element* indices_element = findChild(*layer_material_element, "Materials");
2132 			if (!indices_element || !indices_element->first_property) return Error("Invalid LayerElementMaterial");
2133 
2134 			if (!parseBinaryArray(*indices_element->first_property, &tmp)) return Error("Failed to parse material indices");
2135 
2136 			int tmp_i = 0;
2137 			for (int poly = 0, c = (int)tmp.size(); poly < c; ++poly)
2138 			{
2139 				int tri_count = getTriCountFromPoly(original_indices, &tmp_i);
2140 				for (int i = 0; i < tri_count; ++i)
2141 				{
2142 					geom->materials.push_back(tmp[poly]);
2143 				}
2144 			}
2145 		}
2146 		else
2147 		{
2148 			if (mapping_element->first_property->value != "AllSame") return Error("Mapping not supported");
2149 		}
2150 	}
2151 
2152 	const Element* layer_uv_element = findChild(element, "LayerElementUV");
2153     while (layer_uv_element)
2154     {
2155         const int uv_index = layer_uv_element->first_property ? layer_uv_element->first_property->getValue().toInt() : 0;
2156         if (uv_index >= 0 && uv_index < Geometry::s_uvs_max)
2157         {
2158             std::vector<Vec2>& uvs = geom->uvs[uv_index];
2159 
2160             std::vector<Vec2> tmp;
2161             std::vector<int> tmp_indices;
2162             GeometryImpl::VertexDataMapping mapping;
2163             if (!parseVertexData(*layer_uv_element, "UV", "UVIndex", &tmp, &tmp_indices, &mapping)) return Error("Invalid UVs");
2164             if (!tmp.empty())
2165             {
2166                 uvs.resize(tmp_indices.empty() ? tmp.size() : tmp_indices.size());
2167                 splat(&uvs, mapping, tmp, tmp_indices, original_indices);
2168                 remap(&uvs, to_old_indices);
2169             }
2170         }
2171 
2172         do
2173         {
2174             layer_uv_element = layer_uv_element->sibling;
2175         } while (layer_uv_element && layer_uv_element->id != "LayerElementUV");
2176     }
2177 
2178 	const Element* layer_tangent_element = findChild(element, "LayerElementTangents");
2179 	if (layer_tangent_element)
2180 	{
2181 		std::vector<Vec3> tmp;
2182 		std::vector<int> tmp_indices;
2183 		GeometryImpl::VertexDataMapping mapping;
2184 		if (findChild(*layer_tangent_element, "Tangents"))
2185 		{
2186 			if (!parseVertexData(*layer_tangent_element, "Tangents", "TangentsIndex", &tmp, &tmp_indices, &mapping)) return Error("Invalid tangets");
2187 		}
2188 		else
2189 		{
2190 			if (!parseVertexData(*layer_tangent_element, "Tangent", "TangentIndex", &tmp, &tmp_indices, &mapping))  return Error("Invalid tangets");
2191 		}
2192 		if (!tmp.empty())
2193 		{
2194 			splat(&geom->tangents, mapping, tmp, tmp_indices, original_indices);
2195 			remap(&geom->tangents, to_old_indices);
2196 		}
2197 	}
2198 
2199 	const Element* layer_color_element = findChild(element, "LayerElementColor");
2200 	if (layer_color_element)
2201 	{
2202 		std::vector<Vec4> tmp;
2203 		std::vector<int> tmp_indices;
2204 		GeometryImpl::VertexDataMapping mapping;
2205 		if (!parseVertexData(*layer_color_element, "Colors", "ColorIndex", &tmp, &tmp_indices, &mapping)) return Error("Invalid colors");
2206 		if (!tmp.empty())
2207 		{
2208 			splat(&geom->colors, mapping, tmp, tmp_indices, original_indices);
2209 			remap(&geom->colors, to_old_indices);
2210 		}
2211 	}
2212 
2213 	const Element* layer_normal_element = findChild(element, "LayerElementNormal");
2214 	if (layer_normal_element)
2215 	{
2216 		std::vector<Vec3> tmp;
2217 		std::vector<int> tmp_indices;
2218 		GeometryImpl::VertexDataMapping mapping;
2219 		if (!parseVertexData(*layer_normal_element, "Normals", "NormalsIndex", &tmp, &tmp_indices, &mapping)) return Error("Invalid normals");
2220 		if (!tmp.empty())
2221 		{
2222 			splat(&geom->normals, mapping, tmp, tmp_indices, original_indices);
2223 			remap(&geom->normals, to_old_indices);
2224 		}
2225 	}
2226 
2227 	return geom.release();
2228 }
2229 
2230 
isString(const Property * prop)2231 static bool isString(const Property* prop)
2232 {
2233 	if (!prop) return false;
2234 	return prop->getType() == Property::STRING;
2235 }
2236 
2237 
isLong(const Property * prop)2238 static bool isLong(const Property* prop)
2239 {
2240 	if (!prop) return false;
2241 	return prop->getType() == Property::LONG;
2242 }
2243 
2244 
parseConnections(const Element & root,Scene * scene)2245 static bool parseConnections(const Element& root, Scene* scene)
2246 {
2247 	assert(scene);
2248 
2249 	const Element* connections = findChild(root, "Connections");
2250 	if (!connections) return true;
2251 
2252 	const Element* connection = connections->child;
2253 	while (connection)
2254 	{
2255 		if (!isString(connection->first_property)
2256 			|| !isLong(connection->first_property->next)
2257 			|| !isLong(connection->first_property->next->next))
2258 		{
2259 			Error::s_message = "Invalid connection";
2260 			return false;
2261 		}
2262 
2263 		Scene::Connection c;
2264 		c.from = connection->first_property->next->value.toU64();
2265 		c.to = connection->first_property->next->next->value.toU64();
2266 		if (connection->first_property->value == "OO")
2267 		{
2268 			c.type = Scene::Connection::OBJECT_OBJECT;
2269 		}
2270 		else if (connection->first_property->value == "OP")
2271 		{
2272 			c.type = Scene::Connection::OBJECT_PROPERTY;
2273 			if (!connection->first_property->next->next->next)
2274 			{
2275 				Error::s_message = "Invalid connection";
2276 				return false;
2277 			}
2278 			c.property = connection->first_property->next->next->next->value;
2279 		}
2280 		else
2281 		{
2282 			assert(false);
2283 			Error::s_message = "Not supported";
2284 			return false;
2285 		}
2286 		scene->m_connections.push_back(c);
2287 
2288 		connection = connection->sibling;
2289 	}
2290 	return true;
2291 }
2292 
2293 
parseTakes(Scene * scene)2294 static bool parseTakes(Scene* scene)
2295 {
2296 	const Element* takes = findChild((const Element&)*scene->getRootElement(), "Takes");
2297 	if (!takes) return true;
2298 
2299 	const Element* object = takes->child;
2300 	while (object)
2301 	{
2302 		if (object->id == "Take")
2303 		{
2304 			if (!isString(object->first_property))
2305 			{
2306 				Error::s_message = "Invalid name in take";
2307 				return false;
2308 			}
2309 
2310 			TakeInfo take;
2311 			take.name = object->first_property->value;
2312 			const Element* filename = findChild(*object, "FileName");
2313 			if (filename)
2314 			{
2315 				if (!isString(filename->first_property))
2316 				{
2317 					Error::s_message = "Invalid filename in take";
2318 					return false;
2319 				}
2320 				take.filename = filename->first_property->value;
2321 			}
2322 			const Element* local_time = findChild(*object, "LocalTime");
2323 			if (local_time)
2324 			{
2325 				if (!isLong(local_time->first_property) || !isLong(local_time->first_property->next))
2326 				{
2327 					Error::s_message = "Invalid local time in take";
2328 					return false;
2329 				}
2330 
2331 				take.local_time_from = fbxTimeToSeconds(local_time->first_property->value.toI64());
2332 				take.local_time_to = fbxTimeToSeconds(local_time->first_property->next->value.toI64());
2333 			}
2334 			const Element* reference_time = findChild(*object, "ReferenceTime");
2335 			if (reference_time)
2336 			{
2337 				if (!isLong(reference_time->first_property) || !isLong(reference_time->first_property->next))
2338 				{
2339 					Error::s_message = "Invalid reference time in take";
2340 					return false;
2341 				}
2342 
2343 				take.reference_time_from = fbxTimeToSeconds(reference_time->first_property->value.toI64());
2344 				take.reference_time_to = fbxTimeToSeconds(reference_time->first_property->next->value.toI64());
2345 			}
2346 
2347 			scene->m_take_infos.push_back(take);
2348 		}
2349 
2350 		object = object->sibling;
2351 	}
2352 
2353 	return true;
2354 }
2355 
2356 
getFramerateFromTimeMode(FrameRate time_mode,float custom_frame_rate)2357 static float getFramerateFromTimeMode(FrameRate time_mode, float custom_frame_rate)
2358 {
2359 	switch (time_mode)
2360 	{
2361 		case FrameRate_DEFAULT: return 1;
2362 		case FrameRate_120: return 120;
2363 		case FrameRate_100: return 100;
2364 		case FrameRate_60: return 60;
2365 		case FrameRate_50: return 50;
2366 		case FrameRate_48: return 48;
2367 		case FrameRate_30: return 30;
2368 		case FrameRate_30_DROP: return 30;
2369 		case FrameRate_NTSC_DROP_FRAME: return 29.9700262f;
2370 		case FrameRate_NTSC_FULL_FRAME: return 29.9700262f;
2371 		case FrameRate_PAL: return 25;
2372 		case FrameRate_CINEMA: return 24;
2373 		case FrameRate_1000: return 1000;
2374 		case FrameRate_CINEMA_ND: return 23.976f;
2375 		case FrameRate_CUSTOM: return custom_frame_rate;
2376 	}
2377 	return -1;
2378 }
2379 
2380 
parseGlobalSettings(const Element & root,Scene * scene)2381 static void parseGlobalSettings(const Element& root, Scene* scene)
2382 {
2383 	for (ofbx::Element* settings = root.child; settings; settings = settings->sibling)
2384 	{
2385 		if (settings->id == "GlobalSettings")
2386 		{
2387 			for (ofbx::Element* props70 = settings->child; props70; props70 = props70->sibling)
2388 			{
2389 				if (props70->id == "Properties70")
2390 				{
2391 					for (ofbx::Element* node = props70->child; node; node = node->sibling)
2392 					{
2393 						if (!node->first_property)
2394 							continue;
2395 
2396 #define get_property(name, field, type) if(node->first_property->value == name) \
2397 						{ \
2398 							ofbx::IElementProperty* prop = node->getProperty(4); \
2399 							if (prop) \
2400 							{ \
2401 								ofbx::DataView value = prop->getValue(); \
2402 								scene->m_settings.field = *(type*)value.begin; \
2403 							} \
2404 						}
2405 
2406 						get_property("UpAxis", UpAxis, UpVector);
2407 						get_property("UpAxisSign", UpAxisSign, int);
2408 						get_property("FrontAxis", FrontAxis, FrontVector);
2409 						get_property("FrontAxisSign", FrontAxisSign, int);
2410 						get_property("CoordAxis", CoordAxis, CoordSystem);
2411 						get_property("CoordAxisSign", CoordAxisSign, int);
2412 						get_property("OriginalUpAxis", OriginalUpAxis, int);
2413 						get_property("OriginalUpAxisSign", OriginalUpAxisSign, int);
2414 						get_property("UnitScaleFactor", UnitScaleFactor, float);
2415 						get_property("OriginalUnitScaleFactor", OriginalUnitScaleFactor, float);
2416 						get_property("TimeSpanStart", TimeSpanStart, u64);
2417 						get_property("TimeSpanStop", TimeSpanStop, u64);
2418 						get_property("TimeMode", TimeMode, FrameRate);
2419 						get_property("CustomFrameRate", CustomFrameRate, float);
2420 
2421 #undef get_property
2422 
2423 						scene->m_scene_frame_rate = getFramerateFromTimeMode(scene->m_settings.TimeMode, scene->m_settings.CustomFrameRate);
2424 					}
2425 					break;
2426 				}
2427 			}
2428 			break;
2429 		}
2430 	}
2431 }
2432 
2433 
parseObjects(const Element & root,Scene * scene)2434 static bool parseObjects(const Element& root, Scene* scene)
2435 {
2436 	const Element* objs = findChild(root, "Objects");
2437 	if (!objs) return true;
2438 
2439 	scene->m_root = new Root(*scene, root);
2440 	scene->m_root->id = 0;
2441 	scene->m_object_map[0] = {&root, scene->m_root};
2442 
2443 	const Element* object = objs->child;
2444 	while (object)
2445 	{
2446 		if (!isLong(object->first_property))
2447 		{
2448 			Error::s_message = "Invalid";
2449 			return false;
2450 		}
2451 
2452 		u64 id = object->first_property->value.toU64();
2453 		scene->m_object_map[id] = {object, nullptr};
2454 		object = object->sibling;
2455 	}
2456 
2457 	for (auto iter : scene->m_object_map)
2458 	{
2459 		OptionalError<Object*> obj = nullptr;
2460 
2461 		if (iter.second.object == scene->m_root) continue;
2462 
2463 		if (iter.second.element->id == "Geometry")
2464 		{
2465 			Property* last_prop = iter.second.element->first_property;
2466 			while (last_prop->next) last_prop = last_prop->next;
2467 			if (last_prop && last_prop->value == "Mesh")
2468 			{
2469 				obj = parseGeometry(*scene, *iter.second.element);
2470 			}
2471 		}
2472 		else if (iter.second.element->id == "Material")
2473 		{
2474 			obj = parseMaterial(*scene, *iter.second.element);
2475 		}
2476 		else if (iter.second.element->id == "AnimationStack")
2477 		{
2478 			obj = parse<AnimationStackImpl>(*scene, *iter.second.element);
2479 			if (!obj.isError())
2480 			{
2481 				AnimationStackImpl* stack = (AnimationStackImpl*)obj.getValue();
2482 				scene->m_animation_stacks.push_back(stack);
2483 			}
2484 		}
2485 		else if (iter.second.element->id == "AnimationLayer")
2486 		{
2487 			obj = parse<AnimationLayerImpl>(*scene, *iter.second.element);
2488 		}
2489 		else if (iter.second.element->id == "AnimationCurve")
2490 		{
2491 			obj = parseAnimationCurve(*scene, *iter.second.element);
2492 		}
2493 		else if (iter.second.element->id == "AnimationCurveNode")
2494 		{
2495 			obj = parse<AnimationCurveNodeImpl>(*scene, *iter.second.element);
2496 		}
2497 		else if (iter.second.element->id == "Deformer")
2498 		{
2499 			IElementProperty* class_prop = iter.second.element->getProperty(2);
2500 
2501 			if (class_prop)
2502 			{
2503 				if (class_prop->getValue() == "Cluster")
2504 					obj = parseCluster(*scene, *iter.second.element);
2505 				else if (class_prop->getValue() == "Skin")
2506 					obj = parse<SkinImpl>(*scene, *iter.second.element);
2507 			}
2508 		}
2509 		else if (iter.second.element->id == "NodeAttribute")
2510 		{
2511 			obj = parseNodeAttribute(*scene, *iter.second.element);
2512 		}
2513 		else if (iter.second.element->id == "Model")
2514 		{
2515 			IElementProperty* class_prop = iter.second.element->getProperty(2);
2516 
2517 			if (class_prop)
2518 			{
2519 				if (class_prop->getValue() == "Mesh")
2520 				{
2521 					obj = parseMesh(*scene, *iter.second.element);
2522 					if (!obj.isError())
2523 					{
2524 						Mesh* mesh = (Mesh*)obj.getValue();
2525 						scene->m_meshes.push_back(mesh);
2526 						obj = mesh;
2527 					}
2528 				}
2529 				else if (class_prop->getValue() == "LimbNode")
2530 					obj = parseLimbNode(*scene, *iter.second.element);
2531 				else if (class_prop->getValue() == "Null")
2532 					obj = parse<NullImpl>(*scene, *iter.second.element);
2533 				else if (class_prop->getValue() == "Root")
2534 					obj = parse<NullImpl>(*scene, *iter.second.element);
2535 			}
2536 		}
2537 		else if (iter.second.element->id == "Texture")
2538 		{
2539 			obj = parseTexture(*scene, *iter.second.element);
2540 		}
2541 
2542 		if (obj.isError()) return false;
2543 
2544 		scene->m_object_map[iter.first].object = obj.getValue();
2545 		if (obj.getValue())
2546 		{
2547 			scene->m_all_objects.push_back(obj.getValue());
2548 			obj.getValue()->id = iter.first;
2549 		}
2550 	}
2551 
2552 	for (const Scene::Connection& con : scene->m_connections)
2553 	{
2554 		Object* parent = scene->m_object_map[con.to].object;
2555 		Object* child = scene->m_object_map[con.from].object;
2556 		if (!child) continue;
2557 		if (!parent) continue;
2558 
2559 		switch (child->getType())
2560 		{
2561 			case Object::Type::NODE_ATTRIBUTE:
2562 				if (parent->node_attribute)
2563 				{
2564 					Error::s_message = "Invalid node attribute";
2565 					return false;
2566 				}
2567 				parent->node_attribute = (NodeAttribute*)child;
2568 				break;
2569 			case Object::Type::ANIMATION_CURVE_NODE:
2570 				if (parent->isNode())
2571 				{
2572 					AnimationCurveNodeImpl* node = (AnimationCurveNodeImpl*)child;
2573 					node->bone = parent;
2574 					node->bone_link_property = con.property;
2575 				}
2576 				break;
2577 		}
2578 
2579 		switch (parent->getType())
2580 		{
2581 			case Object::Type::MESH:
2582 			{
2583 				MeshImpl* mesh = (MeshImpl*)parent;
2584 				switch (child->getType())
2585 				{
2586 					case Object::Type::GEOMETRY:
2587 						if (mesh->geometry)
2588 						{
2589 							Error::s_message = "Invalid mesh";
2590 							return false;
2591 						}
2592 						mesh->geometry = (Geometry*)child;
2593 						break;
2594 					case Object::Type::MATERIAL: mesh->materials.push_back((Material*)child); break;
2595 				}
2596 				break;
2597 			}
2598 			case Object::Type::SKIN:
2599 			{
2600 				SkinImpl* skin = (SkinImpl*)parent;
2601 				if (child->getType() == Object::Type::CLUSTER)
2602 				{
2603 					ClusterImpl* cluster = (ClusterImpl*)child;
2604 					skin->clusters.push_back(cluster);
2605 					if (cluster->skin)
2606 					{
2607 						Error::s_message = "Invalid cluster";
2608 						return false;
2609 					}
2610 					cluster->skin = skin;
2611 				}
2612 				break;
2613 			}
2614 			case Object::Type::MATERIAL:
2615 			{
2616 				MaterialImpl* mat = (MaterialImpl*)parent;
2617 				if (child->getType() == Object::Type::TEXTURE)
2618 				{
2619 					Texture::TextureType type = Texture::COUNT;
2620 					if (con.property == "NormalMap")
2621 						type = Texture::NORMAL;
2622 					else if (con.property == "DiffuseColor")
2623 						type = Texture::DIFFUSE;
2624 					if (type == Texture::COUNT) break;
2625 
2626 					if (mat->textures[type])
2627 					{
2628 						break;// This may happen for some models (eg. 2 normal maps in use)
2629 						Error::s_message = "Invalid material";
2630 						return false;
2631 					}
2632 
2633 					mat->textures[type] = (Texture*)child;
2634 				}
2635 				break;
2636 			}
2637 			case Object::Type::GEOMETRY:
2638 			{
2639 				GeometryImpl* geom = (GeometryImpl*)parent;
2640 				if (child->getType() == Object::Type::SKIN) geom->skin = (Skin*)child;
2641 				break;
2642 			}
2643 			case Object::Type::CLUSTER:
2644 			{
2645 				ClusterImpl* cluster = (ClusterImpl*)parent;
2646 				if (child->getType() == Object::Type::LIMB_NODE || child->getType() == Object::Type::MESH || child->getType() == Object::Type::NULL_NODE)
2647 				{
2648 					if (cluster->link)
2649 					{
2650 						Error::s_message = "Invalid cluster";
2651 						return false;
2652 					}
2653 
2654 					cluster->link = child;
2655 				}
2656 				break;
2657 			}
2658 			case Object::Type::ANIMATION_LAYER:
2659 			{
2660 				if (child->getType() == Object::Type::ANIMATION_CURVE_NODE)
2661 				{
2662 					((AnimationLayerImpl*)parent)->curve_nodes.push_back((AnimationCurveNodeImpl*)child);
2663 				}
2664 			}
2665 			break;
2666 			case Object::Type::ANIMATION_CURVE_NODE:
2667 			{
2668 				AnimationCurveNodeImpl* node = (AnimationCurveNodeImpl*)parent;
2669 				if (child->getType() == Object::Type::ANIMATION_CURVE)
2670 				{
2671 					if (!node->curves[0].curve)
2672 					{
2673 						node->curves[0].connection = &con;
2674 						node->curves[0].curve = (AnimationCurve*)child;
2675 					}
2676 					else if (!node->curves[1].curve)
2677 					{
2678 						node->curves[1].connection = &con;
2679 						node->curves[1].curve = (AnimationCurve*)child;
2680 					}
2681 					else if (!node->curves[2].curve)
2682 					{
2683 						node->curves[2].connection = &con;
2684 						node->curves[2].curve = (AnimationCurve*)child;
2685 					}
2686 					else
2687 					{
2688 						Error::s_message = "Invalid animation node";
2689 						return false;
2690 					}
2691 				}
2692 				break;
2693 			}
2694 		}
2695 	}
2696 
2697 	for (auto iter : scene->m_object_map)
2698 	{
2699 		Object* obj = iter.second.object;
2700 		if (!obj) continue;
2701 		if(obj->getType() == Object::Type::CLUSTER)
2702 		{
2703 			if (!((ClusterImpl*)iter.second.object)->postprocess())
2704 			{
2705 				Error::s_message = "Failed to postprocess cluster";
2706 				return false;
2707 			}
2708 		}
2709 	}
2710 
2711 	return true;
2712 }
2713 
2714 
getRotationOrder() const2715 RotationOrder Object::getRotationOrder() const
2716 {
2717 	// This assumes that the default rotation order is EULER_XYZ.
2718 	return (RotationOrder) resolveEnumProperty(*this, "RotationOrder", (int) RotationOrder::EULER_XYZ);
2719 }
2720 
2721 
getRotationOffset() const2722 Vec3 Object::getRotationOffset() const
2723 {
2724 	return resolveVec3Property(*this, "RotationOffset", {0, 0, 0});
2725 }
2726 
2727 
getRotationPivot() const2728 Vec3 Object::getRotationPivot() const
2729 {
2730 	return resolveVec3Property(*this, "RotationPivot", {0, 0, 0});
2731 }
2732 
2733 
getPostRotation() const2734 Vec3 Object::getPostRotation() const
2735 {
2736 	return resolveVec3Property(*this, "PostRotation", {0, 0, 0});
2737 }
2738 
2739 
getScalingOffset() const2740 Vec3 Object::getScalingOffset() const
2741 {
2742 	return resolveVec3Property(*this, "ScalingOffset", {0, 0, 0});
2743 }
2744 
2745 
getScalingPivot() const2746 Vec3 Object::getScalingPivot() const
2747 {
2748 	return resolveVec3Property(*this, "ScalingPivot", {0, 0, 0});
2749 }
2750 
2751 
evalLocal(const Vec3 & translation,const Vec3 & rotation) const2752 Matrix Object::evalLocal(const Vec3& translation, const Vec3& rotation) const
2753 {
2754 	return evalLocal(translation, rotation, getLocalScaling());
2755 }
2756 
2757 
evalLocal(const Vec3 & translation,const Vec3 & rotation,const Vec3 & scaling) const2758 Matrix Object::evalLocal(const Vec3& translation, const Vec3& rotation, const Vec3& scaling) const
2759 {
2760 	Vec3 rotation_pivot = getRotationPivot();
2761 	Vec3 scaling_pivot = getScalingPivot();
2762 	RotationOrder rotation_order = getRotationOrder();
2763 
2764 	Matrix s = makeIdentity();
2765 	s.m[0] = scaling.x;
2766 	s.m[5] = scaling.y;
2767 	s.m[10] = scaling.z;
2768 
2769 	Matrix t = makeIdentity();
2770 	setTranslation(translation, &t);
2771 
2772 	Matrix r = getRotationMatrix(rotation, rotation_order);
2773 	Matrix r_pre = getRotationMatrix(getPreRotation(), RotationOrder::EULER_XYZ);
2774 	Matrix r_post_inv = getRotationMatrix(-getPostRotation(), RotationOrder::EULER_ZYX);
2775 
2776 	Matrix r_off = makeIdentity();
2777 	setTranslation(getRotationOffset(), &r_off);
2778 
2779 	Matrix r_p = makeIdentity();
2780 	setTranslation(rotation_pivot, &r_p);
2781 
2782 	Matrix r_p_inv = makeIdentity();
2783 	setTranslation(-rotation_pivot, &r_p_inv);
2784 
2785 	Matrix s_off = makeIdentity();
2786 	setTranslation(getScalingOffset(), &s_off);
2787 
2788 	Matrix s_p = makeIdentity();
2789 	setTranslation(scaling_pivot, &s_p);
2790 
2791 	Matrix s_p_inv = makeIdentity();
2792 	setTranslation(-scaling_pivot, &s_p_inv);
2793 
2794 	// http://help.autodesk.com/view/FBX/2017/ENU/?guid=__files_GUID_10CDD63C_79C1_4F2D_BB28_AD2BE65A02ED_htm
2795 	return t * r_off * r_p * r_pre * r * r_post_inv * r_p_inv * s_off * s_p * s * s_p_inv;
2796 }
2797 
2798 
getLocalTranslation() const2799 Vec3 Object::getLocalTranslation() const
2800 {
2801 	return resolveVec3Property(*this, "Lcl Translation", {0, 0, 0});
2802 }
2803 
2804 
getPreRotation() const2805 Vec3 Object::getPreRotation() const
2806 {
2807 	return resolveVec3Property(*this, "PreRotation", {0, 0, 0});
2808 }
2809 
2810 
getLocalRotation() const2811 Vec3 Object::getLocalRotation() const
2812 {
2813 	return resolveVec3Property(*this, "Lcl Rotation", {0, 0, 0});
2814 }
2815 
2816 
getLocalScaling() const2817 Vec3 Object::getLocalScaling() const
2818 {
2819 	return resolveVec3Property(*this, "Lcl Scaling", {1, 1, 1});
2820 }
2821 
2822 
getGlobalTransform() const2823 Matrix Object::getGlobalTransform() const
2824 {
2825 	const Object* parent = getParent();
2826 	if (!parent) return evalLocal(getLocalTranslation(), getLocalRotation());
2827 
2828 	return parent->getGlobalTransform() * evalLocal(getLocalTranslation(), getLocalRotation());
2829 }
2830 
2831 
getLocalTransform() const2832 Matrix Object::getLocalTransform() const
2833 {
2834     return evalLocal(getLocalTranslation(), getLocalRotation(), getLocalScaling());
2835 }
2836 
2837 
resolveObjectLinkReverse(Object::Type type) const2838 Object* Object::resolveObjectLinkReverse(Object::Type type) const
2839 {
2840 	u64 id = element.getFirstProperty() ? element.getFirstProperty()->getValue().toU64() : 0;
2841 	for (auto& connection : scene.m_connections)
2842 	{
2843 		if (connection.from == id && connection.to != 0)
2844 		{
2845 			Object* obj = scene.m_object_map.find(connection.to)->second.object;
2846 			if (obj && obj->getType() == type) return obj;
2847 		}
2848 	}
2849 	return nullptr;
2850 }
2851 
2852 
getScene() const2853 const IScene& Object::getScene() const
2854 {
2855 	return scene;
2856 }
2857 
2858 
resolveObjectLink(int idx) const2859 Object* Object::resolveObjectLink(int idx) const
2860 {
2861 	u64 id = element.getFirstProperty() ? element.getFirstProperty()->getValue().toU64() : 0;
2862 	for (auto& connection : scene.m_connections)
2863 	{
2864 		if (connection.to == id && connection.from != 0)
2865 		{
2866 			Object* obj = scene.m_object_map.find(connection.from)->second.object;
2867 			if (obj)
2868 			{
2869 				if (idx == 0) return obj;
2870 				--idx;
2871 			}
2872 		}
2873 	}
2874 	return nullptr;
2875 }
2876 
2877 
resolveObjectLink(Object::Type type,const char * property,int idx) const2878 Object* Object::resolveObjectLink(Object::Type type, const char* property, int idx) const
2879 {
2880 	u64 id = element.getFirstProperty() ? element.getFirstProperty()->getValue().toU64() : 0;
2881 	for (auto& connection : scene.m_connections)
2882 	{
2883 		if (connection.to == id && connection.from != 0)
2884 		{
2885 			Object* obj = scene.m_object_map.find(connection.from)->second.object;
2886 			if (obj && obj->getType() == type)
2887 			{
2888 				if (property == nullptr || connection.property == property)
2889 				{
2890 					if (idx == 0) return obj;
2891 					--idx;
2892 				}
2893 			}
2894 		}
2895 	}
2896 	return nullptr;
2897 }
2898 
2899 
getParent() const2900 Object* Object::getParent() const
2901 {
2902 	Object* parent = nullptr;
2903 	for (auto& connection : scene.m_connections)
2904 	{
2905 		if (connection.from == id)
2906 		{
2907 			Object* obj = scene.m_object_map.find(connection.to)->second.object;
2908 			if (obj && obj->is_node)
2909 			{
2910 				assert(parent == nullptr);
2911 				parent = obj;
2912 			}
2913 		}
2914 	}
2915 	return parent;
2916 }
2917 
2918 
load(const u8 * data,int size)2919 IScene* load(const u8* data, int size)
2920 {
2921 	std::unique_ptr<Scene> scene(new Scene());
2922 	scene->m_data.resize(size);
2923 	memcpy(&scene->m_data[0], data, size);
2924 	OptionalError<Element*> root = tokenize(&scene->m_data[0], size);
2925 	if (root.isError())
2926 	{
2927 		Error::s_message = "";
2928 		root = tokenizeText(&scene->m_data[0], size);
2929 		if (root.isError()) return nullptr;
2930 	}
2931 
2932 	scene->m_root_element = root.getValue();
2933 	assert(scene->m_root_element);
2934 
2935 	//if (parseTemplates(*root.getValue()).isError()) return nullptr;
2936 	if(!parseConnections(*root.getValue(), scene.get())) return nullptr;
2937 	if(!parseTakes(scene.get())) return nullptr;
2938 	if(!parseObjects(*root.getValue(), scene.get())) return nullptr;
2939 	parseGlobalSettings(*root.getValue(), scene.get());
2940 
2941 	return scene.release();
2942 }
2943 
2944 
getError()2945 const char* getError()
2946 {
2947 	return Error::s_message;
2948 }
2949 
2950 
2951 } // namespace ofbx
2952