summaryrefslogtreecommitdiff
path: root/editor/import
diff options
context:
space:
mode:
Diffstat (limited to 'editor/import')
-rw-r--r--editor/import/collada.cpp164
-rw-r--r--editor/import/editor_import_collada.cpp2
-rw-r--r--editor/import/resource_importer_layered_texture.cpp124
-rw-r--r--editor/import/resource_importer_layered_texture.h2
-rw-r--r--editor/import/resource_importer_obj.cpp27
-rw-r--r--editor/import/resource_importer_scene.cpp14
-rw-r--r--editor/import/resource_importer_scene.h18
-rw-r--r--editor/import/resource_importer_shader_file.cpp1
-rw-r--r--editor/import/resource_importer_texture.cpp130
-rw-r--r--editor/import/scene_import_settings.cpp28
10 files changed, 286 insertions, 224 deletions
diff --git a/editor/import/collada.cpp b/editor/import/collada.cpp
index fcd706627d..a8d746fde6 100644
--- a/editor/import/collada.cpp
+++ b/editor/import/collada.cpp
@@ -262,7 +262,7 @@ void Collada::_parse_asset(XMLParser &parser) {
COLLADA_PRINT("up axis: " + parser.get_node_data());
} else if (name == "unit") {
- state.unit_scale = parser.get_attribute_value("meter").to_float();
+ state.unit_scale = parser.get_named_attribute_value("meter").to_float();
COLLADA_PRINT("unit scale: " + rtos(state.unit_scale));
}
@@ -273,7 +273,7 @@ void Collada::_parse_asset(XMLParser &parser) {
}
void Collada::_parse_image(XMLParser &parser) {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
if (!(state.import_flags & IMPORT_FLAG_SCENE)) {
if (!parser.is_empty()) {
@@ -286,7 +286,7 @@ void Collada::_parse_image(XMLParser &parser) {
if (state.version < State::Version(1, 4, 0)) {
/* <1.4 */
- String path = parser.get_attribute_value("source").strip_edges();
+ String path = parser.get_named_attribute_value("source").strip_edges();
if (!path.contains("://") && path.is_relative_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().path_join(path.uri_decode()));
@@ -337,9 +337,9 @@ void Collada::_parse_material(XMLParser &parser) {
Material material;
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
if (parser.has_attribute("name")) {
- material.name = parser.get_attribute_value("name");
+ material.name = parser.get_named_attribute_value("name");
}
if (state.version < State::Version(1, 4, 0)) {
@@ -348,7 +348,7 @@ void Collada::_parse_material(XMLParser &parser) {
} 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"));
+ material.instance_effect = _uri_to_id(parser.get_named_attribute_value("url"));
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "material") {
break; //end of <asset>
}
@@ -549,7 +549,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
_parse_effect_material(parser, effect, id); // try again
} else if (parser.get_node_name() == "newparam") {
- String name = parser.get_attribute_value("sid");
+ String name = parser.get_named_attribute_value("sid");
Variant value = _parse_param(parser);
effect.params[name] = value;
COLLADA_PRINT("param: " + name + " value:" + String(value));
@@ -591,7 +591,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
}
} else if (parser.get_node_name() == "texture") {
- String sampler = parser.get_attribute_value("texture");
+ String sampler = parser.get_named_attribute_value("texture");
if (!effect.params.has(sampler)) {
ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
} else {
@@ -609,7 +609,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
} else if (what == "emission") {
effect.emission.texture = uri;
} else if (what == "bump") {
- if (parser.has_attribute("bumptype") && parser.get_attribute_value("bumptype") != "NORMALMAP") {
+ if (parser.has_attribute("bumptype") && parser.get_named_attribute_value("bumptype") != "NORMALMAP") {
WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
}
@@ -654,7 +654,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
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");
+ String sampler = parser.get_named_attribute_value("texture");
if (!effect.params.has(sampler)) {
ERR_PRINT(String("Couldn't find sampler: " + sampler + " in material:" + id).utf8().get_data());
} else {
@@ -665,7 +665,7 @@ void Collada::_parse_effect_material(XMLParser &parser, Effect &effect, String &
} else {
String uri = effect.params[surface];
- if (parser.has_attribute("bumptype") && parser.get_attribute_value("bumptype") != "NORMALMAP") {
+ if (parser.has_attribute("bumptype") && parser.get_named_attribute_value("bumptype") != "NORMALMAP") {
WARN_PRINT("'bump' texture type is not NORMALMAP, only NORMALMAP is supported.");
}
@@ -703,11 +703,11 @@ void Collada::_parse_effect(XMLParser &parser) {
return;
}
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
Effect effect;
if (parser.has_attribute("name")) {
- effect.name = parser.get_attribute_value("name");
+ effect.name = parser.get_named_attribute_value("name");
}
_parse_effect_material(parser, effect, id);
@@ -724,7 +724,7 @@ void Collada::_parse_camera(XMLParser &parser) {
return;
}
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
state.camera_data_map[id] = CameraData();
CameraData &camera = state.camera_data_map[id];
@@ -780,7 +780,7 @@ void Collada::_parse_light(XMLParser &parser) {
return;
}
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
state.light_data_map[id] = LightData();
LightData &light = state.light_data_map[id];
@@ -848,7 +848,7 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
CurveData &curvedata = state.curve_data_map[p_id];
curvedata.name = p_name;
- String closed = parser.get_attribute_value_safe("closed").to_lower();
+ String closed = parser.get_named_attribute_value_safe("closed").to_lower();
curvedata.closed = closed == "true" || closed == "1";
COLLADA_PRINT("curve name: " + p_name);
@@ -865,7 +865,7 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
String section = parser.get_node_name();
if (section == "source") {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
curvedata.sources[id] = CurveData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@@ -888,15 +888,15 @@ void Collada::_parse_curve_geometry(XMLParser &parser, String p_id, String p_nam
} 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();
+ curvedata.sources[current_source].stride = parser.get_named_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"));
+ String semantic = parser.get_named_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_named_attribute_value("source"));
curvedata.control_vertices[semantic] = source;
@@ -945,7 +945,7 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
String section = parser.get_node_name();
if (section == "source") {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
meshdata.sources[id] = MeshData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@@ -961,19 +961,19 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
} 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();
+ meshdata.sources[current_source].stride = parser.get_named_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");
+ String id = parser.get_named_attribute_value("id");
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"));
+ String semantic = parser.get_named_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_named_attribute_value("source"));
if (semantic == "TEXCOORD") {
semantic = "TEXCOORD" + itos(last_ref++);
@@ -998,22 +998,22 @@ void Collada::_parse_mesh_geometry(XMLParser &parser, String p_id, String p_name
MeshData::Primitives prim;
if (parser.has_attribute("material")) {
- prim.material = parser.get_attribute_value("material");
+ prim.material = parser.get_named_attribute_value("material");
}
- prim.count = parser.get_attribute_value("count").to_int();
+ prim.count = parser.get_named_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"));
+ String semantic = parser.get_named_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_named_attribute_value("source"));
if (semantic == "TEXCOORD") {
semantic = "TEXCOORD" + itos(last_ref++);
}
- int offset = parser.get_attribute_value("offset").to_int();
+ int offset = parser.get_named_attribute_value("offset").to_int();
MeshData::Primitives::SourceRef sref;
sref.source = source;
@@ -1074,7 +1074,7 @@ 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"));
+ skindata.base = _uri_to_id(parser.get_named_attribute_value("source"));
String current_source;
@@ -1091,7 +1091,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
COLLADA_PRINT("skeleton bind shape transform: " + skindata.bind_shape);
} else if (section == "source") {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
skindata.sources[id] = SkinControllerData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@@ -1125,7 +1125,7 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
if (skindata.sources.has(current_source)) {
int stride = 1;
if (parser.has_attribute("stride")) {
- stride = parser.get_attribute_value("stride").to_int();
+ stride = parser.get_named_attribute_value("stride").to_int();
}
skindata.sources[current_source].stride = stride;
@@ -1138,8 +1138,8 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_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"));
+ String semantic = parser.get_named_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_named_attribute_value("source"));
joint.sources[semantic] = source;
@@ -1155,15 +1155,15 @@ void Collada::_parse_skin_controller(XMLParser &parser, String p_id) {
} else if (section == "vertex_weights") {
SkinControllerData::Weights weights;
- weights.count = parser.get_attribute_value("count").to_int();
+ weights.count = parser.get_named_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"));
+ String semantic = parser.get_named_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_named_attribute_value("source"));
- int offset = parser.get_attribute_value("offset").to_int();
+ int offset = parser.get_named_attribute_value("offset").to_int();
SkinControllerData::Weights::SourceRef sref;
sref.source = source;
@@ -1228,8 +1228,8 @@ 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");
+ morphdata.mesh = _uri_to_id(parser.get_named_attribute_value("source"));
+ morphdata.mode = parser.get_named_attribute_value("method");
String current_source;
while (parser.read() == OK) {
@@ -1237,7 +1237,7 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
String section = parser.get_node_name();
if (section == "source") {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
morphdata.sources[id] = MorphControllerData::Source();
current_source = id;
COLLADA_PRINT("source data: " + id);
@@ -1261,7 +1261,7 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
if (morphdata.sources.has(current_source)) {
int stride = 1;
if (parser.has_attribute("stride")) {
- stride = parser.get_attribute_value("stride").to_int();
+ stride = parser.get_named_attribute_value("stride").to_int();
}
morphdata.sources[current_source].stride = stride;
@@ -1272,8 +1272,8 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_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"));
+ String semantic = parser.get_named_attribute_value("semantic");
+ String source = _uri_to_id(parser.get_named_attribute_value("source"));
morphdata.targets[semantic] = source;
@@ -1295,7 +1295,7 @@ void Collada::_parse_morph_controller(XMLParser &parser, String p_id) {
}
void Collada::_parse_controller(XMLParser &parser) {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
if (parser.is_empty()) {
return;
@@ -1320,7 +1320,7 @@ 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"));
+ geom->source = _uri_to_id(parser.get_named_attribute_value_safe("url"));
if (parser.is_empty()) { //nothing else to parse...
return geom;
@@ -1329,8 +1329,8 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
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"));
+ String symbol = parser.get_named_attribute_value("symbol");
+ String target = _uri_to_id(parser.get_named_attribute_value("target"));
NodeGeometry::Material mat;
mat.target = target;
@@ -1370,7 +1370,7 @@ Collada::Node *Collada::_parse_visual_instance_geometry(XMLParser &parser) {
Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &parser) {
NodeCamera *cam = memnew(NodeCamera);
- cam->camera = _uri_to_id(parser.get_attribute_value_safe("url"));
+ cam->camera = _uri_to_id(parser.get_named_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);
@@ -1391,7 +1391,7 @@ Collada::Node *Collada::_parse_visual_instance_camera(XMLParser &parser) {
Collada::Node *Collada::_parse_visual_instance_light(XMLParser &parser) {
NodeLight *cam = memnew(NodeLight);
- cam->light = _uri_to_id(parser.get_attribute_value_safe("url"));
+ cam->light = _uri_to_id(parser.get_named_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);
@@ -1437,7 +1437,7 @@ Collada::Node *Collada::_parse_visual_node_instance_data(XMLParser &parser) {
Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
String name;
- String id = parser.get_attribute_value_safe("id");
+ String id = parser.get_named_attribute_value_safe("id");
bool found_name = false;
@@ -1455,25 +1455,25 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
Node *node = nullptr;
- name = parser.has_attribute("name") ? parser.get_attribute_value_safe("name") : parser.get_attribute_value_safe("id");
+ name = parser.has_attribute("name") ? parser.get_named_attribute_value_safe("name") : parser.get_named_attribute_value_safe("id");
if (name.is_empty()) {
name = id;
} else {
found_name = true;
}
- if ((parser.has_attribute("type") && parser.get_attribute_value("type") == "JOINT") || state.idref_joints.has(name)) {
+ if ((parser.has_attribute("type") && parser.get_named_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");
+ joint->sid = parser.get_named_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");
+ joint->sid = parser.get_named_attribute_value_safe("name");
}
if (!joint->sid.is_empty()) {
@@ -1490,7 +1490,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
if (section == "translate") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
- xf.id = parser.get_attribute_value("sid");
+ xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_TRANSLATE;
@@ -1501,7 +1501,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "rotate") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
- xf.id = parser.get_attribute_value("sid");
+ xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_ROTATE;
@@ -1513,7 +1513,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "scale") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
- xf.id = parser.get_attribute_value("sid");
+ xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_SCALE;
@@ -1527,7 +1527,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "matrix") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
- xf.id = parser.get_attribute_value("sid");
+ xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_MATRIX;
@@ -1544,7 +1544,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
} else if (section == "visibility") {
Node::XForm xf;
if (parser.has_attribute("sid")) {
- xf.id = parser.get_attribute_value("sid");
+ xf.id = parser.get_named_attribute_value("sid");
}
xf.op = Node::XForm::OP_VISIBILITY;
@@ -1609,7 +1609,7 @@ Collada::Node *Collada::_parse_visual_scene_node(XMLParser &parser) {
}
void Collada::_parse_visual_scene(XMLParser &parser) {
- String id = parser.get_attribute_value("id");
+ String id = parser.get_named_attribute_value("id");
if (parser.is_empty()) {
return;
@@ -1619,7 +1619,7 @@ void Collada::_parse_visual_scene(XMLParser &parser) {
VisualScene &vscene = state.visual_scene_map[id];
if (parser.has_attribute("name")) {
- vscene.name = parser.get_attribute_value("name");
+ vscene.name = parser.get_named_attribute_value("name");
}
while (parser.read() == OK) {
@@ -1656,7 +1656,7 @@ void Collada::_parse_animation(XMLParser &parser) {
String id = "";
if (parser.has_attribute("id")) {
- id = parser.get_attribute_value("id");
+ id = parser.get_named_attribute_value("id");
}
String current_source;
@@ -1668,7 +1668,7 @@ void Collada::_parse_animation(XMLParser &parser) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
String name = parser.get_node_name();
if (name == "source") {
- current_source = parser.get_attribute_value("id");
+ current_source = parser.get_named_attribute_value("id");
source_param_names[current_source] = Vector<String>();
source_param_types[current_source] = Vector<String>();
@@ -1683,32 +1683,32 @@ void Collada::_parse_animation(XMLParser &parser) {
}
} else if (name == "accessor") {
if (!current_source.is_empty() && parser.has_attribute("stride")) {
- source_strides[current_source] = parser.get_attribute_value("stride").to_int();
+ source_strides[current_source] = parser.get_named_attribute_value("stride").to_int();
}
} else if (name == "sampler") {
- current_sampler = parser.get_attribute_value("id");
+ current_sampler = parser.get_named_attribute_value("id");
samplers[current_sampler] = HashMap<String, String>();
} else if (name == "param") {
if (parser.has_attribute("name")) {
- source_param_names[current_source].push_back(parser.get_attribute_value("name"));
+ source_param_names[current_source].push_back(parser.get_named_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"));
+ source_param_types[current_source].push_back(parser.get_named_attribute_value("type"));
} else {
source_param_types[current_source].push_back("");
}
} else if (name == "input") {
if (!current_sampler.is_empty()) {
- samplers[current_sampler][parser.get_attribute_value("semantic")] = parser.get_attribute_value("source");
+ samplers[current_sampler][parser.get_named_attribute_value("semantic")] = parser.get_named_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"));
+ channel_sources.push_back(parser.get_named_attribute_value("source"));
+ channel_targets.push_back(parser.get_named_attribute_value("target"));
}
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "animation") {
@@ -1857,22 +1857,22 @@ void Collada::_parse_animation_clip(XMLParser &parser) {
AnimationClip clip;
if (parser.has_attribute("name")) {
- clip.name = parser.get_attribute_value("name");
+ clip.name = parser.get_named_attribute_value("name");
} else if (parser.has_attribute("id")) {
- clip.name = parser.get_attribute_value("id");
+ clip.name = parser.get_named_attribute_value("id");
}
if (parser.has_attribute("start")) {
- clip.begin = parser.get_attribute_value("start").to_float();
+ clip.begin = parser.get_named_attribute_value("start").to_float();
}
if (parser.has_attribute("end")) {
- clip.end = parser.get_attribute_value("end").to_float();
+ clip.end = parser.get_named_attribute_value("end").to_float();
}
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"));
+ String url = _uri_to_id(parser.get_named_attribute_value("url"));
clip.tracks.push_back(url);
}
@@ -1894,9 +1894,9 @@ void Collada::_parse_scene(XMLParser &parser) {
String name = parser.get_node_name();
if (name == "instance_visual_scene") {
- state.root_visual_scene = _uri_to_id(parser.get_attribute_value("url"));
+ state.root_visual_scene = _uri_to_id(parser.get_named_attribute_value("url"));
} else if (name == "instance_physics_scene") {
- state.root_physics_scene = _uri_to_id(parser.get_attribute_value("url"));
+ state.root_physics_scene = _uri_to_id(parser.get_named_attribute_value("url"));
}
} else if (parser.get_node_type() == XMLParser::NODE_ELEMENT_END && parser.get_node_name() == "scene") {
@@ -1925,8 +1925,8 @@ void Collada::_parse_library(XMLParser &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");
+ String id = parser.get_named_attribute_value("id");
+ String name2 = parser.get_named_attribute_value_safe("name");
while (parser.read() == OK) {
if (parser.get_node_type() == XMLParser::NODE_ELEMENT) {
if (parser.get_node_name() == "mesh") {
@@ -2346,7 +2346,7 @@ Error Collada::load(const String &p_path, int p_flags) {
{
//version
- String version = parser.get_attribute_value("version");
+ String version = parser.get_named_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();
diff --git a/editor/import/editor_import_collada.cpp b/editor/import/editor_import_collada.cpp
index 4b0ece3367..1ffede6502 100644
--- a/editor/import/editor_import_collada.cpp
+++ b/editor/import/editor_import_collada.cpp
@@ -734,7 +734,7 @@ Error ColladaImport::_create_mesh_surfaces(bool p_optimize, Ref<ImporterMesh> &p
/* CREATE PRIMITIVE ARRAY */
/**************************/
- // The way collada uses indices is more optimal, and friendlier with 3D modelling software,
+ // The way collada uses indices is more optimal, and friendlier with 3D modeling software,
// because it can index everything, not only vertices (similar to how the WII works).
// This is, however, more incompatible with standard video cards, so arrays must be converted.
// Must convert to GL/DX format.
diff --git a/editor/import/resource_importer_layered_texture.cpp b/editor/import/resource_importer_layered_texture.cpp
index bc4ced7ea2..10a0c2662f 100644
--- a/editor/import/resource_importer_layered_texture.cpp
+++ b/editor/import/resource_importer_layered_texture.cpp
@@ -123,6 +123,9 @@ bool ResourceImporterLayeredTexture::get_option_visibility(const String &p_path,
if (p_option == "compress/lossy_quality" && p_options.has("compress/mode")) {
return int(p_options["compress/mode"]) == COMPRESS_LOSSY;
}
+ if ((p_option == "compress/high_quality" || p_option == "compress/hdr_compression") && p_options.has("compress/mode")) {
+ return int(p_options["compress/mode"]) == COMPRESS_VRAM_COMPRESSED;
+ }
return true;
}
@@ -136,9 +139,9 @@ String ResourceImporterLayeredTexture::get_preset_name(int p_idx) const {
void ResourceImporterLayeredTexture::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), 1));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/high_quality"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized,Normal Map (RG Channels)"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "mipmaps/limit", PROPERTY_HINT_RANGE, "-1,256"), -1));
@@ -283,8 +286,8 @@ void ResourceImporterLayeredTexture::_save_tex(Vector<Ref<Image>> p_images, cons
Error ResourceImporterLayeredTexture::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
int compress_mode = p_options["compress/mode"];
float lossy = p_options["compress/lossy_quality"];
+ float high_quality = p_options["compress/high_quality"];
int hdr_compression = p_options["compress/hdr_compression"];
- int bptc_ldr = p_options["compress/bptc_ldr"];
bool mipmaps = p_options["mipmaps/generate"];
int channel_pack = p_options["compress/channel_pack"];
@@ -389,9 +392,10 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
texture_import->compress_mode = compress_mode;
texture_import->lossy = lossy;
texture_import->hdr_compression = hdr_compression;
- texture_import->bptc_ldr = bptc_ldr;
texture_import->mipmaps = mipmaps;
texture_import->used_channels = used_channels;
+ texture_import->high_quality = high_quality;
+
_check_compress_ctex(p_source_file, texture_import);
if (r_metadata) {
Dictionary meta;
@@ -406,12 +410,11 @@ Error ResourceImporterLayeredTexture::import(const String &p_source_file, const
}
const char *ResourceImporterLayeredTexture::compression_formats[] = {
- "bptc",
- "s3tc",
- "etc",
- "etc2",
+ "s3tc_bptc",
+ "etc2_astc",
nullptr
};
+
String ResourceImporterLayeredTexture::get_import_settings_string() const {
String s;
@@ -450,12 +453,16 @@ bool ResourceImporterLayeredTexture::are_import_settings_valid(const String &p_p
bool valid = true;
while (compression_formats[index]) {
String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
- bool test = GLOBAL_GET(setting_path);
- if (test) {
- if (!formats_imported.has(compression_formats[index])) {
- valid = false;
- break;
+ if (ProjectSettings::get_singleton()->has_setting(setting_path)) {
+ bool test = GLOBAL_GET(setting_path);
+ if (test) {
+ if (!formats_imported.has(compression_formats[index])) {
+ valid = false;
+ break;
+ }
}
+ } else {
+ WARN_PRINT("Setting for imported format not found: " + setting_path);
}
index++;
}
@@ -484,64 +491,83 @@ void ResourceImporterLayeredTexture::_check_compress_ctex(const String &p_source
// Must import in all formats, in order of priority (so platform choses the best supported one. IE, etc2 over etc).
// Android, GLES 2.x
- bool can_bptc = GLOBAL_GET("rendering/textures/vram_compression/import_bptc");
- if (can_bptc) {
- r_texture_import->formats_imported.push_back("bptc"); // BPTC needs to be added anyway.
+ const bool can_s3tc_bptc = GLOBAL_GET("rendering/textures/vram_compression/import_s3tc_bptc") || OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_S3TC_BPTC;
+ const bool can_etc2_astc = GLOBAL_GET("rendering/textures/vram_compression/import_etc2_astc") || OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_ETC2_ASTC;
+
+ // Add list of formats imported
+ if (can_s3tc_bptc) {
+ r_texture_import->formats_imported.push_back("s3tc_bptc");
}
+ if (can_etc2_astc) {
+ r_texture_import->formats_imported.push_back("etc2_astc");
+ }
+
bool can_compress_hdr = r_texture_import->hdr_compression > 0;
ERR_FAIL_NULL(r_texture_import->image);
bool is_hdr = (r_texture_import->image->get_format() >= Image::FORMAT_RF && r_texture_import->image->get_format() <= Image::FORMAT_RGBE9995);
- bool is_ldr = (r_texture_import->image->get_format() >= Image::FORMAT_L8 && r_texture_import->image->get_format() <= Image::FORMAT_RGB565);
- bool can_s3tc = GLOBAL_GET("rendering/textures/vram_compression/import_s3tc");
ERR_FAIL_NULL(r_texture_import->slices);
// Can compress hdr, but hdr with alpha is not compressible.
- if (r_texture_import->hdr_compression == 2) {
- // The user selected to compress hdr anyway, so force an alpha-less format.
- if (r_texture_import->image->get_format() == Image::FORMAT_RGBAF) {
- for (int i = 0; i < r_texture_import->slices->size(); i++) {
- r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBF);
- }
+ bool use_uncompressed = false;
+
+ if (is_hdr) {
+ if (r_texture_import->used_channels == Image::USED_CHANNELS_LA || r_texture_import->used_channels == Image::USED_CHANNELS_RGBA) {
+ if (r_texture_import->hdr_compression == 2) {
+ // The user selected to compress hdr anyway, so force an alpha-less format.
+ if (r_texture_import->image->get_format() == Image::FORMAT_RGBAF) {
+ for (int i = 0; i < r_texture_import->slices->size(); i++) {
+ r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBF);
+ }
- } else if (r_texture_import->image->get_format() == Image::FORMAT_RGBAH) {
- for (int i = 0; i < r_texture_import->slices->size(); i++) {
- r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBH);
+ } else if (r_texture_import->image->get_format() == Image::FORMAT_RGBAH) {
+ for (int i = 0; i < r_texture_import->slices->size(); i++) {
+ r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBH);
+ }
+ }
+ } else {
+ can_compress_hdr = false;
}
}
- } else {
- can_compress_hdr = false;
- }
- if (is_hdr && can_compress_hdr) {
- if (!can_bptc) {
+ if (!can_compress_hdr) {
//default to rgbe
if (r_texture_import->image->get_format() != Image::FORMAT_RGBE9995) {
for (int i = 0; i < r_texture_import->slices->size(); i++) {
r_texture_import->slices->write[i]->convert(Image::FORMAT_RGBE9995);
}
}
+ use_uncompressed = true;
}
- } else {
- can_bptc = false;
}
- if (is_ldr && can_bptc) {
- if (r_texture_import->bptc_ldr == 0 || (r_texture_import->bptc_ldr == 1 && !(r_texture_import->used_channels == Image::USED_CHANNELS_LA || r_texture_import->used_channels == Image::USED_CHANNELS_RGBA))) {
- can_bptc = false;
- }
- }
- if (!(r_texture_import->used_channels == Image::USED_CHANNELS_LA || r_texture_import->used_channels == Image::USED_CHANNELS_RGBA)) {
- if (GLOBAL_GET("rendering/textures/vram_compression/import_etc2")) {
- _save_tex(*r_texture_import->slices, r_texture_import->save_path + ".etc2." + extension, r_texture_import->compress_mode, r_texture_import->lossy, Image::COMPRESS_ETC2, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
- r_texture_import->platform_variants->push_back("etc2");
- r_texture_import->formats_imported.push_back("etc2");
+ if (use_uncompressed) {
+ _save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + extension, COMPRESS_VRAM_UNCOMPRESSED, r_texture_import->lossy, Image::COMPRESS_S3TC /* IGNORED */, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
+ } else {
+ if (can_s3tc_bptc) {
+ Image::CompressMode image_compress_mode;
+ String image_compress_format;
+ if (r_texture_import->high_quality || is_hdr) {
+ image_compress_mode = Image::COMPRESS_BPTC;
+ image_compress_format = "bptc";
+ } else {
+ image_compress_mode = Image::COMPRESS_S3TC;
+ image_compress_format = "s3tc";
+ }
+ _save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
+ r_texture_import->platform_variants->push_back(image_compress_format);
}
- if (can_bptc || can_s3tc) {
- _save_tex(*r_texture_import->slices, r_texture_import->save_path + ".s3tc." + extension, r_texture_import->compress_mode, r_texture_import->lossy, can_bptc ? Image::COMPRESS_BPTC : Image::COMPRESS_S3TC, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, false);
- r_texture_import->platform_variants->push_back("s3tc");
- r_texture_import->formats_imported.push_back("s3tc");
+ if (can_etc2_astc) {
+ Image::CompressMode image_compress_mode;
+ String image_compress_format;
+ if (r_texture_import->high_quality || is_hdr) {
+ image_compress_mode = Image::COMPRESS_ASTC;
+ image_compress_format = "astc";
+ } else {
+ image_compress_mode = Image::COMPRESS_ETC2;
+ image_compress_format = "etc2";
+ }
+ _save_tex(*r_texture_import->slices, r_texture_import->save_path + "." + image_compress_format + "." + extension, r_texture_import->compress_mode, r_texture_import->lossy, image_compress_mode, *r_texture_import->csource, r_texture_import->used_channels, r_texture_import->mipmaps, true);
+ r_texture_import->platform_variants->push_back(image_compress_format);
}
- return;
}
- EditorNode::add_io_error(vformat(TTR("%s: No suitable PC VRAM compression algorithm enabled in Project Settings (S3TC or BPTC). This texture may not display correctly on desktop platforms."), p_source_file));
}
diff --git a/editor/import/resource_importer_layered_texture.h b/editor/import/resource_importer_layered_texture.h
index 5118ad7ba4..52fd37639d 100644
--- a/editor/import/resource_importer_layered_texture.h
+++ b/editor/import/resource_importer_layered_texture.h
@@ -51,8 +51,8 @@ public:
int compress_mode = 0;
float lossy = 1.0;
int hdr_compression = 0;
- int bptc_ldr = 0;
bool mipmaps = true;
+ bool high_quality = false;
Image::UsedChannels used_channels = Image::USED_CHANNELS_RGBA;
virtual ~LayeredTextureImport() {}
};
diff --git a/editor/import/resource_importer_obj.cpp b/editor/import/resource_importer_obj.cpp
index f1fd1d5a03..3dd01754a3 100644
--- a/editor/import/resource_importer_obj.cpp
+++ b/editor/import/resource_importer_obj.cpp
@@ -206,6 +206,20 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
Ref<FileAccess> f = FileAccess::open(p_path, FileAccess::READ);
ERR_FAIL_COND_V_MSG(f.is_null(), ERR_CANT_OPEN, vformat("Couldn't open OBJ file '%s', it may not exist or not be readable.", p_path));
+ // Avoid trying to load/interpret potential build artifacts from Visual Studio (e.g. when compiling native plugins inside the project tree)
+ // This should only match, if it's indeed a COFF file header
+ // https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#machine-types
+ const int first_bytes = f->get_16();
+ static const Vector<int> coff_header_machines{
+ 0x0, // IMAGE_FILE_MACHINE_UNKNOWN
+ 0x8664, // IMAGE_FILE_MACHINE_AMD64
+ 0x1c0, // IMAGE_FILE_MACHINE_ARM
+ 0x14c, // IMAGE_FILE_MACHINE_I386
+ 0x200, // IMAGE_FILE_MACHINE_IA64
+ };
+ ERR_FAIL_COND_V_MSG(coff_header_machines.find(first_bytes) != -1, ERR_FILE_CORRUPT, vformat("Couldn't read OBJ file '%s', it seems to be binary, corrupted, or empty.", p_path));
+ f->seek(0);
+
Ref<ArrayMesh> mesh;
mesh.instantiate();
@@ -218,7 +232,8 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
Vector<Vector3> normals;
Vector<Vector2> uvs;
Vector<Color> colors;
- String name;
+ const String default_name = "Mesh";
+ String name = default_name;
HashMap<String, HashMap<String, Ref<StandardMaterial3D>>> material_map;
@@ -395,9 +410,12 @@ static Error _parse_obj(const String &p_path, List<Ref<Mesh>> &r_meshes, bool p_
if (l.begins_with("o ") || f->eof_reached()) {
if (!p_single_mesh) {
- mesh->set_name(name);
- r_meshes.push_back(mesh);
- mesh.instantiate();
+ if (mesh->get_surface_count() > 0) {
+ mesh->set_name(name);
+ r_meshes.push_back(mesh);
+ mesh.instantiate();
+ }
+ name = default_name;
current_group = "";
current_material = "";
}
@@ -460,6 +478,7 @@ Node *EditorOBJImporter::import_scene(const String &p_path, uint32_t p_flags, co
for (const Ref<Mesh> &m : meshes) {
Ref<ImporterMesh> mesh;
mesh.instantiate();
+ mesh->set_name(m->get_name());
for (int i = 0; i < m->get_surface_count(); i++) {
mesh->add_surface(m->surface_get_primitive_type(i), m->surface_get_arrays(i), Array(), Dictionary(), m->surface_get_material(i));
}
diff --git a/editor/import/resource_importer_scene.cpp b/editor/import/resource_importer_scene.cpp
index 102fa903b8..6c6c89bcc0 100644
--- a/editor/import/resource_importer_scene.cpp
+++ b/editor/import/resource_importer_scene.cpp
@@ -1085,10 +1085,10 @@ Node *ResourceImporterScene::_post_fix_animations(Node *p_node, Node *p_root, co
return p_node;
}
-Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps) {
+Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps, float p_applied_root_scale) {
// children first
for (int i = 0; i < p_node->get_child_count(); i++) {
- Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps);
+ Node *r = _post_fix_node(p_node->get_child(i), p_root, collision_map, r_occluder_arrays, r_scanned_meshes, p_node_data, p_material_data, p_animation_data, p_animation_fps, p_applied_root_scale);
if (!r) {
i--; //was erased
}
@@ -1231,7 +1231,8 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
} else {
shapes = get_collision_shapes(
m->get_mesh(),
- node_settings);
+ node_settings,
+ p_applied_root_scale);
}
if (shapes.size()) {
@@ -1242,6 +1243,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
p_node->add_child(col, true);
col->set_owner(p_node->get_owner());
col->set_transform(get_collision_shapes_transform(node_settings));
+ col->set_position(p_applied_root_scale * col->get_position());
base = col;
} break;
case MESH_PHYSICS_RIGID_BODY_AND_MESH: {
@@ -1249,6 +1251,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
rigid_body->set_name(p_node->get_name());
p_node->replace_by(rigid_body);
rigid_body->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
+ rigid_body->set_position(p_applied_root_scale * rigid_body->get_position());
p_node = rigid_body;
mi->set_transform(Transform3D());
rigid_body->add_child(mi, true);
@@ -1258,6 +1261,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
case MESH_PHYSICS_STATIC_COLLIDER_ONLY: {
StaticBody3D *col = memnew(StaticBody3D);
col->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
+ col->set_position(p_applied_root_scale * col->get_position());
col->set_name(p_node->get_name());
p_node->replace_by(col);
memdelete(p_node);
@@ -1267,6 +1271,7 @@ Node *ResourceImporterScene::_post_fix_node(Node *p_node, Node *p_root, HashMap<
case MESH_PHYSICS_AREA_ONLY: {
Area3D *area = memnew(Area3D);
area->set_transform(mi->get_transform() * get_collision_shapes_transform(node_settings));
+ area->set_position(p_applied_root_scale * area->get_position());
area->set_name(p_node->get_name());
p_node->replace_by(area);
memdelete(p_node);
@@ -1865,6 +1870,7 @@ void ResourceImporterScene::get_import_options(const String &p_path, List<Import
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 30));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/trimming"), false));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/remove_immutable_tracks"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "import_script/path", PROPERTY_HINT_FILE, script_ext_hint), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::DICTIONARY, "_subresources", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_NO_EDITOR), Dictionary()));
@@ -2397,7 +2403,7 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
fps = (float)p_options[SNAME("animation/fps")];
}
_pre_fix_animations(scene, scene, node_data, animation_data, fps);
- _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps);
+ _post_fix_node(scene, scene, collision_map, occluder_arrays, scanned_meshes, node_data, material_data, animation_data, fps, apply_root ? root_scale : 1.0);
_post_fix_animations(scene, scene, node_data, animation_data, fps);
String root_type = p_options["nodes/root_type"];
diff --git a/editor/import/resource_importer_scene.h b/editor/import/resource_importer_scene.h
index 2d08d4df50..aa057d3404 100644
--- a/editor/import/resource_importer_scene.h
+++ b/editor/import/resource_importer_scene.h
@@ -279,7 +279,7 @@ public:
Node *_pre_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &r_collision_map, Pair<PackedVector3Array, PackedInt32Array> *r_occluder_arrays, List<Pair<NodePath, Node *>> &r_node_renames);
Node *_pre_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps);
- Node *_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps);
+ Node *_post_fix_node(Node *p_node, Node *p_root, HashMap<Ref<ImporterMesh>, Vector<Ref<Shape3D>>> &collision_map, Pair<PackedVector3Array, PackedInt32Array> &r_occluder_arrays, HashSet<Ref<ImporterMesh>> &r_scanned_meshes, const Dictionary &p_node_data, const Dictionary &p_material_data, const Dictionary &p_animation_data, float p_animation_fps, float p_applied_root_scale);
Node *_post_fix_animations(Node *p_node, Node *p_root, const Dictionary &p_node_data, const Dictionary &p_animation_data, float p_animation_fps);
Ref<Animation> _save_animation_to_file(Ref<Animation> anim, bool p_save_to_file, String p_save_to_path, bool p_keep_custom_tracks);
@@ -298,7 +298,7 @@ public:
ResourceImporterScene(bool p_animation_import = false);
template <class M>
- static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options);
+ static Vector<Ref<Shape3D>> get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options, float p_applied_root_scale);
template <class M>
static Transform3D get_collision_shapes_transform(const M &p_options);
@@ -314,7 +314,7 @@ public:
};
template <class M>
-Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options) {
+Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh> &p_mesh, const M &p_options, float p_applied_root_scale) {
ShapeType generate_shape_type = SHAPE_TYPE_DECOMPOSE_CONVEX;
if (p_options.has(SNAME("physics/shape_type"))) {
generate_shape_type = (ShapeType)p_options[SNAME("physics/shape_type")].operator int();
@@ -409,7 +409,7 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh>
Ref<BoxShape3D> box;
box.instantiate();
if (p_options.has(SNAME("primitive/size"))) {
- box->set_size(p_options[SNAME("primitive/size")]);
+ box->set_size(p_options[SNAME("primitive/size")].operator Vector3() * p_applied_root_scale);
}
Vector<Ref<Shape3D>> shapes;
@@ -420,7 +420,7 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh>
Ref<SphereShape3D> sphere;
sphere.instantiate();
if (p_options.has(SNAME("primitive/radius"))) {
- sphere->set_radius(p_options[SNAME("primitive/radius")]);
+ sphere->set_radius(p_options[SNAME("primitive/radius")].operator float() * p_applied_root_scale);
}
Vector<Ref<Shape3D>> shapes;
@@ -430,10 +430,10 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh>
Ref<CylinderShape3D> cylinder;
cylinder.instantiate();
if (p_options.has(SNAME("primitive/height"))) {
- cylinder->set_height(p_options[SNAME("primitive/height")]);
+ cylinder->set_height(p_options[SNAME("primitive/height")].operator float() * p_applied_root_scale);
}
if (p_options.has(SNAME("primitive/radius"))) {
- cylinder->set_radius(p_options[SNAME("primitive/radius")]);
+ cylinder->set_radius(p_options[SNAME("primitive/radius")].operator float() * p_applied_root_scale);
}
Vector<Ref<Shape3D>> shapes;
@@ -443,10 +443,10 @@ Vector<Ref<Shape3D>> ResourceImporterScene::get_collision_shapes(const Ref<Mesh>
Ref<CapsuleShape3D> capsule;
capsule.instantiate();
if (p_options.has(SNAME("primitive/height"))) {
- capsule->set_height(p_options[SNAME("primitive/height")]);
+ capsule->set_height(p_options[SNAME("primitive/height")].operator float() * p_applied_root_scale);
}
if (p_options.has(SNAME("primitive/radius"))) {
- capsule->set_radius(p_options[SNAME("primitive/radius")]);
+ capsule->set_radius(p_options[SNAME("primitive/radius")].operator float() * p_applied_root_scale);
}
Vector<Ref<Shape3D>> shapes;
diff --git a/editor/import/resource_importer_shader_file.cpp b/editor/import/resource_importer_shader_file.cpp
index 7187e85df0..ba48fc9029 100644
--- a/editor/import/resource_importer_shader_file.cpp
+++ b/editor/import/resource_importer_shader_file.cpp
@@ -91,6 +91,7 @@ static String _include_function(const String &p_path, void *userpointer) {
Error ResourceImporterShaderFile::import(const String &p_source_file, const String &p_save_path, const HashMap<StringName, Variant> &p_options, List<String> *r_platform_variants, List<String> *r_gen_files, Variant *r_metadata) {
/* STEP 1, Read shader code */
+ ERR_FAIL_COND_V_EDMSG((OS::get_singleton()->get_current_rendering_method() == "gl_compatibility"), ERR_UNAVAILABLE, "Cannot import custom .glsl shaders when using the gl_compatibility rendering_method. Please switch to the forward_plus or mobile rendering methods to use custom shaders.");
Error err;
Ref<FileAccess> file = FileAccess::open(p_source_file, FileAccess::READ, &err);
diff --git a/editor/import/resource_importer_texture.cpp b/editor/import/resource_importer_texture.cpp
index 2f543ea02d..c05e7582eb 100644
--- a/editor/import/resource_importer_texture.cpp
+++ b/editor/import/resource_importer_texture.cpp
@@ -169,9 +169,14 @@ String ResourceImporterTexture::get_resource_type() const {
}
bool ResourceImporterTexture::get_option_visibility(const String &p_path, const String &p_option, const HashMap<StringName, Variant> &p_options) const {
- if (p_option == "compress/lossy_quality") {
+ if (p_option == "compress/high_quality" || p_option == "compress/hdr_compression") {
int compress_mode = int(p_options["compress/mode"]);
- if (compress_mode != COMPRESS_LOSSY && compress_mode != COMPRESS_VRAM_COMPRESSED) {
+ if (compress_mode != COMPRESS_VRAM_COMPRESSED) {
+ return false;
+ }
+ } else if (p_option == "compress/lossy_quality") {
+ int compress_mode = int(p_options["compress/mode"]);
+ if (compress_mode != COMPRESS_LOSSY) {
return false;
}
} else if (p_option == "compress/hdr_mode") {
@@ -186,15 +191,6 @@ bool ResourceImporterTexture::get_option_visibility(const String &p_path, const
}
} else if (p_option == "mipmaps/limit") {
return p_options["mipmaps/generate"];
-
- } else if (p_option == "compress/bptc_ldr") {
- int compress_mode = int(p_options["compress/mode"]);
- if (compress_mode < COMPRESS_VRAM_COMPRESSED) {
- return false;
- }
- if (!GLOBAL_GET("rendering/textures/vram_compression/import_bptc")) {
- return false;
- }
}
return true;
@@ -216,9 +212,9 @@ String ResourceImporterTexture::get_preset_name(int p_idx) const {
void ResourceImporterTexture::get_import_options(const String &p_path, List<ImportOption> *r_options, int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/mode", PROPERTY_HINT_ENUM, "Lossless,Lossy,VRAM Compressed,VRAM Uncompressed,Basis Universal", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), p_preset == PRESET_3D ? 2 : 0));
+ r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "compress/high_quality"), false));
r_options->push_back(ImportOption(PropertyInfo(Variant::FLOAT, "compress/lossy_quality", PROPERTY_HINT_RANGE, "0,1,0.01"), 0.7));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/hdr_compression", PROPERTY_HINT_ENUM, "Disabled,Opaque Only,Always"), 1));
- r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/bptc_ldr", PROPERTY_HINT_ENUM, "Disabled,Enabled,RGBA Only"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/normal_map", PROPERTY_HINT_ENUM, "Detect,Enable,Disabled"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "compress/channel_pack", PROPERTY_HINT_ENUM, "sRGB Friendly,Optimized"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "mipmaps/generate"), (p_preset == PRESET_3D ? true : false)));
@@ -289,7 +285,7 @@ void ResourceImporterTexture::save_to_ctex_format(Ref<FileAccess> f, const Ref<I
case COMPRESS_VRAM_COMPRESSED: {
Ref<Image> image = p_image->duplicate();
- image->compress_from_channels(p_compress_format, p_channels, p_lossy_quality);
+ image->compress_from_channels(p_compress_format, p_channels);
f->store_32(CompressedTexture2D::DATA_FORMAT_IMAGE);
f->store_16(image->get_width());
@@ -322,15 +318,11 @@ void ResourceImporterTexture::save_to_ctex_format(Ref<FileAccess> f, const Ref<I
f->store_16(p_image->get_height());
f->store_32(p_image->get_mipmap_count());
f->store_32(p_image->get_format());
-
- for (int i = 0; i < p_image->get_mipmap_count() + 1; i++) {
- Vector<uint8_t> data = Image::basis_universal_packer(p_image->get_image_from_mipmap(i), p_channels);
- int data_len = data.size();
- f->store_32(data_len);
-
- const uint8_t *r = data.ptr();
- f->store_buffer(r, data_len);
- }
+ Vector<uint8_t> data = Image::basis_universal_packer(p_image, p_channels);
+ int data_len = data.size();
+ f->store_32(data_len);
+ const uint8_t *r = data.ptr();
+ f->store_buffer(r, data_len);
} break;
}
}
@@ -387,7 +379,7 @@ void ResourceImporterTexture::_save_ctex(const Ref<Image> &p_image, const String
Ref<Image> image = p_image->duplicate();
- if (((p_compress_mode == COMPRESS_BASIS_UNIVERSAL) || (p_compress_mode == COMPRESS_VRAM_COMPRESSED && p_force_po2_for_compressed)) && p_mipmaps) {
+ if (p_force_po2_for_compressed && p_mipmaps && ((p_compress_mode == COMPRESS_BASIS_UNIVERSAL) || (p_compress_mode == COMPRESS_VRAM_COMPRESSED))) {
image->resize_to_po2();
}
@@ -425,7 +417,7 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
const int pack_channels = p_options["compress/channel_pack"];
const int normal = p_options["compress/normal_map"];
const int hdr_compression = p_options["compress/hdr_compression"];
- const int bptc_ldr = p_options["compress/bptc_ldr"];
+ const int high_quality = p_options["compress/high_quality"];
// Mipmaps.
const bool mipmaps = p_options["mipmaps/generate"];
@@ -598,19 +590,22 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
// Android, GLES 2.x
const bool is_hdr = (image->get_format() >= Image::FORMAT_RF && image->get_format() <= Image::FORMAT_RGBE9995);
- bool is_ldr = (image->get_format() >= Image::FORMAT_L8 && image->get_format() <= Image::FORMAT_RGB565);
- const bool can_bptc = GLOBAL_GET("rendering/textures/vram_compression/import_bptc");
- const bool can_s3tc = GLOBAL_GET("rendering/textures/vram_compression/import_s3tc");
+ const bool can_s3tc_bptc = GLOBAL_GET("rendering/textures/vram_compression/import_s3tc_bptc") || OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_S3TC_BPTC;
+ const bool can_etc2_astc = GLOBAL_GET("rendering/textures/vram_compression/import_etc2_astc") || OS::get_singleton()->get_preferred_texture_format() == OS::PREFERRED_TEXTURE_FORMAT_ETC2_ASTC;
- if (can_bptc) {
- // Add to the list anyway.
- formats_imported.push_back("bptc");
+ // Add list of formats imported
+ if (can_s3tc_bptc) {
+ formats_imported.push_back("s3tc_bptc");
+ }
+ if (can_etc2_astc) {
+ formats_imported.push_back("etc2_astc");
}
bool can_compress_hdr = hdr_compression > 0;
bool has_alpha = image->detect_alpha() != Image::ALPHA_NONE;
+ bool use_uncompressed = false;
- if (is_hdr && can_compress_hdr) {
+ if (is_hdr) {
if (has_alpha) {
// Can compress HDR, but HDR with alpha is not compressible.
if (hdr_compression == 2) {
@@ -629,36 +624,41 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
// Fallback to RGBE99995.
if (image->get_format() != Image::FORMAT_RGBE9995) {
image->convert(Image::FORMAT_RGBE9995);
+ use_uncompressed = true;
}
}
}
- bool ok_on_pc = false;
- if (can_bptc || can_s3tc) {
- ok_on_pc = true;
- Image::CompressMode image_compress_mode = Image::COMPRESS_BPTC;
- if (!bptc_ldr && can_s3tc && is_ldr) {
- image_compress_mode = Image::COMPRESS_S3TC;
+ if (use_uncompressed) {
+ _save_ctex(image, p_save_path + ".ctex", COMPRESS_VRAM_UNCOMPRESSED, lossy, Image::COMPRESS_S3TC /*this is ignored */, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
+ } else {
+ if (can_s3tc_bptc) {
+ Image::CompressMode image_compress_mode;
+ String image_compress_format;
+ if (high_quality || is_hdr) {
+ image_compress_mode = Image::COMPRESS_BPTC;
+ image_compress_format = "bptc";
+ } else {
+ image_compress_mode = Image::COMPRESS_S3TC;
+ image_compress_format = "s3tc";
+ }
+ _save_ctex(image, p_save_path + "." + image_compress_format + ".ctex", compress_mode, lossy, image_compress_mode, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
+ r_platform_variants->push_back(image_compress_format);
}
- _save_ctex(image, p_save_path + ".s3tc.ctex", compress_mode, lossy, image_compress_mode, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
- r_platform_variants->push_back("s3tc");
- formats_imported.push_back("s3tc");
- }
-
- if (GLOBAL_GET("rendering/textures/vram_compression/import_etc2")) {
- _save_ctex(image, p_save_path + ".etc2.ctex", compress_mode, lossy, Image::COMPRESS_ETC2, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
- r_platform_variants->push_back("etc2");
- formats_imported.push_back("etc2");
- }
- if (GLOBAL_GET("rendering/textures/vram_compression/import_etc")) {
- _save_ctex(image, p_save_path + ".etc.ctex", compress_mode, lossy, Image::COMPRESS_ETC, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, true, mipmap_limit, normal_image, roughness_channel);
- r_platform_variants->push_back("etc");
- formats_imported.push_back("etc");
- }
-
- if (!ok_on_pc) {
- EditorNode::add_io_error(vformat(TTR("%s: No suitable desktop VRAM compression algorithm enabled in Project Settings (S3TC or BPTC). This texture may not display correctly on desktop platforms."), p_source_file));
+ if (can_etc2_astc) {
+ Image::CompressMode image_compress_mode;
+ String image_compress_format;
+ if (high_quality || is_hdr) {
+ image_compress_mode = Image::COMPRESS_ASTC;
+ image_compress_format = "astc";
+ } else {
+ image_compress_mode = Image::COMPRESS_ETC2;
+ image_compress_format = "etc2";
+ }
+ _save_ctex(image, p_save_path + "." + image_compress_format + ".ctex", compress_mode, lossy, image_compress_mode, mipmaps, stream, detect_3d, detect_roughness, detect_normal, force_normal, srgb_friendly_pack, false, mipmap_limit, normal_image, roughness_channel);
+ r_platform_variants->push_back(image_compress_format);
+ }
}
} else {
// Import normally.
@@ -692,10 +692,8 @@ Error ResourceImporterTexture::import(const String &p_source_file, const String
}
const char *ResourceImporterTexture::compression_formats[] = {
- "bptc",
- "s3tc",
- "etc",
- "etc2",
+ "s3tc_bptc",
+ "etc2_astc",
nullptr
};
String ResourceImporterTexture::get_import_settings_string() const {
@@ -745,12 +743,16 @@ bool ResourceImporterTexture::are_import_settings_valid(const String &p_path) co
bool valid = true;
while (compression_formats[index]) {
String setting_path = "rendering/textures/vram_compression/import_" + String(compression_formats[index]);
- bool test = GLOBAL_GET(setting_path);
- if (test) {
- if (!formats_imported.has(compression_formats[index])) {
- valid = false;
- break;
+ if (ProjectSettings::get_singleton()->has_setting(setting_path)) {
+ bool test = GLOBAL_GET(setting_path);
+ if (test) {
+ if (!formats_imported.has(compression_formats[index])) {
+ valid = false;
+ break;
+ }
}
+ } else {
+ WARN_PRINT("Setting for imported format not found: " + setting_path);
}
index++;
}
diff --git a/editor/import/scene_import_settings.cpp b/editor/import/scene_import_settings.cpp
index f6ec7da158..8d26feebf4 100644
--- a/editor/import/scene_import_settings.cpp
+++ b/editor/import/scene_import_settings.cpp
@@ -441,7 +441,7 @@ void SceneImportSettings::_update_view_gizmos() {
// This collider_view doesn't have a mesh so we need to generate a new one.
// Generate the mesh collider.
- Vector<Ref<Shape3D>> shapes = ResourceImporterScene::get_collision_shapes(mesh_node->get_mesh(), e.value.settings);
+ Vector<Ref<Shape3D>> shapes = ResourceImporterScene::get_collision_shapes(mesh_node->get_mesh(), e.value.settings, 1.0);
const Transform3D transform = ResourceImporterScene::get_collision_shapes_transform(e.value.settings);
Ref<ArrayMesh> collider_view_mesh;
@@ -703,15 +703,17 @@ void SceneImportSettings::_select(Tree *p_from, String p_type, String p_id) {
}
MeshData &md = mesh_map[p_id];
- if (p_from != mesh_tree) {
- md.mesh_node->uncollapse_tree();
- md.mesh_node->select(0);
- mesh_tree->ensure_cursor_is_visible();
- }
- if (p_from != scene_tree) {
- md.scene_node->uncollapse_tree();
- md.scene_node->select(0);
- scene_tree->ensure_cursor_is_visible();
+ if (md.mesh_node != nullptr) {
+ if (p_from != mesh_tree) {
+ md.mesh_node->uncollapse_tree();
+ md.mesh_node->select(0);
+ mesh_tree->ensure_cursor_is_visible();
+ }
+ if (p_from != scene_tree) {
+ md.scene_node->uncollapse_tree();
+ md.scene_node->select(0);
+ scene_tree->ensure_cursor_is_visible();
+ }
}
mesh_preview->set_mesh(md.mesh);
@@ -1234,6 +1236,12 @@ SceneImportSettings::SceneImportSettings() {
action_menu = memnew(MenuButton);
action_menu->set_text(TTR("Actions..."));
+ // Style the MenuButton like a regular Button to make it more noticeable.
+ action_menu->set_flat(false);
+ action_menu->add_theme_style_override("normal", get_theme_stylebox("normal", "Button"));
+ action_menu->add_theme_style_override("hover", get_theme_stylebox("hover", "Button"));
+ action_menu->add_theme_style_override("pressed", get_theme_stylebox("pressed", "Button"));
+ action_menu->set_focus_mode(Control::FOCUS_ALL);
menu_hb->add_child(action_menu);
action_menu->get_popup()->add_item(TTR("Extract Materials"), ACTION_EXTRACT_MATERIALS);