Browse Source

Lots of 3D improvements:
-Object Manipulator Gizmo keeps proper scale in all windows and projections, (configurable on settings too).
-Manipulator gizmos for other objects (camera, shapes, etc) massively improved and bug-fixed.
-Manipulator gizmos are different for edited object and other objects.
-Properly highlight manipulator gizmo handles when hovered.
-Fixed bugs in fragment program when using more than 1 light together.
-Reload png/jpg files automatically in editor if edited externally.
-Added 4-stages Parallel Split Shadow Mapping, to improve shadow quality in large scenarios
-Added PCF13 to improve smoothness of shadow borders
-General optimization of directional light shadow mapping for Orthogonal,PSM and PSSM.
-Fixed normal mapping when importing DAE files, works nicely now.

Juan Linietsky 11 years ago
parent
commit
72ae89c5aa
36 changed files with 1118 additions and 306 deletions
  1. 2 0
      demos/3d/platformer/engine.cfg
  2. 96 28
      demos/3d/platformer/stage2.xml
  3. BIN
      demos/3d/platformer/tiles.res
  4. 21 0
      drivers/gles1/rasterizer_gles1.cpp
  5. 4 0
      drivers/gles1/rasterizer_gles1.h
  6. 106 26
      drivers/gles2/rasterizer_gles2.cpp
  7. 10 9
      drivers/gles2/rasterizer_gles2.h
  8. 98 7
      drivers/gles2/shaders/material.glsl
  9. 1 1
      platform/android/globals/global_defaults.cpp
  10. 3 2
      scene/3d/light.cpp
  11. 2 1
      scene/3d/light.h
  12. 15 1
      scene/gui/popup.cpp
  13. 3 1
      scene/gui/popup.h
  14. 28 0
      scene/resources/mesh.cpp
  15. 4 0
      scene/resources/mesh.h
  16. 13 0
      servers/visual/rasterizer.h
  17. 17 0
      servers/visual/rasterizer_dummy.cpp
  18. 5 0
      servers/visual/rasterizer_dummy.h
  19. 15 0
      servers/visual/visual_server_raster.cpp
  20. 4 1
      servers/visual/visual_server_raster.h
  21. 4 0
      servers/visual/visual_server_wrap_mt.h
  22. 6 2
      servers/visual_server.h
  23. 0 1
      tools/editor/editor_icons.cpp
  24. 7 11
      tools/editor/editor_node.cpp
  25. 4 2
      tools/editor/editor_node.h
  26. 1 0
      tools/editor/editor_settings.cpp
  27. 1 1
      tools/editor/fileserver/editor_file_server.cpp
  28. BIN
      tools/editor/icons/icon_editor_3d_handle.png
  29. 17 8
      tools/editor/io_plugins/editor_import_collada.cpp
  30. 1 1
      tools/editor/io_plugins/editor_import_collada.h
  31. 266 48
      tools/editor/io_plugins/editor_scene_import_plugin.cpp
  32. 20 14
      tools/editor/io_plugins/editor_scene_import_plugin.h
  33. 200 61
      tools/editor/plugins/spatial_editor_plugin.cpp
  34. 33 4
      tools/editor/plugins/spatial_editor_plugin.h
  35. 109 75
      tools/editor/spatial_editor_gizmos.cpp
  36. 2 1
      tools/editor/spatial_editor_gizmos.h

+ 2 - 0
demos/3d/platformer/engine.cfg

@@ -22,3 +22,5 @@ shoot=[key(Z)]
 
 
 max_shadow_buffer_size=1024
 max_shadow_buffer_size=1024
 framebuffer_shrink=1
 framebuffer_shrink=1
+shadow_filter=1
+;debug_shadow_maps=true

File diff suppressed because it is too large
+ 96 - 28
demos/3d/platformer/stage2.xml


BIN
demos/3d/platformer/tiles.res


+ 21 - 0
drivers/gles1/rasterizer_gles1.cpp

@@ -1982,6 +1982,9 @@ AABB RasterizerGLES1::mesh_get_aabb(RID p_mesh) const {
 	Mesh *mesh = mesh_owner.get( p_mesh );
 	Mesh *mesh = mesh_owner.get( p_mesh );
 	ERR_FAIL_COND_V(!mesh,AABB());
 	ERR_FAIL_COND_V(!mesh,AABB());
 
 
+	if (mesh->custom_aabb!=AABB())
+		return mesh->custom_aabb;
+
 	AABB aabb;
 	AABB aabb;
 
 
 	for (int i=0;i<mesh->surfaces.size();i++) {
 	for (int i=0;i<mesh->surfaces.size();i++) {
@@ -1995,6 +1998,24 @@ AABB RasterizerGLES1::mesh_get_aabb(RID p_mesh) const {
 	return aabb;
 	return aabb;
 }
 }
 
 
+void RasterizerGLES1::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) {
+
+	Mesh *mesh = mesh_owner.get( p_mesh );
+	ERR_FAIL_COND(!mesh);
+
+	mesh->custom_aabb=p_aabb;
+
+}
+
+AABB RasterizerGLES1::mesh_get_custom_aabb(RID p_mesh) const {
+
+	const Mesh *mesh = mesh_owner.get( p_mesh );
+	ERR_FAIL_COND_V(!mesh,AABB());
+
+	return mesh->custom_aabb;
+}
+
+
 /* MULTIMESH API */
 /* MULTIMESH API */
 
 
 RID RasterizerGLES1::multimesh_create() {
 RID RasterizerGLES1::multimesh_create() {

+ 4 - 0
drivers/gles1/rasterizer_gles1.h

@@ -323,6 +323,7 @@ class RasterizerGLES1 : public Rasterizer {
 		Vector<Surface*> surfaces;
 		Vector<Surface*> surfaces;
 		int morph_target_count;
 		int morph_target_count;
 		VS::MorphTargetMode morph_target_mode;
 		VS::MorphTargetMode morph_target_mode;
+		AABB custom_aabb;
 
 
 		mutable uint64_t last_pass;
 		mutable uint64_t last_pass;
 		Mesh() {
 		Mesh() {
@@ -938,6 +939,9 @@ public:
 
 
 	virtual AABB mesh_get_aabb(RID p_mesh) const;
 	virtual AABB mesh_get_aabb(RID p_mesh) const;
 
 
+	virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb);
+	virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
+
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 
 	virtual RID multimesh_create();
 	virtual RID multimesh_create();

+ 106 - 26
drivers/gles2/rasterizer_gles2.cpp

@@ -2241,6 +2241,9 @@ AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh) const {
 	Mesh *mesh = mesh_owner.get( p_mesh );
 	Mesh *mesh = mesh_owner.get( p_mesh );
 	ERR_FAIL_COND_V(!mesh,AABB());
 	ERR_FAIL_COND_V(!mesh,AABB());
 
 
+	if (mesh->custom_aabb!=AABB())
+		return mesh->custom_aabb;
+
 	AABB aabb;
 	AABB aabb;
 
 
 	for (int i=0;i<mesh->surfaces.size();i++) {
 	for (int i=0;i<mesh->surfaces.size();i++) {
@@ -2253,6 +2256,24 @@ AABB RasterizerGLES2::mesh_get_aabb(RID p_mesh) const {
 
 
 	return aabb;
 	return aabb;
 }
 }
+
+
+void RasterizerGLES2::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) {
+
+	Mesh *mesh = mesh_owner.get( p_mesh );
+	ERR_FAIL_COND(!mesh);
+
+	mesh->custom_aabb=p_aabb;
+
+}
+
+AABB RasterizerGLES2::mesh_get_custom_aabb(RID p_mesh) const {
+
+	const Mesh *mesh = mesh_owner.get( p_mesh );
+	ERR_FAIL_COND_V(!mesh,AABB());
+
+	return mesh->custom_aabb;
+}
 /* MULTIMESH API */
 /* MULTIMESH API */
 
 
 RID RasterizerGLES2::multimesh_create() {
 RID RasterizerGLES2::multimesh_create() {
@@ -3114,7 +3135,8 @@ Rasterizer::ShadowType RasterizerGLES2::light_instance_get_shadow_type(RID p_lig
 				case VS::LIGHT_DIRECTIONAL_SHADOW_PERSPECTIVE:{
 				case VS::LIGHT_DIRECTIONAL_SHADOW_PERSPECTIVE:{
 					return SHADOW_PSM;
 					return SHADOW_PSM;
 				} break;
 				} break;
-				case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT:{
+				case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS:
+				case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS:{
 					return SHADOW_PSSM;
 					return SHADOW_PSSM;
 				} break;
 				} break;
 			}
 			}
@@ -3131,9 +3153,13 @@ int RasterizerGLES2::light_instance_get_shadow_passes(RID p_light_instance) cons
 
 
 	LightInstance *lighti = light_instance_owner.get( p_light_instance );
 	LightInstance *lighti = light_instance_owner.get( p_light_instance );
 	ERR_FAIL_COND_V(!lighti,0);
 	ERR_FAIL_COND_V(!lighti,0);
-	if (lighti->base->type==VS::LIGHT_OMNI || (lighti->base->type==VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT))
+
+	if (lighti->base->type==VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
+
+		return 4; // dp4
+	} else if (lighti->base->type==VS::LIGHT_OMNI || (lighti->base->type==VS::LIGHT_DIRECTIONAL && lighti->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS)) {
 		return 2; // dp
 		return 2; // dp
-	else
+	} else
 		return 1;
 		return 1;
 }
 }
 
 
@@ -3145,6 +3171,10 @@ void RasterizerGLES2::light_instance_set_shadow_transform(RID p_light_instance,
 	ERR_FAIL_COND(lighti->base->type!=VS::LIGHT_DIRECTIONAL);
 	ERR_FAIL_COND(lighti->base->type!=VS::LIGHT_DIRECTIONAL);
 //	ERR_FAIL_INDEX(p_index,1);
 //	ERR_FAIL_INDEX(p_index,1);
 
 
+	lighti->custom_projection[p_index]=p_camera;
+	lighti->custom_transform[p_index]=p_transform;
+	lighti->shadow_split[p_index]=1.0/p_split_far;
+#if 0
 	if (p_index==0) {
 	if (p_index==0) {
 		lighti->custom_projection=p_camera;
 		lighti->custom_projection=p_camera;
 		lighti->custom_transform=p_transform;
 		lighti->custom_transform=p_transform;
@@ -3161,7 +3191,7 @@ void RasterizerGLES2::light_instance_set_shadow_transform(RID p_light_instance,
 		lighti->shadow_split2=p_split_far;
 		lighti->shadow_split2=p_split_far;
 
 
 	}
 	}
-
+#endif
 }
 }
 
 
 int RasterizerGLES2::light_instance_get_shadow_size(RID p_light_instance, int p_index) const{
 int RasterizerGLES2::light_instance_get_shadow_size(RID p_light_instance, int p_index) const{
@@ -3407,6 +3437,7 @@ void RasterizerGLES2::begin_frame() {
 
 
 	//fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
 	//fragment_lighting=Globals::get_singleton()->get("rasterizer/use_fragment_lighting");
 	canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
 	canvas_shader.set_conditional(CanvasShaderGLES2::USE_PIXEL_SNAP,GLOBAL_DEF("rasterizer/use_pixel_snap",false));
+	shadow_filter=ShadowFilterTechnique(int(Globals::get_singleton()->get("rasterizer/shadow_filter")));
 
 
 
 
 	window_size = Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height );
 	window_size = Size2( OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height );
@@ -3675,18 +3706,21 @@ void RasterizerGLES2::add_light( RID p_light_instance ) {
 			if (li->base->shadow_enabled) {
 			if (li->base->shadow_enabled) {
 				CameraMatrix bias;
 				CameraMatrix bias;
 				bias.set_light_bias();
 				bias.set_light_bias();
-				Transform modelview=Transform(camera_transform_inverse * li->custom_transform).inverse();
-				li->shadow_projection = bias * li->custom_projection * modelview;
 
 
-				Transform modelview2=Transform(camera_transform_inverse * li->custom_transform2).inverse();
-				li->shadow_projection2 = bias * li->custom_projection2 * modelview2;
+				int passes=light_instance_get_shadow_passes(p_light_instance);
+
+				for(int i=0;i<passes;i++) {
+					Transform modelview=Transform(camera_transform_inverse * li->custom_transform[i]).inverse();
+					li->shadow_projection[i] = bias * li->custom_projection[i] * modelview;
+				}
+
 				lights_use_shadow=true;
 				lights_use_shadow=true;
 			}
 			}
 		} break;
 		} break;
 		case VS::LIGHT_OMNI: {
 		case VS::LIGHT_OMNI: {
 
 
 			if (li->base->shadow_enabled) {
 			if (li->base->shadow_enabled) {
-				li->shadow_projection = Transform(camera_transform_inverse * li->transform).inverse();
+				li->shadow_projection[0] = Transform(camera_transform_inverse * li->transform).inverse();
 				lights_use_shadow=true;
 				lights_use_shadow=true;
 			}
 			}
 		} break;
 		} break;
@@ -3696,7 +3730,7 @@ void RasterizerGLES2::add_light( RID p_light_instance ) {
 				CameraMatrix bias;
 				CameraMatrix bias;
 				bias.set_light_bias();
 				bias.set_light_bias();
 				Transform modelview=Transform(camera_transform_inverse * li->transform).inverse();
 				Transform modelview=Transform(camera_transform_inverse * li->transform).inverse();
-				li->shadow_projection = bias * li->projection * modelview;
+				li->shadow_projection[0] = bias * li->projection * modelview;
 				lights_use_shadow=true;
 				lights_use_shadow=true;
 			}
 			}
 		} break;
 		} break;
@@ -3954,8 +3988,10 @@ void RasterizerGLES2::_add_geometry( const Geometry* p_geometry, const InstanceD
 			light_types[i]=VS::LIGHT_DIRECTIONAL;
 			light_types[i]=VS::LIGHT_DIRECTIONAL;
 			if (directional_lights[i]->base->shadow_enabled) {
 			if (directional_lights[i]->base->shadow_enabled) {
 				light_types[i]|=0x8;
 				light_types[i]|=0x8;
-				if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT)
+				if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS)
 					light_types[i]|=0x10;
 					light_types[i]|=0x10;
+				else if (directional_lights[i]->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS)
+					light_types[i]|=0x30;
 
 
 			}
 			}
 
 
@@ -4152,7 +4188,8 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
 
 
 	//all goes to false by default
 	//all goes to false by default
 	material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PASS,shadow!=NULL);
 	material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PASS,shadow!=NULL);
-	material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF,use_shadow_pcf);
+	material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF,shadow_filter!=SHADOW_FILTER_NONE);
+	material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_PCF_HQ,shadow_filter>SHADOW_FILTER_PCF5);
 	//material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,true);
 	//material_shader.set_conditional(MaterialShaderGLES2::USE_SHADOW_ESM,true);
 
 
 
 
@@ -4379,16 +4416,27 @@ void RasterizerGLES2::_setup_light(uint16_t p_light) {
 
 
 		//}
 		//}
 
 
-		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX,li->shadow_projection);
+		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX,li->shadow_projection[0]);
 		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXEL_SIZE,Vector2(1.0,1.0)/li->near_shadow_buffer->size);
 		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXEL_SIZE,Vector2(1.0,1.0)/li->near_shadow_buffer->size);
 		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,7);
 		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_TEXTURE,7);
 
 
-		if (li->base->type==VS::LIGHT_DIRECTIONAL && li->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT) {
+		if (li->base->type==VS::LIGHT_DIRECTIONAL) {
+
+			if (li->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
+
+				material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2,li->shadow_projection[1]);
+				material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,Vector3(li->shadow_split[0],li->shadow_split[1],li->shadow_split[2]));
+			} else if (li->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
+
+
+				material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2,li->shadow_projection[1]);
+				material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX3,li->shadow_projection[2]);
+				material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX4,li->shadow_projection[3]);
+				material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,Vector3(li->shadow_split[0],li->shadow_split[1],li->shadow_split[2]));
 
 
-			material_shader.set_uniform(MaterialShaderGLES2::SHADOW_MATRIX2,li->shadow_projection2);
-			material_shader.set_uniform(MaterialShaderGLES2::LIGHT_PSSM_SPLIT,li->shadow_split);
+			}
 			//print_line("shadow split: "+rtos(li->shadow_split));
 			//print_line("shadow split: "+rtos(li->shadow_split));
-		}
+		} else
 		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_DARKENING,li->base->vars[VS::LIGHT_PARAM_SHADOW_DARKENING]);
 		material_shader.set_uniform(MaterialShaderGLES2::SHADOW_DARKENING,li->base->vars[VS::LIGHT_PARAM_SHADOW_DARKENING]);
 		//matrix
 		//matrix
 
 
@@ -5126,6 +5174,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
 		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,false);
 		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,false);
 		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false);
 		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false);
 		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false);
 		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false);
+		material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,false);
 		material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false);
 		material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false);
 	}
 	}
 
 
@@ -5179,6 +5228,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,false);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,false);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,false);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,false);
+					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,false);
 					material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,true);
 					material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,true);
 				} else {
 				} else {
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL,(light_type&0x3)==VS::LIGHT_DIRECTIONAL);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_DIRECTIONAL,(light_type&0x3)==VS::LIGHT_DIRECTIONAL);
@@ -5186,6 +5236,7 @@ void RasterizerGLES2::_render_list_forward(RenderList *p_render_list,const Trans
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,(light_type&0x3)==VS::LIGHT_SPOT);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_TYPE_SPOT,(light_type&0x3)==VS::LIGHT_SPOT);
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,(light_type&0x8));
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_SHADOW,(light_type&0x8));
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,(light_type&0x10));
 					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM,(light_type&0x10));
+					material_shader.set_conditional(MaterialShaderGLES2::LIGHT_USE_PSSM4,(light_type&0x20));
 					material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false);
 					material_shader.set_conditional(MaterialShaderGLES2::SHADELESS,false);
 				}
 				}
 
 
@@ -6010,18 +6061,45 @@ void RasterizerGLES2::end_shadow_map() {
 
 
 		case VS::LIGHT_DIRECTIONAL: {
 		case VS::LIGHT_DIRECTIONAL: {
 
 
-			if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT) {
+			if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
+
+				cm = shadow->custom_projection[shadow_pass];
+				light_transform=shadow->custom_transform[shadow_pass];
+
+				if (shadow_pass==0) {
+
+					glViewport(0, sb->size*0.5, sb->size*0.5, sb->size*0.5);
+					glScissor(0, sb->size*0.5, sb->size*0.5, sb->size*0.5);
+				} else if (shadow_pass==1) {
+
+					glViewport(0, 0, sb->size*0.5, sb->size*0.5);
+					glScissor(0, 0, sb->size*0.5, sb->size*0.5);
+
+				} else if (shadow_pass==2) {
+
+					glViewport(sb->size*0.5, sb->size*0.5, sb->size*0.5, sb->size*0.5);
+					glScissor(sb->size*0.5, sb->size*0.5, sb->size*0.5, sb->size*0.5);
+				} else if (shadow_pass==3) {
+
+					glViewport(sb->size*0.5, 0, sb->size*0.5, sb->size*0.5);
+					glScissor(sb->size*0.5, 0, sb->size*0.5, sb->size*0.5);
+
+				}
+
+				glEnable(GL_SCISSOR_TEST);
+
+			} else if (shadow->base->directional_shadow_mode==VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
 
 
 				if (shadow_pass==0) {
 				if (shadow_pass==0) {
 
 
-					cm = shadow->custom_projection;
-					light_transform=shadow->custom_transform;
+					cm = shadow->custom_projection[0];
+					light_transform=shadow->custom_transform[0];
 					glViewport(0, sb->size*0.5, sb->size, sb->size*0.5);
 					glViewport(0, sb->size*0.5, sb->size, sb->size*0.5);
 					glScissor(0, sb->size*0.5, sb->size, sb->size*0.5);
 					glScissor(0, sb->size*0.5, sb->size, sb->size*0.5);
 				} else {
 				} else {
 
 
-					cm = shadow->custom_projection2;
-					light_transform=shadow->custom_transform2;
+					cm = shadow->custom_projection[1];
+					light_transform=shadow->custom_transform[1];
 					glViewport(0, 0, sb->size, sb->size*0.5);
 					glViewport(0, 0, sb->size, sb->size*0.5);
 					glScissor(0, 0, sb->size, sb->size*0.5);
 					glScissor(0, 0, sb->size, sb->size*0.5);
 
 
@@ -6030,8 +6108,8 @@ void RasterizerGLES2::end_shadow_map() {
 				glEnable(GL_SCISSOR_TEST);
 				glEnable(GL_SCISSOR_TEST);
 
 
 			} else {
 			} else {
-				cm = shadow->custom_projection;
-				light_transform=shadow->custom_transform;
+				cm = shadow->custom_projection[0];
+				light_transform=shadow->custom_transform[0];
 				glViewport(0, 0, sb->size, sb->size);
 				glViewport(0, 0, sb->size, sb->size);
 			}
 			}
 
 
@@ -7993,9 +8071,11 @@ RasterizerGLES2::RasterizerGLES2(bool p_compress_arrays,bool p_keep_ram_copy,boo
 	p_default_fragment_lighting=false;
 	p_default_fragment_lighting=false;
 	fragment_lighting=GLOBAL_DEF("rasterizer/use_fragment_lighting",true);
 	fragment_lighting=GLOBAL_DEF("rasterizer/use_fragment_lighting",true);
 	read_depth_supported=true; //todo check for extension
 	read_depth_supported=true; //todo check for extension
-	use_shadow_pcf=GLOBAL_DEF("rasterizer/use_shadow_pcf",true);
+	shadow_filter=ShadowFilterTechnique((int)(GLOBAL_DEF("rasterizer/shadow_filter",SHADOW_FILTER_PCF5)));
+	Globals::get_singleton()->set_custom_property_info("rasterizer/shadow_filter",PropertyInfo(Variant::INT,"rasterizer/shadow_filter",PROPERTY_HINT_ENUM,"None,PCF5,PCF13,ESM,VSM"));
+
 	use_shadow_mapping=true;
 	use_shadow_mapping=true;
-	use_fast_texture_filter=GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true);
+	use_fast_texture_filter=!bool(GLOBAL_DEF("rasterizer/trilinear_mipmap_filter",true));
 	skel_default.resize(1024*4);
 	skel_default.resize(1024*4);
 	for(int i=0;i<1024/3;i++) {
 	for(int i=0;i<1024/3;i++) {
 
 

+ 10 - 9
drivers/gles2/rasterizer_gles2.h

@@ -80,6 +80,8 @@ class RasterizerGLES2 : public Rasterizer {
 	bool read_depth_supported;
 	bool read_depth_supported;
 	bool use_framebuffers;
 	bool use_framebuffers;
 	bool use_shadow_mapping;
 	bool use_shadow_mapping;
+	ShadowFilterTechnique shadow_filter;
+
 	bool use_shadow_esm;
 	bool use_shadow_esm;
 	bool use_shadow_pcf;
 	bool use_shadow_pcf;
 	bool use_hw_skeleton_xform;
 	bool use_hw_skeleton_xform;
@@ -374,6 +376,7 @@ class RasterizerGLES2 : public Rasterizer {
 		Vector<Surface*> surfaces;
 		Vector<Surface*> surfaces;
 		int morph_target_count;
 		int morph_target_count;
 		VS::MorphTargetMode morph_target_mode;
 		VS::MorphTargetMode morph_target_mode;
+		AABB custom_aabb;
 
 
 		mutable uint64_t last_pass;
 		mutable uint64_t last_pass;
 		Mesh() {
 		Mesh() {
@@ -659,11 +662,8 @@ class RasterizerGLES2 : public Rasterizer {
 		Transform transform;
 		Transform transform;
 		CameraMatrix projection;
 		CameraMatrix projection;
 
 
-		Transform custom_transform;
-		CameraMatrix custom_projection;
-
-		Transform custom_transform2;
-		CameraMatrix custom_projection2;
+		Transform custom_transform[4];
+		CameraMatrix custom_projection[4];
 
 
 		Vector3 light_vector;
 		Vector3 light_vector;
 		Vector3 spot_vector;
 		Vector3 spot_vector;
@@ -675,11 +675,9 @@ class RasterizerGLES2 : public Rasterizer {
 
 
 		Vector2 dp;
 		Vector2 dp;
 
 
-		CameraMatrix shadow_projection;
-		CameraMatrix shadow_projection2;
+		CameraMatrix shadow_projection[4];
+		float shadow_split[4];
 
 
-		float shadow_split;
-		float shadow_split2;		
 
 
 
 
 		ShadowBuffer* near_shadow_buffer;
 		ShadowBuffer* near_shadow_buffer;
@@ -1183,6 +1181,9 @@ public:
 
 
 	virtual AABB mesh_get_aabb(RID p_mesh) const;
 	virtual AABB mesh_get_aabb(RID p_mesh) const;
 
 
+	virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb);
+	virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
+
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 
 	virtual RID multimesh_create();
 	virtual RID multimesh_create();

+ 98 - 7
drivers/gles2/shaders/material.glsl

@@ -140,6 +140,12 @@ varying highp vec4 shadow_coord;
 uniform highp mat4 shadow_matrix2;
 uniform highp mat4 shadow_matrix2;
 varying highp vec4 shadow_coord2;
 varying highp vec4 shadow_coord2;
 #endif
 #endif
+#ifdef LIGHT_USE_PSSM4
+uniform highp mat4 shadow_matrix3;
+varying highp vec4 shadow_coord3;
+uniform highp mat4 shadow_matrix4;
+varying highp vec4 shadow_coord4;
+#endif
 
 
 
 
 #endif
 #endif
@@ -290,6 +296,22 @@ VERTEX_SHADER_CODE
 	shadow_coord2.xyz/=shadow_coord2.w;
 	shadow_coord2.xyz/=shadow_coord2.w;
 	shadow_coord2.y*=0.5;
 	shadow_coord2.y*=0.5;
 #endif
 #endif
+#ifdef LIGHT_USE_PSSM4
+	shadow_coord.x*=0.5;
+	shadow_coord2.x*=0.5;
+
+	shadow_coord3 = shadow_matrix3 * vec4(vertex_interp,1.0);
+	shadow_coord3.xyz/=shadow_coord3.w;
+	shadow_coord3.xy*=vec2(0.5);
+	shadow_coord3.xy+=vec2(0.5);
+
+	shadow_coord4 = shadow_matrix4 * vec4(vertex_interp,1.0);
+	shadow_coord4.xyz/=shadow_coord4.w;
+	shadow_coord4.xy*=vec2(0.5);
+	shadow_coord4.x+=0.5;
+
+#endif
+
 #endif
 #endif
 
 
 #ifdef USE_FOG
 #ifdef USE_FOG
@@ -428,7 +450,7 @@ varying vec4 var2_interp;
 #endif
 #endif
 
 
 #ifdef LIGHT_USE_PSSM
 #ifdef LIGHT_USE_PSSM
-uniform float light_pssm_split;
+uniform vec3 light_pssm_split;
 #endif
 #endif
 
 
 varying vec3 vertex_interp;
 varying vec3 vertex_interp;
@@ -504,6 +526,11 @@ varying highp vec4 shadow_coord;
 #ifdef LIGHT_USE_PSSM
 #ifdef LIGHT_USE_PSSM
 varying highp vec4 shadow_coord2;
 varying highp vec4 shadow_coord2;
 #endif
 #endif
+#ifdef LIGHT_USE_PSSM4
+varying highp vec4 shadow_coord3;
+varying highp vec4 shadow_coord4;
+#endif
+
 uniform highp sampler2D shadow_texture;
 uniform highp sampler2D shadow_texture;
 uniform highp vec2 shadow_texel_size;
 uniform highp vec2 shadow_texel_size;
 
 
@@ -523,6 +550,29 @@ uniform float shadow_darkening;
 #ifdef USE_SHADOW_PCF
 #ifdef USE_SHADOW_PCF
 
 
 
 
+#ifdef USE_SHADOW_PCF_HQ
+
+
+float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) {
+
+	float avg=(SHADOW_DEPTH(shadow_texture,coord) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x,0.0)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,0.0)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x,shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x,-shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,-shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(shadow_texel_size.x*2.0,0.0)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x*2.0,0.0)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y*2.0)) < refdepth ?  0.0 : 1.0);
+	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y*2.0)) < refdepth ?  0.0 : 1.0);
+	return avg*(1.0/13.0);
+}
+
+#else
+
 float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) {
 float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) {
 
 
 	float avg=(SHADOW_DEPTH(shadow_texture,coord) < refdepth ?  0.0 : 1.0);
 	float avg=(SHADOW_DEPTH(shadow_texture,coord) < refdepth ?  0.0 : 1.0);
@@ -530,9 +580,13 @@ float SAMPLE_SHADOW_TEX( highp vec2 coord, highp float refdepth) {
 	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,0.0)) < refdepth ?  0.0 : 1.0);
 	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(-shadow_texel_size.x,0.0)) < refdepth ?  0.0 : 1.0);
 	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
 	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
 	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
 	avg+=(SHADOW_DEPTH(shadow_texture,coord+vec2(0.0,-shadow_texel_size.y)) < refdepth ?  0.0 : 1.0);
-        return avg*0.2;
+	return avg*0.2;
 }
 }
 
 
+#endif
+
+
+
 
 
 /*
 /*
 	16x averaging
 	16x averaging
@@ -697,7 +751,7 @@ FRAGMENT_SHADER_CODE
 #if 0
 #if 0
 	highp vec3 splane = vec3(0.0,0.0,0.0);
 	highp vec3 splane = vec3(0.0,0.0,0.0);
 
 
-	if (gl_FragCoord.w > light_pssm_split) {
+	if (gl_FragCoord.w > light_pssm_split.x) {
 
 
 		splane = shadow_coord.xyz;
 		splane = shadow_coord.xyz;
 		splane.y+=1.0;
 		splane.y+=1.0;
@@ -711,19 +765,56 @@ FRAGMENT_SHADER_CODE
 /*
 /*
 	float sa_a = SAMPLE_SHADOW_TEX(shadow_coord.xy,shadow_coord.z);
 	float sa_a = SAMPLE_SHADOW_TEX(shadow_coord.xy,shadow_coord.z);
 	float sa_b = SAMPLE_SHADOW_TEX(shadow_coord2.xy,shadow_coord2.z);
 	float sa_b = SAMPLE_SHADOW_TEX(shadow_coord2.xy,shadow_coord2.z);
-	if (gl_FragCoord.w > light_pssm_split) {
+	if (gl_FragCoord.w > light_pssm_split.x) {
 		shadow_attenuation=sa_a;
 		shadow_attenuation=sa_a;
 	} else {
 	} else {
 		shadow_attenuation=sa_b;
 		shadow_attenuation=sa_b;
 	}
 	}
 */
 */
 
 
-	if (gl_FragCoord.w > light_pssm_split) {
-		shadow_attenuation=SAMPLE_SHADOW_TEX(shadow_coord.xy,shadow_coord.z);
+	vec2 pssm_coord;
+	float pssm_z;
+
+#ifdef LIGHT_USE_PSSM4
+
+
+	if (gl_FragCoord.w > light_pssm_split.y) {
+
+		if (gl_FragCoord.w > light_pssm_split.x) {
+			pssm_coord=shadow_coord.xy;
+			pssm_z=shadow_coord.z;
+
+		} else {
+			pssm_coord=shadow_coord2.xy;
+			pssm_z=shadow_coord2.z;
+		}
+	} else {
+
+
+		if (gl_FragCoord.w > light_pssm_split.z) {
+			pssm_coord=shadow_coord3.xy;
+			pssm_z=shadow_coord3.z;
+		} else {
+			pssm_coord=shadow_coord4.xy;
+			pssm_z=shadow_coord4.z;
+		}
+	}
+
+#else
+
+	if (gl_FragCoord.w > light_pssm_split.x) {
+		pssm_coord=shadow_coord.xy;
+		pssm_z=shadow_coord.z;
+
 	} else {
 	} else {
-		shadow_attenuation=SAMPLE_SHADOW_TEX(shadow_coord2.xy,shadow_coord2.z);
+		pssm_coord=shadow_coord2.xy;
+		pssm_z=shadow_coord2.z;
 	}
 	}
 
 
+#endif
+
+	//one one sample
+	shadow_attenuation=SAMPLE_SHADOW_TEX(pssm_coord,pssm_z);
 
 
 #endif
 #endif
 
 

+ 1 - 1
platform/android/globals/global_defaults.cpp

@@ -7,7 +7,7 @@ void register_android_global_defaults() {
 
 
 	GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false);
 	GLOBAL_DEF("rasterizer.Android/use_fragment_lighting",false);
 	GLOBAL_DEF("display.Android/driver","GLES2");
 	GLOBAL_DEF("display.Android/driver","GLES2");
-	GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
+//	GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
 
 
 	Globals::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2"));
 	Globals::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES1,GLES2"));
 }
 }

+ 3 - 2
scene/3d/light.cpp

@@ -540,14 +540,15 @@ void DirectionalLight::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_shadow_param","param","value"),&DirectionalLight::set_shadow_param);
 	ObjectTypeDB::bind_method(_MD("set_shadow_param","param","value"),&DirectionalLight::set_shadow_param);
 	ObjectTypeDB::bind_method(_MD("get_shadow_param","param"),&DirectionalLight::get_shadow_param);
 	ObjectTypeDB::bind_method(_MD("get_shadow_param","param"),&DirectionalLight::get_shadow_param);
 
 
-	ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode"));
+	ADD_PROPERTY( PropertyInfo(Variant::INT,"shadow/mode",PROPERTY_HINT_ENUM,"Orthogonal,Perspective,PSSM 2 Splits,PSSM 4 Splits"),_SCS("set_shadow_mode"),_SCS("get_shadow_mode"));
 	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/max_distance",PROPERTY_HINT_EXP_RANGE,"0.00,99999,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE);
 	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/max_distance",PROPERTY_HINT_EXP_RANGE,"0.00,99999,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_MAX_DISTANCE);
 	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/split_weight",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
 	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/split_weight",PROPERTY_HINT_RANGE,"0.01,1.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_SPLIT_WEIGHT);
 	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/zoffset_scale",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
 	ADD_PROPERTYI( PropertyInfo(Variant::REAL,"shadow/zoffset_scale",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_shadow_param"),_SCS("get_shadow_param"), SHADOW_PARAM_PSSM_ZOFFSET_SCALE);
 
 
 	BIND_CONSTANT( SHADOW_ORTHOGONAL );
 	BIND_CONSTANT( SHADOW_ORTHOGONAL );
 	BIND_CONSTANT( SHADOW_PERSPECTIVE );
 	BIND_CONSTANT( SHADOW_PERSPECTIVE );
-	BIND_CONSTANT( SHADOW_PARALLEL_SPLIT );
+	BIND_CONSTANT( SHADOW_PARALLEL_2_SPLITS );
+	BIND_CONSTANT( SHADOW_PARALLEL_4_SPLITS );
 	BIND_CONSTANT( SHADOW_PARAM_MAX_DISTANCE );
 	BIND_CONSTANT( SHADOW_PARAM_MAX_DISTANCE );
 	BIND_CONSTANT( SHADOW_PARAM_PSSM_SPLIT_WEIGHT );
 	BIND_CONSTANT( SHADOW_PARAM_PSSM_SPLIT_WEIGHT );
 	BIND_CONSTANT( SHADOW_PARAM_PSSM_ZOFFSET_SCALE );
 	BIND_CONSTANT( SHADOW_PARAM_PSSM_ZOFFSET_SCALE );

+ 2 - 1
scene/3d/light.h

@@ -138,7 +138,8 @@ public:
 	enum ShadowMode {
 	enum ShadowMode {
 		SHADOW_ORTHOGONAL,
 		SHADOW_ORTHOGONAL,
 		SHADOW_PERSPECTIVE,
 		SHADOW_PERSPECTIVE,
-		SHADOW_PARALLEL_SPLIT
+		SHADOW_PARALLEL_2_SPLITS,
+		SHADOW_PARALLEL_4_SPLITS
 	};
 	};
 	enum ShadowParam {
 	enum ShadowParam {
 		SHADOW_PARAM_MAX_DISTANCE,
 		SHADOW_PARAM_MAX_DISTANCE,

+ 15 - 1
scene/gui/popup.cpp

@@ -38,7 +38,13 @@ void Popup::_input_event(InputEvent p_event) {
 
 
 void Popup::_notification(int p_what) {
 void Popup::_notification(int p_what) {
 	
 	
-
+	if (p_what==NOTIFICATION_VISIBILITY_CHANGED) {
+		if (popped_up && !is_visible()) {
+			popped_up=false;
+			notification(NOTIFICATION_POPUP_HIDE);
+			emit_signal("popup_hide");
+		}
+	}
 }
 }
 
 
 void Popup::_fix_size() {
 void Popup::_fix_size() {
@@ -101,6 +107,7 @@ void Popup::popup_centered_minsize(const Size2& p_minsize) {
 
 
 
 
 	popup_centered( total_minsize );
 	popup_centered( total_minsize );
+	popped_up=true;
 
 
 }
 }
 
 
@@ -127,6 +134,7 @@ void Popup::popup_centered(const Size2& p_size) {
 
 
 	_post_popup();
 	_post_popup();
 	notification(NOTIFICATION_POST_POPUP);
 	notification(NOTIFICATION_POST_POPUP);
+	popped_up=true;
 }
 }
 
 
 void Popup::popup_centered_ratio(float p_screen_ratio) {
 void Popup::popup_centered_ratio(float p_screen_ratio) {
@@ -153,6 +161,7 @@ void Popup::popup_centered_ratio(float p_screen_ratio) {
 
 
 	_post_popup();
 	_post_popup();
 	notification(NOTIFICATION_POST_POPUP);
 	notification(NOTIFICATION_POST_POPUP);
+	popped_up=true;
 
 
 }
 }
 
 
@@ -171,6 +180,7 @@ void Popup::popup() {
 
 
 	_post_popup();
 	_post_popup();
 	notification(NOTIFICATION_POST_POPUP);
 	notification(NOTIFICATION_POST_POPUP);
+	popped_up=true;
 }
 }
 
 
 void Popup::set_exclusive(bool p_exclusive) {
 void Popup::set_exclusive(bool p_exclusive) {
@@ -193,8 +203,11 @@ void Popup::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("set_exclusive","enable"),&Popup::set_exclusive);
 	ObjectTypeDB::bind_method(_MD("set_exclusive","enable"),&Popup::set_exclusive);
 	ObjectTypeDB::bind_method(_MD("is_exclusive"),&Popup::is_exclusive);
 	ObjectTypeDB::bind_method(_MD("is_exclusive"),&Popup::is_exclusive);
 	ADD_SIGNAL( MethodInfo("about_to_show") );
 	ADD_SIGNAL( MethodInfo("about_to_show") );
+	ADD_SIGNAL( MethodInfo("popup_hide") );
 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "popup/exclusive"), _SCS("set_exclusive"),_SCS("is_exclusive") );
 	ADD_PROPERTY( PropertyInfo( Variant::BOOL, "popup/exclusive"), _SCS("set_exclusive"),_SCS("is_exclusive") );
 	BIND_CONSTANT(NOTIFICATION_POST_POPUP);
 	BIND_CONSTANT(NOTIFICATION_POST_POPUP);
+	BIND_CONSTANT(NOTIFICATION_POPUP_HIDE);
+
 
 
 }
 }
 
 
@@ -202,6 +215,7 @@ Popup::Popup() {
 
 
 	set_as_toplevel(true);
 	set_as_toplevel(true);
 	exclusive=false;
 	exclusive=false;
+	popped_up=false;
 	hide();
 	hide();
 }
 }
 
 

+ 3 - 1
scene/gui/popup.h

@@ -39,6 +39,7 @@ class Popup : public Control {
 	OBJ_TYPE( Popup, Control );
 	OBJ_TYPE( Popup, Control );
 
 
 	bool exclusive;
 	bool exclusive;
+	bool popped_up;
 	
 	
 protected:
 protected:
 
 
@@ -51,7 +52,8 @@ protected:
 public:
 public:
 
 
 	enum {
 	enum {
-		NOTIFICATION_POST_POPUP=80
+		NOTIFICATION_POST_POPUP=80,
+		NOTIFICATION_POPUP_HIDE=81
 	};
 	};
 	
 	
 	void set_exclusive(bool p_exclusive);
 	void set_exclusive(bool p_exclusive);

+ 28 - 0
scene/resources/mesh.cpp

@@ -99,6 +99,12 @@ bool Mesh::_set(const StringName& p_name, const Variant& p_value) {
 		return true;
 		return true;
 	}
 	}
 
 
+	if (sname=="custom_aabb/custom_aabb") {
+
+		set_custom_aabb(p_value);
+		return true;
+	}
+
 	if (!sname.begins_with("surfaces"))
 	if (!sname.begins_with("surfaces"))
 		return false;
 		return false;
 
 
@@ -165,6 +171,10 @@ bool Mesh::_get(const StringName& p_name,Variant &r_ret) const {
 		int idx=sname.get_slice("/",1).to_int()-1;
 		int idx=sname.get_slice("/",1).to_int()-1;
 		r_ret=surface_get_material(idx);
 		r_ret=surface_get_material(idx);
 		return true;
 		return true;
+	} else if (sname=="custom_aabb/custom_aabb") {
+
+		r_ret=custom_aabb;
+		return true;
 
 
 	} else if (!sname.begins_with("surfaces"))
 	} else if (!sname.begins_with("surfaces"))
 		return false;
 		return false;
@@ -202,6 +212,9 @@ void Mesh::_get_property_list( List<PropertyInfo> *p_list) const {
 		p_list->push_back( PropertyInfo( Variant::DICTIONARY,"surfaces/"+itos(i), PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR ) );
 		p_list->push_back( PropertyInfo( Variant::DICTIONARY,"surfaces/"+itos(i), PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR ) );
 		p_list->push_back( PropertyInfo( Variant::OBJECT,"materials/"+itos(i+1), PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
 		p_list->push_back( PropertyInfo( Variant::OBJECT,"materials/"+itos(i+1), PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) );
 	}
 	}
+
+	p_list->push_back( PropertyInfo( Variant::_AABB,"custom_aabb/custom_aabb" ) );
+
 }
 }
 
 
 
 
@@ -473,6 +486,19 @@ AABB Mesh::get_aabb() const {
 	return aabb;
 	return aabb;
 }
 }
 
 
+
+void Mesh::set_custom_aabb(const AABB& p_custom) {
+
+	custom_aabb=p_custom;
+	VS::get_singleton()->mesh_set_custom_aabb(mesh,custom_aabb);
+}
+
+AABB Mesh::get_custom_aabb() const {
+
+	return custom_aabb;
+}
+
+
 DVector<Face3> Mesh::get_faces() const {
 DVector<Face3> Mesh::get_faces() const {
 
 
 
 
@@ -700,6 +726,8 @@ void Mesh::_bind_methods() {
 	ObjectTypeDB::bind_method(_MD("center_geometry"),&Mesh::center_geometry);
 	ObjectTypeDB::bind_method(_MD("center_geometry"),&Mesh::center_geometry);
 	ObjectTypeDB::set_method_flags(get_type_static(),_SCS("center_geometry"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
 	ObjectTypeDB::set_method_flags(get_type_static(),_SCS("center_geometry"),METHOD_FLAGS_DEFAULT|METHOD_FLAG_EDITOR);
 
 
+	ObjectTypeDB::bind_method(_MD("set_custom_aabb","aabb"),&Mesh::set_custom_aabb);
+	ObjectTypeDB::bind_method(_MD("get_custom_aabb"),&Mesh::get_custom_aabb);
 
 
 
 
 	BIND_CONSTANT( NO_INDEX_ARRAY );
 	BIND_CONSTANT( NO_INDEX_ARRAY );

+ 4 - 0
scene/resources/mesh.h

@@ -107,6 +107,7 @@ private:
 	AABB aabb;
 	AABB aabb;
 	MorphTargetMode morph_target_mode;
 	MorphTargetMode morph_target_mode;
 	Vector<StringName> morph_targets;
 	Vector<StringName> morph_targets;
+	AABB custom_aabb;
 
 
 	mutable Ref<TriangleMesh> triangle_mesh;
 	mutable Ref<TriangleMesh> triangle_mesh;
 
 
@@ -156,6 +157,9 @@ public:
 
 
 	void add_surface_from_mesh_data(const Geometry::MeshData& p_mesh_data);
 	void add_surface_from_mesh_data(const Geometry::MeshData& p_mesh_data);
 
 
+	void set_custom_aabb(const AABB& p_custom);
+	AABB get_custom_aabb() const;
+
 	AABB get_aabb() const;
 	AABB get_aabb() const;
 	virtual RID get_rid() const;
 	virtual RID get_rid() const;
 
 

+ 13 - 0
servers/visual/rasterizer.h

@@ -153,6 +153,16 @@ protected:
 	void _free_fixed_material(const RID& p_material);
 	void _free_fixed_material(const RID& p_material);
 
 
 public:
 public:
+
+	enum ShadowFilterTechnique {
+		SHADOW_FILTER_NONE,
+		SHADOW_FILTER_PCF5,
+		SHADOW_FILTER_PCF13,
+		SHADOW_FILTER_ESM,
+		SHADOW_FILTER_VSM,
+	};
+
+
 	/* TEXTURE API */
 	/* TEXTURE API */
 
 
 	virtual RID texture_create()=0;
 	virtual RID texture_create()=0;
@@ -264,6 +274,9 @@ public:
 		
 		
 	virtual AABB mesh_get_aabb(RID p_mesh) const=0;
 	virtual AABB mesh_get_aabb(RID p_mesh) const=0;
 
 
+	virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb)=0;
+	virtual AABB mesh_get_custom_aabb(RID p_mesh) const=0;
+
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 
 	virtual RID multimesh_create()=0;
 	virtual RID multimesh_create()=0;

+ 17 - 0
servers/visual/rasterizer_dummy.cpp

@@ -587,6 +587,23 @@ AABB RasterizerDummy::mesh_get_aabb(RID p_mesh) const {
 	return aabb;
 	return aabb;
 }
 }
 
 
+void RasterizerDummy::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) {
+
+	Mesh *mesh = mesh_owner.get( p_mesh );
+	ERR_FAIL_COND(!mesh);
+
+	mesh->custom_aabb=p_aabb;
+}
+
+AABB RasterizerDummy::mesh_get_custom_aabb(RID p_mesh) const {
+
+	const Mesh *mesh = mesh_owner.get( p_mesh );
+	ERR_FAIL_COND_V(!mesh,AABB());
+
+	return mesh->custom_aabb;
+
+}
+
 /* MULTIMESH API */
 /* MULTIMESH API */
 
 
 RID RasterizerDummy::multimesh_create() {
 RID RasterizerDummy::multimesh_create() {

+ 5 - 0
servers/visual/rasterizer_dummy.h

@@ -189,6 +189,7 @@ class RasterizerDummy : public Rasterizer {
 		Vector<Surface*> surfaces;
 		Vector<Surface*> surfaces;
 		int morph_target_count;
 		int morph_target_count;
 		VS::MorphTargetMode morph_target_mode;
 		VS::MorphTargetMode morph_target_mode;
+		AABB custom_aabb;
 
 
 		mutable uint64_t last_pass;
 		mutable uint64_t last_pass;
 		Mesh() {
 		Mesh() {
@@ -464,6 +465,10 @@ public:
 
 
 	virtual AABB mesh_get_aabb(RID p_mesh) const;
 	virtual AABB mesh_get_aabb(RID p_mesh) const;
 
 
+	virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb);
+	virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
+
+
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 
 	virtual RID multimesh_create();
 	virtual RID multimesh_create();

+ 15 - 0
servers/visual/visual_server_raster.cpp

@@ -434,6 +434,21 @@ int VisualServerRaster::mesh_get_surface_count(RID p_mesh) const{
 
 
 }
 }
 
 
+
+void VisualServerRaster::mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb) {
+
+	VS_CHANGED;
+	_dependency_queue_update(p_mesh,true);
+	rasterizer->mesh_set_custom_aabb(p_mesh,p_aabb);
+
+}
+
+AABB VisualServerRaster::mesh_get_custom_aabb(RID p_mesh) const {
+
+	return rasterizer->mesh_get_custom_aabb(p_mesh);
+}
+
+
 /* MULTIMESH */
 /* MULTIMESH */
 
 
 RID VisualServerRaster::multimesh_create() {
 RID VisualServerRaster::multimesh_create() {

+ 4 - 1
servers/visual/visual_server_raster.h

@@ -742,7 +742,10 @@ public:
 	
 	
 	virtual void mesh_remove_surface(RID p_mesh,int p_index);
 	virtual void mesh_remove_surface(RID p_mesh,int p_index);
 	virtual int mesh_get_surface_count(RID p_mesh) const;
 	virtual int mesh_get_surface_count(RID p_mesh) const;
-		
+
+	virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb);
+	virtual AABB mesh_get_custom_aabb(RID p_mesh) const;
+
 
 
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 

+ 4 - 0
servers/visual/visual_server_wrap_mt.h

@@ -696,6 +696,7 @@ public:
 	FUNC2(mesh_set_morph_target_count,RID,int);
 	FUNC2(mesh_set_morph_target_count,RID,int);
 	FUNC1RC(int,mesh_get_morph_target_count,RID);
 	FUNC1RC(int,mesh_get_morph_target_count,RID);
 
 
+
 	FUNC2(mesh_set_morph_target_mode,RID,MorphTargetMode);
 	FUNC2(mesh_set_morph_target_mode,RID,MorphTargetMode);
 	FUNC1RC(MorphTargetMode,mesh_get_morph_target_mode,RID);
 	FUNC1RC(MorphTargetMode,mesh_get_morph_target_mode,RID);
 
 
@@ -717,6 +718,9 @@ public:
 	FUNC1RC(int,mesh_get_surface_count,RID);
 	FUNC1RC(int,mesh_get_surface_count,RID);
 
 
 
 
+	FUNC2(mesh_set_custom_aabb,RID,const AABB&);
+	FUNC1RC(AABB,mesh_get_custom_aabb,RID);
+
 
 
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 

+ 6 - 2
servers/visual_server.h

@@ -334,7 +334,10 @@ public:
 	
 	
 	virtual void mesh_remove_surface(RID p_mesh,int p_index)=0;
 	virtual void mesh_remove_surface(RID p_mesh,int p_index)=0;
 	virtual int mesh_get_surface_count(RID p_mesh) const=0;
 	virtual int mesh_get_surface_count(RID p_mesh) const=0;
-		
+
+	virtual void mesh_set_custom_aabb(RID p_mesh,const AABB& p_aabb)=0;
+	virtual AABB mesh_get_custom_aabb(RID p_mesh) const=0;
+
 	/* MULTIMESH API */
 	/* MULTIMESH API */
 
 
 	virtual RID multimesh_create()=0;
 	virtual RID multimesh_create()=0;
@@ -502,7 +505,8 @@ public:
 	enum LightDirectionalShadowMode {
 	enum LightDirectionalShadowMode {
 		LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
 		LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL,
 		LIGHT_DIRECTIONAL_SHADOW_PERSPECTIVE,
 		LIGHT_DIRECTIONAL_SHADOW_PERSPECTIVE,
-		LIGHT_DIRECTIONAL_SHADOW_PARALLEL_SPLIT
+		LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS,
+		LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS
 	};
 	};
 
 
 	virtual void light_directional_set_shadow_mode(RID p_light,LightDirectionalShadowMode p_mode)=0;
 	virtual void light_directional_set_shadow_mode(RID p_light,LightDirectionalShadowMode p_mode)=0;

File diff suppressed because it is too large
+ 0 - 1
tools/editor/editor_icons.cpp


+ 7 - 11
tools/editor/editor_node.cpp

@@ -302,6 +302,10 @@ void EditorNode::_notification(int p_what) {
 		}
 		}
 */
 */
 
 
+		if (bool(EDITOR_DEF("resources/auto_reload_modified_images",true))) {
+
+			_menu_option_confirm(DEPENDENCY_LOAD_CHANGED_IMAGES,true);
+		}
 
 
 		EditorFileSystem::get_singleton()->scan_sources();
 		EditorFileSystem::get_singleton()->scan_sources();
 
 
@@ -2241,9 +2245,9 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
 
 
 			reimport_dialog->popup_reimport();
 			reimport_dialog->popup_reimport();
 		} break;
 		} break;
-		case DEPENDENCY_UPDATE_LOCAL: {
+		case DEPENDENCY_LOAD_CHANGED_IMAGES: {
+
 
 
-			/*
 			List<Ref<Resource> > cached;
 			List<Ref<Resource> > cached;
 			ResourceCache::get_cached_resources(&cached);
 			ResourceCache::get_cached_resources(&cached);
 
 
@@ -2258,15 +2262,6 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
 			}
 			}
 
 
 
 
-			sources_button->get_popup()->set_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_LOCAL),true);
-
-
-			if (sources_button->get_popup()->is_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_IMPORTED)))
-				sources_button->set_icon(gui_base->get_icon("DependencyOk","EditorIcons"));
-			else
-				sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons"));
-
-			*/
 		} break;
 		} break;
 		case DEPENDENCY_UPDATE_IMPORTED: {
 		case DEPENDENCY_UPDATE_IMPORTED: {
 
 
@@ -4165,6 +4160,7 @@ EditorNode::EditorNode() {
 	EditorSettings::get_singleton()->enable_plugins();
 	EditorSettings::get_singleton()->enable_plugins();
 	Node::set_human_readable_collision_renaming(true);
 	Node::set_human_readable_collision_renaming(true);
 
 
+
 //	Ref<ImageTexture> it = gui_base->get_icon("logo","Icons");
 //	Ref<ImageTexture> it = gui_base->get_icon("logo","Icons");
 //	OS::get_singleton()->set_icon( it->get_data() );
 //	OS::get_singleton()->set_icon( it->get_data() );
 
 

+ 4 - 2
tools/editor/editor_node.h

@@ -156,7 +156,7 @@ class EditorNode : public Node {
 		SETTINGS_HELP,
 		SETTINGS_HELP,
 		SETTINGS_ABOUT,
 		SETTINGS_ABOUT,
 		SOURCES_REIMPORT,
 		SOURCES_REIMPORT,
-		DEPENDENCY_UPDATE_LOCAL,
+		DEPENDENCY_LOAD_CHANGED_IMAGES,
 		DEPENDENCY_UPDATE_IMPORTED,
 		DEPENDENCY_UPDATE_IMPORTED,
 
 
 		IMPORT_PLUGIN_BASE=100,
 		IMPORT_PLUGIN_BASE=100,
@@ -403,6 +403,8 @@ protected:
 	static void _bind_methods();		
 	static void _bind_methods();		
 public:
 public:
 
 
+	static EditorNode* get_singleton() { return singleton; }
+
 
 
 	EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
 	EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
 	EditorPlugin *get_editor_plugin_over() { return editor_plugin_over; }
 	EditorPlugin *get_editor_plugin_over() { return editor_plugin_over; }
@@ -419,7 +421,7 @@ public:
 	void save_resource(const Ref<Resource>& p_resource);
 	void save_resource(const Ref<Resource>& p_resource);
 	void save_resource_as(const Ref<Resource>& p_resource);
 	void save_resource_as(const Ref<Resource>& p_resource);
 
 
-
+	static bool has_unsaved_changes() { return singleton->unsaved_cache; }
 
 
 	static HBoxContainer *get_menu_hb() { return singleton->menu_hb; }
 	static HBoxContainer *get_menu_hb() { return singleton->menu_hb; }
 
 

+ 1 - 0
tools/editor/editor_settings.cpp

@@ -445,6 +445,7 @@ void EditorSettings::_load_defaults() {
 
 
 	set("run/auto_save_before_running",true);
 	set("run/auto_save_before_running",true);
 	set("resources/save_compressed_resources",true);
 	set("resources/save_compressed_resources",true);
+	set("resources/auto_reload_modified_images",true);
 }
 }
 
 
 void EditorSettings::notify_changes() {
 void EditorSettings::notify_changes() {

+ 1 - 1
tools/editor/fileserver/editor_file_server.cpp

@@ -311,11 +311,11 @@ void EditorFileServer::stop(){
 EditorFileServer::EditorFileServer() {
 EditorFileServer::EditorFileServer() {
 
 
 	server = TCP_Server::create_ref();
 	server = TCP_Server::create_ref();
-	thread=Thread::create(_thread_start,this);
 	wait_mutex = Mutex::create();
 	wait_mutex = Mutex::create();
 	quit=false;
 	quit=false;
 	active=false;
 	active=false;
 	cmd=CMD_NONE;
 	cmd=CMD_NONE;
+	thread=Thread::create(_thread_start,this);
 
 
 	EDITOR_DEF("file_server/port",6010);
 	EDITOR_DEF("file_server/port",6010);
 	EDITOR_DEF("file_server/password","");
 	EDITOR_DEF("file_server/password","");

BIN
tools/editor/icons/icon_editor_3d_handle.png


+ 17 - 8
tools/editor/io_plugins/editor_import_collada.cpp

@@ -515,9 +515,9 @@ static void _generate_tangents_and_binormals(const DVector<int>& p_indices,const
 			tangent=Vector3();
 			tangent=Vector3();
 		} else {
 		} else {
 			tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
 			tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
-			(t2 * z1 - t1 * z2) * r);
+			(t2 * z1 - t1 * z2) * r).normalized();
 			binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
 			binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
-			(s1 * z2 - s2 * z1) * r);
+			(s1 * z2 - s2 * z1) * r).normalized();
 		}
 		}
 
 
 		tangents[ index_arrayr[idx*3+0] ]+=tangent;
 		tangents[ index_arrayr[idx*3+0] ]+=tangent;
@@ -527,6 +527,8 @@ static void _generate_tangents_and_binormals(const DVector<int>& p_indices,const
 		tangents[ index_arrayr[idx*3+2] ]+=tangent;
 		tangents[ index_arrayr[idx*3+2] ]+=tangent;
 		binormals[ index_arrayr[idx*3+2] ]+=binormal;
 		binormals[ index_arrayr[idx*3+2] ]+=binormal;
 
 
+		//print_line(itos(idx)+" tangent: "+tangent);
+		//print_line(itos(idx)+" binormal: "+binormal);
 	}
 	}
 
 
 	r_tangents.resize(vlen*4);
 	r_tangents.resize(vlen*4);
@@ -2107,7 +2109,7 @@ void EditorSceneImporterCollada::get_extensions(List<String> *r_extensions) cons
 
 
 	r_extensions->push_back("dae");
 	r_extensions->push_back("dae");
 }
 }
-Node* EditorSceneImporterCollada::import_scene(const String& p_path,uint32_t p_flags,Error* r_err) {
+Node* EditorSceneImporterCollada::import_scene(const String& p_path, uint32_t p_flags, List<String> *r_missing_deps, Error* r_err) {
 
 
 
 
 	ColladaImport state;
 	ColladaImport state;
@@ -2122,12 +2124,19 @@ Node* EditorSceneImporterCollada::import_scene(const String& p_path,uint32_t p_f
 
 
 	if (state.missing_textures.size()) {
 	if (state.missing_textures.size()) {
 
 
-		for(int i=0;i<state.missing_textures.size();i++) {
-			EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]);
-		}
+		//for(int i=0;i<state.missing_textures.size();i++) {
+//			EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]);
+//		}
+
+
+		if (r_missing_deps) {
 
 
-		if (p_flags&IMPORT_FAIL_ON_MISSING_DEPENDENCIES)
-			return NULL;
+			for(int i=0;i<state.missing_textures.size();i++) {
+				//EditorNode::add_io_error("Texture Not Found: "+state.missing_textures[i]);
+				r_missing_deps->push_back(state.missing_textures[i]);
+			}
+
+		}
 	}
 	}
 
 
 	if (p_flags&IMPORT_ANIMATION) {
 	if (p_flags&IMPORT_ANIMATION) {

+ 1 - 1
tools/editor/io_plugins/editor_import_collada.h

@@ -40,7 +40,7 @@ public:
 
 
 	virtual uint32_t get_import_flags() const;
 	virtual uint32_t get_import_flags() const;
 	virtual void get_extensions(List<String> *r_extensions) const;
 	virtual void get_extensions(List<String> *r_extensions) const;
-	virtual Node* import_scene(const String& p_path,uint32_t p_flags,Error* r_err=NULL);
+	virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps=NULL,Error* r_err=NULL);
 	virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags);
 	virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags);
 
 
 	EditorSceneImporterCollada();
 	EditorSceneImporterCollada();

+ 266 - 48
tools/editor/io_plugins/editor_scene_import_plugin.cpp

@@ -37,7 +37,7 @@
 #include "scene/3d/mesh_instance.h"
 #include "scene/3d/mesh_instance.h"
 #include "scene/3d/room_instance.h"
 #include "scene/3d/room_instance.h"
 #include "scene/3d/portal.h"
 #include "scene/3d/portal.h"
-
+#include "os/os.h"
 
 
 
 
 
 
@@ -102,6 +102,13 @@ class EditorSceneImportDialog : public ConfirmationDialog  {
 	OBJ_TYPE(EditorSceneImportDialog,ConfirmationDialog);
 	OBJ_TYPE(EditorSceneImportDialog,ConfirmationDialog);
 
 
 
 
+	struct FlagInfo {
+		int value;
+		const char *text;
+	};
+
+	static const FlagInfo scene_flag_names[];
+
 	EditorImportTextureOptions *texture_options;
 	EditorImportTextureOptions *texture_options;
 	EditorImportAnimationOptions *animation_options;
 	EditorImportAnimationOptions *animation_options;
 
 
@@ -118,6 +125,11 @@ class EditorSceneImportDialog : public ConfirmationDialog  {
 	EditorDirDialog *save_select;
 	EditorDirDialog *save_select;
 	OptionButton *texture_action;
 	OptionButton *texture_action;
 
 
+	ConfirmationDialog *confirm_open;
+
+	ConfirmationDialog *confirm_import;
+	RichTextLabel *missing_files;
+
 	Vector<TreeItem*> scene_flags;
 	Vector<TreeItem*> scene_flags;
 
 
 	Map<Ref<Mesh>,Ref<Shape> > collision_map;
 	Map<Ref<Mesh>,Ref<Shape> > collision_map;
@@ -129,7 +141,17 @@ class EditorSceneImportDialog : public ConfirmationDialog  {
 	void _browse();
 	void _browse();
 	void _browse_target();
 	void _browse_target();
 	void _browse_script();
 	void _browse_script();
-	void _import();
+	void _import(bool p_and_open=false);
+	void _import_confirm();
+
+	Ref<ResourceImportMetadata> wip_rimd;
+	Node *wip_import;
+	String wip_save_file;
+	bool wip_blocked;
+	bool wip_open;
+
+	void _dialog_hid();
+	void _open_and_import();
 
 
 
 
 protected:
 protected:
@@ -295,8 +317,22 @@ void EditorSceneImportDialog::_choose_script(const String& p_path) {
 
 
 }
 }
 
 
-void EditorSceneImportDialog::_import() {
 
 
+void EditorSceneImportDialog::_open_and_import() {
+
+	bool unsaved=EditorNode::has_unsaved_changes();
+
+	if (unsaved) {
+
+		confirm_open->popup_centered_minsize(Size2(300,80));
+	} else {
+		_import(true);
+	}
+}
+
+void EditorSceneImportDialog::_import(bool p_and_open) {
+
+	wip_open=p_and_open;
 //'	ImportMonitorBlock imb;
 //'	ImportMonitorBlock imb;
 
 
 	if (import_path->get_text()=="") {
 	if (import_path->get_text()=="") {
@@ -322,8 +358,10 @@ void EditorSceneImportDialog::_import() {
 
 
 	for(int i=0;i<scene_flags.size();i++) {
 	for(int i=0;i<scene_flags.size();i++) {
 
 
-		if (scene_flags[i]->is_checked(0))
-			flags|=(1<<i);
+		if (scene_flags[i]->is_checked(0)) {
+			int md = scene_flags[i]->get_metadata(0);
+			flags|=md;
+		}
 	}
 	}
 
 
 
 
@@ -353,6 +391,8 @@ void EditorSceneImportDialog::_import() {
 
 
 
 
 
 
+
+
 	Node *scene=NULL;
 	Node *scene=NULL;
 
 
 
 
@@ -367,7 +407,8 @@ void EditorSceneImportDialog::_import() {
 	rim->set_option("post_import_script",script_path->get_text()!=String()?EditorImportPlugin::validate_source_path(script_path->get_text()):String());
 	rim->set_option("post_import_script",script_path->get_text()!=String()?EditorImportPlugin::validate_source_path(script_path->get_text()):String());
 	rim->set_option("reimport",true);
 	rim->set_option("reimport",true);
 
 
-	Error err = plugin->import(save_file,rim);
+	List<String> missing;
+	Error err = plugin->import1(rim,&scene,&missing);
 
 
 	if (err) {
 	if (err) {
 
 
@@ -376,6 +417,35 @@ void EditorSceneImportDialog::_import() {
 		return;
 		return;
 	}
 	}
 
 
+	if (missing.size()) {
+
+		missing_files->clear();
+		for(List<String>::Element *E=missing.front();E;E=E->next()) {
+
+			missing_files->add_text(E->get());
+			missing_files->add_newline();
+		}
+		wip_import=scene;
+		wip_rimd=rim;
+		wip_save_file=save_file;
+		confirm_import->popup_centered_ratio();
+		return;
+
+	} else {
+
+		err = plugin->import2(scene,save_file,rim);
+
+		if (err) {
+
+			error_dialog->set_text("Error importing scene.");
+			error_dialog->popup_centered(Size2(200,100));
+			return;
+		}
+		if (wip_open)
+			EditorNode::get_singleton()->load_scene(save_file);
+
+	}
+
 	hide();
 	hide();
 
 
 	/*
 	/*
@@ -398,6 +468,34 @@ void EditorSceneImportDialog::_import() {
 	*/
 	*/
 };
 };
 
 
+
+void EditorSceneImportDialog::_import_confirm() {
+
+	wip_blocked=true;
+	print_line("import confirm!");
+	Error err = plugin->import2(wip_import,wip_save_file,wip_rimd);
+	wip_blocked=false;
+	wip_import=NULL;
+	wip_rimd=Ref<ResourceImportMetadata>();
+	confirm_import->hide();
+	if (err) {
+
+		wip_save_file="";
+		error_dialog->set_text("Error importing scene.");
+		error_dialog->popup_centered(Size2(200,100));
+		return;
+	}
+
+	if (wip_open)
+		EditorNode::get_singleton()->load_scene(wip_save_file);
+	wip_open=false;
+	wip_save_file="";
+
+	hide();
+
+}
+
+
 void EditorSceneImportDialog::_browse() {
 void EditorSceneImportDialog::_browse() {
 
 
 	file_select->popup_centered_ratio();
 	file_select->popup_centered_ratio();
@@ -429,7 +527,8 @@ void EditorSceneImportDialog::popup_import(const String &p_from) {
 
 
 		for(int i=0;i<scene_flags.size();i++) {
 		for(int i=0;i<scene_flags.size();i++) {
 
 
-			scene_flags[i]->set_checked(0,flags&(1<<i));
+			int md = scene_flags[i]->get_metadata(0);
+			scene_flags[i]->set_checked(0,flags&md);
 		}
 		}
 
 
 		texture_options->set_flags(rimd->get_option("texture_flags"));
 		texture_options->set_flags(rimd->get_option("texture_flags"));
@@ -491,6 +590,20 @@ Error EditorSceneImportDialog::import(const String& p_from, const String& p_to,
 	return OK;
 	return OK;
 }
 }
 
 
+void EditorSceneImportDialog::_dialog_hid() {
+
+	if (wip_blocked)
+		return;
+	print_line("DIALOGHID!");
+	if (wip_import) {
+		memdelete(wip_import);
+		wip_import=NULL;
+		wip_save_file="";
+		wip_rimd=Ref<ResourceImportMetadata>();
+	}
+}
+
+
 void EditorSceneImportDialog::_bind_methods() {
 void EditorSceneImportDialog::_bind_methods() {
 
 
 
 
@@ -501,25 +614,34 @@ void EditorSceneImportDialog::_bind_methods() {
 	ObjectTypeDB::bind_method("_browse",&EditorSceneImportDialog::_browse);
 	ObjectTypeDB::bind_method("_browse",&EditorSceneImportDialog::_browse);
 	ObjectTypeDB::bind_method("_browse_target",&EditorSceneImportDialog::_browse_target);
 	ObjectTypeDB::bind_method("_browse_target",&EditorSceneImportDialog::_browse_target);
 	ObjectTypeDB::bind_method("_browse_script",&EditorSceneImportDialog::_browse_script);
 	ObjectTypeDB::bind_method("_browse_script",&EditorSceneImportDialog::_browse_script);
+	ObjectTypeDB::bind_method("_dialog_hid",&EditorSceneImportDialog::_dialog_hid);
+	ObjectTypeDB::bind_method("_import_confirm",&EditorSceneImportDialog::_import_confirm);
+	ObjectTypeDB::bind_method("_open_and_import",&EditorSceneImportDialog::_open_and_import);
+
 	ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) );
 	ADD_SIGNAL( MethodInfo("imported",PropertyInfo(Variant::OBJECT,"scene")) );
 }
 }
 
 
 
 
 
 
-static const char *scene_flag_names[]={
-	"Create Collisions (-col,-colonly)",
-	"Create Portals (-portal)",
-	"Create Rooms (-room)",
-	"Simplify Rooms",
-	"Create Billboards (-bb)",
-	"Create Impostors (-imp:dist)",
-	"Create LODs (-lod:dist)",
-	"Remove Nodes (-noimp)",
-	"Import Animations",
-	"Compress Geometry",
-	"Fail on Missing Images",
-	"Force Generation of Tangent Arrays",
-	NULL
+
+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}
 };
 };
 
 
 
 
@@ -601,15 +723,17 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
 	TreeItem *importopts = import_options->create_item(root);
 	TreeItem *importopts = import_options->create_item(root);
 	importopts->set_text(0,"Import:");
 	importopts->set_text(0,"Import:");
 
 
-	const char ** fn=scene_flag_names;
+	const FlagInfo* fn=scene_flag_names;
 
 
-	while(*fn) {
+	while(fn->text) {
 
 
 		TreeItem *opt = import_options->create_item(importopts);
 		TreeItem *opt = import_options->create_item(importopts);
 		opt->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
 		opt->set_cell_mode(0,TreeItem::CELL_MODE_CHECK);
 		opt->set_checked(0,true);
 		opt->set_checked(0,true);
 		opt->set_editable(0,true);
 		opt->set_editable(0,true);
-		opt->set_text(0,*fn);
+		opt->set_text(0,fn->text);
+		opt->set_metadata(0,fn->value);
+
 		scene_flags.push_back(opt);
 		scene_flags.push_back(opt);
 		fn++;
 		fn++;
 	}
 	}
@@ -664,12 +788,44 @@ EditorSceneImportDialog::EditorSceneImportDialog(EditorNode *p_editor, EditorSce
 	texture_options->set_v_size_flags(SIZE_EXPAND_FILL);
 	texture_options->set_v_size_flags(SIZE_EXPAND_FILL);
 	//animation_options->set_flags(EditorImport::
 	//animation_options->set_flags(EditorImport::
 	texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM);
 	texture_options->set_format(EditorTextureImportPlugin::IMAGE_FORMAT_COMPRESS_RAM);
+	texture_options->set_flags( EditorTextureImportPlugin::IMAGE_FLAG_FIX_BORDER_ALPHA | EditorTextureImportPlugin::IMAGE_FLAG_REPEAT  | EditorTextureImportPlugin::IMAGE_FLAG_FILTER );
+
 
 
 	animation_options = memnew( EditorImportAnimationOptions );
 	animation_options = memnew( EditorImportAnimationOptions );
 	ovb->add_child(animation_options);
 	ovb->add_child(animation_options);
 	animation_options->set_v_size_flags(SIZE_EXPAND_FILL);
 	animation_options->set_v_size_flags(SIZE_EXPAND_FILL);
 	animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE);
 	animation_options->set_flags(EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP|EditorSceneAnimationImportPlugin::ANIMATION_KEEP_VALUE_TRACKS|EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE);
 
 
+
+	confirm_import = memnew( ConfirmationDialog );
+	add_child(confirm_import);
+	VBoxContainer *cvb = memnew( VBoxContainer );
+	confirm_import->add_child(cvb);
+	confirm_import->set_child_rect(cvb);
+
+	PanelContainer *pc = memnew( PanelContainer );
+	pc->add_style_override("panel",get_stylebox("normal","TextEdit"));
+	//ec->add_child(pc);
+	missing_files = memnew( RichTextLabel );
+	cvb->add_margin_child("The Following Files are Missing:",pc,true);
+	pc->add_child(missing_files);
+	confirm_import->get_ok()->set_text("Import Anyway");
+	confirm_import->get_cancel()->set_text("Cancel");
+	confirm_import->connect("popup_hide",this,"_dialog_hid");
+	confirm_import->connect("confirmed",this,"_import_confirm");
+	confirm_import->set_hide_on_ok(false);
+
+	add_button("Import & Open",!OS::get_singleton()->get_swap_ok_cancel())->connect("pressed",this,"_open_and_import");
+
+	confirm_open = memnew( ConfirmationDialog );
+	add_child(confirm_open);
+	confirm_open->set_text("Edited scene has not been saved, open imported scene anyway?");
+	confirm_open->connect("confirmed",this,"_import",varray(true));
+
+
+	wip_import=NULL;
+	wip_blocked=false;
+	wip_open=false;
 	//texture_options->set_format(EditorImport::IMAGE_FORMAT_C);
 	//texture_options->set_format(EditorImport::IMAGE_FORMAT_C);
 
 
 }
 }
@@ -1167,6 +1323,24 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
 
 
 			}
 			}
 
 
+			for(int i=0;i<mesh->get_surface_count();i++) {
+
+				Ref<FixedMaterial> fm = mesh->surface_get_material(i);
+				if (fm.is_valid()) {
+					String name = fm->get_name();
+					if (_teststr(name,"alpha")) {
+						fm->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA,true);
+						name=_fixstr(name,"alpha");
+					}
+
+					if (_teststr(name,"vcol")) {
+						fm->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY,true);
+						name=_fixstr(name,"vcol");
+					}
+					fm->set_name(name);
+				}
+			}
+
 		}
 		}
 
 
 	}
 	}
@@ -1314,7 +1488,8 @@ Error EditorImport::import_scene(const String& p_path,const String& p_dest_path,
 }
 }
 #endif
 #endif
 
 
-Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from){
+
+Error EditorSceneImportPlugin::import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing) {
 
 
 	Ref<ResourceImportMetadata> from=p_from;
 	Ref<ResourceImportMetadata> from=p_from;
 
 
@@ -1326,7 +1501,9 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 	String ext=src_path.extension().to_lower();
 	String ext=src_path.extension().to_lower();
 
 
 
 
-	EditorNode::progress_add_task("import","Import Scene",104);
+	EditorProgress progress("import","Import Scene",104);
+	progress.step("Importing Scene..",0);
+
 	for(int i=0;i<importers.size();i++) {
 	for(int i=0;i<importers.size();i++) {
 
 
 		List<String> extensions;
 		List<String> extensions;
@@ -1345,9 +1522,6 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 			break;
 			break;
 	}
 	}
 
 
-	if (!importer.is_valid()) {
-		EditorNode::progress_end_task("import");
-	}
 	ERR_FAIL_COND_V(!importer.is_valid(),ERR_FILE_UNRECOGNIZED);
 	ERR_FAIL_COND_V(!importer.is_valid(),ERR_FILE_UNRECOGNIZED);
 
 
 	int animation_flags=p_from->get_option("animation_flags");
 	int animation_flags=p_from->get_option("animation_flags");
@@ -1357,26 +1531,39 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 	if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP)
 	if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_DETECT_LOOP)
 		import_flags|=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP;
 		import_flags|=EditorSceneImporter::IMPORT_ANIMATION_DETECT_LOOP;
 	if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
 	if (animation_flags&EditorSceneAnimationImportPlugin::ANIMATION_OPTIMIZE)
-		import_flags|=EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE;		
+		import_flags|=EditorSceneImporter::IMPORT_ANIMATION_OPTIMIZE;
 	if (scene_flags&SCENE_FLAG_IMPORT_ANIMATIONS)
 	if (scene_flags&SCENE_FLAG_IMPORT_ANIMATIONS)
 		import_flags|=EditorSceneImporter::IMPORT_ANIMATION;
 		import_flags|=EditorSceneImporter::IMPORT_ANIMATION;
-	if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES)
-		import_flags|=EditorSceneImporter::IMPORT_FAIL_ON_MISSING_DEPENDENCIES;
+//	if (scene_flags&SCENE_FLAG_FAIL_ON_MISSING_IMAGES)
+//		import_flags|=EditorSceneImporter::IMPORT_FAIL_ON_MISSING_DEPENDENCIES;
 	if (scene_flags&SCENE_FLAG_GENERATE_TANGENT_ARRAYS)
 	if (scene_flags&SCENE_FLAG_GENERATE_TANGENT_ARRAYS)
 		import_flags|=EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
 		import_flags|=EditorSceneImporter::IMPORT_GENERATE_TANGENT_ARRAYS;
 
 
 
 
 
 
-	EditorNode::progress_task_step("import","Importing Scene..",0);
 
 
 
 
 	Error err=OK;
 	Error err=OK;
-	Node *scene = importer->import_scene(src_path,import_flags,&err);
+	Node *scene = importer->import_scene(src_path,import_flags,r_missing,&err);	
 	if (!scene || err!=OK) {
 	if (!scene || err!=OK) {
-		EditorNode::progress_end_task("import");
 		return err;
 		return err;
 	}
 	}
 
 
+	*r_node=scene;
+	return OK;
+}
+
+Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from) {
+
+	Error err=OK;
+	Ref<ResourceImportMetadata> from=p_from;
+	String src_path=EditorImportPlugin::expand_source_path(from->get_source_path(0));
+	int animation_flags=p_from->get_option("animation_flags");
+	int scene_flags = from->get_option("flags");
+
+	EditorProgress progress("import","Import Scene",104);
+	progress.step("Importing Scene..",2);
+
 
 
 	bool merge = !bool(from->get_option("reimport"));
 	bool merge = !bool(from->get_option("reimport"));
 	from->set_source_md5(0,FileAccess::get_md5(src_path));
 	from->set_source_md5(0,FileAccess::get_md5(src_path));
@@ -1390,16 +1577,13 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 	Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata);
 	Ref<ResourceImportMetadata> imd = memnew(ResourceImportMetadata);
 
 
 	Set< Ref<ImageTexture> > imagemap;
 	Set< Ref<ImageTexture> > imagemap;
-	EditorNode::progress_task_step("import","Post-Processing Scene..",1);
-
-
 
 
 	scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);
 	scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap);
 
 
 
 
 	/// BEFORE ANYTHING, RUN SCRIPT
 	/// BEFORE ANYTHING, RUN SCRIPT
 
 
-	EditorNode::progress_task_step("import","Running Custom Script..",2);
+	progress.step("Running Custom Script..",2);
 
 
 	String post_import_script_path = from->get_option("post_import_script");
 	String post_import_script_path = from->get_option("post_import_script");
 	Ref<EditorScenePostImport>  post_import_script;
 	Ref<EditorScenePostImport>  post_import_script;
@@ -1425,7 +1609,6 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 		err = post_import_script->post_import(scene);
 		err = post_import_script->post_import(scene);
 		if (err) {
 		if (err) {
 			EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path);
 			EditorNode::add_io_error("Error running Post-Import script: '"+post_import_script_path);
-			EditorNode::progress_end_task("import");
 			return err;
 			return err;
 		}
 		}
 	}
 	}
@@ -1451,7 +1634,7 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 		String path = texture->get_path();
 		String path = texture->get_path();
 		String fname= path.get_file();
 		String fname= path.get_file();
 		String target_path = Globals::get_singleton()->localize_path(target_res_path.plus_file(fname));
 		String target_path = Globals::get_singleton()->localize_path(target_res_path.plus_file(fname));
-		EditorNode::progress_task_step("import","Import Img: "+fname,3+(idx)*100/imagemap.size());
+		progress.step("Import Img: "+fname,3+(idx)*100/imagemap.size());
 
 
 		idx++;
 		idx++;
 
 
@@ -1472,17 +1655,37 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 
 
 			target_path=target_path.basename()+".tex";
 			target_path=target_path.basename()+".tex";
 
 
-			if (FileAccess::exists(target_path)) {
-				texture->set_path(target_path);
-				continue; //already imported
-			}
 			Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
 			Ref<ResourceImportMetadata> imd = memnew( ResourceImportMetadata );
+			print_line("flags: "+itos(image_flags));
 			imd->set_option("flags",image_flags);
 			imd->set_option("flags",image_flags);
 			imd->set_option("format",image_format);
 			imd->set_option("format",image_format);
 			imd->set_option("quality",image_quality);
 			imd->set_option("quality",image_quality);
 			imd->set_option("atlas",false);
 			imd->set_option("atlas",false);
 			imd->add_source(EditorImportPlugin::validate_source_path(path));
 			imd->add_source(EditorImportPlugin::validate_source_path(path));
 
 
+
+			if (FileAccess::exists(target_path)) {
+
+				 Ref<ResourceImportMetadata> rimdex = ResourceLoader::load_import_metadata(target_path);
+				 if (rimdex.is_valid()) {
+					//make sure the options are the same, otherwise re-import
+					List<String> opts;
+					imd->get_options(&opts);
+					bool differ=false;
+					for (List<String>::Element *E=opts.front();E;E=E->next()) {
+						if (!(rimdex->get_option(E->get())==imd->get_option(E->get()))) {
+							differ=true;
+							break;
+						}
+					}
+
+					if (!differ) {
+						texture->set_path(target_path);
+						continue; //already imported
+					}
+				}
+			}
+
 			Error err = EditorTextureImportPlugin::get_singleton(EditorTextureImportPlugin::MODE_TEXTURE_3D)->import(target_path,imd);
 			Error err = EditorTextureImportPlugin::get_singleton(EditorTextureImportPlugin::MODE_TEXTURE_3D)->import(target_path,imd);
 
 
 		}
 		}
@@ -1494,7 +1697,7 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 
 
 	if (merge) {
 	if (merge) {
 
 
-		EditorNode::progress_task_step("import","Merging..",103);
+		progress.step("Merging..",103);
 
 
 		FileAccess *fa = FileAccess::create(FileAccess::ACCESS_FILESYSTEM);
 		FileAccess *fa = FileAccess::create(FileAccess::ACCESS_FILESYSTEM);
 		if (fa->file_exists(p_dest_path)) {
 		if (fa->file_exists(p_dest_path)) {
@@ -1521,7 +1724,7 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 	}
 	}
 
 
 
 
-	EditorNode::progress_task_step("import","Saving..",104);
+	progress.step("Saving..",104);
 
 
 	Ref<PackedScene> packer = memnew( PackedScene );
 	Ref<PackedScene> packer = memnew( PackedScene );
 	packer->pack(scene);
 	packer->pack(scene);
@@ -1552,12 +1755,27 @@ Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<Resou
 	String op=_getrelpath(p_path,p_dest_path);
 	String op=_getrelpath(p_path,p_dest_path);
 
 
 	*/
 	*/
-	EditorNode::progress_end_task("import");
+
 
 
 	return err;
 	return err;
 
 
 }
 }
 
 
+
+Error EditorSceneImportPlugin::import(const String& p_dest_path, const Ref<ResourceImportMetadata>& p_from){
+
+
+	Node *n=NULL;
+	Error err = import1(p_from,&n);
+	if (err!=OK) {
+		if (n) {
+			memdelete(n);
+		}
+		return err;
+	}
+	return import2(n,p_dest_path,p_from);
+}
+
 void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter>& p_importer) {
 void EditorSceneImportPlugin::add_importer(const Ref<EditorSceneImporter>& p_importer) {
 
 
 	importers.push_back(p_importer);
 	importers.push_back(p_importer);

+ 20 - 14
tools/editor/io_plugins/editor_scene_import_plugin.h

@@ -65,7 +65,7 @@ public:
 
 
 	virtual uint32_t get_import_flags() const=0;
 	virtual uint32_t get_import_flags() const=0;
 	virtual void get_extensions(List<String> *r_extensions) const=0;
 	virtual void get_extensions(List<String> *r_extensions) const=0;
-	virtual Node* import_scene(const String& p_path,uint32_t p_flags,Error* r_err=NULL)=0;
+	virtual Node* import_scene(const String& p_path,uint32_t p_flags,List<String> *r_missing_deps,Error* r_err=NULL)=0;
 	virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags)=0;
 	virtual Ref<Animation> import_animation(const String& p_path,uint32_t p_flags)=0;
 
 
 
 
@@ -109,19 +109,22 @@ public:
 
 
 	enum SceneFlags {
 	enum SceneFlags {
 
 
-		SCENE_FLAG_CREATE_COLLISIONS=1,
-		SCENE_FLAG_CREATE_PORTALS=2,
-		SCENE_FLAG_CREATE_ROOMS=4,
-		SCENE_FLAG_SIMPLIFY_ROOMS=8,
-		SCENE_FLAG_CREATE_BILLBOARDS=16,
-		SCENE_FLAG_CREATE_IMPOSTORS=32,
-		SCENE_FLAG_CREATE_LODS=64,
-		SCENE_FLAG_REMOVE_NOIMP=128,
-		SCENE_FLAG_IMPORT_ANIMATIONS=256,
-		SCENE_FLAG_COMPRESS_GEOMETRY=512,
-		SCENE_FLAG_FAIL_ON_MISSING_IMAGES=1024,
-		SCENE_FLAG_GENERATE_TANGENT_ARRAYS=2048,
-		SCENE_FLAG_DONT_SAVE_TO_DB=8192
+		SCENE_FLAG_CREATE_COLLISIONS=1<<0,
+		SCENE_FLAG_CREATE_PORTALS=1<<1,
+		SCENE_FLAG_CREATE_ROOMS=1<<2,
+		SCENE_FLAG_SIMPLIFY_ROOMS=1<<3,
+		SCENE_FLAG_CREATE_BILLBOARDS=1<<4,
+		SCENE_FLAG_CREATE_IMPOSTORS=1<<5,
+		SCENE_FLAG_CREATE_LODS=1<<6,
+		SCENE_FLAG_CREATE_CARS=1<<8,
+		SCENE_FLAG_CREATE_WHEELS=1<<9,
+		SCENE_FLAG_DETECT_ALPHA=1<<15,
+		SCENE_FLAG_DETECT_VCOLOR=1<<16,
+
+		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,
 	};
 	};
 
 
 
 
@@ -130,6 +133,9 @@ public:
 	virtual void import_dialog(const String& p_from="");
 	virtual void import_dialog(const String& p_from="");
 	virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from);
 	virtual Error import(const String& p_path, const Ref<ResourceImportMetadata>& p_from);
 
 
+	Error import1(const Ref<ResourceImportMetadata>& p_from,Node**r_node,List<String> *r_missing=NULL);
+	Error import2(Node* p_scene,const String& p_path, const Ref<ResourceImportMetadata>& p_from);
+
 	void add_importer(const Ref<EditorSceneImporter>& p_importer);
 	void add_importer(const Ref<EditorSceneImporter>& p_importer);
 	const Vector<Ref<EditorSceneImporter> >& get_importers() { return importers; }
 	const Vector<Ref<EditorSceneImporter> >& get_importers() { return importers; }
 
 

+ 200 - 61
tools/editor/plugins/spatial_editor_plugin.cpp

@@ -81,7 +81,7 @@ bool SpatialEditorGizmo::intersect_ray(const Camera *p_camera, const Point2 &p_p
 
 
 SpatialEditorGizmo::SpatialEditorGizmo(){
 SpatialEditorGizmo::SpatialEditorGizmo(){
 
 
-
+	selected=false;
 }
 }
 
 
 
 
@@ -288,7 +288,7 @@ ObjectID SpatialEditorViewport::_select_ray(const Point2& p_pos, bool p_append,b
 		Vector3 normal;
 		Vector3 normal;
 
 
 		int handle=-1;
 		int handle=-1;
-		bool inters = seg->intersect_ray(camera,p_pos,point,normal,&handle,p_alt_select);
+		bool inters = seg->intersect_ray(camera,p_pos,point,normal,NULL,p_alt_select);
 
 
 		if (!inters)
 		if (!inters)
 			continue;
 			continue;
@@ -553,7 +553,8 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2& p_screenpos,bool p_hili
 	Plane cplane(ray_pos,cn.normalized());
 	Plane cplane(ray_pos,cn.normalized());
 
 
 	Transform gt = spatial_editor->get_gizmo_transform();
 	Transform gt = spatial_editor->get_gizmo_transform();
-	float gs=0;
+	float gs=gizmo_scale;
+	/*
 	if (orthogonal) {
 	if (orthogonal) {
 		gs= cursor.distance/surface->get_size().get_aspect();
 		gs= cursor.distance/surface->get_size().get_aspect();
 
 
@@ -562,7 +563,7 @@ bool SpatialEditorViewport::_gizmo_select(const Vector2& p_screenpos,bool p_hili
 	}
 	}
 
 
 	gs*=GIZMO_SCALE_DEFAULT;
 	gs*=GIZMO_SCALE_DEFAULT;
-
+*/
 
 
 	if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) {
 	if (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) {
 
 
@@ -855,6 +856,29 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
 
 
 						//gizmo has priority over everything
 						//gizmo has priority over everything
 
 
+
+						if (spatial_editor->get_selected()) {
+
+							Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
+							if (seg.is_valid()) {
+								int handle=-1;
+								Vector3 point;
+								Vector3 normal;
+								bool inters = seg->intersect_ray(camera,_edit.mouse_pos,point,normal,&handle,b.mod.shift);
+								if (inters && handle!=-1) {
+
+									_edit.gizmo=seg;
+									_edit.gizmo_handle=handle;
+									//_edit.gizmo_initial_pos=seg->get_handle_pos(gizmo_handle);
+									_edit.gizmo_initial_value=seg->get_handle_value(handle);
+									break;
+
+								}
+							}
+						}
+
+
+
 						if (_gizmo_select(_edit.mouse_pos))
 						if (_gizmo_select(_edit.mouse_pos))
 							break;
 							break;
 
 
@@ -1012,7 +1036,35 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
 			const InputEventMouseMotion &m=p_event.mouse_motion;
 			const InputEventMouseMotion &m=p_event.mouse_motion;
 			_edit.mouse_pos=Point2(p_event.mouse_motion.x,p_event.mouse_motion.y);
 			_edit.mouse_pos=Point2(p_event.mouse_motion.x,p_event.mouse_motion.y);
 
 
-			if (!(m.button_mask&1) && !_edit.gizmo.is_valid()) {
+
+			if (spatial_editor->get_selected()) {
+
+
+				Ref<SpatialEditorGizmo> seg = spatial_editor->get_selected()->get_gizmo();
+				if (seg.is_valid()) {
+
+					int selected_handle=-1;
+
+					int handle=-1;
+					Vector3 point;
+					Vector3 normal;
+					bool inters = seg->intersect_ray(camera,_edit.mouse_pos,point,normal,&handle,false);
+					if (inters && handle!=-1) {
+
+						selected_handle=handle;
+
+					}
+
+					if (selected_handle!=spatial_editor->get_over_gizmo_handle()) {
+						spatial_editor->set_over_gizmo_handle(selected_handle);
+						spatial_editor->get_selected()->update_gizmo();
+						if (selected_handle!=-1)
+							spatial_editor->select_gizmo_hilight_axis(-1);
+					}
+				}
+			}
+
+			if (spatial_editor->get_over_gizmo_handle()==-1 && !(m.button_mask&1) && !_edit.gizmo.is_valid()) {
 
 
 				_gizmo_select(_edit.mouse_pos,true);
 				_gizmo_select(_edit.mouse_pos,true);
 
 
@@ -1436,6 +1488,7 @@ void SpatialEditorViewport::_sinput(const InputEvent &p_event) {
 					orthogonal = !orthogonal;
 					orthogonal = !orthogonal;
 					_menu_option(orthogonal?VIEW_PERSPECTIVE:VIEW_ORTHOGONAL);
 					_menu_option(orthogonal?VIEW_PERSPECTIVE:VIEW_ORTHOGONAL);
 
 
+
 				} break;
 				} break;
 				case KEY_K: {
 				case KEY_K: {
 
 
@@ -1500,6 +1553,13 @@ void SpatialEditorViewport::_notification(int p_what) {
 		bool visible=is_visible();
 		bool visible=is_visible();
 
 
 		set_process(visible);
 		set_process(visible);
+		call_deferred("update_transform_gizmo_view");
+	}
+
+	if (p_what==NOTIFICATION_RESIZED) {
+
+		call_deferred("update_transform_gizmo_view");
+
 	}
 	}
 
 
 	if (p_what==NOTIFICATION_PROCESS) {
 	if (p_what==NOTIFICATION_PROCESS) {
@@ -1534,7 +1594,7 @@ void SpatialEditorViewport::_notification(int p_what) {
 
 
 		if (camera->get_global_transform()!=camera_transform) {
 		if (camera->get_global_transform()!=camera_transform) {
 			camera->set_global_transform( camera_transform );
 			camera->set_global_transform( camera_transform );
-			//_update_transform_gizmo_view();
+			update_transform_gizmo_view();
 		}
 		}
 
 
 		Map<Node*,Object*> &selection = editor_selection->get_selection();
 		Map<Node*,Object*> &selection = editor_selection->get_selection();
@@ -1637,6 +1697,7 @@ void SpatialEditorViewport::_notification(int p_what) {
 		surface->connect("input_event",this,"_sinput");
 		surface->connect("input_event",this,"_sinput");
 		surface->connect("mouse_enter",this,"_smouseenter");
 		surface->connect("mouse_enter",this,"_smouseenter");
 		preview_camera->set_icon(get_icon("Camera","EditorIcons"));
 		preview_camera->set_icon(get_icon("Camera","EditorIcons"));
+		_init_gizmo_instance(index);
 
 
 	}
 	}
 
 
@@ -1779,12 +1840,15 @@ void SpatialEditorViewport::_menu_option(int p_option) {
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true );
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), true );
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), false );
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), false );
 			orthogonal=false;
 			orthogonal=false;
+			call_deferred("update_transform_gizmo_view");
+
 		} break;
 		} break;
 		case VIEW_ORTHOGONAL: {
 		case VIEW_ORTHOGONAL: {
 
 
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), false );
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_PERSPECTIVE), false );
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), true );
 			view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ORTHOGONAL), true );
 			orthogonal=true;
 			orthogonal=true;
+			call_deferred("update_transform_gizmo_view");
 
 
 		} break;
 		} break;
 
 
@@ -1801,6 +1865,30 @@ void SpatialEditorViewport::_preview_exited_scene() {
 }
 }
 
 
 
 
+void SpatialEditorViewport::_init_gizmo_instance(int p_idx) {
+
+	uint32_t layer=1<<(GIZMO_BASE_LAYER+p_idx);
+
+	for(int i=0;i<3;i++) {
+		move_gizmo_instance[i]=VS::get_singleton()->instance_create();
+		VS::get_singleton()->instance_set_base(move_gizmo_instance[i],spatial_editor->get_move_gizmo(i)->get_rid());
+		VS::get_singleton()->instance_set_scenario(move_gizmo_instance[i],get_scene()->get_root()->get_world()->get_scenario());
+		VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
+		//VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
+		VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
+		VS::get_singleton()->instance_set_layer_mask(move_gizmo_instance[i],layer);
+
+		rotate_gizmo_instance[i]=VS::get_singleton()->instance_create();
+		VS::get_singleton()->instance_set_base(rotate_gizmo_instance[i],spatial_editor->get_rotate_gizmo(i)->get_rid());
+		VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i],get_scene()->get_root()->get_world()->get_scenario());
+		VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
+		//VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
+		VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
+		VS::get_singleton()->instance_set_layer_mask(rotate_gizmo_instance[i],layer);
+	}
+
+}
+
 void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
 void SpatialEditorViewport::_toggle_camera_preview(bool p_activate) {
 
 
 
 
@@ -1840,6 +1928,43 @@ void SpatialEditorViewport::set_can_preview(Camera* p_preview) {
 	}
 	}
 }
 }
 
 
+void SpatialEditorViewport::update_transform_gizmo_view() {
+
+	if (!is_visible())
+		return;
+
+	Transform xform = spatial_editor->get_gizmo_transform();
+
+
+	Transform camera_xform = camera->get_transform();
+	Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized();
+	Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized();
+	Plane p(camera_xform.origin,camz);
+	float gizmo_d = Math::abs( p.distance_to(xform.origin ));
+	float d0 = camera->unproject_position(camera_xform.origin+camz*gizmo_d).y;
+	float d1 = camera->unproject_position(camera_xform.origin+camz*gizmo_d+camy).y;
+	float dd = Math::abs(d0-d1);
+	if (dd==0)
+		dd=0.0001;
+
+	float gsize = EditorSettings::get_singleton()->get("3d_editor/manipulator_gizmo_size");
+	gizmo_scale=(gsize/Math::abs(dd));
+	Vector3 scale = Vector3(1,1,1) * gizmo_scale;
+
+	xform.basis.scale(scale);
+
+	//xform.basis.scale(GIZMO_SCALE_DEFAULT*Vector3(1,1,1));
+
+
+	for(int i=0;i<3;i++) {
+		VisualServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform );
+		VisualServer::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,spatial_editor->is_gizmo_visible()&& (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_MOVE) );
+		VisualServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform );
+		VisualServer::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,spatial_editor->is_gizmo_visible() && (spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_SELECT || spatial_editor->get_tool_mode()==SpatialEditor::TOOL_MODE_ROTATE) );
+	}
+
+}
+
 void SpatialEditorViewport::set_state(const Dictionary& p_state) {
 void SpatialEditorViewport::set_state(const Dictionary& p_state) {
 
 
 	cursor.pos=p_state["pos"];
 	cursor.pos=p_state["pos"];
@@ -1879,6 +2004,7 @@ void SpatialEditorViewport::_bind_methods(){
 	ObjectTypeDB::bind_method(_MD("_menu_option"),&SpatialEditorViewport::_menu_option);
 	ObjectTypeDB::bind_method(_MD("_menu_option"),&SpatialEditorViewport::_menu_option);
 	ObjectTypeDB::bind_method(_MD("_toggle_camera_preview"),&SpatialEditorViewport::_toggle_camera_preview);
 	ObjectTypeDB::bind_method(_MD("_toggle_camera_preview"),&SpatialEditorViewport::_toggle_camera_preview);
 	ObjectTypeDB::bind_method(_MD("_preview_exited_scene"),&SpatialEditorViewport::_preview_exited_scene);
 	ObjectTypeDB::bind_method(_MD("_preview_exited_scene"),&SpatialEditorViewport::_preview_exited_scene);
+	ObjectTypeDB::bind_method(_MD("update_transform_gizmo_view"),&SpatialEditorViewport::update_transform_gizmo_view);
 
 
 	ADD_SIGNAL( MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")) );
 	ADD_SIGNAL( MethodInfo("toggle_maximize_view", PropertyInfo(Variant::OBJECT, "viewport")) );
 }
 }
@@ -1886,8 +2012,9 @@ void SpatialEditorViewport::_bind_methods(){
 
 
 
 
 
 
-SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor) {
+SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, EditorNode *p_editor, int p_index) {
 
 
+	index=p_index;
 	editor=p_editor;
 	editor=p_editor;
 	editor_selection=editor->get_editor_selection();;
 	editor_selection=editor->get_editor_selection();;
 	undo_redo=editor->get_undo_redo();
 	undo_redo=editor->get_undo_redo();
@@ -1907,6 +2034,7 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor,Edi
 	surface->set_area_as_parent_rect();
 	surface->set_area_as_parent_rect();
 	camera = memnew(Camera);
 	camera = memnew(Camera);
 	camera->set_disable_gizmo(true);
 	camera->set_disable_gizmo(true);
+	camera->set_visible_layers( ((1<<20)-1)|(1<<(GIZMO_BASE_LAYER+p_index)) );
 	//camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment());
 	//camera->set_environment(SpatialEditor::get_singleton()->get_viewport_environment());
 	viewport->add_child(camera);
 	viewport->add_child(camera);
 	camera->make_current();
 	camera->make_current();
@@ -1945,6 +2073,8 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor,Edi
 	preview_camera->connect("toggled",this,"_toggle_camera_preview");
 	preview_camera->connect("toggled",this,"_toggle_camera_preview");
 	previewing=NULL;
 	previewing=NULL;
 	preview=NULL;
 	preview=NULL;
+	gizmo_scale=1.0;
+	EditorSettings::get_singleton()->connect("settings_changed",this,"update_transform_gizmo_view");
 
 
 }
 }
 
 
@@ -1963,39 +2093,6 @@ SpatialEditorSelectedItem::~SpatialEditorSelectedItem() {
 }
 }
 
 
 
 
-void SpatialEditor::_update_transform_gizmo_view() {
-
-
-	Transform xform = gizmo.transform;
-
-/*
-	Transform camera_xform = camera->get_transform();
-	Vector3 camz = -camera_xform.get_basis().get_axis(2).normalized();
-	Vector3 camy = -camera_xform.get_basis().get_axis(1).normalized();
-	Plane p(camera_xform.origin,camz);
-	float gizmo_d = Math::abs( p.distance_to(xform.origin ));
-	float d0 = camera->unproject_position(camera_xform.origin+camz*gizmo_d).y;
-	float d1 = camera->unproject_position(camera_xform.origin+camz*gizmo_d+camy).y;
-	float dd = Math::abs(d0-d1);
-	if (dd==0)
-		dd=0.0001;
-
-	gizmo.scale=(60.0/Math::abs(dd));
-	Vector3 scale = Vector3(1,1,1) * gizmo.scale;
-
-	//xform.basis.scale(scale);
-*/
-	xform.basis.scale(GIZMO_SCALE_DEFAULT*Vector3(1,1,1));
-
-
-	for(int i=0;i<3;i++) {
-		VisualServer::get_singleton()->instance_set_transform(move_gizmo_instance[i], xform );
-		VisualServer::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,gizmo.visible && (tool_mode==TOOL_MODE_SELECT || tool_mode==TOOL_MODE_MOVE) );
-		VisualServer::get_singleton()->instance_set_transform(rotate_gizmo_instance[i], xform );
-		VisualServer::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,gizmo.visible && (tool_mode==TOOL_MODE_SELECT || tool_mode==TOOL_MODE_ROTATE) );
-	}
-
-}
 
 
 void SpatialEditor::select_gizmo_hilight_axis(int p_axis) {
 void SpatialEditor::select_gizmo_hilight_axis(int p_axis) {
 
 
@@ -2048,7 +2145,9 @@ void SpatialEditor::update_transform_gizmo() {
 	gizmo.transform.origin=pcenter;
 	gizmo.transform.origin=pcenter;
 	gizmo.transform.basis=gizmo_basis;
 	gizmo.transform.basis=gizmo_basis;
 
 
-	_update_transform_gizmo_view();
+	for(int i=0;i<4;i++) {
+		viewports[i]->update_transform_gizmo_view();
+	}
 
 
 }
 }
 
 
@@ -2233,6 +2332,28 @@ void SpatialEditor::set_state(const Dictionary& p_state) {
 
 
 void SpatialEditor::edit(Spatial *p_spatial) {
 void SpatialEditor::edit(Spatial *p_spatial) {
 	
 	
+	if (p_spatial!=selected) {
+		if (selected) {
+
+			Ref<SpatialEditorGizmo> seg = selected->get_gizmo();
+			if (seg.is_valid()) {
+				seg->set_selected(false);
+				selected->update_gizmo();
+			}
+		}
+
+		selected=p_spatial;
+		over_gizmo_handle=-1;
+
+		if (selected) {
+
+			Ref<SpatialEditorGizmo> seg = selected->get_gizmo();
+			if (seg.is_valid()) {
+				seg->set_selected(true);
+				selected->update_gizmo();
+			}
+		}
+	}
 
 
 	if (p_spatial) {
 	if (p_spatial) {
 		//_validate_selection();
 		//_validate_selection();
@@ -2654,22 +2775,7 @@ void SpatialEditor::_init_indicators() {
 		for(int i=0;i<3;i++) {
 		for(int i=0;i<3;i++) {
 
 
 			move_gizmo[i]=Ref<Mesh>( memnew( Mesh ) );
 			move_gizmo[i]=Ref<Mesh>( memnew( Mesh ) );
-			move_gizmo_instance[i]=VS::get_singleton()->instance_create();
-			VS::get_singleton()->instance_set_base(move_gizmo_instance[i],move_gizmo[i]->get_rid());
-			VS::get_singleton()->instance_set_scenario(move_gizmo_instance[i],get_scene()->get_root()->get_world()->get_scenario());
-			VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
-			VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
-			VS::get_singleton()->instance_geometry_set_flag(move_gizmo_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
-
-
-
 			rotate_gizmo[i]=Ref<Mesh>( memnew( Mesh ) );
 			rotate_gizmo[i]=Ref<Mesh>( memnew( Mesh ) );
-			rotate_gizmo_instance[i]=VS::get_singleton()->instance_create();
-			VS::get_singleton()->instance_set_base(rotate_gizmo_instance[i],rotate_gizmo[i]->get_rid());
-			VS::get_singleton()->instance_set_scenario(rotate_gizmo_instance[i],get_scene()->get_root()->get_world()->get_scenario());
-			VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_VISIBLE,false);
-			VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_DEPH_SCALE,true);
-			VS::get_singleton()->instance_geometry_set_flag(rotate_gizmo_instance[i],VS::INSTANCE_FLAG_CAST_SHADOW,false);
 
 
 
 
 			Ref<FixedMaterial> mat = memnew( FixedMaterial );
 			Ref<FixedMaterial> mat = memnew( FixedMaterial );
@@ -2795,6 +2901,10 @@ void SpatialEditor::_init_indicators() {
 		}
 		}
 	}
 	}
 
 
+	/*for(int i=0;i<4;i++) {
+
+		viewports[i]->init_gizmo_instance(i);
+	}*/
 
 
 	_generate_selection_box();
 	_generate_selection_box();
 
 
@@ -2928,6 +3038,7 @@ void SpatialEditor::_notification(int p_what) {
 		_init_indicators();
 		_init_indicators();
 
 
 	}
 	}
+
 	if (p_what==NOTIFICATION_EXIT_SCENE) {
 	if (p_what==NOTIFICATION_EXIT_SCENE) {
 
 
 		_finish_indicators();
 		_finish_indicators();
@@ -2969,14 +3080,29 @@ void SpatialEditor::_request_gizmo(Object* p_obj) {
 
 
 		Ref<SpatialEditorGizmo> seg = gizmos->get_gizmo(sp);
 		Ref<SpatialEditorGizmo> seg = gizmos->get_gizmo(sp);
 
 
-		if (seg.is_valid())
+		if (seg.is_valid()) {
 			sp->set_gizmo(seg);
 			sp->set_gizmo(seg);
+		}
 
 
 		for (List<EditorPlugin*>::Element *E=gizmo_plugins.front();E;E=E->next()) {
 		for (List<EditorPlugin*>::Element *E=gizmo_plugins.front();E;E=E->next()) {
 
 
-			if (E->get()->create_spatial_gizmo(sp))
+			if (E->get()->create_spatial_gizmo(sp)) {
+
+				seg = sp->get_gizmo();
+				if (sp==selected && seg.is_valid()) {
+
+					seg->set_selected(true);
+					selected->update_gizmo();
+				}
 				return;
 				return;
+			}
 		}
 		}
+
+		if (seg.is_valid() && sp==selected) {
+			seg->set_selected(true);
+			selected->update_gizmo();
+		}
+
 	}
 	}
 
 
 }
 }
@@ -3023,11 +3149,18 @@ void SpatialEditor::_toggle_maximize_view(Object* p_viewport) {
 
 
 }
 }
 
 
+
+void SpatialEditor::_node_removed(Node* p_node) {
+
+	if (p_node==selected)
+		selected=NULL;
+}
+
 void SpatialEditor::_bind_methods() {
 void SpatialEditor::_bind_methods() {
 
 
 //	ObjectTypeDB::bind_method("_input_event",&SpatialEditor::_input_event);
 //	ObjectTypeDB::bind_method("_input_event",&SpatialEditor::_input_event);
 	ObjectTypeDB::bind_method("_unhandled_key_input",&SpatialEditor::_unhandled_key_input);
 	ObjectTypeDB::bind_method("_unhandled_key_input",&SpatialEditor::_unhandled_key_input);
-	//ObjectTypeDB::bind_method("_node_removed",&SpatialEditor::_node_removed);
+	ObjectTypeDB::bind_method("_node_removed",&SpatialEditor::_node_removed);
 	ObjectTypeDB::bind_method("_menu_item_pressed",&SpatialEditor::_menu_item_pressed);
 	ObjectTypeDB::bind_method("_menu_item_pressed",&SpatialEditor::_menu_item_pressed);
 	ObjectTypeDB::bind_method("_xform_dialog_action",&SpatialEditor::_xform_dialog_action);
 	ObjectTypeDB::bind_method("_xform_dialog_action",&SpatialEditor::_xform_dialog_action);
 	ObjectTypeDB::bind_method("_instance_scene",&SpatialEditor::_instance_scene);
 	ObjectTypeDB::bind_method("_instance_scene",&SpatialEditor::_instance_scene);
@@ -3178,7 +3311,7 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 	viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
 	viewport_base->set_v_size_flags(SIZE_EXPAND_FILL);
 	for(int i=0;i<4;i++) {
 	for(int i=0;i<4;i++) {
 
 
-		viewports[i] = memnew( SpatialEditorViewport(this,editor) );
+		viewports[i] = memnew( SpatialEditorViewport(this,editor,i) );
 		viewports[i]->connect("toggle_maximize_view",this,"_toggle_maximize_view");
 		viewports[i]->connect("toggle_maximize_view",this,"_toggle_maximize_view");
 		viewport_base->add_child(viewports[i]);
 		viewport_base->add_child(viewports[i]);
 	}
 	}
@@ -3333,9 +3466,15 @@ SpatialEditor::SpatialEditor(EditorNode *p_editor) {
 
 
 	scenario_debug=VisualServer::SCENARIO_DEBUG_DISABLED;
 	scenario_debug=VisualServer::SCENARIO_DEBUG_DISABLED;
 
 
+	selected=NULL;
 
 
 	set_process_unhandled_key_input(true);
 	set_process_unhandled_key_input(true);
 	add_to_group("_spatial_editor_group");
 	add_to_group("_spatial_editor_group");
+
+	EDITOR_DEF("3d_editor/manipulator_gizmo_size",80);
+	EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::INT,"3d_editor/manipulator_gizmo_size",PROPERTY_HINT_RANGE,"16,1024,1"));
+
+	over_gizmo_handle=-1;
 }
 }
 
 
 SpatialEditor::~SpatialEditor() {
 SpatialEditor::~SpatialEditor() {
@@ -3366,7 +3505,7 @@ void SpatialEditorPlugin::make_visible(bool p_visible) {
 
 
 }
 }
 void SpatialEditorPlugin::edit(Object *p_object) {
 void SpatialEditorPlugin::edit(Object *p_object) {
-	
+
 	spatial_editor->edit(p_object->cast_to<Spatial>());
 	spatial_editor->edit(p_object->cast_to<Spatial>());
 }
 }
 
 

+ 33 - 4
tools/editor/plugins/spatial_editor_plugin.h

@@ -44,8 +44,13 @@ class SpatialEditorGizmos;
 class SpatialEditorGizmo : public SpatialGizmo {
 class SpatialEditorGizmo : public SpatialGizmo {
 
 
 	OBJ_TYPE(SpatialEditorGizmo,SpatialGizmo);
 	OBJ_TYPE(SpatialEditorGizmo,SpatialGizmo);
+
+	bool selected;
 public:
 public:
 
 
+	void set_selected(bool p_selected) { selected=p_selected; }
+	bool is_selected() const { return selected; }
+
 	virtual String get_handle_name(int p_idx) const;
 	virtual String get_handle_name(int p_idx) const;
 	virtual Variant get_handle_value(int p_idx) const;
 	virtual Variant get_handle_value(int p_idx) const;
 	virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point);
 	virtual void set_handle(int p_idx,Camera *p_camera, const Point2& p_point);
@@ -74,8 +79,13 @@ class SpatialEditorViewport : public Control {
 		VIEW_ENVIRONMENT,
 		VIEW_ENVIRONMENT,
 		VIEW_ORTHOGONAL
 		VIEW_ORTHOGONAL
 	};
 	};
+	enum {
+		GIZMO_BASE_LAYER=25
+	};
 
 
+	int index;
 	void _menu_option(int p_option);
 	void _menu_option(int p_option);
+	Size2 prev_size;
 
 
 	EditorNode *editor;
 	EditorNode *editor;
 	EditorSelection *editor_selection;
 	EditorSelection *editor_selection;
@@ -90,6 +100,7 @@ class SpatialEditorViewport : public Control {
 	Camera *camera;
 	Camera *camera;
 	bool transforming;
 	bool transforming;
 	bool orthogonal;
 	bool orthogonal;
+	float gizmo_scale;
 
 
 	void _compute_edit(const Point2& p_point);
 	void _compute_edit(const Point2& p_point);
 	void _clear_selected();
 	void _clear_selected();
@@ -174,6 +185,9 @@ class SpatialEditorViewport : public Control {
 		Cursor() { x_rot=y_rot=0; distance=4; region_select=false; }
 		Cursor() { x_rot=y_rot=0; distance=4; region_select=false; }
 	} cursor;
 	} cursor;
 
 
+	RID move_gizmo_instance[3], rotate_gizmo_instance[3];
+
+
 	String last_message;
 	String last_message;
 	String message;
 	String message;
 	float message_time;
 	float message_time;
@@ -193,19 +207,24 @@ class SpatialEditorViewport : public Control {
 
 
 	void _preview_exited_scene();
 	void _preview_exited_scene();
 	void _toggle_camera_preview(bool);
 	void _toggle_camera_preview(bool);
+	void _init_gizmo_instance(int p_idx);
+
+
 protected:
 protected:
 
 
 	void _notification(int p_what);
 	void _notification(int p_what);
 	static void _bind_methods();
 	static void _bind_methods();
 public:
 public:
 
 
+	void update_transform_gizmo_view();
+
 	void set_can_preview(Camera* p_preview);
 	void set_can_preview(Camera* p_preview);
 	void set_state(const Dictionary& p_state);
 	void set_state(const Dictionary& p_state);
 	Dictionary get_state() const;
 	Dictionary get_state() const;
 
 
 
 
 
 
-	SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor);
+	SpatialEditorViewport(SpatialEditor *p_spatial_editor,EditorNode *p_editor,int p_index);
 };
 };
 
 
 
 
@@ -275,11 +294,12 @@ private:
 	bool grid_enabled;
 	bool grid_enabled;
 
 
 	Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
 	Ref<Mesh> move_gizmo[3], rotate_gizmo[3];
-	RID move_gizmo_instance[3], rotate_gizmo_instance[3];
 	Ref<FixedMaterial> gizmo_color[3];
 	Ref<FixedMaterial> gizmo_color[3];
 	Ref<FixedMaterial> gizmo_hl;
 	Ref<FixedMaterial> gizmo_hl;
 
 
 
 
+	int over_gizmo_handle;
+
 
 
 
 
 	Ref<Mesh> selection_box;
 	Ref<Mesh> selection_box;
@@ -365,8 +385,6 @@ private:
 
 
 	HBoxContainer *hbc_menu;
 	HBoxContainer *hbc_menu;
 
 
-	void _update_transform_gizmo_view();
-
 //
 //
 //
 //
 	void _generate_selection_box();
 	void _generate_selection_box();
@@ -386,10 +404,13 @@ private:
 
 
 	List<EditorPlugin*> gizmo_plugins;
 	List<EditorPlugin*> gizmo_plugins;
 
 
+	Spatial *selected;
+
 	void _request_gizmo(Object* p_obj);
 	void _request_gizmo(Object* p_obj);
 
 
 	static SpatialEditor *singleton;
 	static SpatialEditor *singleton;
 
 
+	void _node_removed(Node* p_node);
 	SpatialEditorGizmos *gizmos;
 	SpatialEditorGizmos *gizmos;
 	SpatialEditor();
 	SpatialEditor();
 
 
@@ -422,6 +443,9 @@ public:
 	float get_rotate_snap() const { return snap_rotate->get_text().to_double(); }
 	float get_rotate_snap() const { return snap_rotate->get_text().to_double(); }
 	float get_scale_snap() const { return snap_scale->get_text().to_double(); }
 	float get_scale_snap() const { return snap_scale->get_text().to_double(); }
 
 
+	Ref<Mesh> get_move_gizmo(int idx) const { return move_gizmo[idx]; }
+	Ref<Mesh> get_rotate_gizmo(int idx) const { return rotate_gizmo[idx]; }
+
 	void update_transform_gizmo();
 	void update_transform_gizmo();
 
 
 	void select_gizmo_hilight_axis(int p_axis);
 	void select_gizmo_hilight_axis(int p_axis);
@@ -442,6 +466,11 @@ public:
 	VSplitContainer *get_shader_split();
 	VSplitContainer *get_shader_split();
 	HSplitContainer *get_palette_split();
 	HSplitContainer *get_palette_split();
 
 
+	Spatial *get_selected() { return selected; }
+
+	int get_over_gizmo_handle() const { return over_gizmo_handle; }
+	void set_over_gizmo_handle(int idx) { over_gizmo_handle=idx; }
+
 	void set_can_preview(Camera* p_preview);
 	void set_can_preview(Camera* p_preview);
 
 
 	Camera *get_camera() { return NULL; }
 	Camera *get_camera() { return NULL; }

+ 109 - 75
tools/editor/spatial_editor_gizmos.cpp

@@ -53,6 +53,7 @@ void SpatialGizmoTool::clear() {
 
 
 	}
 	}
 
 
+	billboard_handle=false;
 	collision_segments.clear();
 	collision_segments.clear();
 	collision_mesh=Ref<TriangleMesh>();
 	collision_mesh=Ref<TriangleMesh>();
 	instances.clear();
 	instances.clear();
@@ -103,10 +104,39 @@ void SpatialGizmoTool::add_lines(const Vector<Vector3> &p_lines, const Ref<Mater
 	Ref<Mesh> mesh = memnew( Mesh );
 	Ref<Mesh> mesh = memnew( Mesh );
 	Array a;
 	Array a;
 	a.resize(Mesh::ARRAY_MAX);
 	a.resize(Mesh::ARRAY_MAX);
+
 	a[Mesh::ARRAY_VERTEX]=p_lines;
 	a[Mesh::ARRAY_VERTEX]=p_lines;
+
+	DVector<Color> color;
+	color.resize(p_lines.size());
+	{
+		DVector<Color>::Write w = color.write();
+		for(int i=0;i<p_lines.size();i++) {
+			if (is_selected())
+				w[i]=Color(1,1,1,0.6);
+			else
+				w[i]=Color(1,1,1,0.25);
+		}
+
+	}
+
+	a[Mesh::ARRAY_COLOR]=color;
+
+
 	mesh->add_surface(Mesh::PRIMITIVE_LINES,a);
 	mesh->add_surface(Mesh::PRIMITIVE_LINES,a);
 	mesh->surface_set_material(0,p_material);
 	mesh->surface_set_material(0,p_material);
 
 
+	if (p_billboard) {
+		float md=0;
+		for(int i=0;i<p_lines.size();i++) {
+
+			md=MAX(0,p_lines[i].length());
+
+		}
+		if (md) {
+			mesh->set_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0));
+		}
+	}
 
 
 	ins.billboard=p_billboard;
 	ins.billboard=p_billboard;
 	ins.mesh=mesh;
 	ins.mesh=mesh;
@@ -145,6 +175,17 @@ void SpatialGizmoTool::add_unscaled_billboard(const Ref<Material>& p_material,fl
 	mesh->add_surface(Mesh::PRIMITIVE_TRIANGLE_FAN,a);
 	mesh->add_surface(Mesh::PRIMITIVE_TRIANGLE_FAN,a);
 	mesh->surface_set_material(0,p_material);
 	mesh->surface_set_material(0,p_material);
 
 
+	if (true) {
+		float md=0;
+		for(int i=0;i<vs.size();i++) {
+
+			md=MAX(0,vs[i].length());
+
+		}
+		if (md) {
+			mesh->set_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0));
+		}
+	}
 
 
 	ins.mesh=mesh;
 	ins.mesh=mesh;
 	ins.unscaled=true;
 	ins.unscaled=true;
@@ -177,12 +218,16 @@ void SpatialGizmoTool::add_collision_segments(const Vector<Vector3> &p_lines) {
 
 
 void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
 void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_billboard,bool p_secondary){
 
 
+	billboard_handle=p_billboard;
+
+	if (!is_selected())
+		return;
+
 	ERR_FAIL_COND(!spatial_node);
 	ERR_FAIL_COND(!spatial_node);
 
 
 	ERR_FAIL_COND(!spatial_node);
 	ERR_FAIL_COND(!spatial_node);
 	Instance ins;
 	Instance ins;
 
 
-	billboard_handle=p_billboard;
 
 
 	Ref<Mesh> mesh = memnew( Mesh );
 	Ref<Mesh> mesh = memnew( Mesh );
 #if 1
 #if 1
@@ -190,11 +235,35 @@ void SpatialGizmoTool::add_handles(const Vector<Vector3> &p_handles, bool p_bill
 	Array a;
 	Array a;
 	a.resize(VS::ARRAY_MAX);
 	a.resize(VS::ARRAY_MAX);
 	a[VS::ARRAY_VERTEX]=p_handles;
 	a[VS::ARRAY_VERTEX]=p_handles;
+	DVector<Color> colors;
+	{
+		colors.resize(p_handles.size());
+		DVector<Color>::Write w=colors.write();
+		for(int i=0;i<p_handles.size();i++) {
+
+			Color col(1,1,1,1);
+			if (SpatialEditor::get_singleton()->get_over_gizmo_handle()!=i)
+				col=Color(0.9,0.9,0.9,0.9);
+			w[i]=col;
+		}
+
+	}
+	a[VS::ARRAY_COLOR]=colors;
 	mesh->add_surface(Mesh::PRIMITIVE_POINTS,a);
 	mesh->add_surface(Mesh::PRIMITIVE_POINTS,a);
-	if (!p_secondary)
-		mesh->surface_set_material(0,SpatialEditorGizmos::singleton->handle2_material);
-	else
-		mesh->surface_set_material(0,SpatialEditorGizmos::singleton->handle2_secondary_material);
+	mesh->surface_set_material(0,SpatialEditorGizmos::singleton->handle2_material);
+
+	if (p_billboard) {
+		float md=0;
+		for(int i=0;i<p_handles.size();i++) {
+
+			md=MAX(0,p_handles[i].length());
+
+		}
+		if (md) {
+			mesh->set_custom_aabb(AABB(Vector3(-md,-md,-md),Vector3(md,md,md)*2.0));
+		}
+	}
+
 
 
 
 
 #else
 #else
@@ -467,6 +536,9 @@ bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_poin
 		int vc=collision_segments.size();
 		int vc=collision_segments.size();
 		const Vector3* vptr=collision_segments.ptr();
 		const Vector3* vptr=collision_segments.ptr();
 		Transform t = spatial_node->get_global_transform();
 		Transform t = spatial_node->get_global_transform();
+		if (billboard_handle) {
+			t.set_look_at(t.origin,t.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1));
+		}
 
 
 		Vector3 cp;
 		Vector3 cp;
 		float cpd=1e20;
 		float cpd=1e20;
@@ -507,7 +579,7 @@ bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_poin
 			}
 			}
 		}
 		}
 
 
-		if (cpd<5) {
+		if (cpd<8) {
 
 
 			r_pos=cp;
 			r_pos=cp;
 			r_normal=-p_camera->project_ray_normal(p_point);
 			r_normal=-p_camera->project_ray_normal(p_point);
@@ -520,6 +592,11 @@ bool SpatialGizmoTool::intersect_ray(const Camera *p_camera,const Point2& p_poin
 
 
 	if (collision_mesh.is_valid()) {
 	if (collision_mesh.is_valid()) {
 		Transform gt = spatial_node->get_global_transform();
 		Transform gt = spatial_node->get_global_transform();
+
+		if (billboard_handle) {
+			gt.set_look_at(gt.origin,gt.origin+p_camera->get_transform().basis.get_axis(2),p_camera->get_transform().basis.get_axis(1));
+		}
+
 		Transform ai=gt.affine_inverse();
 		Transform ai=gt.affine_inverse();
 		Vector3 ray_from = ai.xform(p_camera->project_ray_origin(p_point));
 		Vector3 ray_from = ai.xform(p_camera->project_ray_origin(p_point));
 		Vector3 ray_dir=ai.basis.xform(p_camera->project_ray_normal(p_point)).normalized();
 		Vector3 ray_dir=ai.basis.xform(p_camera->project_ray_normal(p_point)).normalized();
@@ -815,6 +892,7 @@ void LightSpatialGizmo::redraw() {
 		}
 		}
 
 
 		add_lines(points,SpatialEditorGizmos::singleton->light_material,true);
 		add_lines(points,SpatialEditorGizmos::singleton->light_material,true);
+		add_collision_segments(points);
 
 
 		add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon,0.05);
 		add_unscaled_billboard(SpatialEditorGizmos::singleton->light_material_omni_icon,0.05);
 
 
@@ -2117,6 +2195,20 @@ Ref<SpatialEditorGizmo> SpatialEditorGizmos::get_gizmo(Spatial *p_spatial) {
 	return Ref<SpatialEditorGizmo>();
 	return Ref<SpatialEditorGizmo>();
 }
 }
 
 
+
+Ref<FixedMaterial> SpatialEditorGizmos::create_line_material(const Color& p_base_color) {
+
+	Ref<FixedMaterial> line_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
+	line_material->set_flag(Material::FLAG_UNSHADED, true);
+	line_material->set_line_width(3.0);
+	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+	line_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
+	line_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,p_base_color);
+
+	return line_material;
+
+}
+
 SpatialEditorGizmos::SpatialEditorGizmos() {
 SpatialEditorGizmos::SpatialEditorGizmos() {
 
 
 	singleton=this;
 	singleton=this;
@@ -2133,15 +2225,9 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 	handle2_material->set_texture(FixedMaterial::PARAM_DIFFUSE,handle_t);
 	handle2_material->set_texture(FixedMaterial::PARAM_DIFFUSE,handle_t);
 	handle2_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
 	handle2_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1));
 	handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
 	handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
+	handle2_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
 
 
-	handle2_secondary_material = handle2_material->duplicate();
-	handle2_secondary_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,.5));
-
-	light_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	light_material->set_flag(Material::FLAG_UNSHADED, true);
-	light_material->set_line_width(3.0);
-	light_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	light_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,0.2,0.3));
+	light_material = create_line_material(Color(1,1,0.2));
 
 
 	light_material_omni_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
 	light_material_omni_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
 	light_material_omni_icon->set_flag(Material::FLAG_UNSHADED, true);
 	light_material_omni_icon->set_flag(Material::FLAG_UNSHADED, true);
@@ -2160,22 +2246,10 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 	light_material_directional_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
 	light_material_directional_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
 	light_material_directional_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons"));
 	light_material_directional_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoDirectionalLight","EditorIcons"));
 
 
-	camera_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	camera_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.7) );
-	camera_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	camera_material->set_line_width(3);
-	camera_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
-	camera_material->set_flag(Material::FLAG_UNSHADED,true);
-	camera_material->set_hint(Material::HINT_NO_DEPTH_DRAW,true);
+	camera_material = create_line_material(Color(1.0,0.5,1.0));
 
 
 
 
-
-	skeleton_material=Ref<FixedMaterial>( memnew( FixedMaterial ));
-
-	//skeleton_material->set_parameter( FixedMaterial::PARAM_DIFFUSE,Color(0.6,1.0,0.3,0.1) );
-	skeleton_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	skeleton_material->set_fixed_flag(FixedMaterial::FLAG_USE_COLOR_ARRAY, true);
-	skeleton_material->set_line_width(3);
+	skeleton_material = create_line_material(Color(0.6,1.0,0.3));
 	skeleton_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 	skeleton_material->set_flag(Material::FLAG_DOUBLE_SIDED,true);
 	skeleton_material->set_flag(Material::FLAG_UNSHADED,true);
 	skeleton_material->set_flag(Material::FLAG_UNSHADED,true);
 	skeleton_material->set_flag(Material::FLAG_ONTOP,true);
 	skeleton_material->set_flag(Material::FLAG_ONTOP,true);
@@ -2224,48 +2298,11 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 	sample_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
 	sample_player_icon->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1,1,1,0.9));
 	sample_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons"));
 	sample_player_icon->set_texture(FixedMaterial::PARAM_DIFFUSE,SpatialEditor::get_singleton()->get_icon("GizmoSpatialSamplePlayer","EditorIcons"));
 
 
-	room_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	room_material->set_flag(Material::FLAG_UNSHADED, true);
-	room_material->set_flag(Material::FLAG_DOUBLE_SIDED, true);
-	//room_material->set_hint(Material::HINT_NO_DEPTH_DRAW, true);
-	room_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	room_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.6,0.9,0.8));
-	room_material->set_line_width(3);
-
-	portal_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	portal_material->set_flag(Material::FLAG_UNSHADED, true);
-	portal_material->set_flag(Material::FLAG_DOUBLE_SIDED, true);
-	//portal_material->set_hint(Material::HINT_NO_DEPTH_DRAW, true);
-	portal_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	portal_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.8,0.6,0.8));
-	portal_material->set_line_width(3);
-
-
-	raycast_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	raycast_material->set_flag(Material::FLAG_UNSHADED, true);
-	raycast_material->set_flag(Material::FLAG_DOUBLE_SIDED, true);
-	//raycast_material->set_hint(Material::HINT_NO_DEPTH_DRAW, true);
-	raycast_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	raycast_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.8,0.6,0.8));
-	raycast_material->set_line_width(3);
-
-	car_wheel_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	car_wheel_material->set_flag(Material::FLAG_UNSHADED, true);
-	car_wheel_material->set_flag(Material::FLAG_DOUBLE_SIDED, true);
-	//car_wheel_material->set_hint(Material::HINT_NO_DEPTH_DRAW, true);
-	car_wheel_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	car_wheel_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(0.6,0.8,1.0,0.8));
-	car_wheel_material->set_line_width(3);
-
-
-
-	visibility_notifier_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	visibility_notifier_material->set_flag(Material::FLAG_UNSHADED, true);
-	visibility_notifier_material->set_flag(Material::FLAG_DOUBLE_SIDED, true);
-	//visibility_notifier_material->set_hint(Material::HINT_NO_DEPTH_DRAW, true);
-	visibility_notifier_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	visibility_notifier_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(1.0,0.5,1.0,0.8));
-	visibility_notifier_material->set_line_width(3);
+	room_material = create_line_material(Color(1.0,0.6,0.9));
+	portal_material = create_line_material(Color(1.0,0.8,0.6));
+	raycast_material = create_line_material(Color(1.0,0.8,0.6));
+	car_wheel_material = create_line_material(Color(0.6,0.8,1.0));
+	visibility_notifier_material = create_line_material(Color(1.0,0.5,1.0));
 
 
 	stream_player_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
 	stream_player_icon = Ref<FixedMaterial>( memnew( FixedMaterial ));
 	stream_player_icon->set_flag(Material::FLAG_UNSHADED, true);
 	stream_player_icon->set_flag(Material::FLAG_UNSHADED, true);
@@ -2326,11 +2363,8 @@ SpatialEditorGizmos::SpatialEditorGizmos() {
 		test_cube_tm->create(vertices);
 		test_cube_tm->create(vertices);
 	}
 	}
 
 
+	shape_material = create_line_material(Color(0.2,1,1.0));
 
 
-	shape_material = Ref<FixedMaterial>( memnew( FixedMaterial ));
-	shape_material->set_flag(Material::FLAG_UNSHADED, true);
-	shape_material->set_line_width(3.0);
-	shape_material->set_fixed_flag(FixedMaterial::FLAG_USE_ALPHA, true);
-	shape_material->set_parameter(FixedMaterial::PARAM_DIFFUSE,Color(0.2,1,1.0,0.3));
 
 
 }
 }
+

+ 2 - 1
tools/editor/spatial_editor_gizmos.h

@@ -331,8 +331,8 @@ public:
 class SpatialEditorGizmos  {
 class SpatialEditorGizmos  {
 public:
 public:
 
 
+	Ref<FixedMaterial> create_line_material(const Color& p_base_color);
 	Ref<FixedMaterial> handle2_material;
 	Ref<FixedMaterial> handle2_material;
-	Ref<FixedMaterial> handle2_secondary_material;
 	Ref<FixedMaterial> handle_material;
 	Ref<FixedMaterial> handle_material;
 	Ref<FixedMaterial> light_material;
 	Ref<FixedMaterial> light_material;
 	Ref<FixedMaterial> light_material_omni_icon;
 	Ref<FixedMaterial> light_material_omni_icon;
@@ -364,3 +364,4 @@ public:
 };
 };
 
 
 #endif // SPATIAL_EDITOR_GIZMOS_H
 #endif // SPATIAL_EDITOR_GIZMOS_H
+

Some files were not shown because too many files changed in this diff