Import 3D Scene Improvements
-=-=-=-=-=-=-=-=-=-=-=-=-=-=- -If re-importing from the "dependency changed" dialog, edited scene will keep the local changes. -Imported scene will keep track of changes in the source asset -Geometry changes in source geometry or nodes with a different transform will be updated. -Materials will be kept if changed locally. -New nodes added will be kept -If nodes were reparented or renamed, they will still keep track -Deleted notes will be restored, use the -noimp option to avoid this. -In general, you can trust that if you do local modifications to the imported scene, they will not be erased after re-import. -Erasing your changes is done by re-importing from the "Re-Import" menu, re-opening the "Import 3D Scene" dialog. This wil re-import fresh. Overall, This should allow you to work on a scene and see changes made to 3D assets in real-time. So Please test!!
This commit is contained in:
parent
ddc0e7fd3b
commit
e086bccd63
19 changed files with 667 additions and 124 deletions
|
@ -305,7 +305,7 @@ public:
|
|||
richtext->push_color(Color(1,0.5,0.5));
|
||||
richtext->add_text("leprechauns");
|
||||
richtext->pop();
|
||||
#if 0
|
||||
|
||||
richtext->add_text(" and ");
|
||||
richtext->push_color(Color(0,1.0,0.5));
|
||||
richtext->add_text("faeries.\n");
|
||||
|
@ -329,7 +329,7 @@ public:
|
|||
richtext->pop();
|
||||
richtext->add_text("of the rich text label for huge text (not like this text will really be huge but, you know).\nAs long as it is so long that it will work nicely for a test/demo, then it's welcomed in my book...\nChanging subject, the day is cloudy today and I'm wondering if I'll get che chance to travel somewhere nice. Sometimes, watching the clouds from satellite images may give a nice insight about how pressure zones in our planet work, althogh it also makes it pretty obvious to see why most weather forecasts get it wrong so often.\nClouds are so difficult to predict!\nBut it's pretty cool how our civilization has adapted to having water falling from the sky each time it rains...");
|
||||
//richtext->add_text("Hello!\nGorgeous..");
|
||||
#endif
|
||||
|
||||
|
||||
//richtext->push_meta("http://www.scrollingcapabilities.xz");
|
||||
///richtext->add_text("Hello!\n");
|
||||
|
|
|
@ -49,6 +49,12 @@
|
|||
#define _GL_R16F_EXT 0x822D
|
||||
#define _GL_R32F_EXT 0x822E
|
||||
|
||||
|
||||
#define _GL_RED_EXT 0x1903
|
||||
#define _GL_RG_EXT 0x8227
|
||||
#define _GL_R8_EXT 0x8229
|
||||
#define _GL_RG8_EXT 0x822B
|
||||
|
||||
#define _DEPTH_COMPONENT24_OES 0x81A6
|
||||
|
||||
#ifdef GLEW_ENABLED
|
||||
|
@ -7874,6 +7880,7 @@ void RasterizerGLES2::_update_framebuffer() {
|
|||
glDeleteFramebuffers(1,&framebuffer.luminance[i].fbo);
|
||||
|
||||
}
|
||||
|
||||
for(int i=0;i<3;i++) {
|
||||
|
||||
glDeleteTextures(1,&framebuffer.blur[i].color);
|
||||
|
@ -7925,12 +7932,15 @@ void RasterizerGLES2::_update_framebuffer() {
|
|||
#endif
|
||||
//color
|
||||
|
||||
GLuint format_rgba = use_fp16_fb?_GL_RGBA16F_EXT:GL_RGBA;
|
||||
// GLuint format_rgba = use_fp16_fb?_GL_RGBA16F_EXT:GL_RGBA;
|
||||
GLuint format_rgba = GL_RGBA;
|
||||
GLuint format_rgb = use_fp16_fb?_GL_RGB16F_EXT:GL_RGB;
|
||||
GLuint format_type = use_fp16_fb?_GL_HALF_FLOAT_OES:GL_UNSIGNED_BYTE;
|
||||
GLuint format_luminance = use_fp16_fb?_GL_R32F_EXT:GL_RGBA;
|
||||
GLuint format_luminance_type = use_fp16_fb?GL_FLOAT:GL_UNSIGNED_BYTE;
|
||||
GLuint format_luminance_components = use_fp16_fb?GL_RED:GL_RGBA;
|
||||
GLuint format_luminance = use_fp16_fb?_GL_RED_EXT:GL_RGBA;
|
||||
GLuint format_luminance_type = use_fp16_fb?(full_float_fb_supported?GL_FLOAT:_GL_HALF_FLOAT_OES):GL_UNSIGNED_BYTE;
|
||||
GLuint format_luminance_components = use_fp16_fb?_GL_RED_EXT:GL_RGBA;
|
||||
|
||||
|
||||
|
||||
glGenTextures(1, &framebuffer.color);
|
||||
glBindTexture(GL_TEXTURE_2D, framebuffer.color);
|
||||
|
@ -8085,10 +8095,12 @@ void RasterizerGLES2::_update_framebuffer() {
|
|||
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
|
||||
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
base_size/=3;
|
||||
|
||||
DEBUG_TEST_ERROR("Shadow Buffer Init");
|
||||
ERR_CONTINUE( status != GL_FRAMEBUFFER_COMPLETE );
|
||||
|
||||
base_size/=3;
|
||||
framebuffer.luminance.push_back(lb);
|
||||
|
||||
}
|
||||
|
@ -8239,6 +8251,7 @@ void RasterizerGLES2::init() {
|
|||
// use_attribute_instancing=true;
|
||||
use_texture_instancing=false;
|
||||
use_attribute_instancing=true;
|
||||
full_float_fb_supported=true;
|
||||
#ifdef OSX_ENABLED
|
||||
use_rgba_shadowmaps=true;
|
||||
use_fp16_fb=false;
|
||||
|
@ -8291,9 +8304,11 @@ void RasterizerGLES2::init() {
|
|||
}
|
||||
|
||||
if (use_fp16_fb) {
|
||||
use_fp16_fb=extensions.has("GL_OES_texture_half_float") && extensions.has("GL_EXT_color_buffer_half_float");
|
||||
use_fp16_fb=extensions.has("GL_OES_texture_half_float") && extensions.has("GL_EXT_color_buffer_half_float") && extensions.has("GL_EXT_texture_rg");
|
||||
}
|
||||
|
||||
full_float_fb_supported=extensions.has("GL_EXT_color_buffer_float");
|
||||
|
||||
|
||||
//etc_supported=false;
|
||||
use_hw_skeleton_xform=false;
|
||||
|
|
|
@ -79,6 +79,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
bool npo2_textures_available;
|
||||
bool read_depth_supported;
|
||||
bool use_framebuffers;
|
||||
bool full_float_fb_supported;
|
||||
bool use_shadow_mapping;
|
||||
bool use_fp16_fb;
|
||||
ShadowFilterTechnique shadow_filter;
|
||||
|
@ -90,6 +91,7 @@ class RasterizerGLES2 : public Rasterizer {
|
|||
bool use_texture_instancing;
|
||||
bool use_attribute_instancing;
|
||||
bool use_rgba_shadowmaps;
|
||||
|
||||
bool use_half_float;
|
||||
|
||||
|
||||
|
|
|
@ -440,7 +440,7 @@ void main() {
|
|||
highp float vd_lum = dot(texture2D( source_vd_lum, vec2(0.0) ), _multcv );
|
||||
lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance*(1.0/LUM_RANGE),max_luminance*(1.0/LUM_RANGE));
|
||||
#else
|
||||
highp float vd_lum=texture2D( source_vd_lum, vec2(0.0) );
|
||||
highp float vd_lum=texture2D( source_vd_lum, vec2(0.0) ).r;
|
||||
lum_accum = clamp( vd_lum + (lum_accum-vd_lum)*hdr_time_delta*hdr_exp_adj_speed,min_luminance,max_luminance);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
void register_android_global_defaults() {
|
||||
|
||||
GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false);
|
||||
GLOBAL_DEF("rasterizer.Android/fp16_framebuffer",false);
|
||||
GLOBAL_DEF("display.Android/driver","GLES2");
|
||||
// GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
|
||||
|
||||
|
|
|
@ -494,6 +494,17 @@ Ref<World> Spatial::get_world() const {
|
|||
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void Spatial::set_import_transform(const Transform& p_transform) {
|
||||
data.import_transform=p_transform;
|
||||
}
|
||||
|
||||
Transform Spatial::get_import_transform() const {
|
||||
|
||||
return data.import_transform;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void Spatial::_bind_methods() {
|
||||
|
||||
|
@ -517,6 +528,9 @@ void Spatial::_bind_methods() {
|
|||
|
||||
#ifdef TOOLS_ENABLED
|
||||
ObjectTypeDB::bind_method(_MD("_update_gizmo"), &Spatial::_update_gizmo);
|
||||
ObjectTypeDB::bind_method(_MD("_set_import_transform"), &Spatial::set_import_transform);
|
||||
ObjectTypeDB::bind_method(_MD("_get_import_transform"), &Spatial::get_import_transform);
|
||||
ADD_PROPERTY( PropertyInfo(Variant::TRANSFORM,"_import_transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_import_transform"),_SCS("_get_import_transform"));
|
||||
#endif
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("update_gizmo"), &Spatial::update_gizmo);
|
||||
|
|
|
@ -95,6 +95,7 @@ class Spatial : public Node {
|
|||
Ref<SpatialGizmo> gizmo;
|
||||
bool gizmo_disabled;
|
||||
bool gizmo_dirty;
|
||||
Transform import_transform;
|
||||
#endif
|
||||
|
||||
} data;
|
||||
|
@ -158,6 +159,11 @@ public:
|
|||
|
||||
Transform get_relative_transform(const Node *p_parent) const;
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void set_import_transform(const Transform& p_transform) ;
|
||||
Transform get_import_transform() const;
|
||||
#endif
|
||||
|
||||
Spatial();
|
||||
~Spatial();
|
||||
|
||||
|
|
|
@ -1561,8 +1561,9 @@ RichTextLabel::RichTextLabel() {
|
|||
scroll_active=true;
|
||||
scroll_w=0;
|
||||
|
||||
vscroll = memnew( VScrollBar );
|
||||
vscroll = memnew( VScrollBar );
|
||||
add_child(vscroll);
|
||||
vscroll->set_drag_slave(String(".."));
|
||||
vscroll->set_step(1);
|
||||
vscroll->set_anchor_and_margin( MARGIN_TOP, ANCHOR_BEGIN, 0);
|
||||
vscroll->set_anchor_and_margin( MARGIN_BOTTOM, ANCHOR_END, 0);
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "scroll_bar.h"
|
||||
#include "os/keyboard.h"
|
||||
#include "print_string.h"
|
||||
|
||||
#include "os/os.h"
|
||||
bool ScrollBar::focus_by_default=false;
|
||||
|
||||
|
||||
|
@ -293,6 +293,117 @@ void ScrollBar::_notification(int p_what) {
|
|||
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_ENTER_SCENE) {
|
||||
|
||||
|
||||
if (has_node(drag_slave_path)) {
|
||||
Node *n = get_node(drag_slave_path);
|
||||
drag_slave=n->cast_to<Control>();
|
||||
}
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->connect("input_event",this,"_drag_slave_input");
|
||||
drag_slave->connect("exit_scene",this,"_drag_slave_exit",varray(),CONNECT_ONESHOT);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (p_what==NOTIFICATION_EXIT_SCENE) {
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->disconnect("input_event",this,"_drag_slave_input");
|
||||
drag_slave->disconnect("exit_scene",this,"_drag_slave_exit");
|
||||
}
|
||||
|
||||
drag_slave=NULL;
|
||||
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_FIXED_PROCESS) {
|
||||
|
||||
if (drag_slave_touching) {
|
||||
|
||||
if (drag_slave_touching_deaccel) {
|
||||
|
||||
Vector2 pos = Vector2(orientation==HORIZONTAL?get_val():0,orientation==VERTICAL?get_val():0);
|
||||
pos+=drag_slave_speed*get_fixed_process_delta_time();
|
||||
|
||||
bool turnoff=false;
|
||||
|
||||
if (orientation==HORIZONTAL) {
|
||||
|
||||
if (pos.x<0) {
|
||||
pos.x=0;
|
||||
turnoff=true;
|
||||
}
|
||||
|
||||
if (pos.x > (get_max()-get_page())) {
|
||||
pos.x=get_max()-get_page();
|
||||
turnoff=true;
|
||||
}
|
||||
|
||||
set_val(pos.x);
|
||||
|
||||
float sgn_x = drag_slave_speed.x<0? -1 : 1;
|
||||
float val_x = Math::abs(drag_slave_speed.x);
|
||||
val_x-=1000*get_fixed_process_delta_time();
|
||||
|
||||
if (val_x<0) {
|
||||
turnoff=true;
|
||||
}
|
||||
|
||||
drag_slave_speed.x=sgn_x*val_x;
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if (pos.y<0) {
|
||||
pos.y=0;
|
||||
turnoff=true;
|
||||
}
|
||||
|
||||
if (pos.y > (get_max()-get_page())) {
|
||||
pos.y=get_max()-get_page();
|
||||
turnoff=true;
|
||||
}
|
||||
|
||||
set_val(pos.y);
|
||||
|
||||
float sgn_y = drag_slave_speed.y<0? -1 : 1;
|
||||
float val_y = Math::abs(drag_slave_speed.y);
|
||||
val_y-=1000*get_fixed_process_delta_time();
|
||||
|
||||
if (val_y<0) {
|
||||
turnoff=true;
|
||||
}
|
||||
drag_slave_speed.y=sgn_y*val_y;
|
||||
}
|
||||
|
||||
|
||||
if (turnoff) {
|
||||
set_fixed_process(false);
|
||||
drag_slave_touching=false;
|
||||
drag_slave_touching_deaccel=false;
|
||||
}
|
||||
|
||||
|
||||
} else {
|
||||
|
||||
|
||||
if (time_since_motion==0 || time_since_motion>0.1) {
|
||||
|
||||
Vector2 diff = drag_slave_accum - last_drag_slave_accum;
|
||||
last_drag_slave_accum=drag_slave_accum;
|
||||
drag_slave_speed=diff/get_fixed_process_delta_time();
|
||||
}
|
||||
|
||||
time_since_motion+=get_fixed_process_delta_time();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
if (p_what==NOTIFICATION_MOUSE_EXIT) {
|
||||
|
||||
hilite=HILITE_NONE;
|
||||
|
@ -434,34 +545,119 @@ float ScrollBar::get_custom_step() const {
|
|||
|
||||
void ScrollBar::_drag_slave_exit() {
|
||||
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->disconnect("input_event",this,"_drag_slave_input");
|
||||
}
|
||||
drag_slave=NULL;
|
||||
}
|
||||
|
||||
|
||||
void ScrollBar::_drag_slave_input(const InputEvent& p_input) {
|
||||
|
||||
switch(p_input.type) {
|
||||
|
||||
case InputEvent::MOUSE_BUTTON: {
|
||||
|
||||
const InputEventMouseButton &mb=p_input.mouse_button;
|
||||
|
||||
if (mb.button_index!=1)
|
||||
break;
|
||||
|
||||
if (mb.pressed) {
|
||||
|
||||
if (drag_slave_touching) {
|
||||
set_fixed_process(false);
|
||||
drag_slave_touching_deaccel=false;
|
||||
drag_slave_touching=false;
|
||||
drag_slave_speed=Vector2();
|
||||
drag_slave_accum=Vector2();
|
||||
last_drag_slave_accum=Vector2();
|
||||
drag_slave_from=Vector2();
|
||||
}
|
||||
|
||||
if (true) {
|
||||
drag_slave_speed=Vector2();
|
||||
drag_slave_accum=Vector2();
|
||||
last_drag_slave_accum=Vector2();
|
||||
//drag_slave_from=Vector2(h_scroll->get_val(),v_scroll->get_val());
|
||||
drag_slave_from= Vector2(orientation==HORIZONTAL?get_val():0,orientation==VERTICAL?get_val():0);
|
||||
|
||||
drag_slave_touching=OS::get_singleton()->has_touchscreen_ui_hint();
|
||||
drag_slave_touching_deaccel=false;
|
||||
time_since_motion=0;
|
||||
if (drag_slave_touching) {
|
||||
set_fixed_process(true);
|
||||
time_since_motion=0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (drag_slave_touching) {
|
||||
|
||||
if (drag_slave_speed==Vector2()) {
|
||||
drag_slave_touching_deaccel=false;
|
||||
drag_slave_touching=false;
|
||||
set_fixed_process(false);
|
||||
} else {
|
||||
|
||||
drag_slave_touching_deaccel=true;
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case InputEvent::MOUSE_MOTION: {
|
||||
|
||||
const InputEventMouseMotion &mm=p_input.mouse_motion;
|
||||
|
||||
if (drag_slave_touching && ! drag_slave_touching_deaccel) {
|
||||
|
||||
Vector2 motion = Vector2(mm.relative_x,mm.relative_y);
|
||||
|
||||
drag_slave_accum-=motion;
|
||||
Vector2 diff = drag_slave_from+drag_slave_accum;
|
||||
|
||||
if (orientation==HORIZONTAL)
|
||||
set_val(diff.x);
|
||||
//else
|
||||
// drag_slave_accum.x=0;
|
||||
if (orientation==VERTICAL)
|
||||
set_val(diff.y);
|
||||
//else
|
||||
// drag_slave_accum.y=0;
|
||||
time_since_motion=0;
|
||||
}
|
||||
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void ScrollBar::set_drag_slave(const NodePath& p_path) {
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->disconnect("input_event",this,"_drag_slave_input");
|
||||
drag_slave->disconnect("exit_scene",this,"_drag_slave_exit");
|
||||
if (is_inside_scene()) {
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->disconnect("input_event",this,"_drag_slave_input");
|
||||
drag_slave->disconnect("exit_scene",this,"_drag_slave_exit");
|
||||
}
|
||||
}
|
||||
|
||||
drag_slave=NULL;
|
||||
drag_slave_path=p_path;
|
||||
if (has_node(p_path)) {
|
||||
Node *n = get_node(p_path);
|
||||
drag_slave=n->cast_to<Control>();
|
||||
}
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->connect("input_event",this,"_drag_slave_input");
|
||||
drag_slave->connect("exit_scene",this,"_drag_slave_exit",varray(),CONNECT_ONESHOT);
|
||||
}
|
||||
if (is_inside_scene()) {
|
||||
|
||||
if (has_node(p_path)) {
|
||||
Node *n = get_node(p_path);
|
||||
drag_slave=n->cast_to<Control>();
|
||||
}
|
||||
|
||||
if (drag_slave) {
|
||||
drag_slave->connect("input_event",this,"_drag_slave_input");
|
||||
drag_slave->connect("exit_scene",this,"_drag_slave_exit",varray(),CONNECT_ONESHOT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NodePath ScrollBar::get_drag_slave() const{
|
||||
|
@ -629,7 +825,11 @@ ScrollBar::ScrollBar(Orientation p_orientation)
|
|||
drag_slave=NULL;
|
||||
|
||||
drag.active=false;
|
||||
|
||||
|
||||
drag_slave_speed=Vector2();
|
||||
drag_slave_touching=false;
|
||||
drag_slave_touching_deaccel=false;
|
||||
|
||||
if (focus_by_default)
|
||||
set_focus_mode( FOCUS_ALL );
|
||||
|
||||
|
|
|
@ -74,6 +74,16 @@ class ScrollBar : public Range {
|
|||
Node* drag_slave;
|
||||
NodePath drag_slave_path;
|
||||
|
||||
Vector2 drag_slave_speed;
|
||||
Vector2 drag_slave_accum;
|
||||
Vector2 drag_slave_from;
|
||||
Vector2 last_drag_slave_accum;
|
||||
float last_drag_slave_time;
|
||||
float time_since_motion;
|
||||
bool drag_slave_touching;
|
||||
bool drag_slave_touching_deaccel;
|
||||
bool click_handled;
|
||||
|
||||
void _drag_slave_exit();
|
||||
void _drag_slave_input(const InputEvent& p_input);
|
||||
|
||||
|
|
|
@ -235,7 +235,7 @@ void ScrollContainer::_notification(int p_what) {
|
|||
}
|
||||
|
||||
if (pos.y<0) {
|
||||
pos.x=0;
|
||||
pos.y=0;
|
||||
turnoff_v=true;
|
||||
}
|
||||
if (pos.y > (v_scroll->get_max()-v_scroll->get_page())) {
|
||||
|
|
|
@ -1698,6 +1698,20 @@ Array Node::_get_children() const {
|
|||
return arr;
|
||||
}
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void Node::set_import_path(const NodePath& p_import_path) {
|
||||
|
||||
|
||||
data.import_path=p_import_path;
|
||||
}
|
||||
|
||||
NodePath Node::get_import_path() const {
|
||||
|
||||
return data.import_path;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
void Node::_bind_methods() {
|
||||
|
||||
|
@ -1760,6 +1774,12 @@ void Node::_bind_methods() {
|
|||
ObjectTypeDB::bind_method(_MD("get_viewport"),&Node::get_viewport);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("queue_free"),&Node::queue_delete);
|
||||
#ifdef TOOLS_ENABLED
|
||||
ObjectTypeDB::bind_method(_MD("_set_import_path","import_path"),&Node::set_import_path);
|
||||
ObjectTypeDB::bind_method(_MD("_get_import_path"),&Node::get_import_path);
|
||||
ADD_PROPERTY( PropertyInfo(Variant::NODE_PATH,"_import_path",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_import_path"),_SCS("_get_import_path"));
|
||||
|
||||
#endif
|
||||
|
||||
BIND_CONSTANT( NOTIFICATION_ENTER_SCENE );
|
||||
BIND_CONSTANT( NOTIFICATION_EXIT_SCENE );
|
||||
|
|
|
@ -82,6 +82,9 @@ private:
|
|||
StringName name;
|
||||
SceneMainLoop *scene;
|
||||
bool inside_scene;
|
||||
#ifdef TOOLS_ENABLED
|
||||
NodePath import_path; //path used when imported, used by scene editors to keep tracking
|
||||
#endif
|
||||
|
||||
Viewport *viewport;
|
||||
|
||||
|
@ -269,11 +272,18 @@ public:
|
|||
|
||||
void queue_delete();
|
||||
|
||||
//shitty hacks for speed
|
||||
static void set_human_readable_collision_renaming(bool p_enabled);
|
||||
static void init_node_hrcr();
|
||||
|
||||
void force_parent_owned() { data.parent_owned=true; } //hack to avoid duplicate nodes
|
||||
|
||||
#ifdef TOOLS_ENABLED
|
||||
void set_import_path(const NodePath& p_import_path); //path used when imported, used by scene editors to keep tracking
|
||||
NodePath get_import_path() const;
|
||||
#endif
|
||||
|
||||
|
||||
_FORCE_INLINE_ Viewport *get_viewport() const { return data.viewport; }
|
||||
|
||||
/* CANVAS */
|
||||
|
|
|
@ -3046,6 +3046,33 @@ void EditorNode::_load_error_notify(void* p_ud,const String& p_text) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
bool EditorNode::_find_scene_in_use(Node* p_node,const String& p_path) const {
|
||||
|
||||
if (p_node->get_filename()==p_path) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
|
||||
if (_find_scene_in_use(p_node->get_child(i),p_path)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool EditorNode::is_scene_in_use(const String& p_path) {
|
||||
|
||||
Node *es = get_edited_scene();
|
||||
if (es)
|
||||
return _find_scene_in_use(es,p_path);
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
void EditorNode::register_editor_types() {
|
||||
|
||||
ObjectTypeDB::register_type<EditorPlugin>();
|
||||
|
@ -3212,6 +3239,7 @@ Error EditorNode::export_platform(const String& p_platform, const String& p_path
|
|||
}
|
||||
|
||||
|
||||
|
||||
EditorNode::EditorNode() {
|
||||
|
||||
EditorHelp::generate_doc(); //before any editor classes are crated
|
||||
|
|
|
@ -398,6 +398,9 @@ class EditorNode : public Node {
|
|||
|
||||
static Vector<EditorNodeInitCallback> _init_callbacks;
|
||||
|
||||
bool _find_scene_in_use(Node* p_node,const String& p_path) const;
|
||||
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
static void _bind_methods();
|
||||
|
@ -485,6 +488,10 @@ public:
|
|||
static void progress_task_step_bg(const String& p_task,int p_step=-1);
|
||||
static void progress_end_task_bg(const String& p_task);
|
||||
|
||||
void save_scene(String p_file) { _save_scene(p_file); }
|
||||
|
||||
bool is_scene_in_use(const String& p_path);
|
||||
|
||||
void scan_import_changes();
|
||||
EditorNode();
|
||||
~EditorNode();
|
||||
|
|
|
@ -42,6 +42,9 @@ void EditorReImportDialog::popup_reimport() {
|
|||
List<String> ril;
|
||||
EditorFileSystem::get_singleton()->get_changed_sources(&ril);
|
||||
|
||||
scene_must_save=false;
|
||||
|
||||
|
||||
TreeItem *root = tree->create_item();
|
||||
for(List<String>::Element *E=ril.front();E;E=E->next()) {
|
||||
|
||||
|
@ -52,11 +55,34 @@ void EditorReImportDialog::popup_reimport() {
|
|||
item->set_tooltip(0,E->get());
|
||||
item->set_checked(0,true);
|
||||
item->set_editable(0,true);
|
||||
|
||||
items.push_back(item);
|
||||
|
||||
String name = E->get();
|
||||
|
||||
if (EditorFileSystem::get_singleton()->get_file_type(name)=="PackedScene" && EditorNode::get_singleton()->is_scene_in_use(name)) {
|
||||
|
||||
scene_must_save=true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (scene_must_save) {
|
||||
if (EditorNode::get_singleton()->get_edited_scene() && EditorNode::get_singleton()->get_edited_scene()->get_filename()=="") {
|
||||
|
||||
error->set_text("Current scene must be saved to re-import.");
|
||||
error->popup_centered(Size2(250,100));
|
||||
get_ok()->set_text("Re-Import");
|
||||
get_ok()->set_disabled(true);
|
||||
return;
|
||||
|
||||
}
|
||||
get_ok()->set_disabled(false);
|
||||
get_ok()->set_text("Save & Re-Import");
|
||||
} else {
|
||||
get_ok()->set_text("Re-Import");
|
||||
get_ok()->set_disabled(false);
|
||||
}
|
||||
|
||||
popup_centered(Size2(600,400));
|
||||
|
||||
|
||||
|
@ -70,7 +96,17 @@ void EditorReImportDialog::ok_pressed() {
|
|||
error->popup_centered(Size2(250,100));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
EditorProgress ep("reimport","Re-Importing",items.size());
|
||||
String reload_fname;
|
||||
if (scene_must_save && EditorNode::get_singleton()->get_edited_scene()) {
|
||||
reload_fname = EditorNode::get_singleton()->get_edited_scene()->get_filename();
|
||||
EditorNode::get_singleton()->save_scene(reload_fname);
|
||||
EditorNode::get_singleton()->clear_scene();
|
||||
}
|
||||
|
||||
for(int i=0;i<items.size();i++) {
|
||||
|
||||
String it = items[i]->get_metadata(0);
|
||||
|
@ -87,6 +123,9 @@ void EditorReImportDialog::ok_pressed() {
|
|||
}
|
||||
|
||||
}
|
||||
if (reload_fname!="") {
|
||||
EditorNode::get_singleton()->load_scene(reload_fname);
|
||||
}
|
||||
|
||||
EditorFileSystem::get_singleton()->scan_sources();
|
||||
}
|
||||
|
@ -100,5 +139,6 @@ EditorReImportDialog::EditorReImportDialog() {
|
|||
set_title("Re-Import Changed Resources");
|
||||
error = memnew( AcceptDialog);
|
||||
add_child(error);
|
||||
scene_must_save=false;
|
||||
|
||||
}
|
||||
|
|
|
@ -39,6 +39,7 @@ class EditorReImportDialog : public ConfirmationDialog {
|
|||
Tree *tree;
|
||||
Vector<TreeItem*> items;
|
||||
AcceptDialog *error;
|
||||
bool scene_must_save;
|
||||
|
||||
void ok_pressed();
|
||||
public:
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include "io/resource_saver.h"
|
||||
#include "scene/3d/mesh_instance.h"
|
||||
#include "scene/3d/room_instance.h"
|
||||
#include "scene/3d/body_shape.h"
|
||||
#include "scene/3d/physics_body.h"
|
||||
#include "scene/3d/portal.h"
|
||||
#include "os/os.h"
|
||||
|
||||
|
@ -104,7 +106,9 @@ class EditorSceneImportDialog : public ConfirmationDialog {
|
|||
|
||||
struct FlagInfo {
|
||||
int value;
|
||||
const char *category;
|
||||
const char *text;
|
||||
bool defval;
|
||||
};
|
||||
|
||||
static const FlagInfo scene_flag_names[];
|
||||
|
@ -626,22 +630,24 @@ void EditorSceneImportDialog::_bind_methods() {
|
|||
|
||||
const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_names[]={
|
||||
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create Collisions (-col},-colonly)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create Portals (-portal)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,"Create Rooms (-room)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS,"Simplify Rooms"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create Billboards (-bb)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create Impostors (-imp:dist)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create LODs (-lod:dist)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create Cars (-car)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create Car Wheels (-wheel)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,"Set Alpha in Materials (-alpha)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,"Set Vert. Color in Materials (-vcol)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,"Remove Nodes (-noimp)"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,"Import Animations"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,"Compress Geometry"},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,"Force Generation of Tangent Arrays"},
|
||||
{-1,NULL}
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_REMOVE_NOIMP,"Actions","Remove Nodes (-noimp)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_IMPORT_ANIMATIONS,"Actions","Import Animations",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_COMPRESS_GEOMETRY,"Actions","Compress Geometry",false},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_GENERATE_TANGENT_ARRAYS,"Actions","Force Generation of Tangent Arrays",false},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_DETECT_ALPHA,"Materials","Set Alpha in Materials (-alpha)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_DETECT_VCOLOR,"Materials","Set Vert. Color in Materials (-vcol)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES,"Actions","SRGB->Linear Of Diffuse Textures",false},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create","Create Collisions (-col},-colonly)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create","Create Portals (-portal)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_ROOMS,"Create","Create Rooms (-room)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_SIMPLIFY_ROOMS,"Create","Simplify Rooms",false},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create","Create Billboards (-bb)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create","Create Impostors (-imp:dist)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create","Create LODs (-lod:dist)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Cars (-car)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Car Wheels (-wheel)",true},
|
||||
{EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,"Create","Create Navigation Meshes (-navmesh)",true},
|
||||
{-1,NULL,NULL,false}
|
||||
};
|
||||
|
||||
|
||||
|
@ -717,19 +723,25 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
|
|||
TreeItem *root = import_options->create_item(NULL);
|
||||
import_options->set_hide_root(true);
|
||||
|
||||
|
||||
|
||||
|
||||
TreeItem *importopts = import_options->create_item(root);
|
||||
importopts->set_text(0,"Import:");
|
||||
|
||||
const FlagInfo* fn=scene_flag_names;
|
||||
|
||||
Map<String,TreeItem*> categories;
|
||||
|
||||
while(fn->text) {
|
||||
|
||||
TreeItem *opt = import_options->create_item(importopts);
|
||||
String cat = fn->category;
|
||||
TreeItem *parent;
|
||||
if (!categories.has(cat)) {
|
||||
parent = import_options->create_item(root);
|
||||
parent->set_text(0,cat);
|
||||
categories[cat]=parent;
|
||||
} else {
|
||||
parent=categories[cat];
|
||||
}
|
||||
|
||||
TreeItem *opt = import_options->create_item(parent);
|
||||
opt->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
|
||||
opt->set_checked(0,true);
|
||||
opt->set_checked(0,fn->defval);
|
||||
opt->set_editable(0,true);
|
||||
opt->set_text(0,fn->text);
|
||||
opt->set_metadata(0,fn->value);
|
||||
|
@ -875,7 +887,7 @@ static String _fixstr(const String& p_what,const String& p_str) {
|
|||
|
||||
|
||||
|
||||
void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<ImageTexture> >& image_map) {
|
||||
void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map<Ref<ImageTexture>, bool> &image_map) {
|
||||
|
||||
|
||||
switch(p_var.get_type()) {
|
||||
|
@ -885,9 +897,9 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<Image
|
|||
Ref<Resource> res = p_var;
|
||||
if (res.is_valid()) {
|
||||
|
||||
if (res->is_type("Texture")) {
|
||||
if (res->is_type("Texture") && !image_map.has(res)) {
|
||||
|
||||
image_map.insert(res);
|
||||
image_map.insert(res,false);
|
||||
|
||||
|
||||
} else {
|
||||
|
@ -898,7 +910,17 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<Image
|
|||
for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
|
||||
|
||||
if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) {
|
||||
_find_resources(res->get(E->get().name),image_map);
|
||||
if (E->get().type==Variant::OBJECT && res->cast_to<FixedMaterial>() && (E->get().name=="textures/diffuse" || E->get().name=="textures/detail" || E->get().name=="textures/emission")) {
|
||||
|
||||
Ref<ImageTexture> tex =res->get(E->get().name);
|
||||
if (tex.is_valid()) {
|
||||
|
||||
image_map.insert(tex,true);
|
||||
}
|
||||
|
||||
} else {
|
||||
_find_resources(res->get(E->get().name),image_map);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -938,7 +960,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var,Set<Ref<Image
|
|||
}
|
||||
|
||||
|
||||
Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map) {
|
||||
Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map) {
|
||||
|
||||
// children first..
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
|
@ -1010,6 +1032,36 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (p_flags&(SCENE_FLAG_DETECT_ALPHA|SCENE_FLAG_DETECT_VCOLOR) && p_node->cast_to<MeshInstance>()) {
|
||||
|
||||
MeshInstance *mi = p_node->cast_to<MeshInstance>();
|
||||
|
||||
Ref<Mesh> m = mi->get_mesh();
|
||||
|
||||
if (m.is_valid()) {
|
||||
|
||||
for(int i=0;i<m->get_surface_count();i++) {
|
||||
|
||||
Ref<FixedMaterial> mat = m->surface_get_material(i);
|
||||
if (!mat.is_valid())
|
||||
continue;
|
||||
|
||||
if (p_flags&SCENE_FLAG_DETECT_ALPHA && _teststr(mat->get_name(),"alpha")) {
|
||||
|
||||
mat->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
|
||||
mat->set_name(_fixstr(mat->get_name(),"alpha"));
|
||||
}
|
||||
if (p_flags&SCENE_FLAG_DETECT_VCOLOR && _teststr(mat->get_name(),"vcol")) {
|
||||
|
||||
mat->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
|
||||
mat->set_name(_fixstr(mat->get_name(),"vcol"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (p_flags&SCENE_FLAG_REMOVE_NOIMP && p_node->cast_to<AnimationPlayer>()) {
|
||||
//remove animations referencing non-importable nodes
|
||||
AnimationPlayer *ap = p_node->cast_to<AnimationPlayer>();
|
||||
|
@ -1141,21 +1193,42 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
|
|||
|
||||
MeshInstance *mi = p_node->cast_to<MeshInstance>();
|
||||
Node * col = mi->create_trimesh_collision_node();
|
||||
|
||||
ERR_FAIL_COND_V(!col,NULL);
|
||||
|
||||
col->set_name(_fixstr(name,"colonly"));
|
||||
col->cast_to<Spatial>()->set_transform(mi->get_transform());
|
||||
p_node->replace_by(col);
|
||||
memdelete(p_node);
|
||||
p_node=col;
|
||||
|
||||
StaticBody *sb = col->cast_to<StaticBody>();
|
||||
CollisionShape *colshape = memnew( CollisionShape);
|
||||
colshape->set_shape(sb->get_shape(0));
|
||||
colshape->set_name("shape");
|
||||
sb->add_child(colshape);
|
||||
colshape->set_owner(p_node->get_owner());
|
||||
|
||||
|
||||
} else if (p_flags&SCENE_FLAG_CREATE_COLLISIONS &&_teststr(name,"col") && p_node->cast_to<MeshInstance>()) {
|
||||
|
||||
|
||||
MeshInstance *mi = p_node->cast_to<MeshInstance>();
|
||||
|
||||
mi->set_name(_fixstr(name,"col"));
|
||||
mi->create_trimesh_collision();
|
||||
Node *col= mi->create_trimesh_collision_node();
|
||||
ERR_FAIL_COND_V(!col,NULL);
|
||||
|
||||
col->set_name("col");
|
||||
p_node->add_child(col);
|
||||
|
||||
|
||||
StaticBody *sb = col->cast_to<StaticBody>();
|
||||
CollisionShape *colshape = memnew( CollisionShape);
|
||||
colshape->set_shape(sb->get_shape(0));
|
||||
colshape->set_name("shape");
|
||||
sb->add_child(colshape);
|
||||
colshape->set_owner(p_node->get_owner());
|
||||
|
||||
} else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to<MeshInstance>()) {
|
||||
|
||||
|
||||
|
@ -1346,92 +1419,122 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return p_node;
|
||||
}
|
||||
|
||||
|
||||
void EditorSceneImportPlugin::_merge_node(Node *p_node,Node*p_root,Node *p_existing,Set<Ref<Resource> >& checked_resources) {
|
||||
void EditorSceneImportPlugin::_merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes) {
|
||||
|
||||
|
||||
NodePath path = p_root->get_path_to(p_node);
|
||||
NodePath path = p_node->get_import_path();
|
||||
|
||||
bool valid=false;
|
||||
if (!path.is_empty() && p_imported_scene->has_node(path)) {
|
||||
|
||||
if (p_existing->has_node(path)) {
|
||||
Node *imported_node = p_imported_scene->get_node(path);
|
||||
|
||||
Node *existing = p_existing->get_node(path);
|
||||
|
||||
if (existing->get_type()==p_node->get_type()) {
|
||||
if (imported_node->get_type()==p_node->get_type()) {
|
||||
//same thing, check what it is
|
||||
|
||||
if (existing->get_type()=="MeshInstance") {
|
||||
if (p_node->get_type()=="MeshInstance") {
|
||||
|
||||
//merge mesh instance, this is a special case!
|
||||
MeshInstance *mi_existing=existing->cast_to<MeshInstance>();
|
||||
MeshInstance *mi_imported=imported_node->cast_to<MeshInstance>();
|
||||
MeshInstance *mi_node=p_node->cast_to<MeshInstance>();
|
||||
|
||||
Ref<Mesh> mesh_existing = mi_existing->get_mesh();
|
||||
Ref<Mesh> mesh_imported = mi_imported->get_mesh();
|
||||
Ref<Mesh> mesh_node = mi_node->get_mesh();
|
||||
|
||||
if (mesh_existing.is_null() || checked_resources.has(mesh_node)) {
|
||||
if (mesh_node.is_null() && mesh_imported.is_valid()) {
|
||||
|
||||
if (mesh_node.is_valid())
|
||||
mi_existing->set_mesh(mesh_node);
|
||||
} else if (mesh_node.is_valid()) {
|
||||
mi_node->set_mesh(mesh_imported);
|
||||
|
||||
//mesh will always be overwritten, so check materials from original
|
||||
} else if (mesh_node.is_valid() && mesh_imported.is_valid()) {
|
||||
|
||||
for(int i=0;i<mesh_node->get_surface_count();i++) {
|
||||
if (checked_resources.has(mesh_imported)) {
|
||||
|
||||
String name = mesh_node->surface_get_name(i);
|
||||
mi_node->set_mesh(mesh_imported);
|
||||
} else {
|
||||
//mix up meshes
|
||||
//import new geometry but keep materials
|
||||
for(int i=0;i<mesh_imported->get_surface_count();i++) {
|
||||
|
||||
if (name!="") {
|
||||
String name = mesh_imported->surface_get_name(i);
|
||||
|
||||
for(int j=0;j<mesh_existing->get_surface_count();j++) {
|
||||
for(int j=0;j<mesh_node->get_surface_count();j++) {
|
||||
|
||||
Ref<Material> keep;
|
||||
Ref<Material> mat = mesh_node->surface_get_material(j);
|
||||
if (mat.is_valid() && mesh_node->surface_get_name(j)==name ) {
|
||||
|
||||
if (name==mesh_existing->surface_get_name(j)) {
|
||||
|
||||
Ref<Material> mat = mesh_existing->surface_get_material(j);
|
||||
|
||||
if (mat.is_valid()) {
|
||||
if (mat->get_path()!="" && mat->get_path().begins_with("res://") && mat->get_path().find("::")==-1) {
|
||||
keep=mat; //mat was loaded from file
|
||||
} else if (mat->is_edited()) {
|
||||
keep=mat; //mat was edited
|
||||
}
|
||||
}
|
||||
mesh_imported->surface_set_material(i,mat);
|
||||
break;
|
||||
}
|
||||
if (keep.is_valid())
|
||||
mesh_node->surface_set_material(i,keep); //kept
|
||||
}
|
||||
}
|
||||
// was imported, do nothing further
|
||||
checked_resources.insert(mesh_imported);
|
||||
mi_node->set_mesh(mesh_imported);
|
||||
}
|
||||
|
||||
mi_existing->set_mesh(mesh_node); //always overwrite mesh
|
||||
checked_resources.insert(mesh_node);
|
||||
|
||||
}
|
||||
} else if (existing->get_type()=="Path") {
|
||||
|
||||
Path *path_existing =existing->cast_to<Path>();
|
||||
} else if (p_node->get_type()=="Path") {
|
||||
//for paths, overwrite path
|
||||
Path *path_imported =imported_node->cast_to<Path>();
|
||||
Path *path_node =p_node->cast_to<Path>();
|
||||
|
||||
if (path_node->get_curve().is_valid()) {
|
||||
if (path_imported->get_curve().is_valid()) {
|
||||
|
||||
if (!path_existing->get_curve().is_valid() || !path_existing->get_curve()->is_edited()) {
|
||||
path_existing->set_curve(path_node->get_curve());
|
||||
}
|
||||
path_node->set_curve(path_imported->get_curve());
|
||||
}
|
||||
} else if (p_node->get_type()=="Portal") {
|
||||
//for paths, overwrite path
|
||||
|
||||
Portal *portal_imported =imported_node->cast_to<Portal>();
|
||||
Portal *portal_node =p_node->cast_to<Portal>();
|
||||
|
||||
portal_node->set_shape( portal_imported->get_shape() );
|
||||
|
||||
} else if (p_node->get_type()=="Room") {
|
||||
//for paths, overwrite path
|
||||
|
||||
Room *room_imported =imported_node->cast_to<Room>();
|
||||
Room *room_node =p_node->cast_to<Room>();
|
||||
|
||||
room_node->set_room( room_imported->get_room() );
|
||||
|
||||
} else if (p_node->get_type()=="CollisionShape") {
|
||||
//for paths, overwrite path
|
||||
|
||||
CollisionShape *collision_imported =imported_node->cast_to<CollisionShape>();
|
||||
CollisionShape *collision_node =p_node->cast_to<CollisionShape>();
|
||||
|
||||
collision_node->set_shape( collision_imported->get_shape() );
|
||||
}
|
||||
}
|
||||
|
||||
valid=true;
|
||||
} else {
|
||||
if (p_node->cast_to<Spatial>() && imported_node->cast_to<Spatial>()) {
|
||||
//apply transform if changed
|
||||
Spatial *snode = p_node->cast_to<Spatial>();
|
||||
Spatial *simp = imported_node->cast_to<Spatial>();
|
||||
|
||||
if (snode->get_import_transform() == snode->get_transform()) {
|
||||
//not moved, apply new
|
||||
snode->set_import_transform(simp->get_transform());
|
||||
snode->set_transform(simp->get_transform());
|
||||
} else if (snode->get_import_transform() == simp->get_import_transform()) {
|
||||
//do nothing, nothing changed keep local changes
|
||||
} else {
|
||||
//changed both, imported and edited, merge
|
||||
Transform local_xform = snode->get_import_transform().affine_inverse() * snode->get_transform();
|
||||
snode->set_import_transform(simp->get_import_transform());
|
||||
snode->set_transform(simp->get_import_transform() * local_xform);
|
||||
}
|
||||
}
|
||||
|
||||
checked_nodes.insert(imported_node);
|
||||
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
|
||||
if (p_node!=p_root && p_existing->has_node(p_root->get_path_to(p_node->get_parent()))) {
|
||||
|
||||
|
@ -1461,25 +1564,76 @@ void EditorSceneImportPlugin::_merge_node(Node *p_node,Node*p_root,Node *p_exist
|
|||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (valid) {
|
||||
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
_merge_node(p_node->get_child(i),p_root,p_existing,checked_resources);
|
||||
}
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
_merge_existing_node(p_node->get_child(i),p_imported_scene,checked_resources,checked_nodes);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void EditorSceneImportPlugin::_merge_scenes(Node *p_existing,Node *p_new) {
|
||||
void EditorSceneImportPlugin::_add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes) {
|
||||
|
||||
|
||||
for(int i=0;i<p_imported->get_child_count();i++) {
|
||||
|
||||
|
||||
Node *imported_node = p_imported->get_child(i);
|
||||
|
||||
if (imported_node->get_owner()!=p_imported_scene)
|
||||
continue; //end of the road
|
||||
|
||||
Vector<StringName> nn;
|
||||
nn.push_back(imported_node->get_name());
|
||||
NodePath imported_path(nn,false);
|
||||
|
||||
if (!p_node->has_node(imported_path) && !checked_nodes.has(imported_node)) {
|
||||
//not there, re-add it
|
||||
//add it.. because not existing in existing scene
|
||||
Object *o = ObjectTypeDB::instance(imported_node->get_type());
|
||||
Node *n=NULL;
|
||||
if (o)
|
||||
n=o->cast_to<Node>();
|
||||
|
||||
if (n) {
|
||||
|
||||
List<PropertyInfo> pl;
|
||||
imported_node->get_property_list(&pl);
|
||||
for(List<PropertyInfo>::Element *E=pl.front();E;E=E->next()) {
|
||||
if (!(E->get().usage&PROPERTY_USAGE_STORAGE))
|
||||
continue;
|
||||
n->set( E->get().name, imported_node->get(E->get().name) );
|
||||
}
|
||||
|
||||
p_node->add_child(n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (p_node->has_node(imported_path)) {
|
||||
|
||||
Node *other_node = p_node->get_node(imported_path);
|
||||
|
||||
_add_new_nodes(other_node,imported_node,p_imported_scene,checked_nodes);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void EditorSceneImportPlugin::_merge_scenes(Node *p_node,Node *p_imported) {
|
||||
|
||||
Set<Ref<Resource> > checked_resources;
|
||||
_merge_node(p_new,p_new,p_existing,checked_resources);
|
||||
|
||||
Set<Node*> checked_nodes;
|
||||
_merge_existing_node(p_node,p_imported,checked_resources,checked_nodes);
|
||||
_add_new_nodes(p_node,p_imported,p_imported,checked_nodes);
|
||||
//add existing.. ?
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,const String& p_resource_path,uint32_t p_flags,ImageFormat p_image_format,ImageCompression p_image_compression,uint32_t p_image_flags,float p_quality,uint32_t animation_flags,Node **r_scene,Ref<EditorPostImport> p_post_import) {
|
||||
|
@ -1488,6 +1642,26 @@ Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,
|
|||
}
|
||||
#endif
|
||||
|
||||
void EditorSceneImportPlugin::_tag_import_paths(Node *p_scene,Node *p_node) {
|
||||
|
||||
if (p_scene!=p_node && p_node->get_owner()!=p_scene)
|
||||
return;
|
||||
|
||||
NodePath path = p_scene->get_path_to(p_node);
|
||||
p_node->set_import_path( path );
|
||||
|
||||
Spatial *snode=p_node->cast_to<Spatial>();
|
||||
|
||||
if (snode) {
|
||||
|
||||
snode->set_import_transform(snode->get_transform());
|
||||
}
|
||||
|
||||
for(int i=0;i<p_node->get_child_count();i++) {
|
||||
_tag_import_paths(p_scene,p_node->get_child(i));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing) {
|
||||
|
||||
|
@ -1549,6 +1723,8 @@ Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from
|
|||
return err;
|
||||
}
|
||||
|
||||
_tag_import_paths(scene,scene);
|
||||
|
||||
*r_node=scene;
|
||||
return OK;
|
||||
}
|
||||
|
@ -1566,6 +1742,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
|
|||
|
||||
|
||||
bool merge = !bool(from->get_option("reimport"));
|
||||
|
||||
from->set_source_md5(0,FileAccess::get_md5(src_path));
|
||||
from->set_editor(get_name());
|
||||
|
||||
|
@ -1576,7 +1753,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
|
|||
|
||||
Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata);
|
||||
|
||||
Set< Ref<ImageTexture> > imagemap;
|
||||
Map< Ref<ImageTexture>,bool > imagemap;
|
||||
|
||||
scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);
|
||||
|
||||
|
@ -1622,12 +1799,12 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
|
|||
int image_flags = from->get_option("texture_flags");
|
||||
float image_quality = from->get_option("texture_quality");
|
||||
|
||||
for (Set< Ref<ImageTexture> >::Element *E=imagemap.front();E;E=E->next()) {
|
||||
for (Map< Ref<ImageTexture>,bool >::Element *E=imagemap.front();E;E=E->next()) {
|
||||
|
||||
//texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff
|
||||
//but not yet..
|
||||
|
||||
Ref<ImageTexture> texture = E->get();
|
||||
Ref<ImageTexture> texture = E->key();
|
||||
|
||||
ERR_CONTINUE(!texture.is_valid());
|
||||
|
||||
|
@ -1657,7 +1834,10 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
|
|||
|
||||
Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
|
||||
print_line("flags: "+itos(image_flags));
|
||||
imd->set_option("flags",image_flags);
|
||||
uint32_t flags = image_flags;
|
||||
if (E->get())
|
||||
flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR;
|
||||
imd->set_option("flags",flags);
|
||||
imd->set_option("format",image_format);
|
||||
imd->set_option("quality",image_quality);
|
||||
imd->set_option("atlas",false);
|
||||
|
@ -1697,11 +1877,14 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
|
|||
|
||||
if (merge) {
|
||||
|
||||
print_line("MERGING?????");
|
||||
progress.step("Merging..",103);
|
||||
|
||||
FileAccess *fa = FileAccess::create(FileAccess::ACCESS_FILESYSTEM);
|
||||
FileAccess *fa = FileAccess::create(FileAccess::ACCESS_RESOURCES);
|
||||
print_line("OPEN IN FS: "+p_dest_path);
|
||||
if (fa->file_exists(p_dest_path)) {
|
||||
|
||||
print_line("TRY REALLY TO MERGE?");
|
||||
//try to merge
|
||||
|
||||
Ref<PackedScene> s = ResourceLoader::load(p_dest_path);
|
||||
|
@ -1711,7 +1894,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c
|
|||
|
||||
if (existing) {
|
||||
|
||||
_merge_scenes(scene,existing);
|
||||
_merge_scenes(existing,scene);
|
||||
|
||||
memdelete(scene);
|
||||
scene=existing;
|
||||
|
|
|
@ -99,11 +99,14 @@ class EditorSceneImportPlugin : public EditorImportPlugin {
|
|||
|
||||
Vector<Ref<EditorSceneImporter> > importers;
|
||||
|
||||
void _find_resources(const Variant& p_var,Set<Ref<ImageTexture> >& image_map);
|
||||
Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Set<Ref<ImageTexture> >& image_map);
|
||||
void _merge_node(Node *p_node,Node*p_root,Node *p_existing,Set<Ref<Resource> >& checked_resources);
|
||||
void _merge_scenes(Node *p_existing,Node *p_new);
|
||||
void _find_resources(const Variant& p_var,Map<Ref<ImageTexture>,bool >& image_map);
|
||||
Node* _fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>,Ref<Shape> > &collision_map,uint32_t p_flags,Map<Ref<ImageTexture>,bool >& image_map);
|
||||
void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set<Ref<Resource> >& checked_resources,Set<Node*> &checked_nodes);
|
||||
void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set<Node*> &checked_nodes);
|
||||
|
||||
void _merge_scenes(Node *p_node, Node *p_imported);
|
||||
|
||||
void _tag_import_paths(Node *p_scene,Node *p_node);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -120,11 +123,13 @@ public:
|
|||
SCENE_FLAG_CREATE_WHEELS=1<<9,
|
||||
SCENE_FLAG_DETECT_ALPHA=1<<15,
|
||||
SCENE_FLAG_DETECT_VCOLOR=1<<16,
|
||||
SCENE_FLAG_CREATE_NAVMESH=1<<17,
|
||||
|
||||
SCENE_FLAG_REMOVE_NOIMP=1<<24,
|
||||
SCENE_FLAG_IMPORT_ANIMATIONS=1<<25,
|
||||
SCENE_FLAG_COMPRESS_GEOMETRY=1<<26,
|
||||
SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27,
|
||||
SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28,
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue