Преглед изворни кода

-Improve resource previews

-Also fixed draw_texture_rect() tile parameter
Juan Linietsky пре 9 година
родитељ
комит
d3495b128a
27 измењених фајлова са 1195 додато и 271 уклоњено
  1. 1 0
      scene/gui/box_container.cpp
  2. 4 1
      servers/visual/visual_server_raster.cpp
  3. 10 4
      tools/editor/editor_node.cpp
  4. 2 0
      tools/editor/editor_node.h
  5. 8 0
      tools/editor/editor_plugin.cpp
  6. 2 1
      tools/editor/editor_plugin.h
  7. BIN
      tools/editor/icons/icon_checkerboard.png
  8. BIN
      tools/editor/icons/icon_material_preview_cube.png
  9. BIN
      tools/editor/icons/icon_material_preview_cube_off.png
  10. BIN
      tools/editor/icons/icon_material_preview_light_1.png
  11. BIN
      tools/editor/icons/icon_material_preview_light_1_off.png
  12. BIN
      tools/editor/icons/icon_material_preview_light_2.png
  13. BIN
      tools/editor/icons/icon_material_preview_light_2_off.png
  14. BIN
      tools/editor/icons/icon_material_preview_sphere.png
  15. BIN
      tools/editor/icons/icon_material_preview_sphere_off.png
  16. 5 10
      tools/editor/plugins/color_ramp_editor_plugin.cpp
  17. 1 1
      tools/editor/plugins/color_ramp_editor_plugin.h
  18. 381 0
      tools/editor/plugins/material_editor_plugin.cpp
  19. 71 0
      tools/editor/plugins/material_editor_plugin.h
  20. 117 218
      tools/editor/plugins/mesh_editor_plugin.cpp
  21. 29 31
      tools/editor/plugins/mesh_editor_plugin.h
  22. 300 0
      tools/editor/plugins/mesh_instance_editor_plugin.cpp
  23. 69 0
      tools/editor/plugins/mesh_instance_editor_plugin.h
  24. 4 5
      tools/editor/plugins/sample_editor_plugin.cpp
  25. 141 0
      tools/editor/plugins/texture_editor_plugin.cpp
  26. 49 0
      tools/editor/plugins/texture_editor_plugin.h
  27. 1 0
      tools/editor/script_editor_debugger.cpp

+ 1 - 0
scene/gui/box_container.cpp

@@ -280,6 +280,7 @@ BoxContainer::AlignMode BoxContainer::get_alignment() const {
 void BoxContainer::add_spacer(bool p_begin) {
 
 	Control *c = memnew( Control );
+	c->set_stop_mouse(false);
 	if (vertical)
 		c->set_v_size_flags(SIZE_EXPAND_FILL);
 	else

+ 4 - 1
servers/visual/visual_server_raster.cpp

@@ -3661,8 +3661,11 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p
 	rect->modulate=p_modulate;
 	rect->rect=p_rect;
 	rect->flags=0;
-	if (p_tile)
+	if (p_tile) {
 		rect->flags|=Rasterizer::CANVAS_RECT_TILE;
+		rect->flags|=Rasterizer::CANVAS_RECT_REGION;
+		rect->source=Rect2(0,0,p_rect.size.width,p_rect.size.height);
+	}
 
 	if (p_rect.size.x<0) {
 

+ 10 - 4
tools/editor/editor_node.cpp

@@ -64,6 +64,8 @@
 #include "addon_editor_plugin.h"
 #include "plugins/spatial_editor_plugin.h"
 #include "plugins/sample_editor_plugin.h"
+#include "plugins/texture_editor_plugin.h"
+#include "plugins/material_editor_plugin.h"
 #include "plugins/sample_library_editor_plugin.h"
 #include "plugins/sample_player_editor_plugin.h"
 #include "plugins/camera_editor_plugin.h"
@@ -72,6 +74,7 @@
 #include "plugins/item_list_editor_plugin.h"
 #include "plugins/stream_editor_plugin.h"
 #include "plugins/multimesh_editor_plugin.h"
+#include "plugins/mesh_instance_editor_plugin.h"
 #include "plugins/mesh_editor_plugin.h"
 #include "plugins/theme_editor_plugin.h"
 
@@ -5818,6 +5821,7 @@ EditorNode::EditorNode() {
 	HBoxContainer *prop_editor_hb = memnew( HBoxContainer );
 
 	prop_editor_base->add_child(prop_editor_hb);
+	prop_editor_vb=prop_editor_base;
 
 	resource_new_button = memnew( ToolButton );
 	resource_new_button->set_tooltip(TTR("Create a new resource in memory and edit it."));
@@ -6223,9 +6227,9 @@ EditorNode::EditorNode() {
 	add_editor_plugin( memnew( MultiMeshEditorPlugin(this) ) );
 	add_editor_plugin( memnew( MeshInstanceEditorPlugin(this) ) );
 	add_editor_plugin( memnew( AnimationTreeEditorPlugin(this) ) );
-	add_editor_plugin( memnew( SamplePlayerEditorPlugin(this) ) );
+	//add_editor_plugin( memnew( SamplePlayerEditorPlugin(this) ) ); - this is kind of useless at this point
 	add_editor_plugin( memnew( MeshLibraryEditorPlugin(this) ) );
-	add_editor_plugin( memnew( StreamEditorPlugin(this) ) );
+	//add_editor_plugin( memnew( StreamEditorPlugin(this) ) );
 	add_editor_plugin( memnew( StyleBoxEditorPlugin(this) ) );
 	add_editor_plugin( memnew( ParticlesEditorPlugin(this) ) );
 	add_editor_plugin( memnew( ResourcePreloaderEditorPlugin(this) ) );
@@ -6244,9 +6248,11 @@ EditorNode::EditorNode() {
 	add_editor_plugin( memnew( Polygon2DEditorPlugin(this) ) );
 	add_editor_plugin( memnew( LightOccluder2DEditorPlugin(this) ) );
 	add_editor_plugin( memnew( NavigationPolygonEditorPlugin(this) ) );
-	add_editor_plugin( memnew( ColorRampEditorPlugin(this,true) ) );
-	add_editor_plugin( memnew( ColorRampEditorPlugin(this,false) ) );
+	add_editor_plugin( memnew( ColorRampEditorPlugin(this) ) );
 	add_editor_plugin( memnew( CollisionShape2DEditorPlugin(this) ) );
+	add_editor_plugin( memnew( TextureEditorPlugin(this) ) );
+	add_editor_plugin( memnew( MaterialEditorPlugin(this) ) );
+	add_editor_plugin( memnew( MeshEditorPlugin(this) ) );
 
 	for(int i=0;i<EditorPlugins::get_plugin_count();i++)
 		add_editor_plugin( EditorPlugins::create(i,this) );

+ 2 - 0
tools/editor/editor_node.h

@@ -269,6 +269,7 @@ private:
 	SceneTreeDock *scene_tree_dock;
 	//ResourcesDock *resources_dock;
 	PropertyEditor *property_editor;
+	VBoxContainer *prop_editor_vb;
 	ScenesDock *scenes_dock;
 	EditorRunNative *run_native;
 
@@ -580,6 +581,7 @@ public:
 	EditorPlugin *get_editor_plugin_screen() { return editor_plugin_screen; }
 	EditorPluginList *get_editor_plugins_over() { return editor_plugins_over; }
 	PropertyEditor *get_property_editor() { return property_editor; }
+	VBoxContainer *get_property_editor_vb() { return prop_editor_vb; }
 
 	static void add_editor_plugin(EditorPlugin *p_editor);
 	static void remove_editor_plugin(EditorPlugin *p_editor);

+ 8 - 0
tools/editor/editor_plugin.cpp

@@ -110,6 +110,12 @@ void EditorPlugin::add_control_to_container(CustomControlContainer p_location,Co
 			CanvasItemEditor::get_singleton()->get_bottom_split()->add_child(p_control);
 
 		} break;
+		case CONTAINER_PROPERTY_EDITOR_BOTTOM: {
+
+			EditorNode::get_singleton()->get_property_editor_vb()->add_child(p_control);
+
+		} break;
+
 
 	}
 }
@@ -319,6 +325,8 @@ void EditorPlugin::_bind_methods() {
 	BIND_CONSTANT( CONTAINER_SPATIAL_EDITOR_BOTTOM );
 	BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_MENU );
 	BIND_CONSTANT( CONTAINER_CANVAS_EDITOR_SIDE );
+	BIND_CONSTANT( CONTAINER_PROPERTY_EDITOR_BOTTOM );
+
 
 	BIND_CONSTANT( DOCK_SLOT_LEFT_UL );
 	BIND_CONSTANT( DOCK_SLOT_LEFT_BL );

+ 2 - 1
tools/editor/editor_plugin.h

@@ -73,7 +73,8 @@ public:
 		CONTAINER_SPATIAL_EDITOR_BOTTOM,
 		CONTAINER_CANVAS_EDITOR_MENU,
 		CONTAINER_CANVAS_EDITOR_SIDE,
-		CONTAINER_CANVAS_EDITOR_BOTTOM
+		CONTAINER_CANVAS_EDITOR_BOTTOM,
+		CONTAINER_PROPERTY_EDITOR_BOTTOM
 	};
 
 	enum DockSlot {

BIN
tools/editor/icons/icon_checkerboard.png


BIN
tools/editor/icons/icon_material_preview_cube.png


BIN
tools/editor/icons/icon_material_preview_cube_off.png


BIN
tools/editor/icons/icon_material_preview_light_1.png


BIN
tools/editor/icons/icon_material_preview_light_1_off.png


BIN
tools/editor/icons/icon_material_preview_light_2.png


BIN
tools/editor/icons/icon_material_preview_light_2_off.png


BIN
tools/editor/icons/icon_material_preview_sphere.png


BIN
tools/editor/icons/icon_material_preview_sphere_off.png


+ 5 - 10
tools/editor/plugins/color_ramp_editor_plugin.cpp

@@ -6,16 +6,13 @@
 #include "spatial_editor_plugin.h"
 #include "canvas_item_editor_plugin.h"
 
-ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node, bool p_2d) {
+ColorRampEditorPlugin::ColorRampEditorPlugin(EditorNode *p_node) {
 
 	editor=p_node;
 	ramp_editor = memnew( ColorRampEdit );
 
-	_2d=p_2d;
-	if (p_2d)
-		add_control_to_container(CONTAINER_CANVAS_EDITOR_BOTTOM,ramp_editor);
-	else
-		add_control_to_container(CONTAINER_SPATIAL_EDITOR_BOTTOM,ramp_editor);
+
+	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,ramp_editor);
 
 	ramp_editor->set_custom_minimum_size(Size2(100, 48));
 	ramp_editor->hide();
@@ -33,10 +30,8 @@ void ColorRampEditorPlugin::edit(Object *p_object) {
 
 bool ColorRampEditorPlugin::handles(Object *p_object) const {
 
-	if (_2d)
-		return p_object->is_type("ColorRamp") && CanvasItemEditor::get_singleton()->is_visible() == true;
-	else
-		return p_object->is_type("ColorRamp") && SpatialEditor::get_singleton()->is_visible() == true;
+	return p_object->is_type("ColorRamp");
+
 }
 
 void ColorRampEditorPlugin::make_visible(bool p_visible) {

+ 1 - 1
tools/editor/plugins/color_ramp_editor_plugin.h

@@ -30,7 +30,7 @@ public:
 	virtual bool handles(Object *p_node) const;
 	virtual void make_visible(bool p_visible);
 
-	ColorRampEditorPlugin(EditorNode *p_node, bool p_2d);
+	ColorRampEditorPlugin(EditorNode *p_node);
 	~ColorRampEditorPlugin();
 
 };

+ 381 - 0
tools/editor/plugins/material_editor_plugin.cpp

@@ -0,0 +1,381 @@
+#include "material_editor_plugin.h"
+#include "scene/main/viewport.h"
+
+void MaterialEditor::_input_event(InputEvent p_event) {
+
+
+}
+
+void MaterialEditor::_notification(int p_what) {
+
+	if (p_what==NOTIFICATION_FIXED_PROCESS) {
+
+	}
+
+
+	if (p_what==NOTIFICATION_READY) {
+
+		//get_scene()->connect("node_removed",this,"_node_removed");
+
+		if (first_enter) {
+			//it's in propertyeditor so.. could be moved around
+
+			light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons"));
+			light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons"));
+			light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons"));
+			light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons"));
+
+			sphere_switch->set_normal_texture(get_icon("MaterialPreviewSphereOff","EditorIcons"));
+			sphere_switch->set_pressed_texture(get_icon("MaterialPreviewSphere","EditorIcons"));
+			box_switch->set_normal_texture(get_icon("MaterialPreviewCubeOff","EditorIcons"));
+			box_switch->set_pressed_texture(get_icon("MaterialPreviewCube","EditorIcons"));
+
+			first_enter=false;
+		}
+
+	}
+
+	if (p_what==NOTIFICATION_DRAW) {
+
+
+		Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons");
+		Size2 size = get_size();
+
+		draw_texture_rect(checkerboard,Rect2(Point2(),size),true);
+
+	}
+}
+
+
+
+void MaterialEditor::edit(Ref<Material> p_material) {
+
+	material=p_material;
+
+	if (!material.is_null()) {
+		sphere_mesh->surface_set_material(0,material);
+		box_mesh->surface_set_material(0,material);
+	} else {
+
+		hide();
+	}
+
+}
+
+
+void MaterialEditor::_button_pressed(Node* p_button) {
+
+	if (p_button==light_1_switch) {
+		light1->set_enabled(!light_1_switch->is_pressed());
+	}
+
+	if (p_button==light_2_switch) {
+		light2->set_enabled(!light_2_switch->is_pressed());
+	}
+
+	if (p_button==box_switch) {
+		box_instance->show();
+		sphere_instance->hide();
+		box_switch->set_pressed(true);
+		sphere_switch->set_pressed(false);
+	}
+
+	if (p_button==sphere_switch) {
+		box_instance->hide();
+		sphere_instance->show();
+		box_switch->set_pressed(false);
+		sphere_switch->set_pressed(true);
+	}
+
+}
+
+void MaterialEditor::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("_input_event"),&MaterialEditor::_input_event);
+	ObjectTypeDB::bind_method(_MD("_button_pressed"),&MaterialEditor::_button_pressed);
+
+}
+
+MaterialEditor::MaterialEditor() {
+
+	viewport = memnew( Viewport );
+	Ref<World> world;
+	world.instance();
+	viewport->set_world(world); //use own world
+	add_child(viewport);
+	viewport->set_process_input(false);
+
+	camera = memnew( Camera );
+	camera->set_transform(Transform(Matrix3(),Vector3(0,0,3)));
+	camera->set_perspective(45,0.1,10);
+	viewport->add_child(camera);
+
+	light1 = memnew( DirectionalLight );
+	light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
+	viewport->add_child(light1);
+
+	light2 = memnew( DirectionalLight );
+	light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
+	light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7));
+	light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7));
+	viewport->add_child(light2);
+
+	sphere_instance = memnew( MeshInstance );
+	viewport->add_child(sphere_instance);
+
+	box_instance = memnew( MeshInstance );
+	viewport->add_child(box_instance);
+
+	Transform box_xform;
+	box_xform.basis.rotate(Vector3(1,0,0),Math::deg2rad(-25));
+	box_xform.basis = box_xform.basis * Matrix3().rotated(Vector3(0,1,0),Math::deg2rad(-25));
+	box_xform.basis.scale(Vector3(0.8,0.8,0.8));
+	box_instance->set_transform(box_xform);
+
+	{
+
+		sphere_mesh.instance();
+
+
+		int lats=32;
+		int lons=32;
+		float radius=1.0;
+
+		DVector<Vector3> vertices;
+		DVector<Vector3> normals;
+		DVector<Vector2> uvs;
+		DVector<float> tangents;
+		Matrix3 tt = Matrix3(Vector3(0,1,0),Math_PI*0.5);
+
+		for(int i = 1; i <= lats; i++) {
+			double lat0 = Math_PI * (-0.5 + (double) (i - 1) / lats);
+			double z0  = Math::sin(lat0);
+			double zr0 =  Math::cos(lat0);
+
+			double lat1 = Math_PI * (-0.5 + (double) i / lats);
+			double z1 = Math::sin(lat1);
+			double zr1 = Math::cos(lat1);
+
+			for(int j = lons; j >= 1; j--) {
+
+				double lng0 = 2 * Math_PI * (double) (j - 1) / lons;
+				double x0 = Math::cos(lng0);
+				double y0 = Math::sin(lng0);
+
+				double lng1 = 2 * Math_PI * (double) (j) / lons;
+				double x1 = Math::cos(lng1);
+				double y1 = Math::sin(lng1);
+
+
+				Vector3 v[4]={
+					Vector3(x1 * zr0, z0, y1 *zr0),
+					Vector3(x1 * zr1, z1, y1 *zr1),
+					Vector3(x0 * zr1, z1, y0 *zr1),
+					Vector3(x0 * zr0, z0, y0 *zr0)
+				};
+
+	#define ADD_POINT(m_idx) \
+		normals.push_back(v[m_idx]);\
+		vertices.push_back(v[m_idx]*radius);\
+		{ Vector2 uv(Math::atan2(v[m_idx].x,v[m_idx].z),Math::atan2(-v[m_idx].y,v[m_idx].z));\
+		  uv/=Math_PI;\
+		  uv*=4.0;\
+		  uv=uv*0.5+Vector2(0.5,0.5);\
+		  uvs.push_back(uv);\
+		 }\
+		 { Vector3 t = tt.xform(v[m_idx]);\
+		   tangents.push_back(t.x);\
+		   tangents.push_back(t.y);\
+		   tangents.push_back(t.z);\
+		   tangents.push_back(1.0);\
+		  }
+
+
+
+				ADD_POINT(0);
+				ADD_POINT(1);
+				ADD_POINT(2);
+
+				ADD_POINT(2);
+				ADD_POINT(3);
+				ADD_POINT(0);
+			}
+		}
+
+		Array arr;
+		arr.resize(VS::ARRAY_MAX);
+		arr[VS::ARRAY_VERTEX]=vertices;
+		arr[VS::ARRAY_NORMAL]=normals;
+		arr[VS::ARRAY_TANGENT]=tangents;
+		arr[VS::ARRAY_TEX_UV]=uvs;
+
+		sphere_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,arr);
+
+		sphere_instance->set_mesh(sphere_mesh);
+
+	}
+	{
+
+
+		box_mesh.instance();
+
+		DVector<Vector3> vertices;
+		DVector<Vector3> normals;
+		DVector<float> tangents;
+		DVector<Vector3> uvs;
+
+		int vtx_idx=0;
+	#define ADD_VTX(m_idx);\
+		vertices.push_back( face_points[m_idx] );\
+		normals.push_back( normal_points[m_idx] );\
+		tangents.push_back( normal_points[m_idx][1] );\
+		tangents.push_back( normal_points[m_idx][2] );\
+		tangents.push_back( normal_points[m_idx][0] );\
+		tangents.push_back( 1.0 );\
+		uvs.push_back( Vector3(uv_points[m_idx*2+0],uv_points[m_idx*2+1],0) );\
+		vtx_idx++;\
+
+		for (int i=0;i<6;i++) {
+
+
+			Vector3 face_points[4];
+			Vector3 normal_points[4];
+			float uv_points[8]={0,0,0,1,1,1,1,0};
+
+			for (int j=0;j<4;j++) {
+
+				float v[3];
+				v[0]=1.0;
+				v[1]=1-2*((j>>1)&1);
+				v[2]=v[1]*(1-2*(j&1));
+
+				for (int k=0;k<3;k++) {
+
+					if (i<3)
+						face_points[j][(i+k)%3]=v[k]*(i>=3?-1:1);
+					else
+						face_points[3-j][(i+k)%3]=v[k]*(i>=3?-1:1);
+				}
+				normal_points[j]=Vector3();
+				normal_points[j][i%3]=(i>=3?-1:1);
+			}
+
+		//tri 1
+			ADD_VTX(0);
+			ADD_VTX(1);
+			ADD_VTX(2);
+		//tri 2
+			ADD_VTX(2);
+			ADD_VTX(3);
+			ADD_VTX(0);
+
+		}
+
+
+
+		Array d;
+		d.resize(VS::ARRAY_MAX);
+		d[VisualServer::ARRAY_NORMAL]= normals ;
+		d[VisualServer::ARRAY_TANGENT]= tangents ;
+		d[VisualServer::ARRAY_TEX_UV]= uvs ;
+		d[VisualServer::ARRAY_VERTEX]= vertices ;
+
+		DVector<int> indices;
+		indices.resize(vertices.size());
+		for(int i=0;i<vertices.size();i++)
+			indices.set(i,i);
+		d[VisualServer::ARRAY_INDEX]=indices;
+
+		box_mesh->add_surface(Mesh::PRIMITIVE_TRIANGLES,d);
+		box_instance->set_mesh(box_mesh);
+		box_instance->hide();
+
+
+
+	}
+
+	set_custom_minimum_size(Size2(1,150));
+
+	HBoxContainer *hb = memnew( HBoxContainer );
+	add_child(hb);
+	hb->set_area_as_parent_rect(2);
+
+	VBoxContainer *vb_shape = memnew( VBoxContainer );
+	hb->add_child(vb_shape);
+
+	sphere_switch = memnew( TextureButton );
+	sphere_switch->set_toggle_mode(true);
+	sphere_switch->set_pressed(true);
+	vb_shape->add_child(sphere_switch);
+	sphere_switch->connect("pressed",this,"_button_pressed",varray(sphere_switch));
+
+	box_switch = memnew( TextureButton );
+	box_switch->set_toggle_mode(true);
+	box_switch->set_pressed(false);
+	vb_shape->add_child(box_switch);
+	box_switch->connect("pressed",this,"_button_pressed",varray(box_switch));
+
+	hb->add_spacer();
+
+	VBoxContainer *vb_light = memnew( VBoxContainer );
+	hb->add_child(vb_light);
+
+	light_1_switch = memnew( TextureButton );
+	light_1_switch->set_toggle_mode(true);
+	vb_light->add_child(light_1_switch);
+	light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch));
+
+	light_2_switch = memnew( TextureButton );
+	light_2_switch->set_toggle_mode(true);
+	vb_light->add_child(light_2_switch);
+	light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch));
+
+	first_enter=true;
+
+}
+
+
+void MaterialEditorPlugin::edit(Object *p_object) {
+
+	Material * s = p_object->cast_to<Material>();
+	if (!s)
+		return;
+
+	material_editor->edit(Ref<Material>(s));
+}
+
+bool MaterialEditorPlugin::handles(Object *p_object) const {
+
+	return p_object->is_type("Material");
+}
+
+void MaterialEditorPlugin::make_visible(bool p_visible) {
+
+	if (p_visible) {
+		material_editor->show();
+//		material_editor->set_process(true);
+	} else {
+
+		material_editor->hide();
+//		material_editor->set_process(false);
+	}
+
+}
+
+MaterialEditorPlugin::MaterialEditorPlugin(EditorNode *p_node) {
+
+	editor=p_node;
+	material_editor = memnew( MaterialEditor );
+	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,material_editor);
+	material_editor->hide();
+
+
+
+}
+
+
+MaterialEditorPlugin::~MaterialEditorPlugin()
+{
+}
+
+

+ 71 - 0
tools/editor/plugins/material_editor_plugin.h

@@ -0,0 +1,71 @@
+#ifndef MATERIAL_EDITOR_PLUGIN_H
+#define MATERIAL_EDITOR_PLUGIN_H
+
+#include "tools/editor/editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "scene/resources/material.h"
+#include "scene/3d/light.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/3d/camera.h"
+
+
+class MaterialEditor : public Control {
+
+	OBJ_TYPE(MaterialEditor, Control);
+
+
+	Viewport *viewport;
+	MeshInstance *sphere_instance;
+	MeshInstance *box_instance;
+	DirectionalLight *light1;
+	DirectionalLight *light2;
+	Camera *camera;
+
+	Ref<Mesh> sphere_mesh;
+	Ref<Mesh> box_mesh;
+
+	TextureButton *sphere_switch;
+	TextureButton *box_switch;
+
+	TextureButton *light_1_switch;
+	TextureButton *light_2_switch;
+
+
+	Ref<Material> material;
+
+
+	void _button_pressed(Node* p_button);
+	bool first_enter;
+
+protected:
+	void _notification(int p_what);
+	void _input_event(InputEvent p_event);
+	static void _bind_methods();
+public:
+
+	void edit(Ref<Material> p_material);
+	MaterialEditor();
+};
+
+
+class MaterialEditorPlugin : public EditorPlugin {
+
+	OBJ_TYPE( MaterialEditorPlugin, EditorPlugin );
+
+	MaterialEditor *material_editor;
+	EditorNode *editor;
+
+public:
+
+	virtual String get_name() const { return "Material"; }
+	bool has_main_screen() const { return false; }
+	virtual void edit(Object *p_node);
+	virtual bool handles(Object *p_node) const;
+	virtual void make_visible(bool p_visible);
+
+	MaterialEditorPlugin(EditorNode *p_node);
+	~MaterialEditorPlugin();
+
+};
+
+#endif // MATERIAL_EDITOR_PLUGIN_H

+ 117 - 218
tools/editor/plugins/mesh_editor_plugin.cpp

@@ -1,300 +1,199 @@
 #include "mesh_editor_plugin.h"
 
-#include "scene/3d/physics_body.h"
-#include "scene/3d/body_shape.h"
-#include "scene/gui/box_container.h"
-#include "scene/3d/navigation_mesh.h"
-#include "spatial_editor_plugin.h"
+void MeshEditor::_input_event(InputEvent p_event) {
 
-void MeshInstanceEditor::_node_removed(Node *p_node) {
 
-	if(p_node==node) {
-		node=NULL;
-		options->hide();
-	}
+	if (p_event.type==InputEvent::MOUSE_MOTION && p_event.mouse_motion.button_mask&BUTTON_MASK_LEFT) {
 
+		rot_x-=p_event.mouse_motion.relative_y*0.01;
+		rot_y-=p_event.mouse_motion.relative_x*0.01;
+		if (rot_x<-Math_PI/2)
+			rot_x=-Math_PI/2;
+		else if (rot_x>Math_PI/2) {
+			rot_x=Math_PI/2;
+		}
+		_update_rotation();
+	}
 }
 
+void MeshEditor::_notification(int p_what) {
 
+	if (p_what==NOTIFICATION_FIXED_PROCESS) {
 
-void MeshInstanceEditor::edit(MeshInstance *p_mesh) {
-
-	node=p_mesh;
-
-}
-
-void MeshInstanceEditor::_menu_option(int p_option) {
-
-	Ref<Mesh> mesh = node->get_mesh();
-	if (mesh.is_null()) {
-		err_dialog->set_text(TTR("Mesh is empty!"));
-		err_dialog->popup_centered_minsize();
-		return;
 	}
 
-	switch(p_option) {
-		case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY:
-		case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: {
-
-			bool trimesh_shape = (p_option==MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
-
-			EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
-			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
-
-			List<Node*> selection = editor_selection->get_selected_node_list();
-
-			if (selection.empty()) {
-				Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
-				if (shape.is_null())
-					return;
-
-				CollisionShape *cshape = memnew( CollisionShape );
-				cshape->set_shape(shape);
-				StaticBody *body = memnew( StaticBody );
-				body->add_child(cshape);
-
-				Node *owner = node==get_tree()->get_edited_scene_root() ? node : node->get_owner();
-
-				if (trimesh_shape)
-					ur->create_action(TTR("Create Static Trimesh Body"));
-				else
-					ur->create_action(TTR("Create Static Convex Body"));
-
-				ur->add_do_method(node,"add_child",body);
-				ur->add_do_method(body,"set_owner",owner);
-				ur->add_do_method(cshape,"set_owner",owner);
-				ur->add_do_reference(body);
-				ur->add_undo_method(node,"remove_child",body);
-				ur->commit_action();
-				return;
-			}
-
-			if (trimesh_shape)
-				ur->create_action(TTR("Create Static Trimesh Body"));
-			else
-				ur->create_action(TTR("Create Static Convex Body"));
-
-			for (List<Node*>::Element *E=selection.front();E;E=E->next()) {
-
-				MeshInstance *instance = E->get()->cast_to<MeshInstance>();
-				if (!instance)
-					continue;
-
-				Ref<Mesh> m = instance->get_mesh();
-				if (m.is_null())
-					continue;
-
-				Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape();
-				if (shape.is_null())
-					continue;
-
-				CollisionShape *cshape = memnew( CollisionShape );
-				cshape->set_shape(shape);
-				StaticBody *body = memnew( StaticBody );
-				body->add_child(cshape);
-
-				Node *owner = instance==get_tree()->get_edited_scene_root() ? instance : instance->get_owner();
-
-				ur->add_do_method(instance,"add_child",body);
-				ur->add_do_method(body,"set_owner",owner);
-				ur->add_do_method(cshape,"set_owner",owner);
-				ur->add_do_reference(body);
-				ur->add_undo_method(instance,"remove_child",body);
-			}
-
-			ur->commit_action();
 
-		} break;
+	if (p_what==NOTIFICATION_READY) {
 
-		case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE:
-		case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: {
+		//get_scene()->connect("node_removed",this,"_node_removed");
 
-			if (node==get_tree()->get_edited_scene_root()) {
-				err_dialog->set_text(TTR("This doesn't work on scene root!"));
-				err_dialog->popup_centered_minsize();
-				return;
-			}
+		if (first_enter) {
+			//it's in propertyeditor so.. could be moved around
 
-			bool trimesh_shape = (p_option==MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);
+			light_1_switch->set_normal_texture(get_icon("MaterialPreviewLight1","EditorIcons"));
+			light_1_switch->set_pressed_texture(get_icon("MaterialPreviewLight1Off","EditorIcons"));
+			light_2_switch->set_normal_texture(get_icon("MaterialPreviewLight2","EditorIcons"));
+			light_2_switch->set_pressed_texture(get_icon("MaterialPreviewLight2Off","EditorIcons"));
+			first_enter=false;
+		}
 
-			Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
-			if (shape.is_null())
-				return;
+	}
 
-			CollisionShape *cshape = memnew( CollisionShape );
-			cshape->set_shape(shape);
+	if (p_what==NOTIFICATION_DRAW) {
 
-			Node *owner =  node->get_owner();
 
-			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+		Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons");
+		Size2 size = get_size();
 
-			if (trimesh_shape)
-				ur->create_action(TTR("Create Trimesh Shape"));
-			else
-				ur->create_action(TTR("Create Convex Shape"));
+		draw_texture_rect(checkerboard,Rect2(Point2(),size),true);
 
-			ur->add_do_method(node->get_parent(),"add_child",cshape);
-			ur->add_do_method(node->get_parent(),"move_child",cshape,node->get_index()+1);
-			ur->add_do_method(cshape,"set_owner",owner);
-			ur->add_do_reference(cshape);
-			ur->add_undo_method(node->get_parent(),"remove_child",cshape);
-			ur->commit_action();
+	}
+}
 
-		} break;
+void MeshEditor::_update_rotation() {
 
-		case MENU_OPTION_CREATE_NAVMESH: {
+	Transform t;
+	t.basis.rotate(Vector3(0, 1, 0), rot_y);
+	t.basis.rotate(Vector3(1, 0, 0), rot_x);
+	mesh_instance->set_transform(t);
 
-			Ref<NavigationMesh> nmesh = memnew( NavigationMesh );
+}
 
-			if (nmesh.is_null())
-				return;
+void MeshEditor::edit(Ref<Mesh> p_mesh) {
 
-			nmesh->create_from_mesh(mesh);
-			NavigationMeshInstance *nmi = memnew(  NavigationMeshInstance );
-			nmi->set_navigation_mesh(nmesh);
+	mesh=p_mesh;
+	mesh_instance->set_mesh(mesh);
 
-			Node *owner = node==get_tree()->get_edited_scene_root() ? node : node->get_owner();
+	if (mesh.is_null()) {
 
-			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
-			ur->create_action(TTR("Create Navigation Mesh"));
+		hide();
+	} else {
+		rot_x=0;
+		rot_y=0;
+		_update_rotation();
+	}
 
-			ur->add_do_method(node,"add_child",nmi);
-			ur->add_do_method(nmi,"set_owner",owner);
+}
 
-			ur->add_do_reference(nmi);
-			ur->add_undo_method(node,"remove_child",nmi);
-			ur->commit_action();
-		} break;
 
-		case MENU_OPTION_CREATE_OUTLINE_MESH: {
+void MeshEditor::_button_pressed(Node* p_button) {
 
-			outline_dialog->popup_centered(Vector2(200, 90));
-		} break;
+	if (p_button==light_1_switch) {
+		light1->set_enabled(!light_1_switch->is_pressed());
 	}
 
-}
+	if (p_button==light_2_switch) {
+		light2->set_enabled(!light_2_switch->is_pressed());
+	}
 
-void MeshInstanceEditor::_create_outline_mesh() {
 
-	Ref<Mesh> mesh = node->get_mesh();
-	if (mesh.is_null()) {
-		err_dialog->set_text(TTR("MeshInstance lacks a Mesh!"));
-		err_dialog->popup_centered_minsize();
-		return;
-	}
+}
 
-	Ref<Mesh> mesho = mesh->create_outline(outline_size->get_val());
+void MeshEditor::_bind_methods() {
 
-	if (mesho.is_null()) {
-		err_dialog->set_text(TTR("Could not create outline!"));
-		err_dialog->popup_centered_minsize();
-		return;
-	}
+	ObjectTypeDB::bind_method(_MD("_input_event"),&MeshEditor::_input_event);
+	ObjectTypeDB::bind_method(_MD("_button_pressed"),&MeshEditor::_button_pressed);
 
-	MeshInstance *mi = memnew( MeshInstance );
-	mi->set_mesh(mesho);
-	Node *owner=node->get_owner();
-	if (get_tree()->get_edited_scene_root()==node) {
-		owner=node;
-	}
+}
 
-	UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+MeshEditor::MeshEditor() {
 
-	ur->create_action(TTR("Create Outline"));
+	viewport = memnew( Viewport );
+	Ref<World> world;
+	world.instance();
+	viewport->set_world(world); //use own world
+	add_child(viewport);
+	viewport->set_process_input(false);
 
-	ur->add_do_method(node,"add_child",mi);
-	ur->add_do_method(mi,"set_owner",owner);
+	camera = memnew( Camera );
+	camera->set_transform(Transform(Matrix3(),Vector3(0,0,3)));
+	camera->set_perspective(45,0.1,10);
+	viewport->add_child(camera);
 
-	ur->add_do_reference(mi);
-	ur->add_undo_method(node,"remove_child",mi);
-	ur->commit_action();
-}
+	light1 = memnew( DirectionalLight );
+	light1->set_transform(Transform().looking_at(Vector3(-1,-1,-1),Vector3(0,1,0)));
+	viewport->add_child(light1);
 
-void MeshInstanceEditor::_bind_methods() {
+	light2 = memnew( DirectionalLight );
+	light2->set_transform(Transform().looking_at(Vector3(0,1,0),Vector3(0,0,1)));
+	light2->set_color(Light::COLOR_DIFFUSE,Color(0.7,0.7,0.7));
+	light2->set_color(Light::COLOR_SPECULAR,Color(0.7,0.7,0.7));
+	viewport->add_child(light2);
 
-	ObjectTypeDB::bind_method("_menu_option",&MeshInstanceEditor::_menu_option);
-	ObjectTypeDB::bind_method("_create_outline_mesh",&MeshInstanceEditor::_create_outline_mesh);
-}
+	mesh_instance = memnew( MeshInstance );
+	viewport->add_child(mesh_instance);
 
-MeshInstanceEditor::MeshInstanceEditor() {
 
 
-	options = memnew( MenuButton );
-	SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
+	set_custom_minimum_size(Size2(1,150));
 
-	options->set_text("Mesh");
-	options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance","EditorIcons"));
+	HBoxContainer *hb = memnew( HBoxContainer );
+	add_child(hb);
+	hb->set_area_as_parent_rect(2);
 
-	options->get_popup()->add_item(TTR("Create Trimesh Static Body"),MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
-	options->get_popup()->add_item(TTR("Create Convex Static Body"),MENU_OPTION_CREATE_STATIC_CONVEX_BODY);
-	options->get_popup()->add_separator();
-	options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"),MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);
-	options->get_popup()->add_item(TTR("Create Convex Collision Sibling"),MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE);
-	options->get_popup()->add_separator();
-	options->get_popup()->add_item(TTR("Create Navigation Mesh"),MENU_OPTION_CREATE_NAVMESH);
-	options->get_popup()->add_separator();
-	options->get_popup()->add_item(TTR("Create Outline Mesh.."),MENU_OPTION_CREATE_OUTLINE_MESH);
+	hb->add_spacer();
 
-	options->get_popup()->connect("item_pressed", this,"_menu_option");
+	VBoxContainer *vb_light = memnew( VBoxContainer );
+	hb->add_child(vb_light);
 
-	outline_dialog = memnew( ConfirmationDialog );
-	outline_dialog->set_title(TTR("Create Outline Mesh"));
-	outline_dialog->get_ok()->set_text(TTR("Create"));
+	light_1_switch = memnew( TextureButton );
+	light_1_switch->set_toggle_mode(true);
+	vb_light->add_child(light_1_switch);
+	light_1_switch->connect("pressed",this,"_button_pressed",varray(light_1_switch));
 
-	VBoxContainer *outline_dialog_vbc = memnew( VBoxContainer );
-	outline_dialog->add_child(outline_dialog_vbc);
-	outline_dialog->set_child_rect(outline_dialog_vbc);
+	light_2_switch = memnew( TextureButton );
+	light_2_switch->set_toggle_mode(true);
+	vb_light->add_child(light_2_switch);
+	light_2_switch->connect("pressed",this,"_button_pressed",varray(light_2_switch));
 
-	outline_size = memnew( SpinBox );
-	outline_size->set_min(0.001);
-	outline_size->set_max(1024);
-	outline_size->set_step(0.001);
-	outline_size->set_val(0.05);
-	outline_dialog_vbc->add_margin_child(TTR("Outline Size:"),outline_size);
+	first_enter=true;
 
-	add_child(outline_dialog);
-	outline_dialog->connect("confirmed",this,"_create_outline_mesh");
+	rot_x=0;
+	rot_y=0;
 
-	err_dialog = memnew( AcceptDialog );
-	add_child(err_dialog);
 
 }
 
 
-void MeshInstanceEditorPlugin::edit(Object *p_object) {
+void MeshEditorPlugin::edit(Object *p_object) {
 
-	mesh_editor->edit(p_object->cast_to<MeshInstance>());
+	Mesh * s = p_object->cast_to<Mesh>();
+	if (!s)
+		return;
+
+	mesh_editor->edit(Ref<Mesh>(s));
 }
 
-bool MeshInstanceEditorPlugin::handles(Object *p_object) const {
+bool MeshEditorPlugin::handles(Object *p_object) const {
 
-	return p_object->is_type("MeshInstance");
+	return p_object->is_type("Mesh");
 }
 
-void MeshInstanceEditorPlugin::make_visible(bool p_visible) {
+void MeshEditorPlugin::make_visible(bool p_visible) {
 
 	if (p_visible) {
-		mesh_editor->options->show();
+		mesh_editor->show();
+//		mesh_editor->set_process(true);
 	} else {
 
-		mesh_editor->options->hide();
-		mesh_editor->edit(NULL);
+		mesh_editor->hide();
+//		mesh_editor->set_process(false);
 	}
 
 }
 
-MeshInstanceEditorPlugin::MeshInstanceEditorPlugin(EditorNode *p_node) {
+MeshEditorPlugin::MeshEditorPlugin(EditorNode *p_node) {
 
 	editor=p_node;
-	mesh_editor = memnew( MeshInstanceEditor );
-	editor->get_viewport()->add_child(mesh_editor);
+	mesh_editor = memnew( MeshEditor );
+	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,mesh_editor);
+	mesh_editor->hide();
 
-	mesh_editor->options->hide();
-}
 
 
-MeshInstanceEditorPlugin::~MeshInstanceEditorPlugin()
-{
 }
 
 
+MeshEditorPlugin::~MeshEditorPlugin()
+{
+}

+ 29 - 31
tools/editor/plugins/mesh_editor_plugin.h

@@ -1,68 +1,66 @@
 #ifndef MESH_EDITOR_PLUGIN_H
 #define MESH_EDITOR_PLUGIN_H
 
-
 #include "tools/editor/editor_plugin.h"
 #include "tools/editor/editor_node.h"
+#include "scene/resources/material.h"
+#include "scene/3d/light.h"
 #include "scene/3d/mesh_instance.h"
-#include "scene/gui/spin_box.h"
-
+#include "scene/3d/camera.h"
 
-class MeshInstanceEditor : public Node {
+class MeshEditor : public Control {
 
-	OBJ_TYPE(MeshInstanceEditor, Node );
+	OBJ_TYPE(MeshEditor, Control);
 
 
-	enum Menu {
 
-		MENU_OPTION_CREATE_STATIC_TRIMESH_BODY,
-		MENU_OPTION_CREATE_STATIC_CONVEX_BODY,
-		MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE,
-		MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE,
-		MENU_OPTION_CREATE_NAVMESH,
-		MENU_OPTION_CREATE_OUTLINE_MESH,
-	};
+	float rot_x;
+	float rot_y;
 
-	MeshInstance *node;
+	Viewport *viewport;
+	MeshInstance *mesh_instance;
+	DirectionalLight *light1;
+	DirectionalLight *light2;
+	Camera *camera;
 
-	MenuButton *options;
+	Ref<Mesh> mesh;
 
-	ConfirmationDialog *outline_dialog;
-	SpinBox *outline_size;
 
-	AcceptDialog *err_dialog;
+	TextureButton *light_1_switch;
+	TextureButton *light_2_switch;
 
-	void _menu_option(int p_option);
-	void _create_outline_mesh();
-
-friend class MeshInstanceEditorPlugin;
+	void _button_pressed(Node* p_button);
+	bool first_enter;
 
+	void _update_rotation();
 protected:
-	void _node_removed(Node *p_node);
+	void _notification(int p_what);
+	void _input_event(InputEvent p_event);
 	static void _bind_methods();
 public:
 
-	void edit(MeshInstance *p_mesh);
-	MeshInstanceEditor();
+	void edit(Ref<Mesh> p_mesh);
+	MeshEditor();
 };
 
-class MeshInstanceEditorPlugin : public EditorPlugin {
 
-	OBJ_TYPE( MeshInstanceEditorPlugin, EditorPlugin );
+class MeshEditorPlugin : public EditorPlugin {
+
+	OBJ_TYPE( MeshEditorPlugin, EditorPlugin );
 
-	MeshInstanceEditor *mesh_editor;
+	MeshEditor *mesh_editor;
 	EditorNode *editor;
 
 public:
 
-	virtual String get_name() const { return "MeshInstance"; }
+	virtual String get_name() const { return "Mesh"; }
 	bool has_main_screen() const { return false; }
 	virtual void edit(Object *p_node);
 	virtual bool handles(Object *p_node) const;
 	virtual void make_visible(bool p_visible);
 
-	MeshInstanceEditorPlugin(EditorNode *p_node);
-	~MeshInstanceEditorPlugin();
+	MeshEditorPlugin(EditorNode *p_node);
+	~MeshEditorPlugin();
 
 };
 

+ 300 - 0
tools/editor/plugins/mesh_instance_editor_plugin.cpp

@@ -0,0 +1,300 @@
+#include "mesh_instance_editor_plugin.h"
+
+#include "scene/3d/physics_body.h"
+#include "scene/3d/body_shape.h"
+#include "scene/gui/box_container.h"
+#include "scene/3d/navigation_mesh.h"
+#include "spatial_editor_plugin.h"
+
+void MeshInstanceEditor::_node_removed(Node *p_node) {
+
+	if(p_node==node) {
+		node=NULL;
+		options->hide();
+	}
+
+}
+
+
+
+void MeshInstanceEditor::edit(MeshInstance *p_mesh) {
+
+	node=p_mesh;
+
+}
+
+void MeshInstanceEditor::_menu_option(int p_option) {
+
+	Ref<Mesh> mesh = node->get_mesh();
+	if (mesh.is_null()) {
+		err_dialog->set_text(TTR("Mesh is empty!"));
+		err_dialog->popup_centered_minsize();
+		return;
+	}
+
+	switch(p_option) {
+		case MENU_OPTION_CREATE_STATIC_TRIMESH_BODY:
+		case MENU_OPTION_CREATE_STATIC_CONVEX_BODY: {
+
+			bool trimesh_shape = (p_option==MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
+
+			EditorSelection *editor_selection = EditorNode::get_singleton()->get_editor_selection();
+			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+			List<Node*> selection = editor_selection->get_selected_node_list();
+
+			if (selection.empty()) {
+				Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
+				if (shape.is_null())
+					return;
+
+				CollisionShape *cshape = memnew( CollisionShape );
+				cshape->set_shape(shape);
+				StaticBody *body = memnew( StaticBody );
+				body->add_child(cshape);
+
+				Node *owner = node==get_tree()->get_edited_scene_root() ? node : node->get_owner();
+
+				if (trimesh_shape)
+					ur->create_action(TTR("Create Static Trimesh Body"));
+				else
+					ur->create_action(TTR("Create Static Convex Body"));
+
+				ur->add_do_method(node,"add_child",body);
+				ur->add_do_method(body,"set_owner",owner);
+				ur->add_do_method(cshape,"set_owner",owner);
+				ur->add_do_reference(body);
+				ur->add_undo_method(node,"remove_child",body);
+				ur->commit_action();
+				return;
+			}
+
+			if (trimesh_shape)
+				ur->create_action(TTR("Create Static Trimesh Body"));
+			else
+				ur->create_action(TTR("Create Static Convex Body"));
+
+			for (List<Node*>::Element *E=selection.front();E;E=E->next()) {
+
+				MeshInstance *instance = E->get()->cast_to<MeshInstance>();
+				if (!instance)
+					continue;
+
+				Ref<Mesh> m = instance->get_mesh();
+				if (m.is_null())
+					continue;
+
+				Ref<Shape> shape = trimesh_shape ? m->create_trimesh_shape() : m->create_convex_shape();
+				if (shape.is_null())
+					continue;
+
+				CollisionShape *cshape = memnew( CollisionShape );
+				cshape->set_shape(shape);
+				StaticBody *body = memnew( StaticBody );
+				body->add_child(cshape);
+
+				Node *owner = instance==get_tree()->get_edited_scene_root() ? instance : instance->get_owner();
+
+				ur->add_do_method(instance,"add_child",body);
+				ur->add_do_method(body,"set_owner",owner);
+				ur->add_do_method(cshape,"set_owner",owner);
+				ur->add_do_reference(body);
+				ur->add_undo_method(instance,"remove_child",body);
+			}
+
+			ur->commit_action();
+
+		} break;
+
+		case MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE:
+		case MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE: {
+
+			if (node==get_tree()->get_edited_scene_root()) {
+				err_dialog->set_text(TTR("This doesn't work on scene root!"));
+				err_dialog->popup_centered_minsize();
+				return;
+			}
+
+			bool trimesh_shape = (p_option==MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);
+
+			Ref<Shape> shape = trimesh_shape ? mesh->create_trimesh_shape() : mesh->create_convex_shape();
+			if (shape.is_null())
+				return;
+
+			CollisionShape *cshape = memnew( CollisionShape );
+			cshape->set_shape(shape);
+
+			Node *owner =  node->get_owner();
+
+			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+			if (trimesh_shape)
+				ur->create_action(TTR("Create Trimesh Shape"));
+			else
+				ur->create_action(TTR("Create Convex Shape"));
+
+			ur->add_do_method(node->get_parent(),"add_child",cshape);
+			ur->add_do_method(node->get_parent(),"move_child",cshape,node->get_index()+1);
+			ur->add_do_method(cshape,"set_owner",owner);
+			ur->add_do_reference(cshape);
+			ur->add_undo_method(node->get_parent(),"remove_child",cshape);
+			ur->commit_action();
+
+		} break;
+
+		case MENU_OPTION_CREATE_NAVMESH: {
+
+			Ref<NavigationMesh> nmesh = memnew( NavigationMesh );
+
+			if (nmesh.is_null())
+				return;
+
+			nmesh->create_from_mesh(mesh);
+			NavigationMeshInstance *nmi = memnew(  NavigationMeshInstance );
+			nmi->set_navigation_mesh(nmesh);
+
+			Node *owner = node==get_tree()->get_edited_scene_root() ? node : node->get_owner();
+
+			UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+			ur->create_action(TTR("Create Navigation Mesh"));
+
+			ur->add_do_method(node,"add_child",nmi);
+			ur->add_do_method(nmi,"set_owner",owner);
+
+			ur->add_do_reference(nmi);
+			ur->add_undo_method(node,"remove_child",nmi);
+			ur->commit_action();
+		} break;
+
+		case MENU_OPTION_CREATE_OUTLINE_MESH: {
+
+			outline_dialog->popup_centered(Vector2(200, 90));
+		} break;
+	}
+
+}
+
+void MeshInstanceEditor::_create_outline_mesh() {
+
+	Ref<Mesh> mesh = node->get_mesh();
+	if (mesh.is_null()) {
+		err_dialog->set_text(TTR("MeshInstance lacks a Mesh!"));
+		err_dialog->popup_centered_minsize();
+		return;
+	}
+
+	Ref<Mesh> mesho = mesh->create_outline(outline_size->get_val());
+
+	if (mesho.is_null()) {
+		err_dialog->set_text(TTR("Could not create outline!"));
+		err_dialog->popup_centered_minsize();
+		return;
+	}
+
+	MeshInstance *mi = memnew( MeshInstance );
+	mi->set_mesh(mesho);
+	Node *owner=node->get_owner();
+	if (get_tree()->get_edited_scene_root()==node) {
+		owner=node;
+	}
+
+	UndoRedo *ur = EditorNode::get_singleton()->get_undo_redo();
+
+	ur->create_action(TTR("Create Outline"));
+
+	ur->add_do_method(node,"add_child",mi);
+	ur->add_do_method(mi,"set_owner",owner);
+
+	ur->add_do_reference(mi);
+	ur->add_undo_method(node,"remove_child",mi);
+	ur->commit_action();
+}
+
+void MeshInstanceEditor::_bind_methods() {
+
+	ObjectTypeDB::bind_method("_menu_option",&MeshInstanceEditor::_menu_option);
+	ObjectTypeDB::bind_method("_create_outline_mesh",&MeshInstanceEditor::_create_outline_mesh);
+}
+
+MeshInstanceEditor::MeshInstanceEditor() {
+
+
+	options = memnew( MenuButton );
+	SpatialEditor::get_singleton()->add_control_to_menu_panel(options);
+
+	options->set_text("Mesh");
+	options->set_icon(EditorNode::get_singleton()->get_gui_base()->get_icon("MeshInstance","EditorIcons"));
+
+	options->get_popup()->add_item(TTR("Create Trimesh Static Body"),MENU_OPTION_CREATE_STATIC_TRIMESH_BODY);
+	options->get_popup()->add_item(TTR("Create Convex Static Body"),MENU_OPTION_CREATE_STATIC_CONVEX_BODY);
+	options->get_popup()->add_separator();
+	options->get_popup()->add_item(TTR("Create Trimesh Collision Sibling"),MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE);
+	options->get_popup()->add_item(TTR("Create Convex Collision Sibling"),MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE);
+	options->get_popup()->add_separator();
+	options->get_popup()->add_item(TTR("Create Navigation Mesh"),MENU_OPTION_CREATE_NAVMESH);
+	options->get_popup()->add_separator();
+	options->get_popup()->add_item(TTR("Create Outline Mesh.."),MENU_OPTION_CREATE_OUTLINE_MESH);
+
+	options->get_popup()->connect("item_pressed", this,"_menu_option");
+
+	outline_dialog = memnew( ConfirmationDialog );
+	outline_dialog->set_title(TTR("Create Outline Mesh"));
+	outline_dialog->get_ok()->set_text(TTR("Create"));
+
+	VBoxContainer *outline_dialog_vbc = memnew( VBoxContainer );
+	outline_dialog->add_child(outline_dialog_vbc);
+	outline_dialog->set_child_rect(outline_dialog_vbc);
+
+	outline_size = memnew( SpinBox );
+	outline_size->set_min(0.001);
+	outline_size->set_max(1024);
+	outline_size->set_step(0.001);
+	outline_size->set_val(0.05);
+	outline_dialog_vbc->add_margin_child(TTR("Outline Size:"),outline_size);
+
+	add_child(outline_dialog);
+	outline_dialog->connect("confirmed",this,"_create_outline_mesh");
+
+	err_dialog = memnew( AcceptDialog );
+	add_child(err_dialog);
+
+}
+
+
+void MeshInstanceEditorPlugin::edit(Object *p_object) {
+
+	mesh_editor->edit(p_object->cast_to<MeshInstance>());
+}
+
+bool MeshInstanceEditorPlugin::handles(Object *p_object) const {
+
+	return p_object->is_type("MeshInstance");
+}
+
+void MeshInstanceEditorPlugin::make_visible(bool p_visible) {
+
+	if (p_visible) {
+		mesh_editor->options->show();
+	} else {
+
+		mesh_editor->options->hide();
+		mesh_editor->edit(NULL);
+	}
+
+}
+
+MeshInstanceEditorPlugin::MeshInstanceEditorPlugin(EditorNode *p_node) {
+
+	editor=p_node;
+	mesh_editor = memnew( MeshInstanceEditor );
+	editor->get_viewport()->add_child(mesh_editor);
+
+	mesh_editor->options->hide();
+}
+
+
+MeshInstanceEditorPlugin::~MeshInstanceEditorPlugin()
+{
+}
+
+

+ 69 - 0
tools/editor/plugins/mesh_instance_editor_plugin.h

@@ -0,0 +1,69 @@
+#ifndef MESH_INSTANCE_EDITOR_PLUGIN_H
+#define MESH_INSTANCE_EDITOR_PLUGIN_H
+
+
+#include "tools/editor/editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "scene/3d/mesh_instance.h"
+#include "scene/gui/spin_box.h"
+
+
+class MeshInstanceEditor : public Node {
+
+	OBJ_TYPE(MeshInstanceEditor, Node );
+
+
+	enum Menu {
+
+		MENU_OPTION_CREATE_STATIC_TRIMESH_BODY,
+		MENU_OPTION_CREATE_STATIC_CONVEX_BODY,
+		MENU_OPTION_CREATE_TRIMESH_COLLISION_SHAPE,
+		MENU_OPTION_CREATE_CONVEX_COLLISION_SHAPE,
+		MENU_OPTION_CREATE_NAVMESH,
+		MENU_OPTION_CREATE_OUTLINE_MESH,
+	};
+
+	MeshInstance *node;
+
+	MenuButton *options;
+
+	ConfirmationDialog *outline_dialog;
+	SpinBox *outline_size;
+
+	AcceptDialog *err_dialog;
+
+	void _menu_option(int p_option);
+	void _create_outline_mesh();
+
+friend class MeshInstanceEditorPlugin;
+
+protected:
+	void _node_removed(Node *p_node);
+	static void _bind_methods();
+public:
+
+	void edit(MeshInstance *p_mesh);
+	MeshInstanceEditor();
+};
+
+class MeshInstanceEditorPlugin : public EditorPlugin {
+
+	OBJ_TYPE( MeshInstanceEditorPlugin, EditorPlugin );
+
+	MeshInstanceEditor *mesh_editor;
+	EditorNode *editor;
+
+public:
+
+	virtual String get_name() const { return "MeshInstance"; }
+	bool has_main_screen() const { return false; }
+	virtual void edit(Object *p_node);
+	virtual bool handles(Object *p_node) const;
+	virtual void make_visible(bool p_visible);
+
+	MeshInstanceEditorPlugin(EditorNode *p_node);
+	~MeshInstanceEditorPlugin();
+
+};
+
+#endif // MESH_EDITOR_PLUGIN_H

+ 4 - 5
tools/editor/plugins/sample_editor_plugin.cpp

@@ -328,7 +328,7 @@ void SampleEditor::_update_sample() {
 		return; //bye or unsupported
 
 	generate_preview_texture(sample,peakdisplay);
-	info_label->set_text(TTR("Length:")+" "+vformat(TTR("%d frames"), sample->get_length())+" ("+String::num(sample->get_length()/(float)sample->get_mix_rate(),2)+" s), "+(sample->get_format()==Sample::FORMAT_PCM16?TTR("16 Bits"):TTR("8 Bits"))+", "+(sample->is_stereo()?TTR("Stereo"):TTR("Mono"))+".");
+	info_label->set_text(TTR("Length:")+" "+String::num(sample->get_length()/(float)sample->get_mix_rate(),2)+"s");
 
 	library->add_sample("default",sample);
 }
@@ -404,6 +404,8 @@ SampleEditor::SampleEditor() {
 	play->connect("pressed", this,"_play_pressed");
 	stop->connect("pressed", this,"_stop_pressed");
 
+	set_custom_minimum_size(Size2(1,150));
+
 }
 
 
@@ -438,10 +440,7 @@ SampleEditorPlugin::SampleEditorPlugin(EditorNode *p_node) {
 
 	editor=p_node;
 	sample_editor = memnew( SampleEditor );
-	editor->get_viewport()->add_child(sample_editor);
-	sample_editor->set_area_as_parent_rect();
-	sample_editor->set_anchor( MARGIN_TOP, Control::ANCHOR_END);
-	sample_editor->set_margin( MARGIN_TOP, 120 );
+	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,sample_editor);
 	sample_editor->hide();
 
 

+ 141 - 0
tools/editor/plugins/texture_editor_plugin.cpp

@@ -0,0 +1,141 @@
+#include "texture_editor_plugin.h"
+
+#include "io/resource_loader.h"
+#include "globals.h"
+#include "tools/editor/editor_settings.h"
+
+void TextureEditor::_input_event(InputEvent p_event) {
+
+
+}
+
+void TextureEditor::_notification(int p_what) {
+
+	if (p_what==NOTIFICATION_FIXED_PROCESS) {
+
+	}
+
+
+	if (p_what==NOTIFICATION_READY) {
+
+		//get_scene()->connect("node_removed",this,"_node_removed");
+
+	}
+
+	if (p_what==NOTIFICATION_DRAW) {
+
+
+		Ref<Texture> checkerboard = get_icon("Checkerboard","EditorIcons");
+		Size2 size = get_size();
+
+		draw_texture_rect(checkerboard,Rect2(Point2(),size),true);
+
+		int tex_width = texture->get_width() * size.height / texture ->get_height();
+		int tex_height = size.height;
+
+		if (tex_width>size.width) {
+			tex_width=size.width;
+			tex_height=texture->get_height() * tex_width / texture->get_width();
+		}
+
+		int ofs_x = (size.width - tex_width)/2;
+		int ofs_y = (size.height - tex_height)/2;
+
+		draw_texture_rect(texture,Rect2(ofs_x,ofs_y,tex_width,tex_height));
+
+		Ref<Font> font = get_font("font","Label");
+
+		String format;
+		if (texture->cast_to<ImageTexture>()) {
+			format = Image::get_format_name(texture->cast_to<ImageTexture>()->get_format());
+		} else {
+			format=texture->get_type();
+		}
+		String text = itos(texture->get_width())+"x"+itos(texture->get_height())+" "+format;
+
+		Size2 rect = font->get_string_size(text);
+
+		Vector2 draw_from = size-rect+Size2(-2,font->get_ascent()-2);
+		if (draw_from.x<0)
+			draw_from.x=0;
+
+		draw_string(font,draw_from+Vector2(2,2),text,Color(0,0,0,0.5),size.width);
+		draw_string(font,draw_from-Vector2(2,2),text,Color(0,0,0,0.5),size.width);
+		draw_string(font,draw_from,text,Color(1,1,1,1),size.width);
+	}
+}
+
+
+
+void TextureEditor::edit(Ref<Texture> p_texture) {
+
+	texture=p_texture;
+
+	if (!texture.is_null())
+		update();
+	else {
+
+		hide();
+	}
+
+}
+
+
+
+void TextureEditor::_bind_methods() {
+
+	ObjectTypeDB::bind_method(_MD("_input_event"),&TextureEditor::_input_event);
+
+}
+
+TextureEditor::TextureEditor() {
+
+	set_custom_minimum_size(Size2(1,150));
+
+}
+
+
+void TextureEditorPlugin::edit(Object *p_object) {
+
+	Texture * s = p_object->cast_to<Texture>();
+	if (!s)
+		return;
+
+	texture_editor->edit(Ref<Texture>(s));
+}
+
+bool TextureEditorPlugin::handles(Object *p_object) const {
+
+	return p_object->is_type("Texture");
+}
+
+void TextureEditorPlugin::make_visible(bool p_visible) {
+
+	if (p_visible) {
+		texture_editor->show();
+//		texture_editor->set_process(true);
+	} else {
+
+		texture_editor->hide();
+//		texture_editor->set_process(false);
+	}
+
+}
+
+TextureEditorPlugin::TextureEditorPlugin(EditorNode *p_node) {
+
+	editor=p_node;
+	texture_editor = memnew( TextureEditor );
+	add_control_to_container(CONTAINER_PROPERTY_EDITOR_BOTTOM,texture_editor);
+	texture_editor->hide();
+
+
+
+}
+
+
+TextureEditorPlugin::~TextureEditorPlugin()
+{
+}
+
+

+ 49 - 0
tools/editor/plugins/texture_editor_plugin.h

@@ -0,0 +1,49 @@
+#ifndef TEXTURE_EDITOR_PLUGIN_H
+#define TEXTURE_EDITOR_PLUGIN_H
+
+
+
+#include "tools/editor/editor_plugin.h"
+#include "tools/editor/editor_node.h"
+#include "scene/resources/texture.h"
+
+
+class TextureEditor : public Control {
+
+	OBJ_TYPE(TextureEditor, Control);
+
+
+	Ref<Texture> texture;
+
+protected:
+	void _notification(int p_what);
+	void _input_event(InputEvent p_event);
+	static void _bind_methods();
+public:
+
+	void edit(Ref<Texture> p_texture);
+	TextureEditor();
+};
+
+
+class TextureEditorPlugin : public EditorPlugin {
+
+	OBJ_TYPE( TextureEditorPlugin, EditorPlugin );
+
+	TextureEditor *texture_editor;
+	EditorNode *editor;
+
+public:
+
+	virtual String get_name() const { return "Texture"; }
+	bool has_main_screen() const { return false; }
+	virtual void edit(Object *p_node);
+	virtual bool handles(Object *p_node) const;
+	virtual void make_visible(bool p_visible);
+
+	TextureEditorPlugin(EditorNode *p_node);
+	~TextureEditorPlugin();
+
+};
+
+#endif // TEXTURE_EDITOR_PLUGIN_H

+ 1 - 0
tools/editor/script_editor_debugger.cpp

@@ -944,6 +944,7 @@ void ScriptEditorDebugger::_notification(int p_what) {
 				}
 				last_error_count=error_count;
 			}
+
 			if (connection.is_null()) {
 
 				if (server->is_connection_available()) {