summaryrefslogtreecommitdiff
path: root/editor/import
diff options
context:
space:
mode:
Diffstat (limited to 'editor/import')
-rw-r--r--editor/import/SCsub2
-rw-r--r--editor/import/collada.cpp2582
-rw-r--r--editor/import/collada.h647
-rw-r--r--editor/import/editor_import_collada.cpp116
-rw-r--r--editor/import/editor_import_collada.h2
-rw-r--r--editor/import/editor_import_plugin.h2
-rw-r--r--editor/import/editor_scene_importer_gltf.cpp94
-rw-r--r--editor/import/editor_scene_importer_gltf.h26
-rw-r--r--editor/import/resource_importer_bitmask.h2
-rw-r--r--editor/import/resource_importer_csv.h2
-rw-r--r--editor/import/resource_importer_csv_translation.h2
-rw-r--r--editor/import/resource_importer_image.h2
-rw-r--r--editor/import/resource_importer_layered_texture.cpp6
-rw-r--r--editor/import/resource_importer_layered_texture.h2
-rw-r--r--editor/import/resource_importer_obj.cpp12
-rw-r--r--editor/import/resource_importer_obj.h4
-rw-r--r--editor/import/resource_importer_scene.cpp156
-rw-r--r--editor/import/resource_importer_scene.h10
-rw-r--r--editor/import/resource_importer_texture.cpp10
-rw-r--r--editor/import/resource_importer_texture.h10
-rw-r--r--editor/import/resource_importer_texture_atlas.h2
-rw-r--r--editor/import/resource_importer_wav.h2
22 files changed, 3461 insertions, 232 deletions
diff --git a/editor/import/SCsub b/editor/import/SCsub
index 2b1e889fb0..359d04e5df 100644
--- a/editor/import/SCsub
+++ b/editor/import/SCsub
@@ -1,5 +1,5 @@
#!/usr/bin/env python
-Import('env')
+Import("env")
env.add_source_files(env.editor_sources, "*.cpp")
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
new file mode 100644
index 0000000000..9e49fa9066
--- /dev/null
+++ b/editor/import/collada.cpp
@@ -0,0 +1,2582 @@
+/*************************************************************************/
+/* collada.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#include "collada.h"
+
+#include <stdio.h>
+
+//#define DEBUG_DEFAULT_ANIMATION
+//#define DEBUG_COLLADA
+#ifdef DEBUG_COLLADA
+#define COLLADA_PRINT(m_what) print_line(m_what)
+#else
+#define COLLADA_PRINT(m_what)
+#endif
+
+#define COLLADA_IMPORT_SCALE_SCENE
+
+/* HELPERS */
+
+String Collada::Effect::get_texture_path(const String &p_source, Collada &state) const {
+
+ const String &image = p_source;
+ ERR_FAIL_COND_V(!state.state.image_map.has(image), "");
+ return state.state.image_map[image].path;
+}
+
+Transform Collada::get_root_transform() const {
+
+ Transform unit_scale_transform;
+#ifndef COLLADA_IMPORT_SCALE_SCENE
+ unit_scale_transform.scale(Vector3(state.unit_scale, state.unit_scale, state.unit_scale));
+#endif
+ return unit_scale_transform;
+}
+
+void Collada::Vertex::fix_unit_scale(Collada &state) {
+#ifdef COLLADA_IMPORT_SCALE_SCENE
+ vertex *= state.state.unit_scale;
+#endif
+}
+
+static String _uri_to_id(const String &p_uri) {
+
+ if (p_uri.begins_with("#"))
+ return p_uri.substr(1, p_uri.size() - 1);
+ else
+ return p_uri;
+}
+
+/** HELPER FUNCTIONS **/
+
+Transform Collada::fix_transform(const Transform &p_transform) {
+
+ Transform tr = p_transform;
+
+#ifndef NO_UP_AXIS_SWAP
+
+ if (state.up_axis != Vector3::AXIS_Y) {
+
+ for (int i = 0; i < 3; i++)
+ SWAP(tr.basis[1][i], tr.basis[state.up_axis][i]);
+ for (int i = 0; i < 3; i++)
+ SWAP(tr.basis[i][1], tr.basis[i][state.up_axis]);
+
+ SWAP(tr.origin[1], tr.origin[state.up_axis]);
+
+ tr.basis[state.up_axis][0] = -tr.basis[state.up_axis][0];
+ tr.basis[state.up_axis][1] = -tr.basis[state.up_axis][1];
+ tr.basis[0][state.up_axis] = -tr.basis[0][state.up_axis];
+ tr.basis[1][state.up_axis] = -tr.basis[1][state.up_axis];
+ tr.origin[state.up_axis] = -tr.origin[state.up_axis];
+ }
+#endif
+
+ //tr.scale(Vector3(state.unit_scale.unit_scale.unit_scale));
+ return tr;
+ //return state.matrix_fix * p_transform;
+}
+
+static Transform _read_transform_from_array(const Vector<float> &array, int ofs = 0) {
+
+ Transform tr;
+ // i wonder why collada matrices are transposed, given that's opposed to opengl..
+ tr.basis.elements[0][0] = array[0 + ofs];
+ tr.basis.elements[0][1] = array[1 + ofs];
+ tr.basis.elements[0][2] = array[2 + ofs];
+ tr.basis.elements[1][0] = array[4 + ofs];
+ tr.basis.elements[1][1] = array[5 + ofs];
+ tr.basis.elements[1][2] = array[6 + ofs];
+ tr.basis.elements[2][0] = array[8 + ofs];
+ tr.basis.elements[2][1] = array[9 + ofs];
+ tr.basis.elements[2][2] = array[10 + ofs];
+ tr.origin.x = array[3 + ofs];
+ tr.origin.y = array[7 + ofs];
+ tr.origin.z = array[11 + ofs];
+ return tr;
+}
+
+/* STRUCTURES */
+
+Transform Collada::Node::compute_transform(Collada &state) const {
+
+ Transform xform;
+
+ for (int i = 0; i < xform_list.size(); i++) {
+
+ Transform xform_step;
+ const XForm &xf = xform_list[i];
+ switch (xf.op) {
+
+ case XForm::OP_ROTATE: {
+ if (xf.data.size() >= 4) {
+
+ xform_step.rotate(Vector3(xf.data[0], xf.data[1], xf.data[2]), Math::deg2rad(xf.data[3]));
+ }
+ } break;
+ case XForm::OP_SCALE: {
+
+ if (xf.data.size() >= 3) {
+
+ xform_step.scale(Vector3(xf.data[0], xf.data[1], xf.data[2]));
+ }
+
+ } break;
+ case XForm::OP_TRANSLATE: {
+
+ if (xf.data.size() >= 3) {
+
+ xform_step.origin = Vector3(xf.data[0], xf.data[1], xf.data[2]);
+ }
+
+ } break;
+ case XForm::OP_MATRIX: {
+
+ if (xf.data.size() >= 16) {
+ xform_step = _read_transform_from_array(xf.data, 0);
+ }
+
+ } break;
+ default: {
+ }
+ }
+
+ xform = xform * xform_step;
+ }
+
+#ifdef COLLADA_IMPORT_SCALE_SCENE
+ xform.origin *= state.state.unit_scale;
+#endif
+ return xform;
+}
+
+Transform Collada::Node::get_transform() const {
+
+ return default_transform;
+}
+
+Transform Collada::Node::get_global_transform() const {
+
+ if (parent)
+ return parent->get_global_transform() * default_transform;
+ else
+ return default_transform;
+}
+
+Vector<float> Collada::AnimationTrack::get_value_at_time(float p_time) const {
+
+ ERR_FAIL_COND_V(keys.size() == 0, Vector<float>());
+ int i = 0;
+
+ for (i = 0; i < keys.size(); i++) {
+
+ if (keys[i].time > p_time)
+ break;
+ }
+
+ if (i == 0)
+ return keys[0].data;
+ if (i == keys.size())
+ return keys[keys.size() - 1].data;
+
+ switch (keys[i].interp_type) {
+
+ case INTERP_BEZIER: //wait for bezier
+ case INTERP_LINEAR: {
+
+ float c = (p_time - keys[i - 1].time) / (keys[i].time - keys[i - 1].time);
+
+ if (keys[i].data.size() == 16) {
+ //interpolate a matrix
+ Transform src = _read_transform_from_array(keys[i - 1].data);
+ Transform dst = _read_transform_from_array(keys[i].data);
+
+ Transform interp = c < 0.001 ? src : src.interpolate_with(dst, c);
+
+ Vector<float> ret;
+ ret.resize(16);
+ Transform tr;
+ // i wonder why collada matrices are transposed, given that's opposed to opengl..
+ ret.write[0] = interp.basis.elements[0][0];
+ ret.write[1] = interp.basis.elements[0][1];
+ ret.write[2] = interp.basis.elements[0][2];
+ ret.write[4] = interp.basis.elements[1][0];
+ ret.write[5] = interp.basis.elements[1][1];
+ ret.write[6] = interp.basis.elements[1][2];
+ ret.write[8] = interp.basis.elements[2][0];
+ ret.write[9] = interp.basis.elements[2][1];
+ ret.write[10] = interp.basis.elements[2][2];
+ ret.write[3] = interp.origin.x;
+ ret.write[7] = interp.origin.y;
+ ret.write[11] = interp.origin.z;
+ ret.write[12] = 0;
+ ret.write[13] = 0;
+ ret.write[14] = 0;
+ ret.write[15] = 1;
+
+ return ret;
+ } else {
+
+ Vector<float> dest;
+ dest.resize(keys[i].data.size());
+ for (int j = 0; j < dest.size(); j++) {
+
+ dest.write[j] = keys[i].data[j] * c + keys[i - 1].data[j] * (1.0 - c);
+ }
+ return dest;
+ //interpolate one by one
+ }
+ } break;
+ }
+
+ ERR_FAIL_V(Vector<float>());
+}
+
+void Collada::_parse_asset(XMLParser &parser) {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+
+ if (name == "up_axis") {
+
+ parser.read();
+ if (parser.get_node_data() == "X_UP")
+ state.up_axis = Vector3::AXIS_X;
+ if (parser.get_node_data() == "Y_UP")
+ state.up_axis = Vector3::AXIS_Y;
+ if (parser.get_node_data() == "Z_UP")
+ state.up_axis = Vector3::AXIS_Z;
+
+ COLLADA_PRINT("up axis: " + parser.get_node_data());
+ } else if (name == "unit") {
+
+ state.unit_scale = parser.get_attribute_value("meter").to_double();
+ COLLADA_PRINT("unit scale: " + rtos(state.unit_scale));
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "asset")
+ break; //end of <asset>
+ }
+}
+
+void Collada::_parse_image(XMLParser &parser) {
+
+ String id = parser.get_attribute_value("id");
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ Image image;
+
+ if (state.version < State::Version(1, 4, 0)) {
+ /* <1.4 */
+ String path = parser.get_attribute_value("source").strip_edges();
+ if (path.find("://") == -1 && path.is_rel_path()) {
+ // path is relative to file being loaded, so convert to a resource path
+ image.path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path.percent_decode()));
+ }
+ } else {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+
+ if (name == "init_from") {
+
+ parser.read();
+ String path = parser.get_node_data().strip_edges().percent_decode();
+
+ if (path.find("://") == -1 && path.is_rel_path()) {
+ // path is relative to file being loaded, so convert to a resource path
+ path = ProjectSettings::get_singleton()->localize_path(state.local_path.get_base_dir().plus_file(path));
+
+ } else if (path.find("file:///") == 0) {
+ path = path.replace_first("file:///", "");
+ path = ProjectSettings::get_singleton()->localize_path(path);
+ }
+
+ image.path = path;
+
+ } else if (name == "data") {
+
+ ERR_PRINT("COLLADA Embedded image data not supported!");
+
+ } else if (name == "extra" && !parser.is_empty())
+ parser.skip_section();
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "image")
+ break; //end of <asset>
+ }
+ }
+
+ state.image_map[id] = image;
+}
+
+void Collada::_parse_material(XMLParser &parser) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ Material material;
+
+ String id = parser.get_attribute_value("id");
+ if (parser.has_attribute("name"))
+ material.name = parser.get_attribute_value("name");
+
+ if (state.version < State::Version(1, 4, 0)) {
+ /* <1.4 */
+ ERR_PRINT("Collada Materials < 1.4 are not supported (yet)");
+ } else {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT && parser.get_node_name() == "instance_effect") {
+
+ material.instance_effect = _uri_to_id(parser.get_attribute_value("url"));
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "material")
+ break; //end of <asset>
+ }
+ }
+
+ state.material_map[id] = material;
+}
+
+//! reads floats from inside of xml element until end of xml element
+Vector<float> Collada::_read_float_array(XMLParser &parser) {
+
+ if (parser.is_empty())
+ return Vector<float>();
+
+ Vector<String> splitters;
+ splitters.push_back(" ");
+ splitters.push_back("\n");
+ splitters.push_back("\r");
+ splitters.push_back("\t");
+
+ Vector<float> array;
+ while (parser.read() == OK) {
+ // TODO: check for comments inside the element
+ // and ignore them.
+
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+ // parse float data
+ String str = parser.get_node_data();
+ array = str.split_floats_mk(splitters, false);
+ //array=str.split_floats(" ",false);
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ break; // end parsing text
+ }
+
+ return array;
+}
+
+Vector<String> Collada::_read_string_array(XMLParser &parser) {
+
+ if (parser.is_empty())
+ return Vector<String>();
+
+ Vector<String> array;
+ while (parser.read() == OK) {
+ // TODO: check for comments inside the element
+ // and ignore them.
+
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+ // parse String data
+ String str = parser.get_node_data();
+ array = str.split_spaces();
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ break; // end parsing text
+ }
+
+ return array;
+}
+
+Transform Collada::_read_transform(XMLParser &parser) {
+
+ if (parser.is_empty())
+ return Transform();
+
+ Vector<String> array;
+ while (parser.read() == OK) {
+ // TODO: check for comments inside the element
+ // and ignore them.
+
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+ // parse float data
+ String str = parser.get_node_data();
+ array = str.split_spaces();
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ break; // end parsing text
+ }
+
+ ERR_FAIL_COND_V(array.size() != 16, Transform());
+ Vector<float> farr;
+ farr.resize(16);
+ for (int i = 0; i < 16; i++) {
+ farr.write[i] = array[i].to_double();
+ }
+
+ return _read_transform_from_array(farr);
+}
+
+String Collada::_read_empty_draw_type(XMLParser &parser) {
+
+ String empty_draw_type = "";
+
+ if (parser.is_empty())
+ return empty_draw_type;
+
+ while (parser.read() == OK) {
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+ empty_draw_type = parser.get_node_data();
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END)
+ break; // end parsing text
+ }
+ return empty_draw_type;
+}
+
+Variant Collada::_parse_param(XMLParser &parser) {
+
+ if (parser.is_empty())
+ return Variant();
+
+ String from = parser.get_node_name();
+ Variant data;
+
+ while (parser.read() == OK) {
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "float") {
+
+ parser.read();
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+
+ data = parser.get_node_data().to_double();
+ }
+ } else if (parser.get_node_name() == "float2") {
+
+ Vector<float> v2 = _read_float_array(parser);
+
+ if (v2.size() >= 2) {
+
+ data = Vector2(v2[0], v2[1]);
+ }
+ } else if (parser.get_node_name() == "float3") {
+
+ Vector<float> v3 = _read_float_array(parser);
+
+ if (v3.size() >= 3) {
+
+ data = Vector3(v3[0], v3[1], v3[2]);
+ }
+ } else if (parser.get_node_name() == "float4") {
+
+ Vector<float> v4 = _read_float_array(parser);
+
+ if (v4.size() >= 4) {
+
+ data = Color(v4[0], v4[1], v4[2], v4[3]);
+ }
+ } else if (parser.get_node_name() == "sampler2D") {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "source") {
+
+ parser.read();
+
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+
+ data = parser.get_node_data();
+ }
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "sampler2D")
+ break;
+ }
+ } else if (parser.get_node_name() == "surface") {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "init_from") {
+
+ parser.read();
+
+ if (parser.get_node_type() == XMLParser::NODE_TEXT) {
+
+ data = parser.get_node_data();
+ }
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "surface")
+ break;
+ }
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == from)
+ break;
+ }
+
+ COLLADA_PRINT("newparam ending " + parser.get_node_name());
+ return data;
+}
+
+void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &id) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ // first come the tags we descend, but ignore the top-levels
+
+ COLLADA_PRINT("node name: " + parser.get_node_name());
+
+ if (!parser.is_empty() && (parser.get_node_name() == "profile_COMMON" || parser.get_node_name() == "technique" || parser.get_node_name() == "extra")) {
+
+ _parse_effect_material(parser, effect, id); // try again
+
+ } else if (parser.get_node_name() == "newparam") {
+ String name = parser.get_attribute_value("sid");
+ Variant value = _parse_param(parser);
+ effect.params[name] = value;
+ COLLADA_PRINT("param: " + name + " value:" + String(value));
+
+ } else if (parser.get_node_name() == "constant" ||
+ parser.get_node_name() == "lambert" ||
+ parser.get_node_name() == "phong" ||
+ parser.get_node_name() == "blinn") {
+
+ COLLADA_PRINT("shade model: " + parser.get_node_name());
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String what = parser.get_node_name();
+
+ if (what == "emission" ||
+ what == "diffuse" ||
+ what == "specular" ||
+ what == "reflective") {
+
+ // color or texture types
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "color") {
+
+ Vector<float> colorarr = _read_float_array(parser);
+ COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
+
+ if (colorarr.size() >= 3) {
+
+ // alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
+ Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
+ if (what == "diffuse")
+ effect.diffuse.color = color;
+ if (what == "specular")
+ effect.specular.color = color;
+ if (what == "emission")
+ effect.emission.color = color;
+
+ COLLADA_PRINT(what + " color: " + color);
+ }
+
+ } else if (parser.get_node_name() == "texture") {
+
+ String sampler = parser.get_attribute_value("texture");
+ if (!effect.params.has(sampler)) {
+ ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
+ } else {
+ String surface = effect.params[sampler];
+
+ if (!effect.params.has(surface)) {
+ ERR_PRINT(String("Couldn't find surface: " + surface + " in material:" + id).utf8().get_data());
+ } else {
+ String uri = effect.params[surface];
+
+ if (what == "diffuse") {
+ effect.diffuse.texture = uri;
+ } else if (what == "specular") {
+ effect.specular.texture = uri;
+ } else if (what == "emission") {
+ effect.emission.texture = uri;
+ } else if (what == "bump") {
+ if (parser.has_attribute("bumptype") && parser.get_attribute_value("bumptype") != "NORMALMAP") {
+ WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
+ }
+
+ effect.bump.texture = uri;
+ }
+
+ COLLADA_PRINT(what + " texture: " + uri);
+ }
+ }
+ } else if (!parser.is_empty())
+ parser.skip_section();
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == what)
+ break;
+ }
+
+ } else if (what == "shininess") {
+ effect.shininess = _parse_param(parser);
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && (parser.get_node_name() == "constant" ||
+ parser.get_node_name() == "lambert" ||
+ parser.get_node_name() == "phong" ||
+ parser.get_node_name() == "blinn"))
+ break;
+ }
+ } else if (parser.get_node_name() == "double_sided" || parser.get_node_name() == "show_double_sided") { // colladamax / google earth
+
+ // 3DS Max / Google Earth double sided extension
+ parser.read();
+ effect.found_double_sided = true;
+ effect.double_sided = parser.get_node_data().to_int();
+ COLLADA_PRINT("double sided: " + itos(parser.get_node_data().to_int()));
+ } else if (parser.get_node_name() == "unshaded") {
+ parser.read();
+ effect.unshaded = parser.get_node_data().to_int();
+ } else if (parser.get_node_name() == "bump") {
+
+ // color or texture types
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "texture") {
+
+ String sampler = parser.get_attribute_value("texture");
+ if (!effect.params.has(sampler)) {
+ ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
+ } else {
+ String surface = effect.params[sampler];
+
+ if (!effect.params.has(surface)) {
+ ERR_PRINT(String("Couldn't find surface: " + surface + " in material:" + id).utf8().get_data());
+ } else {
+ String uri = effect.params[surface];
+
+ if (parser.has_attribute("bumptype") && parser.get_attribute_value("bumptype") != "NORMALMAP") {
+ WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
+ }
+
+ effect.bump.texture = uri;
+ COLLADA_PRINT(" bump: " + uri);
+ }
+ }
+ } else if (!parser.is_empty())
+ parser.skip_section();
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "bump")
+ break;
+ }
+
+ } else if (!parser.is_empty())
+ parser.skip_section();
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END &&
+ (parser.get_node_name() == "effect" ||
+ parser.get_node_name() == "profile_COMMON" ||
+ parser.get_node_name() == "technique" ||
+ parser.get_node_name() == "extra"))
+ break;
+ }
+}
+
+void Collada::_parse_effect(XMLParser &parser) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ String id = parser.get_attribute_value("id");
+
+ Effect effect;
+ if (parser.has_attribute("name"))
+ effect.name = parser.get_attribute_value("name");
+ _parse_effect_material(parser, effect, id);
+
+ state.effect_map[id] = effect;
+
+ COLLADA_PRINT("Effect ID:" + id);
+}
+
+void Collada::_parse_camera(XMLParser &parser) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ String id = parser.get_attribute_value("id");
+
+ state.camera_data_map[id] = CameraData();
+ CameraData &camera = state.camera_data_map[id];
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+
+ if (name == "perspective") {
+
+ camera.mode = CameraData::MODE_PERSPECTIVE;
+ } else if (name == "orthographic") {
+
+ camera.mode = CameraData::MODE_ORTHOGONAL;
+ } else if (name == "xfov") {
+
+ parser.read();
+ camera.perspective.x_fov = parser.get_node_data().to_double();
+
+ } else if (name == "yfov") {
+
+ parser.read();
+ camera.perspective.y_fov = parser.get_node_data().to_double();
+ } else if (name == "xmag") {
+
+ parser.read();
+ camera.orthogonal.x_mag = parser.get_node_data().to_double();
+
+ } else if (name == "ymag") {
+
+ parser.read();
+ camera.orthogonal.y_mag = parser.get_node_data().to_double();
+ } else if (name == "aspect_ratio") {
+
+ parser.read();
+ camera.aspect = parser.get_node_data().to_double();
+
+ } else if (name == "znear") {
+
+ parser.read();
+ camera.z_near = parser.get_node_data().to_double();
+
+ } else if (name == "zfar") {
+
+ parser.read();
+ camera.z_far = parser.get_node_data().to_double();
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "camera")
+ break; //end of <asset>
+ }
+
+ COLLADA_PRINT("Camera ID:" + id);
+}
+
+void Collada::_parse_light(XMLParser &parser) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ String id = parser.get_attribute_value("id");
+
+ state.light_data_map[id] = LightData();
+ LightData &light = state.light_data_map[id];
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+
+ if (name == "ambient") {
+
+ light.mode = LightData::MODE_AMBIENT;
+ } else if (name == "directional") {
+
+ light.mode = LightData::MODE_DIRECTIONAL;
+ } else if (name == "point") {
+
+ light.mode = LightData::MODE_OMNI;
+ } else if (name == "spot") {
+
+ light.mode = LightData::MODE_SPOT;
+ } else if (name == "color") {
+
+ parser.read();
+ Vector<float> colorarr = _read_float_array(parser);
+ COLLADA_PRINT("colorarr size: " + rtos(colorarr.size()));
+
+ if (colorarr.size() >= 4) {
+ // alpha strangely not alright? maybe it needs to be multiplied by value as a channel intensity
+ Color color(colorarr[0], colorarr[1], colorarr[2], 1.0);
+ light.color = color;
+ }
+
+ } else if (name == "constant_attenuation") {
+
+ parser.read();
+ light.constant_att = parser.get_node_data().to_double();
+ } else if (name == "linear_attenuation") {
+
+ parser.read();
+ light.linear_att = parser.get_node_data().to_double();
+ } else if (name == "quadratic_attenuation") {
+
+ parser.read();
+ light.quad_att = parser.get_node_data().to_double();
+ } else if (name == "falloff_angle") {
+
+ parser.read();
+ light.spot_angle = parser.get_node_data().to_double();
+
+ } else if (name == "falloff_exponent") {
+
+ parser.read();
+ light.spot_exp = parser.get_node_data().to_double();
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "light")
+ break; //end of <asset>
+ }
+
+ COLLADA_PRINT("Light ID:" + id);
+}
+
+void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_name) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ //load everything into a pre dictionary
+
+ state.curve_data_map[p_id] = CurveData();
+
+ CurveData &curvedata = state.curve_data_map[p_id];
+ curvedata.name = p_name;
+
+ COLLADA_PRINT("curve name: " + p_name);
+
+ String current_source;
+ // handles geometry node and the curve children in this loop
+ // read sources with arrays and accessor for each curve
+ if (parser.is_empty()) {
+ return;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "source") {
+
+ String id = parser.get_attribute_value("id");
+ curvedata.sources[id] = CurveData::Source();
+ current_source = id;
+ COLLADA_PRINT("source data: " + id);
+
+ } else if (section == "float_array" || section == "array") {
+ // create a new array and read it.
+ if (curvedata.sources.has(current_source)) {
+
+ curvedata.sources[current_source].array = _read_float_array(parser);
+ COLLADA_PRINT("section: " + current_source + " read " + itos(curvedata.sources[current_source].array.size()) + " values.");
+ }
+ } else if (section == "Name_array") {
+ // create a new array and read it.
+ if (curvedata.sources.has(current_source)) {
+
+ curvedata.sources[current_source].sarray = _read_string_array(parser);
+ COLLADA_PRINT("section: " + current_source + " read " + itos(curvedata.sources[current_source].array.size()) + " values.");
+ }
+
+ } else if (section == "technique_common") {
+ //skip it
+ } else if (section == "accessor") { // child of source (below a technique tag)
+
+ if (curvedata.sources.has(current_source)) {
+ curvedata.sources[current_source].stride = parser.get_attribute_value("stride").to_int();
+ COLLADA_PRINT("section: " + current_source + " stride " + itos(curvedata.sources[current_source].stride));
+ }
+ } else if (section == "control_vertices") {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "input") {
+
+ String semantic = parser.get_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_attribute_value("source"));
+
+ curvedata.control_vertices[semantic] = source;
+
+ COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ break;
+ }
+
+ } else if (!parser.is_empty()) {
+
+ parser.skip_section();
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "spline")
+ break;
+ }
+}
+
+void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name) {
+
+ if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+ return;
+ }
+
+ //load everything into a pre dictionary
+
+ state.mesh_data_map[p_id] = MeshData();
+
+ MeshData &meshdata = state.mesh_data_map[p_id];
+ meshdata.name = p_name;
+
+ COLLADA_PRINT("mesh name: " + p_name);
+
+ String current_source;
+ // handles geometry node and the mesh children in this loop
+ // read sources with arrays and accessor for each mesh
+ if (parser.is_empty()) {
+ return;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "source") {
+
+ String id = parser.get_attribute_value("id");
+ meshdata.sources[id] = MeshData::Source();
+ current_source = id;
+ COLLADA_PRINT("source data: " + id);
+
+ } else if (section == "float_array" || section == "array") {
+ // create a new array and read it.
+ if (meshdata.sources.has(current_source)) {
+
+ meshdata.sources[current_source].array = _read_float_array(parser);
+ COLLADA_PRINT("section: " + current_source + " read " + itos(meshdata.sources[current_source].array.size()) + " values.");
+ }
+ } else if (section == "technique_common") {
+ //skip it
+ } else if (section == "accessor") { // child of source (below a technique tag)
+
+ if (meshdata.sources.has(current_source)) {
+ meshdata.sources[current_source].stride = parser.get_attribute_value("stride").to_int();
+ COLLADA_PRINT("section: " + current_source + " stride " + itos(meshdata.sources[current_source].stride));
+ }
+ } else if (section == "vertices") {
+
+ MeshData::Vertices vert;
+ String id = parser.get_attribute_value("id");
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "input") {
+
+ String semantic = parser.get_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_attribute_value("source"));
+
+ vert.sources[semantic] = source;
+
+ COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ break;
+ }
+
+ meshdata.vertices[id] = vert;
+
+ } else if (section == "triangles" || section == "polylist" || section == "polygons") {
+
+ bool polygons = (section == "polygons");
+ if (polygons) {
+ WARN_PRINT("Primitive type \"polygons\" is not well supported (concave shapes may fail). To ensure that the geometry is properly imported, please re-export using \"triangles\" or \"polylist\".");
+ }
+ MeshData::Primitives prim;
+
+ if (parser.has_attribute("material"))
+ prim.material = parser.get_attribute_value("material");
+ prim.count = parser.get_attribute_value("count").to_int();
+ prim.vertex_size = 0;
+ int last_ref = 0;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "input") {
+
+ String semantic = parser.get_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_attribute_value("source"));
+
+ if (semantic == "TEXCOORD") {
+ /*
+ if (parser.has_attribute("set"))// a texcoord
+ semantic+=parser.get_attribute_value("set");
+ else
+ semantic="TEXCOORD0";*/
+ semantic = "TEXCOORD" + itos(last_ref++);
+ }
+ int offset = parser.get_attribute_value("offset").to_int();
+
+ MeshData::Primitives::SourceRef sref;
+ sref.source = source;
+ sref.offset = offset;
+ prim.sources[semantic] = sref;
+ prim.vertex_size = MAX(prim.vertex_size, offset + 1);
+
+ COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source + " offset: " + itos(offset));
+
+ } else if (parser.get_node_name() == "p") { //indices
+
+ Vector<float> values = _read_float_array(parser);
+ if (polygons) {
+
+ ERR_CONTINUE(prim.vertex_size == 0);
+ prim.polygons.push_back(values.size() / prim.vertex_size);
+ int from = prim.indices.size();
+ prim.indices.resize(from + values.size());
+ for (int i = 0; i < values.size(); i++)
+ prim.indices.write[from + i] = values[i];
+
+ } else if (prim.vertex_size > 0) {
+ prim.indices = values;
+ }
+
+ COLLADA_PRINT("read " + itos(values.size()) + " index values");
+
+ } else if (parser.get_node_name() == "vcount") { // primitive
+
+ Vector<float> values = _read_float_array(parser);
+ prim.polygons = values;
+ COLLADA_PRINT("read " + itos(values.size()) + " polygon values");
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ break;
+ }
+
+ meshdata.primitives.push_back(prim);
+
+ } else if (parser.get_node_name() == "double_sided") {
+
+ parser.read();
+ meshdata.found_double_sided = true;
+ meshdata.double_sided = parser.get_node_data().to_int();
+
+ } else if (parser.get_node_name() == "polygons") {
+ ERR_PRINT("Primitive type \"polygons\" not supported, re-export using \"polylist\" or \"triangles\".");
+ } else if (!parser.is_empty()) {
+
+ parser.skip_section();
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "mesh")
+ break;
+ }
+}
+
+void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
+
+ state.skin_controller_data_map[p_id] = SkinControllerData();
+ SkinControllerData &skindata = state.skin_controller_data_map[p_id];
+
+ skindata.base = _uri_to_id(parser.get_attribute_value("source"));
+
+ String current_source;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "bind_shape_matrix") {
+
+ skindata.bind_shape = _read_transform(parser);
+#ifdef COLLADA_IMPORT_SCALE_SCENE
+ skindata.bind_shape.origin *= state.unit_scale;
+
+#endif
+ COLLADA_PRINT("skeleton bind shape transform: " + skindata.bind_shape);
+
+ } else if (section == "source") {
+
+ String id = parser.get_attribute_value("id");
+ skindata.sources[id] = SkinControllerData::Source();
+ current_source = id;
+ COLLADA_PRINT("source data: " + id);
+
+ } else if (section == "float_array" || section == "array") {
+ // create a new array and read it.
+ if (skindata.sources.has(current_source)) {
+
+ skindata.sources[current_source].array = _read_float_array(parser);
+ COLLADA_PRINT("section: " + current_source + " read " + itos(skindata.sources[current_source].array.size()) + " values.");
+ }
+ } else if (section == "Name_array" || section == "IDREF_array") {
+ // create a new array and read it.
+
+ if (section == "IDREF_array")
+ skindata.use_idrefs = true;
+ if (skindata.sources.has(current_source)) {
+
+ skindata.sources[current_source].sarray = _read_string_array(parser);
+ if (section == "IDREF_array") {
+ Vector<String> sa = skindata.sources[current_source].sarray;
+ for (int i = 0; i < sa.size(); i++)
+ state.idref_joints.insert(sa[i]);
+ }
+ COLLADA_PRINT("section: " + current_source + " read " + itos(skindata.sources[current_source].array.size()) + " values.");
+ }
+ } else if (section == "technique_common") {
+ //skip it
+ } else if (section == "accessor") { // child of source (below a technique tag)
+
+ if (skindata.sources.has(current_source)) {
+
+ int stride = 1;
+ if (parser.has_attribute("stride"))
+ stride = parser.get_attribute_value("stride").to_int();
+
+ skindata.sources[current_source].stride = stride;
+ COLLADA_PRINT("section: " + current_source + " stride " + itos(skindata.sources[current_source].stride));
+ }
+
+ } else if (section == "joints") {
+
+ SkinControllerData::Joints joint;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "input") {
+
+ String semantic = parser.get_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_attribute_value("source"));
+
+ joint.sources[semantic] = source;
+
+ COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ break;
+ }
+
+ skindata.joints = joint;
+
+ } else if (section == "vertex_weights") {
+
+ SkinControllerData::Weights weights;
+
+ weights.count = parser.get_attribute_value("count").to_int();
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "input") {
+
+ String semantic = parser.get_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_attribute_value("source"));
+
+ int offset = parser.get_attribute_value("offset").to_int();
+
+ SkinControllerData::Weights::SourceRef sref;
+ sref.source = source;
+ sref.offset = offset;
+ weights.sources[semantic] = sref;
+
+ COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source + " offset: " + itos(offset));
+
+ } else if (parser.get_node_name() == "v") { //indices
+
+ Vector<float> values = _read_float_array(parser);
+ weights.indices = values;
+ COLLADA_PRINT("read " + itos(values.size()) + " index values");
+
+ } else if (parser.get_node_name() == "vcount") { // weightsitive
+
+ Vector<float> values = _read_float_array(parser);
+ weights.sets = values;
+ COLLADA_PRINT("read " + itos(values.size()) + " polygon values");
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ break;
+ }
+
+ skindata.weights = weights;
+ }
+ /*
+ else if (!parser.is_empty())
+ parser.skip_section();
+ */
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "skin")
+ break;
+ }
+
+ /* STORE REST MATRICES */
+
+ Vector<Transform> rests;
+ ERR_FAIL_COND(!skindata.joints.sources.has("JOINT"));
+ ERR_FAIL_COND(!skindata.joints.sources.has("INV_BIND_MATRIX"));
+
+ String joint_arr = skindata.joints.sources["JOINT"];
+ String ibm = skindata.joints.sources["INV_BIND_MATRIX"];
+
+ ERR_FAIL_COND(!skindata.sources.has(joint_arr));
+ ERR_FAIL_COND(!skindata.sources.has(ibm));
+
+ SkinControllerData::Source &joint_source = skindata.sources[joint_arr];
+ SkinControllerData::Source &ibm_source = skindata.sources[ibm];
+
+ ERR_FAIL_COND(joint_source.sarray.size() != ibm_source.array.size() / 16);
+
+ for (int i = 0; i < joint_source.sarray.size(); i++) {
+
+ String name = joint_source.sarray[i];
+ Transform xform = _read_transform_from_array(ibm_source.array, i * 16); //<- this is a mistake, it must be applied to vertices
+ xform.affine_invert(); // inverse for rest, because it's an inverse
+#ifdef COLLADA_IMPORT_SCALE_SCENE
+ xform.origin *= state.unit_scale;
+#endif
+ skindata.bone_rest_map[name] = xform;
+ }
+}
+
+void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
+
+ state.morph_controller_data_map[p_id] = MorphControllerData();
+ MorphControllerData &morphdata = state.morph_controller_data_map[p_id];
+
+ morphdata.mesh = _uri_to_id(parser.get_attribute_value("source"));
+ morphdata.mode = parser.get_attribute_value("method");
+ String current_source;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "source") {
+
+ String id = parser.get_attribute_value("id");
+ morphdata.sources[id] = MorphControllerData::Source();
+ current_source = id;
+ COLLADA_PRINT("source data: " + id);
+
+ } else if (section == "float_array" || section == "array") {
+ // create a new array and read it.
+ if (morphdata.sources.has(current_source)) {
+
+ morphdata.sources[current_source].array = _read_float_array(parser);
+ COLLADA_PRINT("section: " + current_source + " read " + itos(morphdata.sources[current_source].array.size()) + " values.");
+ }
+ } else if (section == "Name_array" || section == "IDREF_array") {
+ // create a new array and read it.
+
+ /*
+ if (section=="IDREF_array")
+ morphdata.use_idrefs=true;
+ */
+ if (morphdata.sources.has(current_source)) {
+
+ morphdata.sources[current_source].sarray = _read_string_array(parser);
+ /*
+ if (section=="IDREF_array") {
+ Vector<String> sa = morphdata.sources[current_source].sarray;
+ for(int i=0;i<sa.size();i++)
+ state.idref_joints.insert(sa[i]);
+ }*/
+ COLLADA_PRINT("section: " + current_source + " read " + itos(morphdata.sources[current_source].array.size()) + " values.");
+ }
+ } else if (section == "technique_common") {
+ //skip it
+ } else if (section == "accessor") { // child of source (below a technique tag)
+
+ if (morphdata.sources.has(current_source)) {
+
+ int stride = 1;
+ if (parser.has_attribute("stride"))
+ stride = parser.get_attribute_value("stride").to_int();
+
+ morphdata.sources[current_source].stride = stride;
+ COLLADA_PRINT("section: " + current_source + " stride " + itos(morphdata.sources[current_source].stride));
+ }
+
+ } else if (section == "targets") {
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "input") {
+
+ String semantic = parser.get_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_attribute_value("source"));
+
+ morphdata.targets[semantic] = source;
+
+ COLLADA_PRINT(section + " input semantic: " + semantic + " source: " + source);
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == section)
+ break;
+ }
+ }
+ /*
+ else if (!parser.is_empty())
+ parser.skip_section();
+ */
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "morph")
+ break;
+ }
+
+ if (morphdata.targets.has("MORPH_WEIGHT")) {
+
+ state.morph_name_map[morphdata.targets["MORPH_WEIGHT"]] = p_id;
+ }
+}
+
+void Collada::_parse_controller(XMLParser &parser) {
+
+ String id = parser.get_attribute_value("id");
+
+ if (parser.is_empty()) {
+ return;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "skin") {
+ _parse_skin_controller(parser, id);
+ } else if (section == "morph") {
+ _parse_morph_controller(parser, id);
+ }
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "controller")
+ break;
+ }
+}
+
+Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
+
+ String type = parser.get_node_name();
+ NodeGeometry *geom = memnew(NodeGeometry);
+ geom->controller = type == "instance_controller";
+ geom->source = _uri_to_id(parser.get_attribute_value_safe("url"));
+
+ if (parser.is_empty()) //nothing else to parse...
+ return geom;
+ // try to find also many materials and skeletons!
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "instance_material") {
+
+ String symbol = parser.get_attribute_value("symbol");
+ String target = _uri_to_id(parser.get_attribute_value("target"));
+
+ NodeGeometry::Material mat;
+ mat.target = target;
+ geom->material_map[symbol] = mat;
+ COLLADA_PRINT("uses material: '" + target + "' on primitive'" + symbol + "'");
+ } else if (parser.get_node_name() == "skeleton") {
+
+ parser.read();
+ String uri = _uri_to_id(parser.get_node_data());
+ if (uri != "") {
+ geom->skeletons.push_back(uri);
+ }
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == type)
+ break;
+ }
+
+ if (geom->controller) {
+
+ if (geom->skeletons.empty()) {
+ //XSI style
+
+ if (state.skin_controller_data_map.has(geom->source)) {
+ SkinControllerData *skin = &state.skin_controller_data_map[geom->source];
+ //case where skeletons reference bones with IDREF (XSI)
+ ERR_FAIL_COND_V(!skin->joints.sources.has("JOINT"), geom);
+ String joint_arr = skin->joints.sources["JOINT"];
+ ERR_FAIL_COND_V(!skin->sources.has(joint_arr), geom);
+ Collada::SkinControllerData::Source &joint_source = skin->sources[joint_arr];
+ geom->skeletons = joint_source.sarray; //quite crazy, but should work.
+ }
+ }
+ }
+
+ return geom;
+}
+
+Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &parser) {
+
+ NodeCamera *cam = memnew(NodeCamera);
+ cam->camera = _uri_to_id(parser.get_attribute_value_safe("url"));
+
+ if (state.up_axis == Vector3::AXIS_Z) //collada weirdness
+ cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
+
+ if (parser.is_empty()) //nothing else to parse...
+ return cam;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "instance_camera")
+ break;
+ }
+
+ return cam;
+}
+
+Collada::Node *Collada::_parse_visual_instance_light(XMLParser &parser) {
+
+ NodeLight *cam = memnew(NodeLight);
+ cam->light = _uri_to_id(parser.get_attribute_value_safe("url"));
+
+ if (state.up_axis == Vector3::AXIS_Z) //collada weirdness
+ cam->post_transform.basis.rotate(Vector3(1, 0, 0), -Math_PI * 0.5);
+
+ if (parser.is_empty()) //nothing else to parse...
+ return cam;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "instance_light")
+ break;
+ }
+
+ return cam;
+}
+
+Collada::Node *Collada::_parse_visual_node_instance_data(XMLParser &parser) {
+
+ String instance_type = parser.get_node_name();
+
+ if (instance_type == "instance_geometry" || instance_type == "instance_controller") {
+ return _parse_visual_instance_geometry(parser);
+ } else if (instance_type == "instance_camera") {
+
+ return _parse_visual_instance_camera(parser);
+ } else if (instance_type == "instance_light") {
+ return _parse_visual_instance_light(parser);
+ }
+
+ if (parser.is_empty()) //nothing else to parse...
+ return nullptr;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == instance_type)
+ break;
+ }
+
+ return nullptr;
+}
+
+Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
+
+ String name;
+
+ String id = parser.get_attribute_value_safe("id");
+
+ bool found_name = false;
+
+ if (id == "") {
+
+ id = "%NODEID%" + itos(Math::rand());
+
+ } else {
+ found_name = true;
+ }
+
+ Vector<Node::XForm> xform_list;
+ Vector<Node *> children;
+
+ String empty_draw_type = "";
+
+ Node *node = nullptr;
+
+ name = parser.has_attribute("name") ? parser.get_attribute_value_safe("name") : parser.get_attribute_value_safe("id");
+ if (name == "") {
+
+ name = id;
+ } else {
+ found_name = true;
+ }
+
+ if ((parser.has_attribute("type") && parser.get_attribute_value("type") == "JOINT") || state.idref_joints.has(name)) {
+ // handle a bone
+
+ NodeJoint *joint = memnew(NodeJoint);
+
+ if (parser.has_attribute("sid")) { //bones may not have sid
+ joint->sid = parser.get_attribute_value("sid");
+ //state.bone_map[joint->sid]=joint;
+ } else if (state.idref_joints.has(name)) {
+ joint->sid = name; //kind of a cheat but..
+ } else if (parser.has_attribute("name")) {
+ joint->sid = parser.get_attribute_value_safe("name");
+ }
+
+ if (joint->sid != "") {
+ state.sid_to_node_map[joint->sid] = id;
+ }
+
+ node = joint;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "translate") {
+ Node::XForm xf;
+ if (parser.has_attribute("sid")) {
+ xf.id = parser.get_attribute_value("sid");
+ }
+ xf.op = Node::XForm::OP_TRANSLATE;
+
+ Vector<float> xlt = _read_float_array(parser);
+ xf.data = xlt;
+ xform_list.push_back(xf);
+
+ } else if (section == "rotate") {
+ Node::XForm xf;
+ if (parser.has_attribute("sid")) {
+ xf.id = parser.get_attribute_value("sid");
+ }
+ xf.op = Node::XForm::OP_ROTATE;
+
+ Vector<float> rot = _read_float_array(parser);
+ xf.data = rot;
+
+ xform_list.push_back(xf);
+
+ } else if (section == "scale") {
+ Node::XForm xf;
+ if (parser.has_attribute("sid")) {
+ xf.id = parser.get_attribute_value("sid");
+ }
+
+ xf.op = Node::XForm::OP_SCALE;
+
+ Vector<float> scale = _read_float_array(parser);
+
+ xf.data = scale;
+
+ xform_list.push_back(xf);
+
+ } else if (section == "matrix") {
+ Node::XForm xf;
+ if (parser.has_attribute("sid")) {
+ xf.id = parser.get_attribute_value("sid");
+ }
+ xf.op = Node::XForm::OP_MATRIX;
+
+ Vector<float> matrix = _read_float_array(parser);
+
+ xf.data = matrix;
+ String mtx;
+ for (int i = 0; i < matrix.size(); i++)
+ mtx += " " + rtos(matrix[i]);
+
+ xform_list.push_back(xf);
+
+ } else if (section == "visibility") {
+ Node::XForm xf;
+ if (parser.has_attribute("sid")) {
+ xf.id = parser.get_attribute_value("sid");
+ }
+ xf.op = Node::XForm::OP_VISIBILITY;
+
+ Vector<float> visible = _read_float_array(parser);
+
+ xf.data = visible;
+
+ xform_list.push_back(xf);
+
+ } else if (section == "empty_draw_type") {
+ empty_draw_type = _read_empty_draw_type(parser);
+ } else if (section == "technique" || section == "extra") {
+
+ } else if (section != "node") {
+ //usually what defines the type of node
+ if (section.begins_with("instance_")) {
+
+ if (!node) {
+
+ node = _parse_visual_node_instance_data(parser);
+
+ } else {
+ ERR_PRINT("Multiple instance_* not supported.");
+ }
+ }
+
+ } else {
+
+ /* Found a child node!! what to do..*/
+
+ Node *child = _parse_visual_scene_node(parser);
+ children.push_back(child);
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "node")
+ break;
+ }
+
+ if (!node) {
+
+ node = memnew(Node); //generic node, nothing of relevance found
+ }
+
+ node->noname = !found_name;
+ node->xform_list = xform_list;
+ node->children = children;
+ for (int i = 0; i < children.size(); i++) {
+ node->children[i]->parent = node;
+ }
+
+ node->name = name;
+ node->id = id;
+ node->empty_draw_type = empty_draw_type;
+
+ if (node->children.size() == 1) {
+ if (node->children[0]->noname && !node->noname) {
+ node->children[0]->name = node->name;
+ node->name = node->name + "-base";
+ }
+ }
+
+ node->default_transform = node->compute_transform(*this);
+ state.scene_map[id] = node;
+
+ return node;
+}
+
+void Collada::_parse_visual_scene(XMLParser &parser) {
+
+ String id = parser.get_attribute_value("id");
+
+ if (parser.is_empty()) {
+ return;
+ }
+
+ state.visual_scene_map[id] = VisualScene();
+ VisualScene &vscene = state.visual_scene_map[id];
+
+ if (parser.has_attribute("name"))
+ vscene.name = parser.get_attribute_value("name");
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String section = parser.get_node_name();
+
+ if (section == "node") {
+ vscene.root_nodes.push_back(_parse_visual_scene_node(parser));
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "visual_scene")
+ break;
+ }
+
+ COLLADA_PRINT("Scene ID:" + id);
+}
+
+void Collada::_parse_animation(XMLParser &parser) {
+
+ if (!(state.import_flags & IMPORT_FLAG_ANIMATION)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+
+ return;
+ }
+
+ Map<String, Vector<float>> float_sources;
+ Map<String, Vector<String>> string_sources;
+ Map<String, int> source_strides;
+ Map<String, Map<String, String>> samplers;
+ Map<String, Vector<String>> source_param_names;
+ Map<String, Vector<String>> source_param_types;
+
+ String id = "";
+ if (parser.has_attribute("id"))
+ id = parser.get_attribute_value("id");
+
+ String current_source;
+ String current_sampler;
+ Vector<String> channel_sources;
+ Vector<String> channel_targets;
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+ if (name == "source") {
+
+ current_source = parser.get_attribute_value("id");
+ source_param_names[current_source] = Vector<String>();
+ source_param_types[current_source] = Vector<String>();
+
+ } else if (name == "float_array") {
+
+ if (current_source != "") {
+ float_sources[current_source] = _read_float_array(parser);
+ }
+
+ } else if (name == "Name_array") {
+
+ if (current_source != "") {
+ string_sources[current_source] = _read_string_array(parser);
+ }
+ } else if (name == "accessor") {
+
+ if (current_source != "" && parser.has_attribute("stride")) {
+ source_strides[current_source] = parser.get_attribute_value("stride").to_int();
+ }
+ } else if (name == "sampler") {
+
+ current_sampler = parser.get_attribute_value("id");
+ samplers[current_sampler] = Map<String, String>();
+ } else if (name == "param") {
+
+ if (parser.has_attribute("name"))
+ source_param_names[current_source].push_back(parser.get_attribute_value("name"));
+ else
+ source_param_names[current_source].push_back("");
+
+ if (parser.has_attribute("type"))
+ source_param_types[current_source].push_back(parser.get_attribute_value("type"));
+ else
+ source_param_types[current_source].push_back("");
+
+ } else if (name == "input") {
+
+ if (current_sampler != "") {
+
+ samplers[current_sampler][parser.get_attribute_value("semantic")] = parser.get_attribute_value("source");
+ }
+
+ } else if (name == "channel") {
+
+ channel_sources.push_back(parser.get_attribute_value("source"));
+ channel_targets.push_back(parser.get_attribute_value("target"));
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation")
+ break; //end of <asset>
+ }
+
+ for (int i = 0; i < channel_sources.size(); i++) {
+
+ String source = _uri_to_id(channel_sources[i]);
+ String target = channel_targets[i];
+ ERR_CONTINUE(!samplers.has(source));
+ Map<String, String> &sampler = samplers[source];
+
+ ERR_CONTINUE(!sampler.has("INPUT")); //no input semantic? wtf?
+ String input_id = _uri_to_id(sampler["INPUT"]);
+ COLLADA_PRINT("input id is " + input_id);
+ ERR_CONTINUE(!float_sources.has(input_id));
+
+ ERR_CONTINUE(!sampler.has("OUTPUT"));
+ String output_id = _uri_to_id(sampler["OUTPUT"]);
+ ERR_CONTINUE(!float_sources.has(output_id));
+
+ ERR_CONTINUE(!source_param_names.has(output_id));
+
+ Vector<String> &names = source_param_names[output_id];
+
+ for (int l = 0; l < names.size(); l++) {
+
+ String name = names[l];
+
+ Vector<float> &time_keys = float_sources[input_id];
+ int key_count = time_keys.size();
+
+ AnimationTrack track; //begin crating track
+ track.id = id;
+
+ track.keys.resize(key_count);
+
+ for (int j = 0; j < key_count; j++) {
+ track.keys.write[j].time = time_keys[j];
+ state.animation_length = MAX(state.animation_length, time_keys[j]);
+ }
+
+ //now read actual values
+
+ int stride = 1;
+
+ if (source_strides.has(output_id))
+ stride = source_strides[output_id];
+ int output_len = stride / names.size();
+
+ ERR_CONTINUE(output_len == 0);
+ ERR_CONTINUE(!float_sources.has(output_id));
+
+ Vector<float> &output = float_sources[output_id];
+
+ ERR_CONTINUE_MSG((output.size() / stride) != key_count, "Wrong number of keys in output.");
+
+ for (int j = 0; j < key_count; j++) {
+ track.keys.write[j].data.resize(output_len);
+ for (int k = 0; k < output_len; k++)
+ track.keys.write[j].data.write[k] = output[l + j * stride + k]; //super weird but should work:
+ }
+
+ if (sampler.has("INTERPOLATION")) {
+
+ String interp_id = _uri_to_id(sampler["INTERPOLATION"]);
+ ERR_CONTINUE(!string_sources.has(interp_id));
+ Vector<String> &interps = string_sources[interp_id];
+ ERR_CONTINUE(interps.size() != key_count);
+
+ for (int j = 0; j < key_count; j++) {
+ if (interps[j] == "BEZIER")
+ track.keys.write[j].interp_type = AnimationTrack::INTERP_BEZIER;
+ else
+ track.keys.write[j].interp_type = AnimationTrack::INTERP_LINEAR;
+ }
+ }
+
+ if (sampler.has("IN_TANGENT") && sampler.has("OUT_TANGENT")) {
+ //bezier control points..
+ String intangent_id = _uri_to_id(sampler["IN_TANGENT"]);
+ ERR_CONTINUE(!float_sources.has(intangent_id));
+ Vector<float> &intangents = float_sources[intangent_id];
+
+ ERR_CONTINUE(intangents.size() != key_count * 2 * names.size());
+
+ String outangent_id = _uri_to_id(sampler["OUT_TANGENT"]);
+ ERR_CONTINUE(!float_sources.has(outangent_id));
+ Vector<float> &outangents = float_sources[outangent_id];
+ ERR_CONTINUE(outangents.size() != key_count * 2 * names.size());
+
+ for (int j = 0; j < key_count; j++) {
+ track.keys.write[j].in_tangent = Vector2(intangents[j * 2 * names.size() + 0 + l * 2], intangents[j * 2 * names.size() + 1 + l * 2]);
+ track.keys.write[j].out_tangent = Vector2(outangents[j * 2 * names.size() + 0 + l * 2], outangents[j * 2 * names.size() + 1 + l * 2]);
+ }
+ }
+
+ if (target.find("/") != -1) { //transform component
+ track.target = target.get_slicec('/', 0);
+ track.param = target.get_slicec('/', 1);
+ if (track.param.find(".") != -1)
+ track.component = track.param.get_slice(".", 1).to_upper();
+ track.param = track.param.get_slice(".", 0);
+ if (names.size() > 1 && track.component == "") {
+ //this is a guess because the collada spec is ambiguous here...
+ //i suppose if you have many names (outputs) you can't use a component and i should abide to that.
+ track.component = name;
+ }
+ } else {
+ track.target = target;
+ }
+
+ state.animation_tracks.push_back(track);
+
+ if (!state.referenced_tracks.has(target))
+ state.referenced_tracks[target] = Vector<int>();
+
+ state.referenced_tracks[target].push_back(state.animation_tracks.size() - 1);
+
+ if (id != "") {
+ if (!state.by_id_tracks.has(id))
+ state.by_id_tracks[id] = Vector<int>();
+
+ state.by_id_tracks[id].push_back(state.animation_tracks.size() - 1);
+ }
+
+ COLLADA_PRINT("loaded animation with " + itos(key_count) + " keys");
+ }
+ }
+}
+
+void Collada::_parse_animation_clip(XMLParser &parser) {
+
+ if (!(state.import_flags & IMPORT_FLAG_ANIMATION)) {
+ if (!parser.is_empty())
+ parser.skip_section();
+
+ return;
+ }
+
+ AnimationClip clip;
+
+ if (parser.has_attribute("name"))
+ clip.name = parser.get_attribute_value("name");
+ else if (parser.has_attribute("id"))
+ clip.name = parser.get_attribute_value("id");
+ if (parser.has_attribute("start"))
+ clip.begin = parser.get_attribute_value("start").to_double();
+ if (parser.has_attribute("end"))
+ clip.end = parser.get_attribute_value("end").to_double();
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+ if (name == "instance_animation") {
+
+ String url = _uri_to_id(parser.get_attribute_value("url"));
+ clip.tracks.push_back(url);
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation_clip")
+ break; //end of <asset>
+ }
+
+ state.animation_clips.push_back(clip);
+}
+
+void Collada::_parse_scene(XMLParser &parser) {
+
+ if (parser.is_empty()) {
+ return;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+
+ if (name == "instance_visual_scene") {
+
+ state.root_visual_scene = _uri_to_id(parser.get_attribute_value("url"));
+ } else if (name == "instance_physics_scene") {
+
+ state.root_physics_scene = _uri_to_id(parser.get_attribute_value("url"));
+ }
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "scene")
+ break; //end of <asset>
+ }
+}
+
+void Collada::_parse_library(XMLParser &parser) {
+
+ if (parser.is_empty()) {
+ return;
+ }
+
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ String name = parser.get_node_name();
+ COLLADA_PRINT("library name is: " + name);
+ if (name == "image") {
+
+ _parse_image(parser);
+ } else if (name == "material") {
+
+ _parse_material(parser);
+ } else if (name == "effect") {
+
+ _parse_effect(parser);
+ } else if (name == "camera") {
+
+ _parse_camera(parser);
+ } else if (name == "light") {
+
+ _parse_light(parser);
+ } else if (name == "geometry") {
+
+ String id = parser.get_attribute_value("id");
+ String name2 = parser.get_attribute_value_safe("name");
+ while (parser.read() == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "mesh") {
+ state.mesh_name_map[id] = (name2 != "") ? name2 : id;
+ _parse_mesh_geometry(parser, id, name2);
+ } else if (parser.get_node_name() == "spline") {
+ state.mesh_name_map[id] = (name2 != "") ? name2 : id;
+ _parse_curve_geometry(parser, id, name2);
+ } else if (!parser.is_empty())
+ parser.skip_section();
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "geometry")
+ break;
+ }
+
+ } else if (name == "controller") {
+
+ _parse_controller(parser);
+ } else if (name == "animation") {
+
+ _parse_animation(parser);
+ } else if (name == "animation_clip") {
+
+ _parse_animation_clip(parser);
+ } else if (name == "visual_scene") {
+
+ COLLADA_PRINT("visual scene");
+ _parse_visual_scene(parser);
+ } else if (!parser.is_empty())
+ parser.skip_section();
+
+ } else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name().begins_with("library_"))
+ break; //end of <asset>
+ }
+}
+
+void Collada::_joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner) {
+
+ if (p_node->type == Node::TYPE_JOINT) {
+
+ NodeJoint *nj = static_cast<NodeJoint *>(p_node);
+ nj->owner = p_owner;
+
+ for (int i = 0; i < nj->children.size(); i++) {
+
+ _joint_set_owner(nj->children.write[i], p_owner);
+ }
+ }
+}
+
+void Collada::_create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton) {
+
+ Node *node = *p_node;
+
+ if (node->type == Node::TYPE_JOINT) {
+
+ if (!p_skeleton) {
+
+ // ohohohoohoo it's a joint node, time to work!
+ NodeSkeleton *sk = memnew(NodeSkeleton);
+ *p_node = sk;
+ sk->children.push_back(node);
+ sk->parent = node->parent;
+ node->parent = sk;
+ p_skeleton = sk;
+ }
+
+ NodeJoint *nj = static_cast<NodeJoint *>(node);
+ nj->owner = p_skeleton;
+ } else {
+ p_skeleton = nullptr;
+ }
+
+ for (int i = 0; i < node->children.size(); i++) {
+ _create_skeletons(&node->children.write[i], p_skeleton);
+ }
+}
+
+bool Collada::_remove_node(Node *p_parent, Node *p_node) {
+
+ for (int i = 0; i < p_parent->children.size(); i++) {
+
+ if (p_parent->children[i] == p_node) {
+ p_parent->children.remove(i);
+ return true;
+ }
+ if (_remove_node(p_parent->children[i], p_node))
+ return true;
+ }
+
+ return false;
+}
+
+void Collada::_remove_node(VisualScene *p_vscene, Node *p_node) {
+
+ for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
+ if (p_vscene->root_nodes[i] == p_node) {
+
+ p_vscene->root_nodes.remove(i);
+ return;
+ }
+ if (_remove_node(p_vscene->root_nodes[i], p_node))
+ return;
+ }
+
+ ERR_PRINT("ERROR: Not found node to remove?");
+}
+
+void Collada::_merge_skeletons(VisualScene *p_vscene, Node *p_node) {
+
+ if (p_node->type == Node::TYPE_GEOMETRY) {
+
+ NodeGeometry *gnode = static_cast<NodeGeometry *>(p_node);
+ if (gnode->controller) {
+
+ // recount skeletons used
+ Set<NodeSkeleton *> skeletons;
+
+ for (int i = 0; i < gnode->skeletons.size(); i++) {
+
+ String nodeid = gnode->skeletons[i];
+
+ ERR_CONTINUE(!state.scene_map.has(nodeid)); //weird, it should have it...
+
+#ifdef NO_SAFE_CAST
+ NodeJoint *nj = static_cast<NodeJoint *>(state.scene_map[nodeid]);
+#else
+ NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]);
+#endif
+ ERR_CONTINUE(!nj); //broken collada
+ ERR_CONTINUE(!nj->owner); //weird, node should have a skeleton owner
+
+ skeletons.insert(nj->owner);
+ }
+
+ if (skeletons.size() > 1) {
+
+ //do the merger!!
+ Set<NodeSkeleton *>::Element *E = skeletons.front();
+ NodeSkeleton *base = E->get();
+
+ for (E = E->next(); E; E = E->next()) {
+
+ NodeSkeleton *merged = E->get();
+ _remove_node(p_vscene, merged);
+ for (int i = 0; i < merged->children.size(); i++) {
+
+ _joint_set_owner(merged->children[i], base);
+ base->children.push_back(merged->children[i]);
+ merged->children[i]->parent = base;
+ }
+
+ merged->children.clear(); //take children from it
+ memdelete(merged);
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < p_node->children.size(); i++) {
+ _merge_skeletons(p_vscene, p_node->children[i]);
+ }
+}
+
+void Collada::_merge_skeletons2(VisualScene *p_vscene) {
+
+ for (Map<String, SkinControllerData>::Element *E = state.skin_controller_data_map.front(); E; E = E->next()) {
+
+ SkinControllerData &cd = E->get();
+
+ NodeSkeleton *skeleton = nullptr;
+
+ for (Map<String, Transform>::Element *F = cd.bone_rest_map.front(); F; F = F->next()) {
+
+ String name;
+
+ if (!state.sid_to_node_map.has(F->key())) {
+ continue;
+ }
+
+ name = state.sid_to_node_map[F->key()];
+
+ ERR_CONTINUE(!state.scene_map.has(name));
+
+ Node *node = state.scene_map[name];
+ ERR_CONTINUE(node->type != Node::TYPE_JOINT);
+
+ NodeSkeleton *sk = nullptr;
+
+ while (node && !sk) {
+
+ if (node->type == Node::TYPE_SKELETON) {
+ sk = static_cast<NodeSkeleton *>(node);
+ }
+ node = node->parent;
+ }
+
+ ERR_CONTINUE(!sk);
+
+ if (!skeleton) {
+ skeleton = sk;
+ continue;
+ }
+
+ if (skeleton != sk) {
+ //whoa.. wtf, merge.
+ _remove_node(p_vscene, sk);
+ for (int i = 0; i < sk->children.size(); i++) {
+
+ _joint_set_owner(sk->children[i], skeleton);
+ skeleton->children.push_back(sk->children[i]);
+ sk->children[i]->parent = skeleton;
+ }
+
+ sk->children.clear(); //take children from it
+ memdelete(sk);
+ }
+ }
+ }
+}
+
+bool Collada::_optimize_skeletons(VisualScene *p_vscene, Node *p_node) {
+
+ Node *node = p_node;
+
+ if (node->type == Node::TYPE_SKELETON && node->parent && node->parent->type == Node::TYPE_NODE && node->parent->children.size() == 1) {
+ //replace parent by this...
+ Node *parent = node->parent;
+
+ //i wonder if this is alright.. i think it is since created skeleton (first joint) is already animated by bone..
+ node->id = parent->id;
+ node->name = parent->name;
+ node->xform_list = parent->xform_list;
+ node->default_transform = parent->default_transform;
+
+ state.scene_map[node->id] = node;
+ node->parent = parent->parent;
+
+ if (parent->parent) {
+ Node *gp = parent->parent;
+ bool found = false;
+ for (int i = 0; i < gp->children.size(); i++) {
+
+ if (gp->children[i] == parent) {
+ gp->children.write[i] = node;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ERR_PRINT("BUG");
+ }
+ } else {
+
+ bool found = false;
+
+ for (int i = 0; i < p_vscene->root_nodes.size(); i++) {
+
+ if (p_vscene->root_nodes[i] == parent) {
+
+ p_vscene->root_nodes.write[i] = node;
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ ERR_PRINT("BUG");
+ }
+ }
+
+ parent->children.clear();
+ memdelete(parent);
+ return true;
+ }
+
+ for (int i = 0; i < node->children.size(); i++) {
+
+ if (_optimize_skeletons(p_vscene, node->children[i]))
+ return false; //stop processing, go up
+ }
+
+ return false;
+}
+
+bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, List<Node *> *p_mgeom) {
+
+ // Bind Shape Matrix scales the bones and makes them gigantic, so the matrix then shrinks the model?
+ // Solution: apply the Bind Shape Matrix to the VERTICES, and if the object comes scaled, it seems to be left alone!
+
+ if (p_node->type == Node::TYPE_GEOMETRY) {
+
+ NodeGeometry *ng = static_cast<NodeGeometry *>(p_node);
+ if (ng->ignore_anim)
+ return false; //already made child of skeleton and processeg
+
+ if (ng->controller && ng->skeletons.size()) {
+
+ String nodeid = ng->skeletons[0];
+
+ ERR_FAIL_COND_V(!state.scene_map.has(nodeid), false); //weird, it should have it...
+#ifdef NO_SAFE_CAST
+ NodeJoint *nj = static_cast<NodeJoint *>(state.scene_map[nodeid]);
+#else
+ NodeJoint *nj = dynamic_cast<NodeJoint *>(state.scene_map[nodeid]);
+#endif
+ ERR_FAIL_COND_V(!nj, false);
+ ERR_FAIL_COND_V(!nj->owner, false); //weird, node should have a skeleton owner
+
+ NodeSkeleton *sk = nj->owner;
+
+ Node *p = sk->parent;
+ bool node_is_parent_of_skeleton = false;
+
+ while (p) {
+ if (p == p_node) {
+ node_is_parent_of_skeleton = true;
+ break;
+ }
+ p = p->parent; // try again
+ }
+
+ ERR_FAIL_COND_V(node_is_parent_of_skeleton, false);
+
+ //this should be correct
+ ERR_FAIL_COND_V(!state.skin_controller_data_map.has(ng->source), false);
+ SkinControllerData &skin = state.skin_controller_data_map[ng->source];
+ Transform skel_inv = sk->get_global_transform().affine_inverse();
+ p_node->default_transform = skel_inv * (skin.bind_shape /* p_node->get_global_transform()*/); // i honestly have no idea what to do with a previous model xform.. most exporters ignore it
+
+ //make rests relative to the skeleton (they seem to be always relative to world)
+ for (Map<String, Transform>::Element *E = skin.bone_rest_map.front(); E; E = E->next()) {
+
+ E->get() = skel_inv * E->get(); //make the bone rest local to the skeleton
+ state.bone_rest_map[E->key()] = E->get(); // make it remember where the bone is globally, now that it's relative
+ }
+
+ //but most exporters seem to work only if i do this..
+ //p_node->default_transform = p_node->get_global_transform();
+
+ //p_node->default_transform=Transform(); //this seems to be correct, because bind shape makes the object local to the skeleton
+ p_node->ignore_anim = true; // collada may animate this later, if it does, then this is not supported (redo your original asset and don't animate the base mesh)
+ p_node->parent = sk;
+ //sk->children.push_back(0,p_node); //avoid INFINITE loop
+ p_mgeom->push_back(p_node);
+ return true;
+ }
+ }
+
+ for (int i = 0; i < p_node->children.size(); i++) {
+
+ if (_move_geometry_to_skeletons(p_vscene, p_node->children[i], p_mgeom)) {
+ p_node->children.remove(i);
+ i--;
+ }
+ }
+
+ return false;
+}
+
+void Collada::_find_morph_nodes(VisualScene *p_vscene, Node *p_node) {
+
+ if (p_node->type == Node::TYPE_GEOMETRY) {
+
+ NodeGeometry *nj = static_cast<NodeGeometry *>(p_node);
+
+ if (nj->controller) {
+
+ String base = nj->source;
+
+ while (base != "" && !state.mesh_data_map.has(base)) {
+
+ if (state.skin_controller_data_map.has(base)) {
+
+ SkinControllerData &sk = state.skin_controller_data_map[base];
+ base = sk.base;
+ } else if (state.morph_controller_data_map.has(base)) {
+
+ state.morph_ownership_map[base] = nj->id;
+ break;
+ } else {
+ ERR_FAIL_MSG("Invalid scene.");
+ }
+ }
+ }
+ }
+
+ for (int i = 0; i < p_node->children.size(); i++) {
+
+ _find_morph_nodes(p_vscene, p_node->children[i]);
+ }
+}
+
+void Collada::_optimize() {
+
+ for (Map<String, VisualScene>::Element *E = state.visual_scene_map.front(); E; E = E->next()) {
+
+ VisualScene &vs = E->get();
+ for (int i = 0; i < vs.root_nodes.size(); i++) {
+ _create_skeletons(&vs.root_nodes.write[i]);
+ }
+
+ for (int i = 0; i < vs.root_nodes.size(); i++) {
+ _merge_skeletons(&vs, vs.root_nodes[i]);
+ }
+
+ _merge_skeletons2(&vs);
+
+ for (int i = 0; i < vs.root_nodes.size(); i++) {
+ _optimize_skeletons(&vs, vs.root_nodes[i]);
+ }
+
+ for (int i = 0; i < vs.root_nodes.size(); i++) {
+
+ List<Node *> mgeom;
+ if (_move_geometry_to_skeletons(&vs, vs.root_nodes[i], &mgeom)) {
+ vs.root_nodes.remove(i);
+ i--;
+ }
+
+ while (!mgeom.empty()) {
+
+ Node *n = mgeom.front()->get();
+ n->parent->children.push_back(n);
+ mgeom.pop_front();
+ }
+ }
+
+ for (int i = 0; i < vs.root_nodes.size(); i++) {
+ _find_morph_nodes(&vs, vs.root_nodes[i]);
+ }
+ }
+}
+
+int Collada::get_uv_channel(String p_name) {
+
+ if (!channel_map.has(p_name)) {
+
+ ERR_FAIL_COND_V(channel_map.size() == 2, 0);
+
+ channel_map[p_name] = channel_map.size();
+ }
+
+ return channel_map[p_name];
+}
+
+Error Collada::load(const String &p_path, int p_flags) {
+
+ Ref<XMLParser> parserr = memnew(XMLParser);
+ XMLParser &parser = *parserr.ptr();
+ Error err = parser.open(p_path);
+ ERR_FAIL_COND_V_MSG(err, err, "Cannot open Collada file '" + p_path + "'.");
+
+ state.local_path = ProjectSettings::get_singleton()->localize_path(p_path);
+ state.import_flags = p_flags;
+ /* Skip headers */
+ while ((err = parser.read()) == OK) {
+
+ if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
+
+ if (parser.get_node_name() == "COLLADA") {
+ break;
+ } else if (!parser.is_empty())
+ parser.skip_section(); // unknown section, likely headers
+ }
+ }
+
+ ERR_FAIL_COND_V_MSG(err != OK, ERR_FILE_CORRUPT, "Corrupted Collada file '" + p_path + "'.");
+
+ /* Start loading Collada */
+
+ {
+ //version
+ String version = parser.get_attribute_value("version");
+ state.version.major = version.get_slice(".", 0).to_int();
+ state.version.minor = version.get_slice(".", 1).to_int();
+ state.version.rev = version.get_slice(".", 2).to_int();
+ COLLADA_PRINT("Collada VERSION: " + version);
+ }
+
+ while ((err = parser.read()) == OK) {
+
+ /* Read all the main sections.. */
+
+ if (parser.get_node_type() != XMLParser::NODE_ELEMENT)
+ continue; //no idea what this may be, but skipping anyway
+
+ String section = parser.get_node_name();
+
+ COLLADA_PRINT("section: " + section);
+
+ if (section == "asset") {
+ _parse_asset(parser);
+
+ } else if (section.begins_with("library_")) {
+
+ _parse_library(parser);
+ } else if (section == "scene") {
+
+ _parse_scene(parser);
+ } else if (!parser.is_empty()) {
+ parser.skip_section(); // unknown section, likely headers
+ }
+ }
+
+ _optimize();
+ return OK;
+}
+
+Collada::Collada() {
+}
diff --git a/editor/import/collada.h b/editor/import/collada.h
new file mode 100644
index 0000000000..b74332fb22
--- /dev/null
+++ b/editor/import/collada.h
@@ -0,0 +1,647 @@
+/*************************************************************************/
+/* collada.h */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/*************************************************************************/
+
+#ifndef COLLADA_H
+#define COLLADA_H
+
+#include "core/io/xml_parser.h"
+#include "core/map.h"
+#include "core/project_settings.h"
+#include "scene/resources/material.h"
+
+class Collada {
+public:
+ enum ImportFlags {
+ IMPORT_FLAG_SCENE = 1,
+ IMPORT_FLAG_ANIMATION = 2
+ };
+
+ struct Image {
+
+ String path;
+ };
+
+ struct Material {
+
+ String name;
+ String instance_effect;
+ };
+
+ struct Effect {
+
+ String name;
+ Map<String, Variant> params;
+
+ struct Channel {
+
+ int uv_idx;
+ String texture;
+ Color color;
+ Channel() { uv_idx = 0; }
+ };
+
+ Channel diffuse, specular, emission, bump;
+ float shininess;
+ bool found_double_sided;
+ bool double_sided;
+ bool unshaded;
+
+ String get_texture_path(const String &p_source, Collada &state) const;
+
+ Effect() {
+ diffuse.color = Color(1, 1, 1, 1);
+ double_sided = true;
+ found_double_sided = false;
+ shininess = 40;
+ unshaded = false;
+ }
+ };
+
+ struct CameraData {
+
+ enum Mode {
+ MODE_PERSPECTIVE,
+ MODE_ORTHOGONAL
+ };
+
+ Mode mode;
+
+ union {
+ struct {
+ float x_fov;
+ float y_fov;
+ } perspective;
+ struct {
+ float x_mag;
+ float y_mag;
+ } orthogonal;
+ };
+
+ float aspect;
+ float z_near;
+ float z_far;
+
+ CameraData() :
+ mode(MODE_PERSPECTIVE),
+ aspect(1),
+ z_near(0.1),
+ z_far(100) {
+ perspective.x_fov = 0;
+ perspective.y_fov = 0;
+ }
+ };
+
+ struct LightData {
+
+ enum Mode {
+ MODE_AMBIENT,
+ MODE_DIRECTIONAL,
+ MODE_OMNI,
+ MODE_SPOT
+ };
+
+ Mode mode;
+
+ Color color;
+
+ float constant_att;
+ float linear_att;
+ float quad_att;
+
+ float spot_angle;
+ float spot_exp;
+
+ LightData() :
+ mode(MODE_AMBIENT),
+ color(Color(1, 1, 1, 1)),
+ constant_att(0),
+ linear_att(0),
+ quad_att(0),
+ spot_angle(45),
+ spot_exp(1) {
+ }
+ };
+
+ struct MeshData {
+
+ String name;
+ struct Source {
+
+ Vector<float> array;
+ int stride;
+ };
+
+ Map<String, Source> sources;
+
+ struct Vertices {
+
+ Map<String, String> sources;
+ };
+
+ Map<String, Vertices> vertices;
+
+ struct Primitives {
+
+ struct SourceRef {
+
+ String source;
+ int offset;
+ };
+
+ String material;
+ Map<String, SourceRef> sources;
+ Vector<float> polygons;
+ Vector<float> indices;
+ int count;
+ int vertex_size;
+ };
+
+ Vector<Primitives> primitives;
+
+ bool found_double_sided;
+ bool double_sided;
+
+ MeshData() {
+ found_double_sided = false;
+ double_sided = true;
+ }
+ };
+
+ struct CurveData {
+
+ String name;
+ bool closed;
+
+ struct Source {
+
+ Vector<String> sarray;
+ Vector<float> array;
+ int stride;
+ };
+
+ Map<String, Source> sources;
+
+ Map<String, String> control_vertices;
+
+ CurveData() {
+
+ closed = false;
+ }
+ };
+ struct SkinControllerData {
+
+ String base;
+ bool use_idrefs;
+
+ Transform bind_shape;
+
+ struct Source {
+
+ Vector<String> sarray; //maybe for names
+ Vector<float> array;
+ int stride;
+ Source() {
+ stride = 1;
+ }
+ };
+
+ Map<String, Source> sources;
+
+ struct Joints {
+
+ Map<String, String> sources;
+ } joints;
+
+ struct Weights {
+
+ struct SourceRef {
+
+ String source;
+ int offset;
+ };
+
+ String material;
+ Map<String, SourceRef> sources;
+ Vector<float> sets;
+ Vector<float> indices;
+ int count;
+ } weights;
+
+ Map<String, Transform> bone_rest_map;
+
+ SkinControllerData() { use_idrefs = false; }
+ };
+
+ struct MorphControllerData {
+
+ String mesh;
+ String mode;
+
+ struct Source {
+
+ int stride;
+ Vector<String> sarray; //maybe for names
+ Vector<float> array;
+ Source() { stride = 1; }
+ };
+
+ Map<String, Source> sources;
+
+ Map<String, String> targets;
+ MorphControllerData() {}
+ };
+
+ struct Vertex {
+
+ int idx;
+ Vector3 vertex;
+ Vector3 normal;
+ Vector3 uv;
+ Vector3 uv2;
+ Plane tangent;
+ Color color;
+ int uid;
+ struct Weight {
+ int bone_idx;
+ float weight;
+ bool operator<(const Weight w) const { return weight > w.weight; } //heaviest first
+ };
+
+ Vector<Weight> weights;
+
+ void fix_weights() {
+
+ weights.sort();
+ if (weights.size() > 4) {
+ //cap to 4 and make weights add up 1
+ weights.resize(4);
+ float total = 0;
+ for (int i = 0; i < 4; i++)
+ total += weights[i].weight;
+ if (total)
+ for (int i = 0; i < 4; i++)
+ weights.write[i].weight /= total;
+ }
+ }
+
+ void fix_unit_scale(Collada &state);
+
+ bool operator<(const Vertex &p_vert) const {
+
+ if (uid == p_vert.uid) {
+ if (vertex == p_vert.vertex) {
+ if (normal == p_vert.normal) {
+ if (uv == p_vert.uv) {
+ if (uv2 == p_vert.uv2) {
+
+ if (!weights.empty() || !p_vert.weights.empty()) {
+
+ if (weights.size() == p_vert.weights.size()) {
+
+ for (int i = 0; i < weights.size(); i++) {
+ if (weights[i].bone_idx != p_vert.weights[i].bone_idx)
+ return weights[i].bone_idx < p_vert.weights[i].bone_idx;
+
+ if (weights[i].weight != p_vert.weights[i].weight)
+ return weights[i].weight < p_vert.weights[i].weight;
+ }
+ } else {
+ return weights.size() < p_vert.weights.size();
+ }
+ }
+
+ return (color < p_vert.color);
+ } else
+ return (uv2 < p_vert.uv2);
+ } else
+ return (uv < p_vert.uv);
+ } else
+ return (normal < p_vert.normal);
+ } else
+ return vertex < p_vert.vertex;
+ } else
+ return uid < p_vert.uid;
+ }
+
+ Vertex() {
+ uid = 0;
+ idx = 0;
+ }
+ };
+ struct Node {
+
+ enum Type {
+
+ TYPE_NODE,
+ TYPE_JOINT,
+ TYPE_SKELETON, //this bone is not collada, it's added afterwards as optimization
+ TYPE_LIGHT,
+ TYPE_CAMERA,
+ TYPE_GEOMETRY
+ };
+
+ struct XForm {
+
+ enum Op {
+ OP_ROTATE,
+ OP_SCALE,
+ OP_TRANSLATE,
+ OP_MATRIX,
+ OP_VISIBILITY
+ };
+
+ String id;
+ Op op;
+ Vector<float> data;
+ };
+
+ Type type;
+
+ String name;
+ String id;
+ String empty_draw_type;
+ bool noname;
+ Vector<XForm> xform_list;
+ Transform default_transform;
+ Transform post_transform;
+ Vector<Node *> children;
+
+ Node *parent;
+
+ Transform compute_transform(Collada &state) const;
+ Transform get_global_transform() const;
+ Transform get_transform() const;
+
+ bool ignore_anim;
+
+ Node() {
+ noname = false;
+ type = TYPE_NODE;
+ parent = nullptr;
+ ignore_anim = false;
+ }
+ virtual ~Node() {
+ for (int i = 0; i < children.size(); i++)
+ memdelete(children[i]);
+ };
+ };
+
+ struct NodeSkeleton : public Node {
+
+ NodeSkeleton() { type = TYPE_SKELETON; }
+ };
+
+ struct NodeJoint : public Node {
+
+ NodeSkeleton *owner;
+ String sid;
+ NodeJoint() {
+ type = TYPE_JOINT;
+ owner = nullptr;
+ }
+ };
+
+ struct NodeGeometry : public Node {
+
+ bool controller;
+ String source;
+
+ struct Material {
+ String target;
+ };
+
+ Map<String, Material> material_map;
+ Vector<String> skeletons;
+
+ NodeGeometry() { type = TYPE_GEOMETRY; }
+ };
+
+ struct NodeCamera : public Node {
+
+ String camera;
+
+ NodeCamera() { type = TYPE_CAMERA; }
+ };
+
+ struct NodeLight : public Node {
+
+ String light;
+
+ NodeLight() { type = TYPE_LIGHT; }
+ };
+
+ struct VisualScene {
+
+ String name;
+ Vector<Node *> root_nodes;
+
+ ~VisualScene() {
+ for (int i = 0; i < root_nodes.size(); i++)
+ memdelete(root_nodes[i]);
+ }
+ };
+
+ struct AnimationClip {
+
+ String name;
+ float begin;
+ float end;
+ Vector<String> tracks;
+
+ AnimationClip() {
+ begin = 0;
+ end = 1;
+ }
+ };
+
+ struct AnimationTrack {
+
+ String id;
+ String target;
+ String param;
+ String component;
+ bool property;
+
+ enum InterpolationType {
+ INTERP_LINEAR,
+ INTERP_BEZIER
+ };
+
+ struct Key {
+
+ enum Type {
+ TYPE_FLOAT,
+ TYPE_MATRIX
+ };
+
+ float time;
+ Vector<float> data;
+ Point2 in_tangent;
+ Point2 out_tangent;
+ InterpolationType interp_type;
+
+ Key() { interp_type = INTERP_LINEAR; }
+ };
+
+ Vector<float> get_value_at_time(float p_time) const;
+
+ Vector<Key> keys;
+
+ AnimationTrack() { property = false; }
+ };
+
+ /****************/
+ /* IMPORT STATE */
+ /****************/
+
+ struct State {
+
+ int import_flags;
+
+ float unit_scale;
+ Vector3::Axis up_axis;
+ bool z_up;
+
+ struct Version {
+
+ int major, minor, rev;
+
+ 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; }
+ Version(int p_major = 0, int p_minor = 0, int p_rev = 0) {
+ major = p_major;
+ minor = p_minor;
+ rev = p_rev;
+ }
+ } version;
+
+ Map<String, CameraData> camera_data_map;
+ Map<String, MeshData> mesh_data_map;
+ Map<String, LightData> light_data_map;
+ Map<String, CurveData> curve_data_map;
+
+ Map<String, String> mesh_name_map;
+ Map<String, String> morph_name_map;
+ Map<String, String> morph_ownership_map;
+ Map<String, SkinControllerData> skin_controller_data_map;
+ Map<String, MorphControllerData> morph_controller_data_map;
+
+ Map<String, Image> image_map;
+ Map<String, Material> material_map;
+ Map<String, Effect> effect_map;
+
+ Map<String, VisualScene> visual_scene_map;
+ Map<String, Node *> scene_map;
+ Set<String> idref_joints;
+ Map<String, String> sid_to_node_map;
+ //Map<String,NodeJoint*> bone_map;
+
+ Map<String, Transform> bone_rest_map;
+
+ String local_path;
+ String root_visual_scene;
+ String root_physics_scene;
+
+ Vector<AnimationClip> animation_clips;
+ Vector<AnimationTrack> animation_tracks;
+ Map<String, Vector<int>> referenced_tracks;
+ Map<String, Vector<int>> by_id_tracks;
+
+ float animation_length;
+
+ State() :
+ import_flags(0),
+ unit_scale(1.0),
+ up_axis(Vector3::AXIS_Y),
+ animation_length(0) {
+ }
+ } state;
+
+ Error load(const String &p_path, int p_flags = 0);
+
+ Collada();
+
+ Transform fix_transform(const Transform &p_transform);
+
+ Transform get_root_transform() const;
+
+ int get_uv_channel(String p_name);
+
+private: // private stuff
+ Map<String, int> channel_map;
+
+ void _parse_asset(XMLParser &parser);
+ void _parse_image(XMLParser &parser);
+ void _parse_material(XMLParser &parser);
+ void _parse_effect_material(XMLParser &parser, Effect &effect, String &id);
+ void _parse_effect(XMLParser &parser);
+ void _parse_camera(XMLParser &parser);
+ void _parse_light(XMLParser &parser);
+ void _parse_animation_clip(XMLParser &parser);
+
+ void _parse_mesh_geometry(XMLParser &parser, String p_id, String p_name);
+ void _parse_curve_geometry(XMLParser &parser, String p_id, String p_name);
+
+ void _parse_skin_controller(XMLParser &parser, String p_id);
+ void _parse_morph_controller(XMLParser &parser, String p_id);
+ void _parse_controller(XMLParser &parser);
+
+ Node *_parse_visual_instance_geometry(XMLParser &parser);
+ Node *_parse_visual_instance_camera(XMLParser &parser);
+ Node *_parse_visual_instance_light(XMLParser &parser);
+
+ Node *_parse_visual_node_instance_data(XMLParser &parser);
+ Node *_parse_visual_scene_node(XMLParser &parser);
+ void _parse_visual_scene(XMLParser &parser);
+
+ void _parse_animation(XMLParser &parser);
+ void _parse_scene(XMLParser &parser);
+ void _parse_library(XMLParser &parser);
+
+ Variant _parse_param(XMLParser &parser);
+ Vector<float> _read_float_array(XMLParser &parser);
+ Vector<String> _read_string_array(XMLParser &parser);
+ Transform _read_transform(XMLParser &parser);
+ String _read_empty_draw_type(XMLParser &parser);
+
+ void _joint_set_owner(Collada::Node *p_node, NodeSkeleton *p_owner);
+ void _create_skeletons(Collada::Node **p_node, NodeSkeleton *p_skeleton = nullptr);
+ void _find_morph_nodes(VisualScene *p_vscene, Node *p_node);
+ bool _remove_node(Node *p_parent, Node *p_node);
+ void _remove_node(VisualScene *p_vscene, Node *p_node);
+ void _merge_skeletons2(VisualScene *p_vscene);
+ void _merge_skeletons(VisualScene *p_vscene, Node *p_node);
+ bool _optimize_skeletons(VisualScene *p_vscene, Node *p_node);
+
+ bool _move_geometry_to_skeletons(VisualScene *p_vscene, Node *p_node, List<Node *> *p_mgeom);
+
+ void _optimize();
+};
+
+#endif // COLLADA_H
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 3cc6e7a50c..697ddfba96 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -31,14 +31,14 @@
#include "editor_import_collada.h"
#include "core/os/os.h"
-#include "editor/collada/collada.h"
#include "editor/editor_node.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/light.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/path.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "editor/import/collada.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/3d/light_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/path_3d.h"
+#include "scene/3d/skeleton_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
#include "scene/resources/packed_scene.h"
@@ -47,18 +47,18 @@
struct ColladaImport {
Collada collada;
- Spatial *scene;
+ Node3D *scene;
Vector<Ref<Animation>> animations;
struct NodeMap {
//String path;
- Spatial *node;
+ Node3D *node;
int bone;
List<int> anim_tracks;
NodeMap() {
- node = NULL;
+ node = nullptr;
bone = -1;
}
};
@@ -76,17 +76,17 @@ struct ColladaImport {
Map<String, Ref<ArrayMesh>> mesh_cache;
Map<String, Ref<Curve3D>> curve_cache;
Map<String, Ref<Material>> material_cache;
- Map<Collada::Node *, Skeleton *> skeleton_map;
+ Map<Collada::Node *, Skeleton3D *> skeleton_map;
- Map<Skeleton *, Map<String, int>> skeleton_bone_map;
+ Map<Skeleton3D *, Map<String, int>> skeleton_bone_map;
Set<String> valid_animated_nodes;
Vector<int> valid_animated_properties;
Map<String, bool> bones_with_animation;
- Error _populate_skeleton(Skeleton *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent);
+ Error _populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent);
Error _create_scene_skeletons(Collada::Node *p_node);
- Error _create_scene(Collada::Node *p_node, Spatial *p_parent);
+ Error _create_scene(Collada::Node *p_node, Node3D *p_parent);
Error _create_resources(Collada::Node *p_node, bool p_use_compression);
Error _create_material(const String &p_target);
Error _create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_mesh, const Map<String, Collada::NodeGeometry::Material> &p_material_map, const Collada::MeshData &meshdata, const Transform &p_local_xform, const Vector<int> &bone_remap, const Collada::SkinControllerData *p_skin_controller, const Collada::MorphControllerData *p_morph_data, Vector<Ref<ArrayMesh>> p_morph_meshes = Vector<Ref<ArrayMesh>>(), bool p_use_compression = false, bool p_use_mesh_material = false);
@@ -110,7 +110,7 @@ struct ColladaImport {
}
};
-Error ColladaImport::_populate_skeleton(Skeleton *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent) {
+Error ColladaImport::_populate_skeleton(Skeleton3D *p_skeleton, Collada::Node *p_node, int &r_bone, int p_parent) {
if (p_node->type != Collada::Node::TYPE_JOINT)
return OK;
@@ -174,7 +174,7 @@ Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
if (p_node->type == Collada::Node::TYPE_SKELETON) {
- Skeleton *sk = memnew(Skeleton);
+ Skeleton3D *sk = memnew(Skeleton3D);
int bone = 0;
for (int i = 0; i < p_node->children.size(); i++) {
@@ -193,15 +193,15 @@ Error ColladaImport::_create_scene_skeletons(Collada::Node *p_node) {
return OK;
}
-Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
+Error ColladaImport::_create_scene(Collada::Node *p_node, Node3D *p_parent) {
- Spatial *node = NULL;
+ Node3D *node = nullptr;
switch (p_node->type) {
case Collada::Node::TYPE_NODE: {
- node = memnew(Spatial);
+ node = memnew(Node3D);
} break;
case Collada::Node::TYPE_JOINT: {
@@ -223,7 +223,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
if (!bool(GLOBAL_DEF("collada/use_ambient", false)))
return OK;
//well, it's an ambient light..
- Light *l = memnew(DirectionalLight);
+ Light3D *l = memnew(DirectionalLight3D);
//l->set_color(Light::COLOR_AMBIENT,ld.color);
//l->set_color(Light::COLOR_DIFFUSE,Color(0,0,0));
//l->set_color(Light::COLOR_SPECULAR,Color(0,0,0));
@@ -232,7 +232,7 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
} else if (ld.mode == Collada::LightData::MODE_DIRECTIONAL) {
//well, it's an ambient light..
- Light *l = memnew(DirectionalLight);
+ Light3D *l = memnew(DirectionalLight3D);
/*
if (found_ambient) //use it here
l->set_color(Light::COLOR_AMBIENT,ambient);
@@ -243,12 +243,12 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
node = l;
} else {
- Light *l;
+ Light3D *l;
if (ld.mode == Collada::LightData::MODE_OMNI)
- l = memnew(OmniLight);
+ l = memnew(OmniLight3D);
else {
- l = memnew(SpotLight);
+ l = memnew(SpotLight3D);
//l->set_parameter(Light::PARAM_SPOT_ANGLE,ld.spot_angle);
//l->set_parameter(Light::PARAM_SPOT_ATTENUATION,ld.spot_exp);
}
@@ -262,13 +262,13 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
} else {
- node = memnew(Spatial);
+ node = memnew(Node3D);
}
} break;
case Collada::Node::TYPE_CAMERA: {
Collada::NodeCamera *cam = static_cast<Collada::NodeCamera *>(p_node);
- Camera *camera = memnew(Camera);
+ Camera3D *camera = memnew(Camera3D);
if (collada.state.camera_data_map.has(cam->camera)) {
@@ -280,12 +280,12 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
if (cd.orthogonal.y_mag) {
- camera->set_keep_aspect_mode(Camera::KEEP_HEIGHT);
+ camera->set_keep_aspect_mode(Camera3D::KEEP_HEIGHT);
camera->set_orthogonal(cd.orthogonal.y_mag * 2.0, cd.z_near, cd.z_far);
} else if (!cd.orthogonal.y_mag && cd.orthogonal.x_mag) {
- camera->set_keep_aspect_mode(Camera::KEEP_WIDTH);
+ camera->set_keep_aspect_mode(Camera3D::KEEP_WIDTH);
camera->set_orthogonal(cd.orthogonal.x_mag * 2.0, cd.z_near, cd.z_far);
}
@@ -314,17 +314,17 @@ Error ColladaImport::_create_scene(Collada::Node *p_node, Spatial *p_parent) {
if (collada.state.curve_data_map.has(ng->source)) {
- node = memnew(Path);
+ node = memnew(Path3D);
} else {
//mesh since nothing else
- node = memnew(MeshInstance);
- //Object::cast_to<MeshInstance>(node)->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT, true);
+ node = memnew(MeshInstance3D);
+ //Object::cast_to<MeshInstance3D>(node)->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
}
} break;
case Collada::Node::TYPE_SKELETON: {
ERR_FAIL_COND_V(!skeleton_map.has(p_node), ERR_CANT_CREATE);
- Skeleton *sk = skeleton_map[p_node];
+ Skeleton3D *sk = skeleton_map[p_node];
node = sk;
} break;
}
@@ -536,7 +536,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
/* NORMAL SOURCE */
- const Collada::MeshData::Source *normal_src = NULL;
+ const Collada::MeshData::Source *normal_src = nullptr;
int normal_ofs = 0;
if (p.sources.has("NORMAL")) {
@@ -547,7 +547,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
normal_src = &meshdata.sources[normal_source_id];
}
- const Collada::MeshData::Source *binormal_src = NULL;
+ const Collada::MeshData::Source *binormal_src = nullptr;
int binormal_ofs = 0;
if (p.sources.has("TEXBINORMAL")) {
@@ -558,7 +558,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
binormal_src = &meshdata.sources[binormal_source_id];
}
- const Collada::MeshData::Source *tangent_src = NULL;
+ const Collada::MeshData::Source *tangent_src = nullptr;
int tangent_ofs = 0;
if (p.sources.has("TEXTANGENT")) {
@@ -569,7 +569,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
tangent_src = &meshdata.sources[tangent_source_id];
}
- const Collada::MeshData::Source *uv_src = NULL;
+ const Collada::MeshData::Source *uv_src = nullptr;
int uv_ofs = 0;
if (p.sources.has("TEXCOORD0")) {
@@ -580,7 +580,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
uv_src = &meshdata.sources[uv_source_id];
}
- const Collada::MeshData::Source *uv2_src = NULL;
+ const Collada::MeshData::Source *uv2_src = nullptr;
int uv2_ofs = 0;
if (p.sources.has("TEXCOORD1")) {
@@ -591,7 +591,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
uv2_src = &meshdata.sources[uv2_source_id];
}
- const Collada::MeshData::Source *color_src = NULL;
+ const Collada::MeshData::Source *color_src = nullptr;
int color_ofs = 0;
if (p.sources.has("COLOR")) {
@@ -614,7 +614,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
if (p_skin_controller) {
- const Collada::SkinControllerData::Source *weight_src = NULL;
+ const Collada::SkinControllerData::Source *weight_src = nullptr;
int weight_ofs = 0;
if (p_skin_controller->weights.sources.has("WEIGHT")) {
@@ -922,10 +922,10 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
if (has_weights) {
Vector<float> weights;
Vector<int> bones;
- weights.resize(VS::ARRAY_WEIGHTS_SIZE);
- bones.resize(VS::ARRAY_WEIGHTS_SIZE);
+ weights.resize(RS::ARRAY_WEIGHTS_SIZE);
+ bones.resize(RS::ARRAY_WEIGHTS_SIZE);
//float sum=0.0;
- for (int l = 0; l < VS::ARRAY_WEIGHTS_SIZE; l++) {
+ for (int l = 0; l < RS::ARRAY_WEIGHTS_SIZE; l++) {
if (l < vertex_array[k].weights.size()) {
weights.write[l] = vertex_array[k].weights[l].weight;
bones.write[l] = vertex_array[k].weights[l].bone_idx;
@@ -963,7 +963,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ArrayMesh> &p_me
////////////////////////////
Array d = surftool->commit_to_arrays();
- d.resize(VS::ARRAY_MAX);
+ d.resize(RS::ARRAY_MAX);
Array mr;
@@ -1010,12 +1010,12 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
if (p_node->type == Collada::Node::TYPE_GEOMETRY && node_map.has(p_node->id)) {
- Spatial *node = node_map[p_node->id].node;
+ Node3D *node = node_map[p_node->id].node;
Collada::NodeGeometry *ng = static_cast<Collada::NodeGeometry *>(p_node);
- if (Object::cast_to<Path>(node)) {
+ if (Object::cast_to<Path3D>(node)) {
- Path *path = Object::cast_to<Path>(node);
+ Path3D *path = Object::cast_to<Path3D>(node);
if (curve_cache.has(ng->source)) {
@@ -1047,7 +1047,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
const Collada::CurveData::Source &interps = cd.sources[cd.control_vertices["INTERPOLATION"]];
ERR_FAIL_COND_V(interps.stride != 1, ERR_INVALID_DATA);
- const Collada::CurveData::Source *tilts = NULL;
+ const Collada::CurveData::Source *tilts = nullptr;
if (cd.control_vertices.has("TILT") && cd.sources.has(cd.control_vertices["TILT"]))
tilts = &cd.sources[cd.control_vertices["TILT"]];
@@ -1083,16 +1083,16 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
}
}
- if (Object::cast_to<MeshInstance>(node)) {
+ if (Object::cast_to<MeshInstance3D>(node)) {
Collada::NodeGeometry *ng2 = static_cast<Collada::NodeGeometry *>(p_node);
- MeshInstance *mi = Object::cast_to<MeshInstance>(node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(node);
ERR_FAIL_COND_V(!mi, ERR_BUG);
- Collada::SkinControllerData *skin = NULL;
- Collada::MorphControllerData *morph = NULL;
+ Collada::SkinControllerData *skin = nullptr;
+ Collada::MorphControllerData *morph = nullptr;
String meshid;
Transform apply_xform;
Vector<int> bone_remap;
@@ -1114,7 +1114,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
String skname = skeletons[0];
ERR_FAIL_COND_V(!node_map.has(skname), ERR_INVALID_DATA);
NodeMap nmsk = node_map[skname];
- Skeleton *sk = Object::cast_to<Skeleton>(nmsk.node);
+ Skeleton3D *sk = Object::cast_to<Skeleton3D>(nmsk.node);
ERR_FAIL_COND_V(!sk, ERR_INVALID_DATA);
ERR_FAIL_COND_V(!skeleton_bone_map.has(sk), ERR_INVALID_DATA);
Map<String, int> &bone_remap_map = skeleton_bone_map[sk];
@@ -1173,7 +1173,7 @@ Error ColladaImport::_create_resources(Collada::Node *p_node, bool p_use_compres
Ref<ArrayMesh> mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
const Collada::MeshData &meshdata = collada.state.mesh_data_map[meshid2];
mesh->set_name(meshdata.name);
- Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, NULL, Vector<Ref<ArrayMesh>>(), false);
+ Error err = _create_mesh_surfaces(false, mesh, ng2->material_map, meshdata, apply_xform, bone_remap, skin, nullptr, Vector<Ref<ArrayMesh>>(), false);
ERR_FAIL_COND_V(err, err);
morphs.push_back(mesh);
@@ -1265,7 +1265,7 @@ Error ColladaImport::load(const String &p_path, int p_flags, bool p_force_make_t
ERR_FAIL_COND_V(!collada.state.visual_scene_map.has(collada.state.root_visual_scene), ERR_INVALID_DATA);
Collada::VisualScene &vs = collada.state.visual_scene_map[collada.state.root_visual_scene];
- scene = memnew(Spatial); // root
+ scene = memnew(Node3D); // root
//determine what's going on with the lights
for (int i = 0; i < vs.root_nodes.size(); i++) {
@@ -1530,7 +1530,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
String path = scene->get_path_to(nm.node);
if (nm.bone >= 0) {
- Skeleton *sk = static_cast<Skeleton *>(nm.node);
+ Skeleton3D *sk = static_cast<Skeleton3D *>(nm.node);
String name = sk->get_bone_name(nm.bone);
path = path + ":" + name;
}
@@ -1621,7 +1621,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
if (nm.bone >= 0) {
//make bone transform relative to rest (in case of skeleton)
- Skeleton *sk = Object::cast_to<Skeleton>(nm.node);
+ Skeleton3D *sk = Object::cast_to<Skeleton3D>(nm.node);
if (sk) {
xform = sk->get_bone_rest(nm.bone).affine_inverse() * xform;
@@ -1662,7 +1662,7 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones
NodeMap &nm = node_map[E->key()];
String path = scene->get_path_to(nm.node);
ERR_CONTINUE(nm.bone < 0);
- Skeleton *sk = static_cast<Skeleton *>(nm.node);
+ Skeleton3D *sk = static_cast<Skeleton3D *>(nm.node);
String name = sk->get_bone_name(nm.bone);
path = path + ":" + name;
@@ -1777,7 +1777,7 @@ Node *EditorSceneImporterCollada::import_scene(const String &p_path, uint32_t p_
Error err = state.load(p_path, flags, p_flags & EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS, p_flags & EditorSceneImporter::IMPORT_USE_COMPRESSION);
- ERR_FAIL_COND_V_MSG(err != OK, NULL, "Cannot load scene from file '" + p_path + "'.");
+ ERR_FAIL_COND_V_MSG(err != OK, nullptr, "Cannot load scene from file '" + p_path + "'.");
if (state.missing_textures.size()) {
diff --git a/editor/import/editor_import_collada.h b/editor/import/editor_import_collada.h
index 822a6450be..932a064e76 100644
--- a/editor/import/editor_import_collada.h
+++ b/editor/import/editor_import_collada.h
@@ -40,7 +40,7 @@ class EditorSceneImporterCollada : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = NULL, Error *r_err = NULL);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorSceneImporterCollada();
diff --git a/editor/import/editor_import_plugin.h b/editor/import/editor_import_plugin.h
index 4383b1b084..be4679b6d3 100644
--- a/editor/import/editor_import_plugin.h
+++ b/editor/import/editor_import_plugin.h
@@ -52,7 +52,7 @@ public:
virtual int get_import_order() const;
virtual void get_import_options(List<ImportOption> *r_options, int p_preset) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata = nullptr);
};
#endif //EDITOR_IMPORT_PLUGIN_H
diff --git a/editor/import/editor_scene_importer_gltf.cpp b/editor/import/editor_scene_importer_gltf.cpp
index 398fc9ff49..6ad2aa4142 100644
--- a/editor/import/editor_scene_importer_gltf.cpp
+++ b/editor/import/editor_scene_importer_gltf.cpp
@@ -37,9 +37,9 @@
#include "core/os/file_access.h"
#include "core/os/os.h"
#include "modules/regex/regex.h"
-#include "scene/3d/bone_attachment.h"
-#include "scene/3d/camera.h"
-#include "scene/3d/mesh_instance.h"
+#include "scene/3d/bone_attachment_3d.h"
+#include "scene/3d/camera_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/surface_tool.h"
@@ -1266,7 +1266,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
}
Vector<uint8_t> data;
- const uint8_t *data_ptr = NULL;
+ const uint8_t *data_ptr = nullptr;
int data_size = 0;
if (d.has("uri")) {
@@ -1307,7 +1307,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
if (mimetype.findn("png") != -1) {
//is a png
- ERR_FAIL_COND_V(Image::_png_mem_loader_func == NULL, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(Image::_png_mem_loader_func == nullptr, ERR_UNAVAILABLE);
const Ref<Image> img = Image::_png_mem_loader_func(data_ptr, data_size);
@@ -1323,7 +1323,7 @@ Error EditorSceneImporterGLTF::_parse_images(GLTFState &state, const String &p_b
if (mimetype.findn("jpeg") != -1) {
//is a jpg
- ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == NULL, ERR_UNAVAILABLE);
+ ERR_FAIL_COND_V(Image::_jpg_mem_loader_func == nullptr, ERR_UNAVAILABLE);
const Ref<Image> img = Image::_jpg_mem_loader_func(data_ptr, data_size);
@@ -2108,7 +2108,7 @@ Error EditorSceneImporterGLTF::_create_skeletons(GLTFState &state) {
GLTFSkeleton &gltf_skeleton = state.skeletons.write[skel_i];
- Skeleton *skeleton = memnew(Skeleton);
+ Skeleton3D *skeleton = memnew(Skeleton3D);
gltf_skeleton.godot_skeleton = skeleton;
// Make a unique name, no gltf node represents this skeleton
@@ -2485,12 +2485,12 @@ void EditorSceneImporterGLTF::_assign_scene_names(GLTFState &state) {
}
}
-BoneAttachment *EditorSceneImporterGLTF::_generate_bone_attachment(GLTFState &state, Skeleton *skeleton, const GLTFNodeIndex node_index) {
+BoneAttachment3D *EditorSceneImporterGLTF::_generate_bone_attachment(GLTFState &state, Skeleton3D *skeleton, const GLTFNodeIndex node_index) {
const GLTFNode *gltf_node = state.nodes[node_index];
const GLTFNode *bone_node = state.nodes[gltf_node->parent];
- BoneAttachment *bone_attachment = memnew(BoneAttachment);
+ BoneAttachment3D *bone_attachment = memnew(BoneAttachment3D);
print_verbose("glTF: Creating bone attachment for: " + gltf_node->name);
ERR_FAIL_COND_V(!bone_node->joint, nullptr);
@@ -2500,12 +2500,12 @@ BoneAttachment *EditorSceneImporterGLTF::_generate_bone_attachment(GLTFState &st
return bone_attachment;
}
-MeshInstance *EditorSceneImporterGLTF::_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
+MeshInstance3D *EditorSceneImporterGLTF::_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
const GLTFNode *gltf_node = state.nodes[node_index];
ERR_FAIL_INDEX_V(gltf_node->mesh, state.meshes.size(), nullptr);
- MeshInstance *mi = memnew(MeshInstance);
+ MeshInstance3D *mi = memnew(MeshInstance3D);
print_verbose("glTF: Creating mesh for: " + gltf_node->name);
GLTFMesh &mesh = state.meshes.write[gltf_node->mesh];
@@ -2522,12 +2522,12 @@ MeshInstance *EditorSceneImporterGLTF::_generate_mesh_instance(GLTFState &state,
return mi;
}
-Camera *EditorSceneImporterGLTF::_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
+Camera3D *EditorSceneImporterGLTF::_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
const GLTFNode *gltf_node = state.nodes[node_index];
ERR_FAIL_INDEX_V(gltf_node->camera, state.cameras.size(), nullptr);
- Camera *camera = memnew(Camera);
+ Camera3D *camera = memnew(Camera3D);
print_verbose("glTF: Creating camera for: " + gltf_node->name);
const GLTFCamera &c = state.cameras[gltf_node->camera];
@@ -2540,26 +2540,26 @@ Camera *EditorSceneImporterGLTF::_generate_camera(GLTFState &state, Node *scene_
return camera;
}
-Spatial *EditorSceneImporterGLTF::_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
+Node3D *EditorSceneImporterGLTF::_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index) {
const GLTFNode *gltf_node = state.nodes[node_index];
- Spatial *spatial = memnew(Spatial);
+ Node3D *spatial = memnew(Node3D);
print_verbose("glTF: Creating spatial for: " + gltf_node->name);
return spatial;
}
-void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene_parent, Spatial *scene_root, const GLTFNodeIndex node_index) {
+void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index) {
const GLTFNode *gltf_node = state.nodes[node_index];
- Spatial *current_node = nullptr;
+ Node3D *current_node = nullptr;
// Is our parent a skeleton
- Skeleton *active_skeleton = Object::cast_to<Skeleton>(scene_parent);
+ Skeleton3D *active_skeleton = Object::cast_to<Skeleton3D>(scene_parent);
if (gltf_node->skeleton >= 0) {
- Skeleton *skeleton = state.skeletons[gltf_node->skeleton].godot_skeleton;
+ Skeleton3D *skeleton = state.skeletons[gltf_node->skeleton].godot_skeleton;
if (active_skeleton != skeleton) {
ERR_FAIL_COND_MSG(active_skeleton != nullptr, "glTF: Generating scene detected direct parented Skeletons");
@@ -2577,7 +2577,7 @@ void EditorSceneImporterGLTF::_generate_scene_node(GLTFState &state, Node *scene
// If we have an active skeleton, and the node is node skinned, we need to create a bone attachment
if (current_node == nullptr && active_skeleton != nullptr && gltf_node->skin < 0) {
- BoneAttachment *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index);
+ BoneAttachment3D *bone_attachment = _generate_bone_attachment(state, active_skeleton, node_index);
scene_parent->add_child(bone_attachment);
bone_attachment->set_owner(scene_root);
@@ -2776,7 +2776,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
const GLTFNode *node = state.nodes[E->key()];
if (node->skeleton >= 0) {
- const Skeleton *sk = Object::cast_to<Skeleton>(state.scene_nodes.find(node_index)->get());
+ const Skeleton3D *sk = Object::cast_to<Skeleton3D>(state.scene_nodes.find(node_index)->get());
ERR_FAIL_COND(sk == nullptr);
const String path = ap->get_parent()->get_path_to(sk);
@@ -2853,7 +2853,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
xform.basis.set_quat_scale(rot, scale);
xform.origin = pos;
- const Skeleton *skeleton = state.skeletons[node->skeleton].godot_skeleton;
+ const Skeleton3D *skeleton = state.skeletons[node->skeleton].godot_skeleton;
const int bone_idx = skeleton->find_bone(node->name);
xform = skeleton->get_bone_rest(bone_idx).affine_inverse() * xform;
@@ -2922,7 +2922,7 @@ void EditorSceneImporterGLTF::_import_animation(GLTFState &state, AnimationPlaye
ap->add_animation(name, animation);
}
-void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Spatial *scene_root) {
+void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Node3D *scene_root) {
for (GLTFNodeIndex node_i = 0; node_i < state.nodes.size(); ++node_i) {
const GLTFNode *node = state.nodes[node_i];
@@ -2930,12 +2930,12 @@ void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Spatial
const GLTFSkinIndex skin_i = node->skin;
Map<GLTFNodeIndex, Node *>::Element *mi_element = state.scene_nodes.find(node_i);
- MeshInstance *mi = Object::cast_to<MeshInstance>(mi_element->get());
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(mi_element->get());
ERR_FAIL_COND(mi == nullptr);
const GLTFSkeletonIndex skel_i = state.skins[node->skin].skeleton;
const GLTFSkeleton &gltf_skeleton = state.skeletons[skel_i];
- Skeleton *skeleton = gltf_skeleton.godot_skeleton;
+ Skeleton3D *skeleton = gltf_skeleton.godot_skeleton;
ERR_FAIL_COND(skeleton == nullptr);
mi->get_parent()->remove_child(mi);
@@ -2949,9 +2949,9 @@ void EditorSceneImporterGLTF::_process_mesh_instances(GLTFState &state, Spatial
}
}
-Spatial *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_bake_fps) {
+Node3D *EditorSceneImporterGLTF::_generate_scene(GLTFState &state, const int p_bake_fps) {
- Spatial *root = memnew(Spatial);
+ Node3D *root = memnew(Node3D);
// scene_name is already unique
root->set_name(state.scene_name);
@@ -2985,19 +2985,19 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla
//text file
Error err = _parse_glb(p_path, state);
if (err)
- return NULL;
+ return nullptr;
} else {
//text file
Error err = _parse_json(p_path, state);
if (err)
- return NULL;
+ return nullptr;
}
- ERR_FAIL_COND_V(!state.json.has("asset"), NULL);
+ ERR_FAIL_COND_V(!state.json.has("asset"), nullptr);
Dictionary asset = state.json["asset"];
- ERR_FAIL_COND_V(!asset.has("version"), NULL);
+ ERR_FAIL_COND_V(!asset.has("version"), nullptr);
String version = asset["version"];
@@ -3008,83 +3008,83 @@ Node *EditorSceneImporterGLTF::import_scene(const String &p_path, uint32_t p_fla
/* STEP 0 PARSE SCENE */
Error err = _parse_scenes(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 1 PARSE NODES */
err = _parse_nodes(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 2 PARSE BUFFERS */
err = _parse_buffers(state, p_path.get_base_dir());
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 3 PARSE BUFFER VIEWS */
err = _parse_buffer_views(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 4 PARSE ACCESSORS */
err = _parse_accessors(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 5 PARSE IMAGES */
err = _parse_images(state, p_path.get_base_dir());
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 6 PARSE TEXTURES */
err = _parse_textures(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 7 PARSE TEXTURES */
err = _parse_materials(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 9 PARSE SKINS */
err = _parse_skins(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 10 DETERMINE SKELETONS */
err = _determine_skeletons(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 11 CREATE SKELETONS */
err = _create_skeletons(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 12 CREATE SKINS */
err = _create_skins(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 13 PARSE MESHES (we have enough info now) */
err = _parse_meshes(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 14 PARSE CAMERAS */
err = _parse_cameras(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 15 PARSE ANIMATIONS */
err = _parse_animations(state);
if (err != OK)
- return NULL;
+ return nullptr;
/* STEP 16 ASSIGN SCENE NAMES */
_assign_scene_names(state);
/* STEP 17 MAKE SCENE! */
- Spatial *scene = _generate_scene(state, p_bake_fps);
+ Node3D *scene = _generate_scene(state, p_bake_fps);
return scene;
}
diff --git a/editor/import/editor_scene_importer_gltf.h b/editor/import/editor_scene_importer_gltf.h
index 9f354fde2d..d127a87782 100644
--- a/editor/import/editor_scene_importer_gltf.h
+++ b/editor/import/editor_scene_importer_gltf.h
@@ -32,12 +32,12 @@
#define EDITOR_SCENE_IMPORTER_GLTF_H
#include "editor/import/resource_importer_scene.h"
-#include "scene/3d/skeleton.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/node_3d.h"
+#include "scene/3d/skeleton_3d.h"
class AnimationPlayer;
-class BoneAttachment;
-class MeshInstance;
+class BoneAttachment3D;
+class MeshInstance3D;
class EditorSceneImporterGLTF : public EditorSceneImporter {
@@ -192,7 +192,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Vector<GLTFNodeIndex> roots;
// The created Skeleton for the scene
- Skeleton *godot_skeleton;
+ Skeleton3D *godot_skeleton;
// Set of unique bone names for the skeleton
Set<String> unique_names;
@@ -395,15 +395,15 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
Error _parse_animations(GLTFState &state);
- BoneAttachment *_generate_bone_attachment(GLTFState &state, Skeleton *skeleton, const GLTFNodeIndex node_index);
- MeshInstance *_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
- Camera *_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
- Spatial *_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
+ BoneAttachment3D *_generate_bone_attachment(GLTFState &state, Skeleton3D *skeleton, const GLTFNodeIndex node_index);
+ MeshInstance3D *_generate_mesh_instance(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
+ Camera3D *_generate_camera(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
+ Node3D *_generate_spatial(GLTFState &state, Node *scene_parent, const GLTFNodeIndex node_index);
- void _generate_scene_node(GLTFState &state, Node *scene_parent, Spatial *scene_root, const GLTFNodeIndex node_index);
- Spatial *_generate_scene(GLTFState &state, const int p_bake_fps);
+ void _generate_scene_node(GLTFState &state, Node *scene_parent, Node3D *scene_root, const GLTFNodeIndex node_index);
+ Node3D *_generate_scene(GLTFState &state, const int p_bake_fps);
- void _process_mesh_instances(GLTFState &state, Spatial *scene_root);
+ void _process_mesh_instances(GLTFState &state, Node3D *scene_root);
void _assign_scene_names(GLTFState &state);
@@ -415,7 +415,7 @@ class EditorSceneImporterGLTF : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = NULL, Error *r_err = NULL);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps = nullptr, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorSceneImporterGLTF();
diff --git a/editor/import/resource_importer_bitmask.h b/editor/import/resource_importer_bitmask.h
index dd95cb687a..927fac566e 100644
--- a/editor/import/resource_importer_bitmask.h
+++ b/editor/import/resource_importer_bitmask.h
@@ -51,7 +51,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterBitMap();
~ResourceImporterBitMap();
diff --git a/editor/import/resource_importer_csv.h b/editor/import/resource_importer_csv.h
index 2030dd1f99..7aa48f68de 100644
--- a/editor/import/resource_importer_csv.h
+++ b/editor/import/resource_importer_csv.h
@@ -49,7 +49,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterCSV();
};
diff --git a/editor/import/resource_importer_csv_translation.h b/editor/import/resource_importer_csv_translation.h
index ec33d6aa16..742f6b8f60 100644
--- a/editor/import/resource_importer_csv_translation.h
+++ b/editor/import/resource_importer_csv_translation.h
@@ -49,7 +49,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterCSVTranslation();
};
diff --git a/editor/import/resource_importer_image.h b/editor/import/resource_importer_image.h
index 6ad77eec1b..abb74d0665 100644
--- a/editor/import/resource_importer_image.h
+++ b/editor/import/resource_importer_image.h
@@ -50,7 +50,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterImage();
};
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index d472070808..a4cbc81b26 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -259,7 +259,7 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
Ref<Image> image;
image.instance();
- Error err = ImageLoader::load_image(p_source_file, image, NULL, false, 1.0);
+ Error err = ImageLoader::load_image(p_source_file, image, nullptr, false, 1.0);
if (err != OK)
return err;
@@ -383,7 +383,7 @@ const char *ResourceImporterLayeredTexture::compression_formats[] = {
"etc",
"etc2",
"pvrtc",
- NULL
+ nullptr
};
String ResourceImporterLayeredTexture::get_import_settings_string() const {
@@ -438,7 +438,7 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p
return valid;
}
-ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = NULL;
+ResourceImporterLayeredTexture *ResourceImporterLayeredTexture::singleton = nullptr;
ResourceImporterLayeredTexture::ResourceImporterLayeredTexture() {
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 6a6bc89a81..40e5c9023e 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -114,7 +114,7 @@ public:
void _save_tex(const Vector<Ref<Image> > &p_images, const String &p_to_path, int p_compress_mode, Image::CompressMode p_vram_compression, bool p_mipmaps);
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
void update_imports();
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index fb1782cb65..6a6eadfa5c 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -32,8 +32,8 @@
#include "core/io/resource_saver.h"
#include "core/os/file_access.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/spatial.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/node_3d.h"
#include "scene/resources/mesh.h"
#include "scene/resources/surface_tool.h"
@@ -428,14 +428,14 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, in
if (r_err) {
*r_err = err;
}
- return NULL;
+ return nullptr;
}
- Spatial *scene = memnew(Spatial);
+ Node3D *scene = memnew(Node3D);
for (List<Ref<Mesh>>::Element *E = meshes.front(); E; E = E->next()) {
- MeshInstance *mi = memnew(MeshInstance);
+ MeshInstance3D *mi = memnew(MeshInstance3D);
mi->set_mesh(E->get());
mi->set_name(E->get()->get_name());
scene->add_child(mi);
@@ -502,7 +502,7 @@ Error ResourceImporterOBJ::import(const String &p_source_file, const String &p_s
List<Ref<Mesh>> meshes;
- Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], p_options["optimize_mesh"], p_options["scale_mesh"], p_options["offset_mesh"], NULL);
+ Error err = _parse_obj(p_source_file, meshes, true, p_options["generate_tangents"], p_options["optimize_mesh"], p_options["scale_mesh"], p_options["offset_mesh"], nullptr);
ERR_FAIL_COND_V(err != OK, err);
ERR_FAIL_COND_V(meshes.size() != 1, ERR_BUG);
diff --git a/editor/import/resource_importer_obj.h b/editor/import/resource_importer_obj.h
index 678be45106..7485e60f7b 100644
--- a/editor/import/resource_importer_obj.h
+++ b/editor/import/resource_importer_obj.h
@@ -40,7 +40,7 @@ class EditorOBJImporter : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorOBJImporter();
@@ -62,7 +62,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterOBJ();
};
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 94a6fee6b7..b5766a48a0 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -32,19 +32,19 @@
#include "core/io/resource_saver.h"
#include "editor/editor_node.h"
-#include "scene/3d/collision_shape.h"
-#include "scene/3d/mesh_instance.h"
-#include "scene/3d/navigation.h"
-#include "scene/3d/physics_body.h"
-#include "scene/3d/vehicle_body.h"
+#include "scene/3d/collision_shape_3d.h"
+#include "scene/3d/mesh_instance_3d.h"
+#include "scene/3d/navigation_3d.h"
+#include "scene/3d/physics_body_3d.h"
+#include "scene/3d/vehicle_body_3d.h"
#include "scene/animation/animation_player.h"
#include "scene/resources/animation.h"
-#include "scene/resources/box_shape.h"
+#include "scene/resources/box_shape_3d.h"
#include "scene/resources/packed_scene.h"
-#include "scene/resources/ray_shape.h"
+#include "scene/resources/ray_shape_3d.h"
#include "scene/resources/resource_format_text.h"
-#include "scene/resources/sphere_shape.h"
-#include "scene/resources/world_margin_shape.h"
+#include "scene/resources/sphere_shape_3d.h"
+#include "scene/resources/world_margin_shape_3d.h"
uint32_t EditorSceneImporter::get_import_flags() const {
@@ -72,7 +72,7 @@ Node *EditorSceneImporter::import_scene(const String &p_path, uint32_t p_flags,
return get_script_instance()->call("_import_scene", p_path, p_flags, p_bake_fps);
}
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps) {
@@ -81,7 +81,7 @@ Ref<Animation> EditorSceneImporter::import_animation(const String &p_path, uint3
return get_script_instance()->call("_import_animation", p_path, p_flags);
}
- ERR_FAIL_V(NULL);
+ ERR_FAIL_V(nullptr);
}
//for documenters, these functions are useful when an importer calls an external conversion helper (like, fbx2gltf),
@@ -276,15 +276,15 @@ static String _fixstr(const String &p_what, const String &p_str) {
return what;
}
-static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape>> &r_shape_list, bool p_convex) {
+static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape3D>> &r_shape_list, bool p_convex) {
if (!p_convex) {
- Ref<Shape> shape = mesh->create_trimesh_shape();
+ Ref<Shape3D> shape = mesh->create_trimesh_shape();
r_shape_list.push_back(shape);
} else {
- Vector<Ref<Shape>> cd = mesh->convex_decompose();
+ Vector<Ref<Shape3D>> cd = mesh->convex_decompose();
if (cd.size()) {
for (int i = 0; i < cd.size(); i++) {
r_shape_list.push_back(cd[i]);
@@ -293,7 +293,7 @@ static void _gen_shape_list(const Ref<Mesh> &mesh, List<Ref<Shape>> &r_shape_lis
}
}
-Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode) {
+Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape3D>>> &collision_map, LightBakeMode p_light_bake_mode) {
// children first
for (int i = 0; i < p_node->get_child_count(); i++) {
@@ -311,12 +311,12 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
if (!isroot && _teststr(name, "noimp")) {
memdelete(p_node);
- return NULL;
+ return nullptr;
}
- if (Object::cast_to<MeshInstance>(p_node)) {
+ if (Object::cast_to<MeshInstance3D>(p_node)) {
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<ArrayMesh> m = mi->get_mesh();
@@ -344,7 +344,7 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
if (p_light_bake_mode != LIGHT_BAKE_DISABLED) {
- mi->set_flag(GeometryInstance::FLAG_USE_BAKED_LIGHT, true);
+ mi->set_flag(GeometryInstance3D::FLAG_USE_BAKED_LIGHT, true);
}
}
@@ -377,12 +377,12 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
if (isroot)
return p_node;
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
if (mi) {
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
- List<Ref<Shape>> shapes;
+ List<Ref<Shape3D>> shapes;
String fixed_name;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
@@ -400,11 +400,11 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
fixed_name = _fixstr(name, "convcolonly");
}
- ERR_FAIL_COND_V(fixed_name == String(), NULL);
+ ERR_FAIL_COND_V(fixed_name == String(), nullptr);
if (shapes.size()) {
- StaticBody *col = memnew(StaticBody);
+ StaticBody3D *col = memnew(StaticBody3D);
col->set_transform(mi->get_transform());
col->set_name(fixed_name);
p_node->replace_by(col);
@@ -412,9 +412,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
p_node = col;
int idx = 0;
- for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) {
+ for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
- CollisionShape *cshape = memnew(CollisionShape);
+ CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
col->add_child(cshape);
@@ -427,55 +427,55 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
} else if (p_node->has_meta("empty_draw_type")) {
String empty_draw_type = String(p_node->get_meta("empty_draw_type"));
- StaticBody *sb = memnew(StaticBody);
+ StaticBody3D *sb = memnew(StaticBody3D);
sb->set_name(_fixstr(name, "colonly"));
- Object::cast_to<Spatial>(sb)->set_transform(Object::cast_to<Spatial>(p_node)->get_transform());
+ Object::cast_to<Node3D>(sb)->set_transform(Object::cast_to<Node3D>(p_node)->get_transform());
p_node->replace_by(sb);
memdelete(p_node);
- p_node = NULL;
- CollisionShape *colshape = memnew(CollisionShape);
+ p_node = nullptr;
+ CollisionShape3D *colshape = memnew(CollisionShape3D);
if (empty_draw_type == "CUBE") {
- BoxShape *boxShape = memnew(BoxShape);
+ BoxShape3D *boxShape = memnew(BoxShape3D);
boxShape->set_extents(Vector3(1, 1, 1));
colshape->set_shape(boxShape);
- colshape->set_name("BoxShape");
+ colshape->set_name("BoxShape3D");
} else if (empty_draw_type == "SINGLE_ARROW") {
- RayShape *rayShape = memnew(RayShape);
+ RayShape3D *rayShape = memnew(RayShape3D);
rayShape->set_length(1);
colshape->set_shape(rayShape);
- colshape->set_name("RayShape");
- Object::cast_to<Spatial>(sb)->rotate_x(Math_PI / 2);
+ colshape->set_name("RayShape3D");
+ Object::cast_to<Node3D>(sb)->rotate_x(Math_PI / 2);
} else if (empty_draw_type == "IMAGE") {
- WorldMarginShape *world_margin_shape = memnew(WorldMarginShape);
+ WorldMarginShape3D *world_margin_shape = memnew(WorldMarginShape3D);
colshape->set_shape(world_margin_shape);
- colshape->set_name("WorldMarginShape");
+ colshape->set_name("WorldMarginShape3D");
} else {
- SphereShape *sphereShape = memnew(SphereShape);
+ SphereShape3D *sphereShape = memnew(SphereShape3D);
sphereShape->set_radius(1);
colshape->set_shape(sphereShape);
- colshape->set_name("SphereShape");
+ colshape->set_name("SphereShape3D");
}
sb->add_child(colshape);
colshape->set_owner(sb->get_owner());
}
- } else if (_teststr(name, "rigid") && Object::cast_to<MeshInstance>(p_node)) {
+ } else if (_teststr(name, "rigid") && Object::cast_to<MeshInstance3D>(p_node)) {
if (isroot)
return p_node;
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
- List<Ref<Shape>> shapes;
+ List<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
} else {
_gen_shape_list(mesh, shapes, true);
}
- RigidBody *rigid_body = memnew(RigidBody);
+ RigidBody3D *rigid_body = memnew(RigidBody3D);
rigid_body->set_name(_fixstr(name, "rigid"));
p_node->replace_by(rigid_body);
rigid_body->set_transform(mi->get_transform());
@@ -486,9 +486,9 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
mi->set_owner(rigid_body->get_owner());
int idx = 0;
- for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) {
+ for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
- CollisionShape *cshape = memnew(CollisionShape);
+ CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
rigid_body->add_child(cshape);
@@ -498,14 +498,14 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
}
- } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<MeshInstance>(p_node)) {
+ } else if ((_teststr(name, "col") || (_teststr(name, "convcol"))) && Object::cast_to<MeshInstance3D>(p_node)) {
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<Mesh> mesh = mi->get_mesh();
if (mesh.is_valid()) {
- List<Ref<Shape>> shapes;
+ List<Ref<Shape3D>> shapes;
String fixed_name;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
@@ -530,15 +530,15 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
if (shapes.size()) {
- StaticBody *col = memnew(StaticBody);
+ StaticBody3D *col = memnew(StaticBody3D);
col->set_name("static_collision");
mi->add_child(col);
col->set_owner(mi->get_owner());
int idx = 0;
- for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) {
+ for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
- CollisionShape *cshape = memnew(CollisionShape);
+ CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
col->add_child(cshape);
@@ -550,22 +550,22 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
}
- } else if (_teststr(name, "navmesh") && Object::cast_to<MeshInstance>(p_node)) {
+ } else if (_teststr(name, "navmesh") && Object::cast_to<MeshInstance3D>(p_node)) {
if (isroot)
return p_node;
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<ArrayMesh> mesh = mi->get_mesh();
- ERR_FAIL_COND_V(mesh.is_null(), NULL);
- NavigationRegion *nmi = memnew(NavigationRegion);
+ ERR_FAIL_COND_V(mesh.is_null(), nullptr);
+ NavigationRegion3D *nmi = memnew(NavigationRegion3D);
nmi->set_name(_fixstr(name, "navmesh"));
Ref<NavigationMesh> nmesh = memnew(NavigationMesh);
nmesh->create_from_mesh(mesh);
nmi->set_navigation_mesh(nmesh);
- Object::cast_to<Spatial>(nmi)->set_transform(mi->get_transform());
+ Object::cast_to<Node3D>(nmi)->set_transform(mi->get_transform());
p_node->replace_by(nmi);
memdelete(p_node);
p_node = nmi;
@@ -575,8 +575,8 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
return p_node;
Node *owner = p_node->get_owner();
- Spatial *s = Object::cast_to<Spatial>(p_node);
- VehicleBody *bv = memnew(VehicleBody);
+ Node3D *s = Object::cast_to<Node3D>(p_node);
+ VehicleBody3D *bv = memnew(VehicleBody3D);
String n = _fixstr(p_node->get_name(), "vehicle");
bv->set_name(n);
p_node->replace_by(bv);
@@ -595,8 +595,8 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
return p_node;
Node *owner = p_node->get_owner();
- Spatial *s = Object::cast_to<Spatial>(p_node);
- VehicleWheel *bv = memnew(VehicleWheel);
+ Node3D *s = Object::cast_to<Node3D>(p_node);
+ VehicleWheel3D *bv = memnew(VehicleWheel3D);
String n = _fixstr(p_node->get_name(), "wheel");
bv->set_name(n);
p_node->replace_by(bv);
@@ -609,16 +609,16 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
p_node = bv;
- } else if (Object::cast_to<MeshInstance>(p_node)) {
+ } else if (Object::cast_to<MeshInstance3D>(p_node)) {
//last attempt, maybe collision inside the mesh data
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
Ref<ArrayMesh> mesh = mi->get_mesh();
if (!mesh.is_null()) {
- List<Ref<Shape>> shapes;
+ List<Ref<Shape3D>> shapes;
if (collision_map.has(mesh)) {
shapes = collision_map[mesh];
} else if (_teststr(mesh->get_name(), "col")) {
@@ -632,15 +632,15 @@ Node *ResourceImporterScene::_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>
}
if (shapes.size()) {
- StaticBody *col = memnew(StaticBody);
+ StaticBody3D *col = memnew(StaticBody3D);
col->set_name("static_collision");
p_node->add_child(col);
col->set_owner(p_node->get_owner());
int idx = 0;
- for (List<Ref<Shape>>::Element *E = shapes.front(); E; E = E->next()) {
+ for (List<Ref<Shape3D>>::Element *E = shapes.front(); E; E = E->next()) {
- CollisionShape *cshape = memnew(CollisionShape);
+ CollisionShape3D *cshape = memnew(CollisionShape3D);
cshape->set_shape(E->get());
col->add_child(cshape);
@@ -934,14 +934,14 @@ void ResourceImporterScene::_find_meshes(Node *p_node, Map<Ref<ArrayMesh>, Trans
List<PropertyInfo> pi;
p_node->get_property_list(&pi);
- MeshInstance *mi = Object::cast_to<MeshInstance>(p_node);
+ MeshInstance3D *mi = Object::cast_to<MeshInstance3D>(p_node);
if (mi) {
Ref<ArrayMesh> mesh = mi->get_mesh();
if (mesh.is_valid() && !meshes.has(mesh)) {
- Spatial *s = mi;
+ Node3D *s = mi;
Transform transform;
while (s) {
transform = transform * s->get_transform();
@@ -1141,7 +1141,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, int p_preset) const {
- r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "Spatial"));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_type", PROPERTY_HINT_TYPE_STRING, "Node"), "Node3D"));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/root_name"), "Scene Root"));
List<String> script_extentions;
@@ -1229,7 +1229,7 @@ Node *ResourceImporterScene::import_scene_from_other_importer(EditorSceneImporte
break;
}
- ERR_FAIL_COND_V(!importer.is_valid(), NULL);
+ ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
List<String> missing;
Error err;
@@ -1261,7 +1261,7 @@ Ref<Animation> ResourceImporterScene::import_animation_from_other_importer(Edito
break;
}
- ERR_FAIL_COND_V(!importer.is_valid(), NULL);
+ ERR_FAIL_COND_V(!importer.is_valid(), nullptr);
return importer->import_animation(p_path, p_flags, p_bake_fps);
}
@@ -1327,13 +1327,13 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
String root_type = p_options["nodes/root_type"];
root_type = root_type.split(" ")[0]; // full root_type is "ClassName (filename.gd)" for a script global class.
- Ref<Script> root_script = NULL;
+ Ref<Script> root_script = nullptr;
if (ScriptServer::is_global_class(root_type)) {
root_script = ResourceLoader::load(ScriptServer::get_global_class_path(root_type));
root_type = ScriptServer::get_global_class_base(root_type);
}
- if (root_type != "Spatial") {
+ if (root_type != "Node3D") {
Node *base_node = Object::cast_to<Node>(ClassDB::instance(root_type));
if (base_node) {
@@ -1348,9 +1348,9 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
scene->set_script(Variant(root_script));
}
- if (Object::cast_to<Spatial>(scene)) {
+ if (Object::cast_to<Node3D>(scene)) {
float root_scale = p_options["nodes/root_scale"];
- Object::cast_to<Spatial>(scene)->scale(Vector3(root_scale, root_scale, root_scale));
+ Object::cast_to<Node3D>(scene)->scale(Vector3(root_scale, root_scale, root_scale));
}
if (p_options["nodes/root_name"] != "Scene Root")
@@ -1368,7 +1368,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
float anim_optimizer_maxang = p_options["animation/optimizer/max_angle"];
int light_bake_mode = p_options["meshes/light_baking"];
- Map<Ref<Mesh>, List<Ref<Shape>>> collision_map;
+ Map<Ref<Mesh>, List<Ref<Shape3D>>> collision_map;
scene = _fix_node(scene, scene, collision_map, LightBakeMode(light_bake_mode));
@@ -1533,7 +1533,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
return OK;
}
-ResourceImporterScene *ResourceImporterScene::singleton = NULL;
+ResourceImporterScene *ResourceImporterScene::singleton = nullptr;
ResourceImporterScene::ResourceImporterScene() {
singleton = this;
@@ -1550,10 +1550,10 @@ Node *EditorSceneImporterESCN::import_scene(const String &p_path, uint32_t p_fla
Error error;
Ref<PackedScene> ps = ResourceFormatLoaderText::singleton->load(p_path, p_path, &error);
- ERR_FAIL_COND_V_MSG(!ps.is_valid(), NULL, "Cannot load scene as text resource from path '" + p_path + "'.");
+ ERR_FAIL_COND_V_MSG(!ps.is_valid(), nullptr, "Cannot load scene as text resource from path '" + p_path + "'.");
Node *scene = ps->instance();
- ERR_FAIL_COND_V(!scene, NULL);
+ ERR_FAIL_COND_V(!scene, nullptr);
return scene;
}
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 6d1043eb28..f48f181951 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -34,7 +34,7 @@
#include "core/io/resource_importer.h"
#include "scene/resources/animation.h"
#include "scene/resources/mesh.h"
-#include "scene/resources/shape.h"
+#include "scene/resources/shape_3d.h"
class Material;
@@ -66,7 +66,7 @@ public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
EditorSceneImporter() {}
@@ -147,14 +147,14 @@ public:
void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_animations, bool p_animations_as_text, bool p_keep_animations, bool p_make_materials, bool p_materials_as_text, bool p_keep_materials, bool p_make_meshes, bool p_meshes_as_text, Map<Ref<Animation>, Ref<Animation>> &p_animations, Map<Ref<Material>, Ref<Material>> &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh>> &p_meshes);
- Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape>>> &collision_map, LightBakeMode p_light_bake_mode);
+ Node *_fix_node(Node *p_node, Node *p_root, Map<Ref<Mesh>, List<Ref<Shape3D>>> &collision_map, LightBakeMode p_light_bake_mode);
void _create_clips(Node *scene, const Array &p_clips, bool p_bake_all);
void _filter_anim_tracks(Ref<Animation> anim, Set<String> &keep);
void _filter_tracks(Node *scene, const String &p_text);
void _optimize_animations(Node *scene, float p_max_lin_error, float p_max_ang_error, float p_max_angle);
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
Node *import_scene_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
Ref<Animation> import_animation_from_other_importer(EditorSceneImporter *p_exception, const String &p_path, uint32_t p_flags, int p_bake_fps);
@@ -168,7 +168,7 @@ class EditorSceneImporterESCN : public EditorSceneImporter {
public:
virtual uint32_t get_import_flags() const;
virtual void get_extensions(List<String> *r_extensions) const;
- virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = NULL);
+ virtual Node *import_scene(const String &p_path, uint32_t p_flags, int p_bake_fps, List<String> *r_missing_deps, Error *r_err = nullptr);
virtual Ref<Animation> import_animation(const String &p_path, uint32_t p_flags, int p_bake_fps);
};
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 0090d30b9c..f8ed9304b6 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -36,7 +36,7 @@
#include "editor/editor_file_system.h"
#include "editor/editor_node.h"
-void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, VS::TextureDetectRoughnessChannel p_channel) {
+void ResourceImporterTexture::_texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, RS::TextureDetectRoughnessChannel p_channel) {
MutexLock lock(singleton->mutex);
@@ -424,7 +424,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
String normal_map = p_options["roughness/src_normal"];
Ref<Image> normal_image;
- Image::RoughnessChannel roughness_channel;
+ Image::RoughnessChannel roughness_channel = Image::ROUGHNESS_CHANNEL_R;
if (mipmaps && roughness > 1 && FileAccess::exists(normal_map)) {
normal_image.instance();
@@ -434,7 +434,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
}
Ref<Image> image;
image.instance();
- Error err = ImageLoader::load_image(p_source_file, image, NULL, hdr_as_srgb, scale);
+ Error err = ImageLoader::load_image(p_source_file, image, nullptr, hdr_as_srgb, scale);
if (err != OK)
return err;
@@ -575,7 +575,7 @@ const char *ResourceImporterTexture::compression_formats[] = {
"etc",
"etc2",
"pvrtc",
- NULL
+ nullptr
};
String ResourceImporterTexture::get_import_settings_string() const {
@@ -630,7 +630,7 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
return valid;
}
-ResourceImporterTexture *ResourceImporterTexture::singleton = NULL;
+ResourceImporterTexture *ResourceImporterTexture::singleton = nullptr;
ResourceImporterTexture::ResourceImporterTexture() {
diff --git a/editor/import/resource_importer_texture.h b/editor/import/resource_importer_texture.h
index ed0fe1be89..e1c71ff1b8 100644
--- a/editor/import/resource_importer_texture.h
+++ b/editor/import/resource_importer_texture.h
@@ -35,7 +35,7 @@
#include "core/io/resource_importer.h"
#include "core/os/file_access.h"
#include "scene/resources/texture.h"
-#include "servers/visual_server.h"
+#include "servers/rendering_server.h"
class StreamTexture;
@@ -63,16 +63,16 @@ protected:
int flags;
String normal_path_for_roughness;
- VS::TextureDetectRoughnessChannel channel_for_roughness;
+ RS::TextureDetectRoughnessChannel channel_for_roughness;
MakeInfo() {
flags = 0;
- channel_for_roughness = VS::TEXTURE_DETECT_ROUGNHESS_R;
+ channel_for_roughness = RS::TEXTURE_DETECT_ROUGNHESS_R;
}
};
Map<StringName, MakeInfo> make_flags;
- static void _texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, VisualServer::TextureDetectRoughnessChannel p_channel);
+ static void _texture_reimport_roughness(const Ref<StreamTexture> &p_tex, const String &p_normal_path, RenderingServer::TextureDetectRoughnessChannel p_channel);
static void _texture_reimport_3d(const Ref<StreamTexture> &p_tex);
static void _texture_reimport_normal(const Ref<StreamTexture> &p_tex);
@@ -104,7 +104,7 @@ public:
virtual void get_import_options(List<ImportOption> *r_options, int p_preset = 0) const;
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
void update_imports();
diff --git a/editor/import/resource_importer_texture_atlas.h b/editor/import/resource_importer_texture_atlas.h
index a36cae5872..c61fa5c040 100644
--- a/editor/import/resource_importer_texture_atlas.h
+++ b/editor/import/resource_importer_texture_atlas.h
@@ -63,7 +63,7 @@ public:
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const;
virtual String get_option_group_file() const;
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
virtual Error import_group_file(const String &p_group_file, const Map<String, Map<StringName, Variant>> &p_source_file_options, const Map<String, String> &p_base_paths);
ResourceImporterTextureAtlas();
diff --git a/editor/import/resource_importer_wav.h b/editor/import/resource_importer_wav.h
index 6df5b88b13..bc2f023e6b 100644
--- a/editor/import/resource_importer_wav.h
+++ b/editor/import/resource_importer_wav.h
@@ -162,7 +162,7 @@ public:
}
}
- virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = NULL, Variant *r_metadata = NULL);
+ virtual Error import(const String &p_source_file, const String &p_save_path, const Map<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files = nullptr, Variant *r_metadata = nullptr);
ResourceImporterWAV();
};