-Ability to set default import presets for type

-More presets for scene importer
-Option in scene importer to export root nodes as separate scenes
-Fixed MeshInstance preview
This commit is contained in:
Juan Linietsky 2017-07-23 18:48:05 -03:00
parent 380eae2cc0
commit 66009706c9
12 changed files with 348 additions and 223 deletions

View file

@ -1239,7 +1239,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
String importer_name;
if (FileAccess::exists(p_file + ".import")) {
//use existing
Ref<ConfigFile> cf;
cf.instance();
Error err = cf->load(p_file + ".import");
@ -1254,6 +1254,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
}
Ref<ResourceImporter> importer;
bool load_default = false;
//find the importer
if (importer_name != "") {
importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
@ -1262,6 +1263,7 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
if (importer.is_null()) {
//not found by name, find by extension
importer = ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_file.get_extension());
load_default = true;
if (importer.is_null()) {
ERR_PRINT("BUG: File queued for import, but can't be imported!");
ERR_FAIL();
@ -1278,6 +1280,17 @@ void EditorFileSystem::_reimport_file(const String &p_file) {
}
}
if (load_default && ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name())) {
//use defaults if exist
Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name());
List<Variant> v;
d.get_key_list(&v);
for (List<Variant>::Element *E = v.front(); E; E = E->next()) {
params[E->get()] = d[E->get()];
}
}
//finally, perform import!!
String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file);

View file

@ -6079,7 +6079,7 @@ EditorNode::EditorNode() {
add_editor_plugin(memnew(TextureEditorPlugin(this)));
add_editor_plugin(memnew(AudioBusesEditorPlugin(audio_bus_editor)));
//add_editor_plugin( memnew( MaterialEditorPlugin(this) ) );
//add_editor_plugin( memnew( MeshEditorPlugin(this) ) );
add_editor_plugin(memnew(MeshEditorPlugin(this)));
for (int i = 0; i < EditorPlugins::get_plugin_count(); i++)
add_editor_plugin(EditorPlugins::create(i, this));

View file

@ -104,14 +104,27 @@ bool ResourceImporterScene::get_option_visibility(const String &p_option, const
}
}
if (p_option == "materials/keep_files" && int(p_options["materials/storage"]) == 0) {
return false;
}
return true;
}
int ResourceImporterScene::get_preset_count() const {
return 0;
return 6;
}
String ResourceImporterScene::get_preset_name(int p_idx) const {
switch (p_idx) {
case PRESET_SINGLE_SCENE: return TTR("Import as Single Scene");
case PRESET_SEPARATE_MATERIALS: return TTR("Import as Separate Materials");
case PRESET_SEPARATE_MESHES: return TTR("Import as Separate Objects");
case PRESET_SEPARATE_MESHES_AND_MATERIALS: return TTR("Import as Separate Objects+Materials");
case PRESET_MULTIPLE_SCENES: return TTR("Import as Multiple Scenes");
case PRESET_MULTIPLE_SCENES_AND_MATERIALS: return TTR("Import as Multiple Scenes+Materials");
}
return "";
}
@ -969,7 +982,7 @@ static String _make_extname(const String &p_str) {
return ext_name;
}
void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
void ResourceImporterScene::_make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes) {
List<PropertyInfo> pi;
@ -984,8 +997,8 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_materials.has(mat)) {
String ext_name = p_base_path + "." + _make_extname(mat->get_name()) + ".material";
if (FileAccess::exists(ext_name)) {
String ext_name = p_base_path.plus_file(_make_extname(mat->get_name()) + ".material");
if (p_keep_materials && FileAccess::exists(ext_name)) {
//if exists, use it
Ref<Material> existing = ResourceLoader::load(ext_name);
p_materials[mat] = existing;
@ -1012,17 +1025,12 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
if (!p_meshes.has(mesh)) {
String ext_name = p_base_path + "." + _make_extname(mesh->get_name()) + ".mesh";
if (FileAccess::exists(ext_name)) {
//if exists, use it
Ref<ArrayMesh> existing = ResourceLoader::load(ext_name);
p_meshes[mesh] = existing;
} else {
//meshes are always overwritten, keeping them is not practical
String ext_name = p_base_path.plus_file(_make_extname(mesh->get_name()) + ".mesh");
ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH);
p_meshes[mesh] = mesh;
mesh_just_added = true;
}
ResourceSaver::save(ext_name, mesh, ResourceSaver::FLAG_CHANGE_PATH);
p_meshes[mesh] = mesh;
mesh_just_added = true;
}
}
@ -1067,7 +1075,7 @@ void ResourceImporterScene::_make_external_resources(Node *p_node, const String
for (int i = 0; i < p_node->get_child_count(); i++) {
_make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_make_meshes, p_materials, p_meshes);
_make_external_resources(p_node->get_child(i), p_base_path, p_make_materials, p_keep_materials, p_make_meshes, p_materials, p_meshes);
}
}
@ -1087,12 +1095,19 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
script_ext_hint += "*." + E->get();
}
bool materials_out = p_preset == PRESET_SEPARATE_MATERIALS || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS;
bool meshes_out = p_preset == PRESET_SEPARATE_MESHES || p_preset == PRESET_SEPARATE_MESHES_AND_MATERIALS;
bool scenes_out = p_preset == PRESET_MULTIPLE_SCENES || p_preset == PRESET_MULTIPLE_SCENES_AND_MATERIALS;
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "nodes/custom_script", PROPERTY_HINT_FILE, script_ext_hint), ""));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Bult-In,Files"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "nodes/storage", PROPERTY_HINT_ENUM, "Single Scene,Instanced Sub-Scenes"), scenes_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/location", PROPERTY_HINT_ENUM, "Node,Mesh"), meshes_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "materials/storage", PROPERTY_HINT_ENUM, "Bult-In,Files", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), materials_out ? 1 : 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "materials/keep_files"), materials_out ? true : false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "geometry/compress"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "geometry/ensure_tangents"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "geometry/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), 0));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT, "geometry/storage", PROPERTY_HINT_ENUM, "Built-In,Files"), meshes_out ? true : false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "external_files/store_in_subdir"), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL, "animation/import", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), true));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL, "animation/fps", PROPERTY_HINT_RANGE, "1,120,1"), 15));
r_options->push_back(ImportOption(PropertyInfo(Variant::STRING, "animation/filter_script", PROPERTY_HINT_MULTILINE_TEXT), ""));
@ -1110,6 +1125,18 @@ void ResourceImporterScene::get_import_options(List<ImportOption> *r_options, in
}
}
void ResourceImporterScene::_replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner) {
if (p_node != p_new_owner && p_node->get_owner() == p_scene) {
p_node->set_owner(p_new_owner);
}
for (int i = 0; i < p_node->get_child_count(); i++) {
Node *n = p_node->get_child(i);
_replace_owner(n, p_scene, p_new_owner);
}
}
Error ResourceImporterScene::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) {
String src_path = p_source_file;
@ -1224,11 +1251,30 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
bool external_materials = p_options["materials/storage"];
bool external_meshes = p_options["geometry/storage"];
bool external_scenes = int(p_options["nodes/storage"]) == 1;
String base_path = p_source_file.get_base_dir();
if (external_materials || external_meshes || external_scenes) {
if (bool(p_options["external_files/store_in_subdir"])) {
String subdir_name = p_source_file.get_file().get_basename();
DirAccess *da = DirAccess::open(base_path);
print_line("at path " + da->get_current_dir() + " making " + subdir_name);
Error err = da->make_dir(subdir_name);
memdelete(da);
ERR_FAIL_COND_V(err != OK && err != ERR_ALREADY_EXISTS, err);
base_path = base_path.plus_file(subdir_name);
}
}
if (external_materials || external_meshes) {
Map<Ref<Material>, Ref<Material> > mat_map;
Map<Ref<ArrayMesh>, Ref<ArrayMesh> > mesh_map;
_make_external_resources(scene, p_source_file.get_basename(), external_materials, external_meshes, mat_map, mesh_map);
bool keep_materials = bool(p_options["materials/keep_files"]);
_make_external_resources(scene, base_path, external_materials, keep_materials, external_meshes, mat_map, mesh_map);
}
progress.step(TTR("Running Custom Script.."), 2);
@ -1263,10 +1309,33 @@ Error ResourceImporterScene::import(const String &p_source_file, const String &p
progress.step(TTR("Saving.."), 104);
if (external_scenes) {
//save sub-scenes as instances!
for (int i = 0; i < scene->get_child_count(); i++) {
Node *child = scene->get_child(i);
if (child->get_owner() != scene)
continue; //not a real child probably created by scene type (ig, a scrollbar)
_replace_owner(child, scene, child);
String cn = String(child->get_name()).strip_edges().replace(".", "_").replace(":", "_");
if (cn == String()) {
cn = "ChildNode" + itos(i);
}
String path = base_path.plus_file(cn + ".scn");
child->set_filename(path);
Ref<PackedScene> packer = memnew(PackedScene);
packer->pack(child);
err = ResourceSaver::save(path, packer); //do not take over, let the changed files reload themselves
ERR_FAIL_COND_V(err != OK, err);
}
}
Ref<PackedScene> packer = memnew(PackedScene);
packer->pack(scene);
print_line("SAVING TO: " + p_save_path + ".scn");
err = ResourceSaver::save(p_save_path + ".scn", packer); //do not take over, let the changed files reload themselves
ERR_FAIL_COND_V(err != OK, err);
memdelete(scene);

View file

@ -82,6 +82,17 @@ class ResourceImporterScene : public ResourceImporter {
static ResourceImporterScene *singleton;
enum Presets {
PRESET_SINGLE_SCENE,
PRESET_SEPARATE_MATERIALS,
PRESET_SEPARATE_MESHES,
PRESET_SEPARATE_MESHES_AND_MATERIALS,
PRESET_MULTIPLE_SCENES,
PRESET_MULTIPLE_SCENES_AND_MATERIALS,
};
void _replace_owner(Node *p_node, Node *p_scene, Node *p_new_owner);
public:
static ResourceImporterScene *get_singleton() { return singleton; }
@ -101,7 +112,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;
void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_make_meshes, Map<Ref<Material>, Ref<Material> > &p_materials, Map<Ref<ArrayMesh>, Ref<ArrayMesh> > &p_meshes);
void _make_external_resources(Node *p_node, const String &p_base_path, bool p_make_materials, bool p_keep_materials, bool p_make_meshes, 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<ArrayMesh>, Ref<Shape> > &collision_map);

View file

@ -134,6 +134,14 @@ void ImportDock::set_edit_path(const String &p_path) {
}
}
preset->get_popup()->add_separator();
preset->get_popup()->add_item(vformat(TTR("Set as Default for '%s'"), params->importer->get_visible_name()), ITEM_SET_AS_DEFAULT);
if (ProjectSettings::get_singleton()->has("importer_defaults/" + params->importer->get_importer_name())) {
preset->get_popup()->add_item(TTR("Load Default"), ITEM_LOAD_DEFAULT);
preset->get_popup()->add_separator();
preset->get_popup()->add_item(vformat(TTR("Clear Default for '%s'"), params->importer->get_visible_name()), ITEM_CLEAR_DEFAULT);
}
params->paths.clear();
params->paths.push_back(p_path);
import->set_disabled(false);
@ -256,17 +264,56 @@ void ImportDock::set_edit_multiple_paths(const Vector<String> &p_paths) {
void ImportDock::_preset_selected(int p_idx) {
print_line("preset selected? " + p_idx);
List<ResourceImporter::ImportOption> options;
switch (p_idx) {
case ITEM_SET_AS_DEFAULT: {
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options, p_idx);
params->importer->get_import_options(&options, p_idx);
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
Dictionary d;
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
params->values[E->get().option.name] = E->get().default_value;
d[E->get().option.name] = E->get().default_value;
}
ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), d);
ProjectSettings::get_singleton()->save();
} break;
case ITEM_LOAD_DEFAULT: {
ERR_FAIL_COND(!ProjectSettings::get_singleton()->has("importer_defaults/" + params->importer->get_importer_name()));
Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + params->importer->get_importer_name());
List<Variant> v;
d.get_key_list(&v);
for (List<Variant>::Element *E = v.front(); E; E = E->next()) {
params->values[E->get()] = d[E->get()];
}
params->update();
} break;
case ITEM_CLEAR_DEFAULT: {
ProjectSettings::get_singleton()->set("importer_defaults/" + params->importer->get_importer_name(), Variant());
ProjectSettings::get_singleton()->save();
} break;
default: {
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options, p_idx);
for (List<ResourceImporter::ImportOption>::Element *E = options.front(); E; E = E->next()) {
params->values[E->get().option.name] = E->get().default_value;
}
params->update();
} break;
}
params->update();
}
void ImportDock::clear() {

View file

@ -57,6 +57,12 @@ class ImportDock : public VBoxContainer {
void _reimport();
enum {
ITEM_SET_AS_DEFAULT = 100,
ITEM_LOAD_DEFAULT,
ITEM_CLEAR_DEFAULT,
};
protected:
static void _bind_methods();

View file

@ -29,18 +29,17 @@
/*************************************************************************/
#include "mesh_editor_plugin.h"
#if 0
void MeshEditor::_gui_input(InputEvent p_event) {
void MeshEditor::_gui_input(Ref<InputEvent> p_event) {
Ref<InputEventMouseMotion> mm = p_event;
if (mm.is_valid() && mm->get_button_mask() & BUTTON_MASK_LEFT) {
if (p_event.type==InputEvent::MOUSE_MOTION && p_event->get_button_mask()&BUTTON_MASK_LEFT) {
rot_x-=p_event->get_relative().y*0.01;
rot_y-=p_event->get_relative().x*0.01;
if (rot_x<-Math_PI/2)
rot_x=-Math_PI/2;
else if (rot_x>Math_PI/2) {
rot_x=Math_PI/2;
rot_x -= mm->get_relative().y * 0.01;
rot_y -= mm->get_relative().x * 0.01;
if (rot_x < -Math_PI / 2)
rot_x = -Math_PI / 2;
else if (rot_x > Math_PI / 2) {
rot_x = Math_PI / 2;
}
_update_rotation();
}
@ -48,35 +47,30 @@ void MeshEditor::_gui_input(InputEvent p_event) {
void MeshEditor::_notification(int p_what) {
if (p_what==NOTIFICATION_FIXED_PROCESS) {
if (p_what == NOTIFICATION_FIXED_PROCESS) {
}
if (p_what==NOTIFICATION_READY) {
if (p_what == NOTIFICATION_READY) {
//get_scene()->connect("node_removed",this,"_node_removed");
if (first_enter) {
//it's in propertyeditor so.. could be moved around
//it's in propertyeditor so. could be moved around
light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons"));
light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons"));
light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons"));
light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons"));
first_enter=false;
light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1", "EditorIcons"));
light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off", "EditorIcons"));
light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2", "EditorIcons"));
light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off", "EditorIcons"));
first_enter = false;
}
}
if (p_what==NOTIFICATION_DRAW) {
if (p_what == NOTIFICATION_DRAW) {
Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons");
Ref<Texture> checkerboard = get_icon("Checkerboard", "EditorIcons");
Size2 size = get_size();
draw_texture_rect(checkerboard,Rect2(Point2(),size),true);
//draw_texture_rect(checkerboard, Rect2(Point2(), size), true);
}
}
@ -85,125 +79,115 @@ void MeshEditor::_update_rotation() {
Transform t;
t.basis.rotate(Vector3(0, 1, 0), -rot_y);
t.basis.rotate(Vector3(1, 0, 0), -rot_x);
mesh_instance->set_transform(t);
rotation->set_transform(t);
}
void MeshEditor::edit(Ref<Mesh> p_mesh) {
mesh=p_mesh;
mesh = p_mesh;
mesh_instance->set_mesh(mesh);
if (mesh.is_null()) {
hide();
} else {
rot_x=0;
rot_y=0;
rot_x = 0;
rot_y = 0;
_update_rotation();
AABB aabb= mesh->get_aabb();
Vector3 ofs = aabb.pos + aabb.size*0.5;
aabb.pos-=ofs;
float m = MAX(aabb.size.x,aabb.size.y)*0.5;
if (m!=0) {
m=1.0/m;
m*=0.5;
Rect3 aabb = mesh->get_aabb();
print_line("aabb: " + aabb);
Vector3 ofs = aabb.position + aabb.size * 0.5;
float m = aabb.get_longest_axis_size();
if (m != 0) {
m = 1.0 / m;
m *= 0.5;
//print_line("scale: "+rtos(m));
Transform xform;
xform.basis.scale(Vector3(m,m,m));
xform.origin=-xform.basis.xform(ofs); //-ofs*m;
xform.origin.z-=aabb.size.z*2;
xform.basis.scale(Vector3(m, m, m));
xform.origin = -xform.basis.xform(ofs); //-ofs*m;
//xform.origin.z -= aabb.get_longest_axis_size() * 2;
mesh_instance->set_transform(xform);
}
}
}
void MeshEditor::_button_pressed(Node *p_button) {
void MeshEditor::_button_pressed(Node* p_button) {
if (p_button==light_1_switch) {
light1->set_enabled(!light_1_switch->is_pressed());
if (p_button == light_1_switch) {
light1->set_visible(!light_1_switch->is_pressed());
}
if (p_button==light_2_switch) {
light2->set_enabled(!light_2_switch->is_pressed());
if (p_button == light_2_switch) {
light2->set_visible(!light_2_switch->is_pressed());
}
}
void MeshEditor::_bind_methods() {
ClassDB::bind_method(D_METHOD("_gui_input"),&MeshEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_button_pressed"),&MeshEditor::_button_pressed);
ClassDB::bind_method(D_METHOD("_gui_input"), &MeshEditor::_gui_input);
ClassDB::bind_method(D_METHOD("_button_pressed"), &MeshEditor::_button_pressed);
}
MeshEditor::MeshEditor() {
viewport = memnew( Viewport );
viewport = memnew(Viewport);
Ref<World> world;
world.instance();
viewport->set_world(world); //use own world
add_child(viewport);
viewport->set_disable_input(true);
set_stretch(true);
camera = memnew( Camera );
camera->set_transform(Transform(Matrix3(),Vector3(0,0,3)));
camera->set_perspective(45,0.1,10);
camera = memnew(Camera);
camera->set_transform(Transform(Basis(), Vector3(0, 0, 1.1)));
camera->set_perspective(45, 0.1, 10);
viewport->add_child(camera);
light1 = memnew( DirectionalLight );
light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
light1 = memnew(DirectionalLight);
light1->set_transform(Transform().looking_at(Vector3(-1, -1, -1), Vector3(0, 1, 0)));
viewport->add_child(light1);
light2 = memnew( DirectionalLight );
light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7));
light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7));
light2 = memnew(DirectionalLight);
light2->set_transform(Transform().looking_at(Vector3(0, 1, 0), Vector3(0, 0, 1)));
light2->set_color(Color(0.7, 0.7, 0.7));
viewport->add_child(light2);
mesh_instance = memnew( MeshInstance );
viewport->add_child(mesh_instance);
rotation = memnew(Spatial);
viewport->add_child(rotation);
mesh_instance = memnew(MeshInstance);
rotation->add_child(mesh_instance);
set_custom_minimum_size(Size2(1, 150) * EDSCALE);
set_custom_minimum_size(Size2(1,150)*EDSCALE);
HBoxContainer *hb = memnew( HBoxContainer );
HBoxContainer *hb = memnew(HBoxContainer);
add_child(hb);
hb->set_area_as_parent_rect(2);
hb->add_spacer();
VBoxContainer *vb_light = memnew( VBoxContainer );
VBoxContainer *vb_light = memnew(VBoxContainer);
hb->add_child(vb_light);
light_1_switch = memnew( TextureButton );
light_1_switch = memnew(TextureButton);
light_1_switch->set_toggle_mode(true);
vb_light->add_child(light_1_switch);
light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch));
light_1_switch->connect("pressed", this, "_button_pressed", varray(light_1_switch));
light_2_switch = memnew( TextureButton );
light_2_switch = memnew(TextureButton);
light_2_switch->set_toggle_mode(true);
vb_light->add_child(light_2_switch);
light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch));
first_enter=true;
rot_x=0;
rot_y=0;
light_2_switch->connect("pressed", this, "_button_pressed", varray(light_2_switch));
first_enter = true;
rot_x = 0;
rot_y = 0;
}
void MeshEditorPlugin::edit(Object *p_object) {
Mesh * s = p_object->cast_to<Mesh>();
Mesh *s = p_object->cast_to<Mesh>();
if (!s)
return;
@ -212,7 +196,7 @@ void MeshEditorPlugin::edit(Object *p_object) {
bool MeshEditorPlugin::handles(Object *p_object) const {
return p_object->is_type("Mesh");
return p_object->is_class("Mesh");
}
void MeshEditorPlugin::make_visible(bool p_visible) {
@ -225,22 +209,15 @@ void MeshEditorPlugin::make_visible(bool p_visible) {
mesh_editor->hide();
//mesh_editor->set_process(false);
}
}
MeshEditorPlugin::MeshEditorPlugin(EditorNode *p_node) {
editor=p_node;
mesh_editor = memnew( MeshEditor );
add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,mesh_editor);
editor = p_node;
mesh_editor = memnew(MeshEditor);
add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM, mesh_editor);
mesh_editor->hide();
}
MeshEditorPlugin::~MeshEditorPlugin()
{
MeshEditorPlugin::~MeshEditorPlugin() {
}
#endif

View file

@ -30,8 +30,6 @@
#ifndef MESH_EDITOR_PLUGIN_H
#define MESH_EDITOR_PLUGIN_H
#if 0
#include "editor/editor_node.h"
#include "editor/editor_plugin.h"
#include "scene/3d/camera.h"
@ -39,51 +37,48 @@
#include "scene/3d/mesh_instance.h"
#include "scene/resources/material.h"
class MeshEditor : public Control {
GDCLASS(MeshEditor, Control);
class MeshEditor : public ViewportContainer {
GDCLASS(MeshEditor, ViewportContainer);
float rot_x;
float rot_y;
Viewport *viewport;
MeshInstance *mesh_instance;
Spatial *rotation;
DirectionalLight *light1;
DirectionalLight *light2;
Camera *camera;
Ref<Mesh> mesh;
TextureButton *light_1_switch;
TextureButton *light_2_switch;
void _button_pressed(Node* p_button);
void _button_pressed(Node *p_button);
bool first_enter;
void _update_rotation();
protected:
void _notification(int p_what);
void _gui_input(InputEvent p_event);
void _gui_input(Ref<InputEvent> p_event);
static void _bind_methods();
public:
public:
void edit(Ref<Mesh> p_mesh);
MeshEditor();
};
class MeshEditorPlugin : public EditorPlugin {
GDCLASS( MeshEditorPlugin, EditorPlugin );
GDCLASS(MeshEditorPlugin, EditorPlugin);
MeshEditor *mesh_editor;
EditorNode *editor;
public:
virtual String get_name() const { return "Mesh"; }
bool has_main_screen() const { return false; }
virtual void edit(Object *p_node);
@ -92,8 +87,6 @@ public:
MeshEditorPlugin(EditorNode *p_node);
~MeshEditorPlugin();
};
#endif // MESH_EDITOR_PLUGIN_H
#endif

View file

@ -32,7 +32,7 @@
#include "scene/resources/convex_polygon_shape.h"
#include "surface_tool.h"
void Mesh::_clear_triangle_mesh() {
void Mesh::_clear_triangle_mesh() const {
triangle_mesh.unref();
;

View file

@ -44,7 +44,7 @@ class Mesh : public Resource {
mutable Ref<TriangleMesh> triangle_mesh; //cached
protected:
void _clear_triangle_mesh();
void _clear_triangle_mesh() const;
static void _bind_methods();

View file

@ -34,42 +34,44 @@
/**
PrimitiveMesh
*/
void PrimitiveMesh::_update() {
if (!cache_is_dirty)
return;
void PrimitiveMesh::_update() const {
Array arr;
arr.resize(VS::ARRAY_MAX);
_create_mesh_array(arr);
PoolVector<Vector3> points = arr[VS::ARRAY_VERTEX];
aabb = Rect3();
int pc = points.size();
ERR_FAIL_COND(pc == 0);
{
PoolVector<Vector3>::Read r = points.read();
for (int i = 0; i < pc; i++) {
if (i == 0)
aabb.position = r[i];
else
aabb.expand_to(r[i]);
}
}
// in with the new
VisualServer::get_singleton()->mesh_clear(mesh);
VisualServer::get_singleton()->mesh_add_surface_from_arrays(mesh, (VisualServer::PrimitiveType)primitive_type, arr);
VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
cache_is_dirty = false;
pending_request = false;
_clear_triangle_mesh();
emit_changed();
}
void PrimitiveMesh::_queue_update(bool p_first_mesh) {
void PrimitiveMesh::_request_update() {
if (first_mesh && p_first_mesh) {
first_mesh = false;
cache_is_dirty = true;
_update();
if (pending_request)
return;
}
if (!cache_is_dirty) {
cache_is_dirty = true;
call_deferred("_update");
}
}
void PrimitiveMesh::set_aabb(Rect3 p_aabb) {
aabb = p_aabb;
_update();
}
int PrimitiveMesh::get_surface_count() const {
@ -78,21 +80,37 @@ int PrimitiveMesh::get_surface_count() const {
int PrimitiveMesh::surface_get_array_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, 1, -1);
if (pending_request) {
_update();
}
return VisualServer::get_singleton()->mesh_surface_get_array_len(mesh, 0);
}
int PrimitiveMesh::surface_get_array_index_len(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, 1, -1);
if (pending_request) {
_update();
}
return VisualServer::get_singleton()->mesh_surface_get_array_index_len(mesh, 0);
}
Array PrimitiveMesh::surface_get_arrays(int p_surface) const {
ERR_FAIL_INDEX_V(p_surface, 1, Array());
if (pending_request) {
_update();
}
return VisualServer::get_singleton()->mesh_surface_get_arrays(mesh, 0);
}
uint32_t PrimitiveMesh::surface_get_format(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, 1, 0);
if (pending_request) {
_update();
}
return VisualServer::get_singleton()->mesh_surface_get_format(mesh, 0);
}
@ -113,10 +131,17 @@ StringName PrimitiveMesh::get_blend_shape_name(int p_index) const {
}
Rect3 PrimitiveMesh::get_aabb() const {
if (pending_request) {
_update();
}
return aabb;
}
RID PrimitiveMesh::get_rid() const {
if (pending_request) {
_update();
}
return mesh;
}
@ -131,10 +156,9 @@ void PrimitiveMesh::_bind_methods() {
void PrimitiveMesh::set_material(const Ref<Material> &p_material) {
material = p_material;
if (!cache_is_dirty) {
if (!pending_request) {
// just apply it, else it'll happen when _update is called.
VisualServer::get_singleton()->mesh_surface_set_material(mesh, 0, material.is_null() ? RID() : material->get_rid());
_change_notify();
emit_changed();
};
@ -152,9 +176,7 @@ PrimitiveMesh::PrimitiveMesh() {
primitive_type = Mesh::PRIMITIVE_TRIANGLES;
// make sure we do an update after we've finished constructing our object
cache_is_dirty = false;
first_mesh = true;
_queue_update();
pending_request = true;
}
PrimitiveMesh::~PrimitiveMesh() {
@ -165,7 +187,7 @@ PrimitiveMesh::~PrimitiveMesh() {
CapsuleMesh
*/
void CapsuleMesh::_create_mesh_array(Array &p_arr) {
void CapsuleMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z, u, v, w;
float onethird = 1.0 / 3.0;
@ -173,8 +195,6 @@ void CapsuleMesh::_create_mesh_array(Array &p_arr) {
// note, this has been aligned with our collision shape but I've left the descriptions as top/middle/bottom
set_aabb(Rect3(Vector3(-radius, -radius, (mid_height * -0.5) - radius), Vector3(radius * 2.0, radius * 2.0, mid_height + (2.0 * radius))));
PoolVector<Vector3> points;
PoolVector<Vector3> normals;
PoolVector<float> tangents;
@ -334,7 +354,7 @@ void CapsuleMesh::_bind_methods() {
void CapsuleMesh::set_radius(const float p_radius) {
radius = p_radius;
_queue_update();
_request_update();
}
float CapsuleMesh::get_radius() const {
@ -343,7 +363,7 @@ float CapsuleMesh::get_radius() const {
void CapsuleMesh::set_mid_height(const float p_mid_height) {
mid_height = p_mid_height;
_queue_update();
_request_update();
}
float CapsuleMesh::get_mid_height() const {
@ -352,7 +372,7 @@ float CapsuleMesh::get_mid_height() const {
void CapsuleMesh::set_radial_segments(const int p_segments) {
radial_segments = p_segments > 4 ? p_segments : 4;
_queue_update();
_request_update();
}
int CapsuleMesh::get_radial_segments() const {
@ -361,7 +381,7 @@ int CapsuleMesh::get_radial_segments() const {
void CapsuleMesh::set_rings(const int p_rings) {
rings = p_rings > 1 ? p_rings : 1;
_queue_update(true); //last property set, force update mesh
_request_update();
}
int CapsuleMesh::get_rings() const {
@ -380,7 +400,7 @@ CapsuleMesh::CapsuleMesh() {
CubeMesh
*/
void CubeMesh::_create_mesh_array(Array &p_arr) {
void CubeMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z;
float onethird = 1.0 / 3.0;
@ -389,7 +409,6 @@ void CubeMesh::_create_mesh_array(Array &p_arr) {
Vector3 start_pos = size * -0.5;
// set our bounding box
set_aabb(Rect3(start_pos, size));
PoolVector<Vector3> points;
PoolVector<Vector3> normals;
@ -592,7 +611,7 @@ void CubeMesh::_bind_methods() {
void CubeMesh::set_size(const Vector3 &p_size) {
size = p_size;
_queue_update();
_request_update();
}
Vector3 CubeMesh::get_size() const {
@ -601,7 +620,7 @@ Vector3 CubeMesh::get_size() const {
void CubeMesh::set_subdivide_width(const int p_subdivide) {
subdivide_w = p_subdivide > 0 ? p_subdivide : 0;
_queue_update();
_request_update();
}
int CubeMesh::get_subdivide_width() const {
@ -610,7 +629,7 @@ int CubeMesh::get_subdivide_width() const {
void CubeMesh::set_subdivide_height(const int p_subdivide) {
subdivide_h = p_subdivide > 0 ? p_subdivide : 0;
_queue_update();
_request_update();
}
int CubeMesh::get_subdivide_height() const {
@ -619,7 +638,7 @@ int CubeMesh::get_subdivide_height() const {
void CubeMesh::set_subdivide_depth(const int p_subdivide) {
subdivide_d = p_subdivide > 0 ? p_subdivide : 0;
_queue_update(true); //last property set, force update mesh
_request_update();
}
int CubeMesh::get_subdivide_depth() const {
@ -638,14 +657,12 @@ CubeMesh::CubeMesh() {
CylinderMesh
*/
void CylinderMesh::_create_mesh_array(Array &p_arr) {
void CylinderMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z, u, v, radius;
radius = bottom_radius > top_radius ? bottom_radius : top_radius;
set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0)));
PoolVector<Vector3> points;
PoolVector<Vector3> normals;
PoolVector<float> tangents;
@ -800,7 +817,7 @@ void CylinderMesh::_bind_methods() {
void CylinderMesh::set_top_radius(const float p_radius) {
top_radius = p_radius;
_queue_update();
_request_update();
}
float CylinderMesh::get_top_radius() const {
@ -809,7 +826,7 @@ float CylinderMesh::get_top_radius() const {
void CylinderMesh::set_bottom_radius(const float p_radius) {
bottom_radius = p_radius;
_queue_update();
_request_update();
}
float CylinderMesh::get_bottom_radius() const {
@ -818,7 +835,7 @@ float CylinderMesh::get_bottom_radius() const {
void CylinderMesh::set_height(const float p_height) {
height = p_height;
_queue_update();
_request_update();
}
float CylinderMesh::get_height() const {
@ -827,7 +844,7 @@ float CylinderMesh::get_height() const {
void CylinderMesh::set_radial_segments(const int p_segments) {
radial_segments = p_segments > 4 ? p_segments : 4;
_queue_update();
_request_update();
}
int CylinderMesh::get_radial_segments() const {
@ -836,7 +853,7 @@ int CylinderMesh::get_radial_segments() const {
void CylinderMesh::set_rings(const int p_rings) {
rings = p_rings > 0 ? p_rings : 0;
_queue_update(true); //last property set, force update mesh
_request_update();
}
int CylinderMesh::get_rings() const {
@ -856,14 +873,12 @@ CylinderMesh::CylinderMesh() {
PlaneMesh
*/
void PlaneMesh::_create_mesh_array(Array &p_arr) {
void PlaneMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, z;
Size2 start_pos = size * -0.5;
set_aabb(Rect3(Vector3(start_pos.x, 0.0, start_pos.y), Vector3(size.x, 0.0, size.y)));
PoolVector<Vector3> points;
PoolVector<Vector3> normals;
PoolVector<float> tangents;
@ -935,7 +950,7 @@ void PlaneMesh::_bind_methods() {
void PlaneMesh::set_size(const Size2 &p_size) {
size = p_size;
_queue_update();
_request_update();
}
Size2 PlaneMesh::get_size() const {
@ -944,7 +959,7 @@ Size2 PlaneMesh::get_size() const {
void PlaneMesh::set_subdivide_width(const int p_subdivide) {
subdivide_w = p_subdivide > 0 ? p_subdivide : 0;
_queue_update();
_request_update();
}
int PlaneMesh::get_subdivide_width() const {
@ -953,7 +968,7 @@ int PlaneMesh::get_subdivide_width() const {
void PlaneMesh::set_subdivide_depth(const int p_subdivide) {
subdivide_d = p_subdivide > 0 ? p_subdivide : 0;
_queue_update(true); //last property set, force update mesh
_request_update();
}
int PlaneMesh::get_subdivide_depth() const {
@ -971,7 +986,7 @@ PlaneMesh::PlaneMesh() {
PrismMesh
*/
void PrismMesh::_create_mesh_array(Array &p_arr) {
void PrismMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z;
float onethird = 1.0 / 3.0;
@ -980,7 +995,6 @@ void PrismMesh::_create_mesh_array(Array &p_arr) {
Vector3 start_pos = size * -0.5;
// set our bounding box
set_aabb(Rect3(start_pos, size));
PoolVector<Vector3> points;
PoolVector<Vector3> normals;
@ -1207,7 +1221,7 @@ void PrismMesh::_bind_methods() {
void PrismMesh::set_left_to_right(const float p_left_to_right) {
left_to_right = p_left_to_right;
_queue_update();
_request_update();
}
float PrismMesh::get_left_to_right() const {
@ -1216,7 +1230,7 @@ float PrismMesh::get_left_to_right() const {
void PrismMesh::set_size(const Vector3 &p_size) {
size = p_size;
_queue_update();
_request_update();
}
Vector3 PrismMesh::get_size() const {
@ -1225,7 +1239,7 @@ Vector3 PrismMesh::get_size() const {
void PrismMesh::set_subdivide_width(const int p_divisions) {
subdivide_w = p_divisions > 0 ? p_divisions : 0;
_queue_update();
_request_update();
}
int PrismMesh::get_subdivide_width() const {
@ -1234,7 +1248,7 @@ int PrismMesh::get_subdivide_width() const {
void PrismMesh::set_subdivide_height(const int p_divisions) {
subdivide_h = p_divisions > 0 ? p_divisions : 0;
_queue_update();
_request_update();
}
int PrismMesh::get_subdivide_height() const {
@ -1243,7 +1257,7 @@ int PrismMesh::get_subdivide_height() const {
void PrismMesh::set_subdivide_depth(const int p_divisions) {
subdivide_d = p_divisions > 0 ? p_divisions : 0;
_queue_update(true); //last property set, force update mesh
_request_update();
}
int PrismMesh::get_subdivide_depth() const {
@ -1263,7 +1277,7 @@ PrismMesh::PrismMesh() {
QuadMesh
*/
void QuadMesh::_create_mesh_array(Array &p_arr) {
void QuadMesh::_create_mesh_array(Array &p_arr) const {
PoolVector<Vector3> faces;
PoolVector<Vector3> normals;
PoolVector<float> tangents;
@ -1312,19 +1326,17 @@ void QuadMesh::_bind_methods() {
QuadMesh::QuadMesh() {
primitive_type = PRIMITIVE_TRIANGLE_FAN;
_queue_update(true);
}
/**
SphereMesh
*/
void SphereMesh::_create_mesh_array(Array &p_arr) {
void SphereMesh::_create_mesh_array(Array &p_arr) const {
int i, j, prevrow, thisrow, point;
float x, y, z;
// set our bounding box
set_aabb(Rect3(Vector3(-radius, height * -0.5, -radius), Vector3(radius * 2.0, height, radius * 2.0)));
PoolVector<Vector3> points;
PoolVector<Vector3> normals;
@ -1413,7 +1425,7 @@ void SphereMesh::_bind_methods() {
void SphereMesh::set_radius(const float p_radius) {
radius = p_radius;
_queue_update();
_request_update();
}
float SphereMesh::get_radius() const {
@ -1422,7 +1434,7 @@ float SphereMesh::get_radius() const {
void SphereMesh::set_height(const float p_height) {
height = p_height;
_queue_update();
_request_update();
}
float SphereMesh::get_height() const {
@ -1431,7 +1443,7 @@ float SphereMesh::get_height() const {
void SphereMesh::set_radial_segments(const int p_radial_segments) {
radial_segments = p_radial_segments > 4 ? p_radial_segments : 4;
_queue_update();
_request_update();
}
int SphereMesh::get_radial_segments() const {
@ -1440,7 +1452,7 @@ int SphereMesh::get_radial_segments() const {
void SphereMesh::set_rings(const int p_rings) {
rings = p_rings > 1 ? p_rings : 1;
_queue_update();
_request_update();
}
int SphereMesh::get_rings() const {
@ -1449,7 +1461,7 @@ int SphereMesh::get_rings() const {
void SphereMesh::set_is_hemisphere(const bool p_is_hemisphere) {
is_hemisphere = p_is_hemisphere;
_queue_update(true); //last property set, force update mesh
_request_update();
}
bool SphereMesh::get_is_hemisphere() const {

View file

@ -47,23 +47,20 @@ class PrimitiveMesh : public Mesh {
private:
RID mesh;
Rect3 aabb;
mutable Rect3 aabb;
Ref<Material> material;
bool first_mesh;
bool cache_is_dirty;
void _update();
mutable bool pending_request;
void _update() const;
protected:
Mesh::PrimitiveType primitive_type;
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr) = 0;
void _queue_update(bool p_first_mesh = false); //pretty bad hack to have the mesh built firt time parameters are set without delay
void set_aabb(Rect3 p_aabb);
virtual void _create_mesh_array(Array &p_arr) const = 0;
void _request_update();
public:
virtual int get_surface_count() const;
@ -99,7 +96,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
void set_radius(const float p_radius);
@ -132,7 +129,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
void set_size(const Vector3 &p_size);
@ -167,7 +164,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
void set_top_radius(const float p_radius);
@ -202,7 +199,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
void set_size(const Size2 &p_size);
@ -233,7 +230,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
void set_left_to_right(const float p_left_to_right);
@ -267,7 +264,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
QuadMesh();
@ -289,7 +286,7 @@ private:
protected:
static void _bind_methods();
virtual void _create_mesh_array(Array &p_arr);
virtual void _create_mesh_array(Array &p_arr) const;
public:
void set_radius(const float p_radius);