Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
godotengine
GitHub Repository: godotengine/godot
Path: blob/master/editor/import/3d/collada.h
9906 views
1
/**************************************************************************/
2
/* collada.h */
3
/**************************************************************************/
4
/* This file is part of: */
5
/* GODOT ENGINE */
6
/* https://godotengine.org */
7
/**************************************************************************/
8
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10
/* */
11
/* Permission is hereby granted, free of charge, to any person obtaining */
12
/* a copy of this software and associated documentation files (the */
13
/* "Software"), to deal in the Software without restriction, including */
14
/* without limitation the rights to use, copy, modify, merge, publish, */
15
/* distribute, sublicense, and/or sell copies of the Software, and to */
16
/* permit persons to whom the Software is furnished to do so, subject to */
17
/* the following conditions: */
18
/* */
19
/* The above copyright notice and this permission notice shall be */
20
/* included in all copies or substantial portions of the Software. */
21
/* */
22
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29
/**************************************************************************/
30
31
#pragma once
32
33
#include "core/io/xml_parser.h"
34
35
class Collada {
36
public:
37
enum ImportFlags {
38
IMPORT_FLAG_SCENE = 1,
39
IMPORT_FLAG_ANIMATION = 2
40
};
41
42
struct Image {
43
String path;
44
};
45
46
struct Material {
47
String name;
48
String instance_effect;
49
};
50
51
struct Effect {
52
String name;
53
HashMap<String, Variant> params;
54
55
struct Channel {
56
int uv_idx = 0;
57
String texture;
58
Color color;
59
};
60
61
Channel diffuse, specular, emission, bump;
62
float shininess = 40;
63
bool found_double_sided = false;
64
bool double_sided = true;
65
bool unshaded = false;
66
67
String get_texture_path(const String &p_source, Collada &p_state) const;
68
69
Effect() {
70
diffuse.color = Color(1, 1, 1, 1);
71
}
72
};
73
74
struct CameraData {
75
enum Mode {
76
MODE_PERSPECTIVE,
77
MODE_ORTHOGONAL
78
};
79
80
Mode mode = MODE_PERSPECTIVE;
81
82
union {
83
struct {
84
float x_fov = 0;
85
float y_fov = 0;
86
} perspective;
87
struct {
88
float x_mag = 0;
89
float y_mag = 0;
90
} orthogonal;
91
};
92
93
float aspect = 1;
94
float z_near = 0.05;
95
float z_far = 4000;
96
97
CameraData() {}
98
};
99
100
struct LightData {
101
enum Mode {
102
MODE_AMBIENT,
103
MODE_DIRECTIONAL,
104
MODE_OMNI,
105
MODE_SPOT
106
};
107
108
Mode mode = MODE_AMBIENT;
109
110
Color color = Color(1, 1, 1, 1);
111
112
float constant_att = 0;
113
float linear_att = 0;
114
float quad_att = 0;
115
116
float spot_angle = 45;
117
float spot_exp = 1;
118
};
119
120
struct MeshData {
121
String name;
122
struct Source {
123
Vector<float> array;
124
int stride = 0;
125
};
126
127
HashMap<String, Source> sources;
128
129
struct Vertices {
130
HashMap<String, String> sources;
131
};
132
133
HashMap<String, Vertices> vertices;
134
135
struct Primitives {
136
struct SourceRef {
137
String source;
138
int offset = 0;
139
};
140
141
String material;
142
HashMap<String, SourceRef> sources;
143
Vector<float> polygons;
144
Vector<float> indices;
145
int count = 0;
146
int vertex_size = 0;
147
};
148
149
Vector<Primitives> primitives;
150
151
bool found_double_sided = false;
152
bool double_sided = true;
153
};
154
155
struct CurveData {
156
String name;
157
bool closed = false;
158
159
struct Source {
160
Vector<String> sarray;
161
Vector<float> array;
162
int stride = 0;
163
};
164
165
HashMap<String, Source> sources;
166
167
HashMap<String, String> control_vertices;
168
};
169
170
struct SkinControllerData {
171
String base;
172
bool use_idrefs = false;
173
174
Transform3D bind_shape;
175
176
struct Source {
177
Vector<String> sarray; //maybe for names
178
Vector<float> array;
179
int stride = 1;
180
};
181
182
HashMap<String, Source> sources;
183
184
struct Joints {
185
HashMap<String, String> sources;
186
} joints;
187
188
struct Weights {
189
struct SourceRef {
190
String source;
191
int offset = 0;
192
};
193
194
String material;
195
HashMap<String, SourceRef> sources;
196
Vector<float> sets;
197
Vector<float> indices;
198
int count = 0;
199
} weights;
200
201
HashMap<String, Transform3D> bone_rest_map;
202
};
203
204
struct MorphControllerData {
205
String mesh;
206
String mode;
207
208
struct Source {
209
int stride = 1;
210
Vector<String> sarray; //maybe for names
211
Vector<float> array;
212
};
213
214
HashMap<String, Source> sources;
215
216
HashMap<String, String> targets;
217
};
218
219
struct Vertex {
220
int idx = 0;
221
Vector3 vertex;
222
Vector3 normal;
223
Vector3 uv;
224
Vector3 uv2;
225
Plane tangent;
226
Color color;
227
int uid = 0;
228
struct Weight {
229
int bone_idx = 0;
230
float weight = 0;
231
bool operator<(const Weight w) const { return weight > w.weight; } //heaviest first
232
};
233
234
Vector<Weight> weights;
235
236
void fix_weights() {
237
weights.sort();
238
if (weights.size() > 4) {
239
//cap to 4 and make weights add up 1
240
weights.resize(4);
241
float total = 0;
242
for (int i = 0; i < 4; i++) {
243
total += weights[i].weight;
244
}
245
if (total) {
246
for (int i = 0; i < 4; i++) {
247
weights.write[i].weight /= total;
248
}
249
}
250
}
251
}
252
253
void fix_unit_scale(const Collada &p_state);
254
255
bool operator<(const Vertex &p_vert) const {
256
if (uid == p_vert.uid) {
257
if (vertex == p_vert.vertex) {
258
if (normal == p_vert.normal) {
259
if (uv == p_vert.uv) {
260
if (uv2 == p_vert.uv2) {
261
if (!weights.is_empty() || !p_vert.weights.is_empty()) {
262
if (weights.size() == p_vert.weights.size()) {
263
for (int i = 0; i < weights.size(); i++) {
264
if (weights[i].bone_idx != p_vert.weights[i].bone_idx) {
265
return weights[i].bone_idx < p_vert.weights[i].bone_idx;
266
}
267
268
if (weights[i].weight != p_vert.weights[i].weight) {
269
return weights[i].weight < p_vert.weights[i].weight;
270
}
271
}
272
} else {
273
return weights.size() < p_vert.weights.size();
274
}
275
}
276
277
return (color < p_vert.color);
278
} else {
279
return (uv2 < p_vert.uv2);
280
}
281
} else {
282
return (uv < p_vert.uv);
283
}
284
} else {
285
return (normal < p_vert.normal);
286
}
287
} else {
288
return vertex < p_vert.vertex;
289
}
290
} else {
291
return uid < p_vert.uid;
292
}
293
}
294
};
295
296
struct Node {
297
enum Type {
298
TYPE_NODE,
299
TYPE_JOINT,
300
TYPE_SKELETON, //this bone is not collada, it's added afterwards as optimization
301
TYPE_LIGHT,
302
TYPE_CAMERA,
303
TYPE_GEOMETRY
304
};
305
306
struct XForm {
307
enum Op {
308
OP_ROTATE,
309
OP_SCALE,
310
OP_TRANSLATE,
311
OP_MATRIX,
312
OP_VISIBILITY
313
};
314
315
String id;
316
Op op = OP_ROTATE;
317
Vector<float> data;
318
};
319
320
Type type = TYPE_NODE;
321
322
String name;
323
String id;
324
String empty_draw_type;
325
bool noname = false;
326
Vector<XForm> xform_list;
327
Transform3D default_transform;
328
Transform3D post_transform;
329
Vector<Node *> children;
330
331
Node *parent = nullptr;
332
333
Transform3D compute_transform(const Collada &p_state) const;
334
Transform3D get_global_transform() const;
335
Transform3D get_transform() const;
336
337
bool ignore_anim = false;
338
339
virtual ~Node() {
340
for (int i = 0; i < children.size(); i++) {
341
memdelete(children[i]);
342
}
343
}
344
};
345
346
struct NodeSkeleton : public Node {
347
NodeSkeleton() { type = TYPE_SKELETON; }
348
};
349
350
struct NodeJoint : public Node {
351
NodeSkeleton *owner = nullptr;
352
String sid;
353
NodeJoint() {
354
type = TYPE_JOINT;
355
}
356
};
357
358
struct NodeGeometry : public Node {
359
bool controller = false;
360
String source;
361
362
struct Material {
363
String target;
364
};
365
366
HashMap<String, Material> material_map;
367
Vector<String> skeletons;
368
369
NodeGeometry() { type = TYPE_GEOMETRY; }
370
};
371
372
struct NodeCamera : public Node {
373
String camera;
374
375
NodeCamera() { type = TYPE_CAMERA; }
376
};
377
378
struct NodeLight : public Node {
379
String light;
380
381
NodeLight() { type = TYPE_LIGHT; }
382
};
383
384
struct VisualScene {
385
String name;
386
Vector<Node *> root_nodes;
387
388
~VisualScene() {
389
for (int i = 0; i < root_nodes.size(); i++) {
390
memdelete(root_nodes[i]);
391
}
392
}
393
};
394
395
struct AnimationClip {
396
String name;
397
float begin = 0;
398
float end = 1;
399
Vector<String> tracks;
400
};
401
402
struct AnimationTrack {
403
String id;
404
String target;
405
String param;
406
String component;
407
bool property = false;
408
409
enum InterpolationType {
410
INTERP_LINEAR,
411
INTERP_BEZIER
412
};
413
414
struct Key {
415
enum Type {
416
TYPE_FLOAT,
417
TYPE_MATRIX
418
};
419
420
float time = 0;
421
Vector<float> data;
422
Point2 in_tangent;
423
Point2 out_tangent;
424
InterpolationType interp_type = INTERP_LINEAR;
425
};
426
427
Vector<float> get_value_at_time(float p_time) const;
428
429
Vector<Key> keys;
430
};
431
432
/****************/
433
/* IMPORT STATE */
434
/****************/
435
436
struct State {
437
int import_flags = 0;
438
439
float unit_scale = 1.0;
440
Vector3::Axis up_axis = Vector3::AXIS_Y;
441
bool z_up = false;
442
443
struct Version {
444
int major = 0, minor = 0, rev = 0;
445
446
bool operator<(const Version &p_ver) const { return (major == p_ver.major) ? ((minor == p_ver.minor) ? (rev < p_ver.rev) : minor < p_ver.minor) : major < p_ver.major; }
447
Version(int p_major = 0, int p_minor = 0, int p_rev = 0) {
448
major = p_major;
449
minor = p_minor;
450
rev = p_rev;
451
}
452
} version;
453
454
HashMap<String, CameraData> camera_data_map;
455
HashMap<String, MeshData> mesh_data_map;
456
HashMap<String, LightData> light_data_map;
457
HashMap<String, CurveData> curve_data_map;
458
459
HashMap<String, String> mesh_name_map;
460
HashMap<String, String> morph_name_map;
461
HashMap<String, String> morph_ownership_map;
462
HashMap<String, SkinControllerData> skin_controller_data_map;
463
HashMap<String, MorphControllerData> morph_controller_data_map;
464
465
HashMap<String, Image> image_map;
466
HashMap<String, Material> material_map;
467
HashMap<String, Effect> effect_map;
468
469
HashMap<String, VisualScene> visual_scene_map;
470
HashMap<String, Node *> scene_map;
471
HashSet<String> idref_joints;
472
HashMap<String, String> sid_to_node_map;
473
//RBMap<String,NodeJoint*> bone_map;
474
475
HashMap<String, Transform3D> bone_rest_map;
476
477
String local_path;
478
String root_visual_scene;
479
String root_physics_scene;
480
481
Vector<AnimationClip> animation_clips;
482
Vector<AnimationTrack> animation_tracks;
483
HashMap<String, Vector<int>> referenced_tracks;
484
HashMap<String, Vector<int>> by_id_tracks;
485
486
float animation_length = 0;
487
} state;
488
489
Error load(const String &p_path, int p_flags = 0);
490
491
Transform3D fix_transform(const Transform3D &p_transform);
492
493
Transform3D get_root_transform() const;
494
495
int get_uv_channel(const String &p_name);
496
497
private: // private stuff
498
HashMap<String, int> channel_map;
499
500
void _parse_asset(XMLParser &p_parser);
501
void _parse_image(XMLParser &p_parser);
502
void _parse_material(XMLParser &p_parser);
503
void _parse_effect_material(XMLParser &p_parser, Effect &p_effect, String &p_id);
504
void _parse_effect(XMLParser &p_parser);
505
void _parse_camera(XMLParser &p_parser);
506
void _parse_light(XMLParser &p_parser);
507
void _parse_animation_clip(XMLParser &p_parser);
508
509
void _parse_mesh_geometry(XMLParser &p_parser, const String &p_id, const String &p_name);
510
void _parse_curve_geometry(XMLParser &p_parser, const String &p_id, const String &p_name);
511
512
void _parse_skin_controller(XMLParser &p_parser, const String &p_id);
513
void _parse_morph_controller(XMLParser &p_parser, const String &p_id);
514
void _parse_controller(XMLParser &p_parser);
515
516
Node *_parse_visual_instance_geometry(XMLParser &p_parser);
517
Node *_parse_visual_instance_camera(XMLParser &p_parser);
518
Node *_parse_visual_instance_light(XMLParser &p_parser);
519
520
Node *_parse_visual_node_instance_data(XMLParser &p_parser);
521
Node *_parse_visual_scene_node(XMLParser &p_parser);
522
void _parse_visual_scene(XMLParser &p_parser);
523
524
void _parse_animation(XMLParser &p_parser);
525
void _parse_scene(XMLParser &p_parser);
526
void _parse_library(XMLParser &p_parser);
527
528
Variant _parse_param(XMLParser &p_parser);
529
Vector<float> _read_float_array(XMLParser &p_parser);
530
Vector<String> _read_string_array(XMLParser &p_parser);
531
Transform3D _read_transform(XMLParser &p_parser);
532
String _read_empty_draw_type(XMLParser &p_parser);
533
534
void _joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner);
535
void _create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton = nullptr);
536
void _find_morph_nodes(VisualScene *p_vscene, Node *p_node);
537
bool _remove_node(Node *p_parent, Node *p_node);
538
void _remove_node(VisualScene *p_vscene, Node *p_node);
539
void _merge_skeletons2(VisualScene *p_vscene);
540
void _merge_skeletons(VisualScene *p_vscene, Node *p_node);
541
bool _optimize_skeletons(VisualScene *p_vscene, Node *p_node);
542
543
bool _move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, List<Node *> *p_mgeom);
544
545
void _optimize();
546
};
547
548