diff --git a/core/bind/core_bind.cpp b/core/bind/core_bind.cpp index 570ed33a5ac9..944bc531ff07 100644 --- a/core/bind/core_bind.cpp +++ b/core/bind/core_bind.cpp @@ -856,6 +856,36 @@ Vector _Geometry::triangulate_polygon(const Vector& p_polygon) { return Geometry::triangulate_polygon(p_polygon); } +Dictionary _Geometry::make_atlas(const Vector& p_rects) { + + Dictionary ret; + + Vector rects; + for (int i=0; i result; + Size2i size; + + Geometry::make_atlas(rects, result, size); + + Size2 r_size = size; + Vector r_result; + for (int i=0; i triangulate_polygon(const Vector& p_polygon); + Dictionary make_atlas(const Vector& p_rects); + _Geometry(); }; diff --git a/core/image.h b/core/image.h index 7a6ee1e4b017..31a815c587fa 100644 --- a/core/image.h +++ b/core/image.h @@ -216,6 +216,14 @@ public: * Convert the image to another format, as close as it can be done. */ void convert( Format p_new_format ); + + Image converted(int p_new_format) { + ERR_FAIL_INDEX_V(p_new_format, FORMAT_MAX, Image()); + + Image ret = *this; + ret.convert((Format)p_new_format); + return ret; + }; /** * Get the current image format. diff --git a/core/math/geometry.cpp b/core/math/geometry.cpp index cb76b9ed0f81..2d525dd1ce82 100644 --- a/core/math/geometry.cpp +++ b/core/math/geometry.cpp @@ -1004,3 +1004,134 @@ DVector Geometry::build_capsule_planes(float p_radius, float p_height, in } + +struct _AtlasWorkRect { + + Size2i s; + Point2i p; + int idx; + _FORCE_INLINE_ bool operator<(const _AtlasWorkRect& p_r) const { return s.width > p_r.s.width; }; +}; + +struct _AtlasWorkRectResult { + + Vector<_AtlasWorkRect> result; + int max_w; + int max_h; +}; + +void Geometry::make_atlas(const Vector& p_rects,Vector& r_result, Size2i& r_size) { + + //super simple, almost brute force scanline stacking fitter + //it's pretty basic for now, but it tries to make sure that the aspect ratio of the + //resulting atlas is somehow square. This is necesary because video cards have limits + //on texture size (usually 2048 or 4096), so the more square a texture, the more chances + //it will work in every hardware. + // for example, it will prioritize a 1024x1024 atlas (works everywhere) instead of a + // 256x8192 atlas (won't work anywhere). + + ERR_FAIL_COND(p_rects.size()==0); + + Vector<_AtlasWorkRect> wrects; + wrects.resize(p_rects.size()); + for(int i=0;i results; + + for(int i=0;i<=12;i++) { + + int w = 1< hmax; + hmax.resize(w); + for(int j=0;j w) { + + ofs=0; + } + + int from_y=0; + for(int k=0;k from_y) + from_y=hmax[ofs+k]; + } + + wrects[j].p.x=ofs; + wrects[j].p.y=from_y; + int end_h = from_y+wrects[j].s.height; + int end_w = ofs+wrects[j].s.width; + if (ofs==0) + limit_h=end_h; + + for(int k=0;k max_h) + max_h=end_h; + + if (end_w > max_w) + max_w=end_w; + + if (ofs==0 || end_h>limit_h ) //while h limit not reched, keep stacking + ofs+=wrects[j].s.width; + + } + + _AtlasWorkRectResult result; + result.result=wrects; + result.max_h=max_h; + result.max_w=max_w; + results.push_back(result); + + } + + //find the result with the best aspect ratio + + int best=-1; + float best_aspect=1e20; + + for(int i=0;iw ? h/w : w/h; + if (aspect < best_aspect) { + best=i; + best_aspect=aspect; + } + } + + r_result.resize(p_rects.size()); + + for(int i=0;i build_box_planes(const Vector3& p_extents); static DVector build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis=Vector3::AXIS_Z); static DVector build_capsule_planes(float p_radius, float p_height, int p_sides, int p_lats, Vector3::Axis p_axis=Vector3::AXIS_Z); - + + static void make_atlas(const Vector& p_rects,Vector& r_result, Size2i& r_size); + }; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index e0ae7e2114a1..bd731abeaf1a 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -515,7 +515,7 @@ static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Varian #define VCALL_PTR0R(m_type,m_method)\ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast(p_self._data._ptr)->m_method(); } #define VCALL_PTR1(m_type,m_method)\ -static void _call_##m_type##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast(p_self._data._ptr)->m_method(*p_args[0]); } +static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { reinterpret_cast(p_self._data._ptr)->m_method(*p_args[0]); } #define VCALL_PTR1R(m_type,m_method)\ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Variant** p_args) { r_ret=reinterpret_cast(p_self._data._ptr)->m_method(*p_args[0]); } #define VCALL_PTR2(m_type,m_method)\ @@ -551,6 +551,7 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var VCALL_PTR3R(Image, resized); VCALL_PTR0R(Image, get_data); VCALL_PTR3(Image, blit_rect); + VCALL_PTR1R(Image, converted); VCALL_PTR0R( AABB, get_area ); VCALL_PTR0R( AABB, has_no_area ); @@ -605,6 +606,25 @@ static void _call_##m_type##_##m_method(Variant& r_ret,Variant& p_self,const Var } } + static void _call_Matrix32_basis_xform(Variant& r_ret,Variant& p_self,const Variant** p_args) { + + switch(p_args[0]->type) { + + case Variant::VECTOR2: r_ret=reinterpret_cast(p_self._data._ptr)->basis_xform( p_args[0]->operator Vector2()); return; + default: r_ret=Variant(); + } + + } + + static void _call_Matrix32_basis_xform_inv(Variant& r_ret,Variant& p_self,const Variant** p_args) { + + switch(p_args[0]->type) { + + case Variant::VECTOR2: r_ret=reinterpret_cast(p_self._data._ptr)->basis_xform_inv( p_args[0]->operator Vector2()); return; + default: r_ret=Variant(); + } + } + VCALL_PTR0R( Matrix3, inverse ); VCALL_PTR0R( Matrix3, transposed ); @@ -1313,6 +1333,7 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC3(IMAGE, IMAGE, Image, resized, INT, "x", INT, "y", INT, "interpolation", varray(((int)Image::INTERPOLATE_BILINEAR))); ADDFUNC0(IMAGE, RAW_ARRAY, Image, get_data, varray()); ADDFUNC3(IMAGE, NIL, Image, blit_rect, IMAGE, "src", RECT2, "src_rect", VECTOR2, "dest", varray(0)); + ADDFUNC1(IMAGE, IMAGE, Image, converted, INT, "format", varray(0)); ADDFUNC0(_RID,INT,RID,get_id,varray()); @@ -1430,6 +1451,8 @@ _VariantCall::addfunc(Variant::m_vtype,Variant::m_ret,_SCS(#m_method),VCALL(m_cl ADDFUNC1(MATRIX32,MATRIX32,Matrix32,translated,VECTOR2,"offset",varray()); ADDFUNC1(MATRIX32,MATRIX32,Matrix32,xform,NIL,"v",varray()); ADDFUNC1(MATRIX32,MATRIX32,Matrix32,xform_inv,NIL,"v",varray()); + ADDFUNC1(MATRIX32,MATRIX32,Matrix32,basis_xform,NIL,"v",varray()); + ADDFUNC1(MATRIX32,MATRIX32,Matrix32,basis_xform_inv,NIL,"v",varray()); ADDFUNC2(MATRIX32,MATRIX32,Matrix32,interpolate_with,MATRIX32,"m",REAL,"c",varray()); ADDFUNC0(MATRIX3,MATRIX3,Matrix3,inverse,varray()); diff --git a/demos/3d/truck_town/car_base.scn b/demos/3d/truck_town/car_base.scn new file mode 100644 index 000000000000..d62c8dcb297f Binary files /dev/null and b/demos/3d/truck_town/car_base.scn differ diff --git a/demos/3d/truck_town/cement.tex b/demos/3d/truck_town/cement.tex new file mode 100644 index 000000000000..a80cde6464f8 Binary files /dev/null and b/demos/3d/truck_town/cement.tex differ diff --git a/demos/3d/truck_town/crane.scn b/demos/3d/truck_town/crane.scn new file mode 100644 index 000000000000..080bd8ea172a Binary files /dev/null and b/demos/3d/truck_town/crane.scn differ diff --git a/demos/3d/truck_town/engine.cfg b/demos/3d/truck_town/engine.cfg new file mode 100644 index 000000000000..8703a251d148 --- /dev/null +++ b/demos/3d/truck_town/engine.cfg @@ -0,0 +1,7 @@ +[application] + +main_scene="res://truck_scene.scn" + +[rasterizer] + +shadow_filter=3 diff --git a/demos/3d/truck_town/follow_camera.gd b/demos/3d/truck_town/follow_camera.gd new file mode 100644 index 000000000000..cf7172d7bb4c --- /dev/null +++ b/demos/3d/truck_town/follow_camera.gd @@ -0,0 +1,69 @@ + +extends Camera + +# member variables here, example: +# var a=2 +# var b="textvar" + +var collision_exception=[] +export var min_distance=0.5 +export var max_distance=4.0 +export var angle_v_adjust=0.0 +export var autoturn_ray_aperture=25 +export var autoturn_speed=50 +var max_height = 2.0 +var min_height = 0 + +func _fixed_process(dt): + var target = get_parent().get_global_transform().origin + var pos = get_global_transform().origin + var up = Vector3(0,1,0) + + var delta = pos - target + + #regular delta follow + + #check ranges + + if (delta.length() < min_distance): + delta = delta.normalized() * min_distance + elif (delta.length() > max_distance): + delta = delta.normalized() * max_distance + + #check upper and lower height + if ( delta.y > max_height): + delta.y = max_height + if ( delta.y < min_height): + delta.y = min_height + + pos = target + delta + + look_at_from_pos(pos,target,up) + + #turn a little up or down + var t = get_transform() + t.basis = Matrix3(t.basis[0],deg2rad(angle_v_adjust)) * t.basis + set_transform(t) + + + +func _ready(): + +#find collision exceptions for ray + var node = self + while(node): + if (node extends RigidBody): + collision_exception.append(node.get_rid()) + break + else: + node=node.get_parent() + # Initalization here + set_fixed_process(true) + #this detaches the camera transform from the parent spatial node + set_as_toplevel(true) + + + + + + diff --git a/demos/3d/truck_town/grass.tex b/demos/3d/truck_town/grass.tex new file mode 100644 index 000000000000..c28d060697d8 Binary files /dev/null and b/demos/3d/truck_town/grass.tex differ diff --git a/demos/3d/truck_town/trailer_truck.scn b/demos/3d/truck_town/trailer_truck.scn new file mode 100644 index 000000000000..0131e9e3a2b6 Binary files /dev/null and b/demos/3d/truck_town/trailer_truck.scn differ diff --git a/demos/3d/truck_town/truck_scene.scn b/demos/3d/truck_town/truck_scene.scn new file mode 100644 index 000000000000..8db74a2f7faa Binary files /dev/null and b/demos/3d/truck_town/truck_scene.scn differ diff --git a/demos/3d/truck_town/trucktown.scn b/demos/3d/truck_town/trucktown.scn new file mode 100644 index 000000000000..57a84315ee20 Binary files /dev/null and b/demos/3d/truck_town/trucktown.scn differ diff --git a/demos/3d/truck_town/vehicle.gd b/demos/3d/truck_town/vehicle.gd new file mode 100644 index 000000000000..1aa7f0faa2b3 --- /dev/null +++ b/demos/3d/truck_town/vehicle.gd @@ -0,0 +1,54 @@ + +extends VehicleBody + +# member variables here, example: +# var a=2 +# var b="textvar" + + +const STEER_SPEED=1 +const STEER_LIMIT=0.4 + +var steer_angle=0 +var steer_target=0 + + +export var engine_force=40 + +func _fixed_process(delta): + + + if (Input.is_action_pressed("ui_left")): + steer_target=-STEER_LIMIT + elif (Input.is_action_pressed("ui_right")): + steer_target=STEER_LIMIT + else: + steer_target=0 + + if (Input.is_action_pressed("ui_up")): + set_engine_force(engine_force) + else: + set_engine_force(0) + + if (Input.is_action_pressed("ui_down")): + set_brake(1) + else: + set_brake(0.0) + + + if (steer_target < steer_angle): + steer_angle -= STEER_SPEED*delta + if (steer_target > steer_angle): + steer_angle=steer_target + elif (steer_target > steer_angle): + steer_angle += STEER_SPEED*delta + if (steer_target < steer_angle): + steer_angle=steer_target + + set_steering(steer_angle) +func _ready(): + # Initalization here + set_fixed_process(true) + pass + + diff --git a/drivers/theoraplayer/video_stream_theoraplayer.cpp b/drivers/theoraplayer/video_stream_theoraplayer.cpp index 12ef5de88fda..b2ff8062cccd 100644 --- a/drivers/theoraplayer/video_stream_theoraplayer.cpp +++ b/drivers/theoraplayer/video_stream_theoraplayer.cpp @@ -86,12 +86,18 @@ public: return fa->get_pos(); }; - TPDataFA(String p_path) { + TPDataFA(const String& p_path) { fa = FileAccess::open(p_path, FileAccess::READ); data_name = "File: " + p_path; }; + TPDataFA(FileAccess* p_fa, const String& p_path) { + + fa = p_fa; + data_name = "File: " + p_path; + }; + ~TPDataFA() { if (fa) @@ -366,6 +372,10 @@ void VideoStreamTheoraplayer::update(float p_time) { void VideoStreamTheoraplayer::set_file(const String& p_file) { + FileAccess* f = FileAccess::open(p_file, FileAccess::READ); + if (!f || !f->is_open()) + return; + if (!audio_factory) { audio_factory = memnew(TPAudioGodotFactory); }; @@ -377,10 +387,11 @@ void VideoStreamTheoraplayer::set_file(const String& p_file) { std::string file = p_file.replace("res://", "").utf8().get_data(); clip = mgr->createVideoClip(file); + memdelete(f); } else { - TheoraDataSource* ds = memnew(TPDataFA(p_file)); + TheoraDataSource* ds = memnew(TPDataFA(f, p_file)); try { clip = mgr->createVideoClip(ds); diff --git a/platform/winrt/SCsub b/platform/winrt/SCsub index c83f4fab32eb..07e2ba81a669 100644 --- a/platform/winrt/SCsub +++ b/platform/winrt/SCsub @@ -3,6 +3,9 @@ Import('env') files = [ 'thread_winrt.cpp', # '#platform/windows/stream_peer_winsock.cpp', + 'gl_context_egl.cpp', + 'app.cpp', + 'os_winrt.cpp', ] -env.Program('#bin/godot_rt.exe', files) +env.Program('#bin/godot_rt', files) diff --git a/platform/winrt/app.cpp b/platform/winrt/app.cpp new file mode 100644 index 000000000000..e3213d574a46 --- /dev/null +++ b/platform/winrt/app.cpp @@ -0,0 +1,162 @@ +// +// This file demonstrates how to initialize EGL in a Windows Store app, using ICoreWindow. +// + +#include "app.h" + +#include "main/main.h" + +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; +using namespace Microsoft::WRL; +using namespace Platform; + +using namespace $ext_safeprojectname$; + +// Helper to convert a length in device-independent pixels (DIPs) to a length in physical pixels. +inline float ConvertDipsToPixels(float dips, float dpi) +{ + static const float dipsPerInch = 96.0f; + return floor(dips * dpi / dipsPerInch + 0.5f); // Round to nearest integer. +} + +// Implementation of the IFrameworkViewSource interface, necessary to run our app. +ref class HelloTriangleApplicationSource sealed : Windows::ApplicationModel::Core::IFrameworkViewSource +{ +public: + virtual Windows::ApplicationModel::Core::IFrameworkView^ CreateView() + { + return ref new App(); + } +}; + +// The main function creates an IFrameworkViewSource for our app, and runs the app. +[Platform::MTAThread] +int main(Platform::Array^) +{ + auto helloTriangleApplicationSource = ref new HelloTriangleApplicationSource(); + CoreApplication::Run(helloTriangleApplicationSource); + return 0; +} + +App::App() : + mWindowClosed(false), + mWindowVisible(true), + mWindowWidth(0), + mWindowHeight(0), + mEglDisplay(EGL_NO_DISPLAY), + mEglContext(EGL_NO_CONTEXT), + mEglSurface(EGL_NO_SURFACE) +{ +} + +// The first method called when the IFrameworkView is being created. +void App::Initialize(CoreApplicationView^ applicationView) +{ + // Register event handlers for app lifecycle. This example includes Activated, so that we + // can make the CoreWindow active and start rendering on the window. + applicationView->Activated += + ref new TypedEventHandler(this, &App::OnActivated); + + // Logic for other event handlers could go here. + // Information about the Suspending and Resuming event handlers can be found here: + // http://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh994930.aspx + + os = new OSWinrt; +} + +// Called when the CoreWindow object is created (or re-created). +void App::SetWindow(CoreWindow^ window) +{ + window->VisibilityChanged += + ref new TypedEventHandler(this, &App::OnVisibilityChanged); + + window->Closed += + ref new TypedEventHandler(this, &App::OnWindowClosed); + + window->SizeChanged += + ref new TypedEventHandler(this, &App::OnWindowSizeChanged); + +#if !(WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + // Disable all pointer visual feedback for better performance when touching. + // This is not supported on Windows Phone applications. + auto pointerVisualizationSettings = PointerVisualizationSettings::GetForCurrentView(); + pointerVisualizationSettings->IsContactFeedbackEnabled = false; + pointerVisualizationSettings->IsBarrelButtonFeedbackEnabled = false; +#endif + + // The CoreWindow has been created, so EGL can be initialized. + ContextEGL* context = memnew(ContextEGL(window)); + os->set_gl_context(context); + UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height)); +} + +// Initializes scene resources +void App::Load(Platform::String^ entryPoint) +{ + char** args = {NULL}; + Main::setup("winrt", 0, args); +} + +// This method is called after the window becomes active. +void App::Run() +{ + + if (Main::start()) + os->run(); +} + +// Terminate events do not cause Uninitialize to be called. It will be called if your IFrameworkView +// class is torn down while the app is in the foreground. +void App::Uninitialize() +{ + Main::cleanup(); + delete os; +} + +// Application lifecycle event handler. +void App::OnActivated(CoreApplicationView^ applicationView, IActivatedEventArgs^ args) +{ + // Run() won't start until the CoreWindow is activated. + CoreWindow::GetForCurrentThread()->Activate(); +} + +// Window event handlers. +void App::OnVisibilityChanged(CoreWindow^ sender, VisibilityChangedEventArgs^ args) +{ + mWindowVisible = args->Visible; +} + +void App::OnWindowClosed(CoreWindow^ sender, CoreWindowEventArgs^ args) +{ + mWindowClosed = true; +} + +void App::OnWindowSizeChanged(CoreWindow^ sender, WindowSizeChangedEventArgs^ args) +{ +#if (WINAPI_FAMILY == WINAPI_FAMILY_PC_APP) + // On Windows 8.1, apps are resized when they are snapped alongside other apps, or when the device is rotated. + // The default framebuffer will be automatically resized when either of these occur. + // In particular, on a 90 degree rotation, the default framebuffer's width and height will switch. + UpdateWindowSize(args->Size); +#else if (WINAPI_FAMILY == WINAPI_FAMILY_PHONE_APP) + // On Windows Phone 8.1, the window size changes when the device is rotated. + // The default framebuffer will not be automatically resized when this occurs. + // It is therefore up to the app to handle rotation-specific logic in its rendering code. +#endif +} + +void App::UpdateWindowSize(Size size) +{ + /* + DisplayInformation^ currentDisplayInformation = DisplayInformation::GetForCurrentView(); + Size pixelSize(ConvertDipsToPixels(size.Width, currentDisplayInformation->LogicalDpi), ConvertDipsToPixels(size.Height, currentDisplayInformation->LogicalDpi)); + + mWindowWidth = static_cast(pixelSize.Width); + mWindowHeight = static_cast(pixelSize.Height); + */ +} diff --git a/platform/winrt/app.h b/platform/winrt/app.h new file mode 100644 index 000000000000..a67b936cdfd6 --- /dev/null +++ b/platform/winrt/app.h @@ -0,0 +1,51 @@ +#pragma once + +#include + +#include + +#include "os_winrt.h" +#include "GLES2/gl2.h" + +namespace $ext_safeprojectname$ +{ + ref class App sealed : public Windows::ApplicationModel::Core::IFrameworkView + { + public: + App(); + + // IFrameworkView Methods. + virtual void Initialize(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView); + virtual void SetWindow(Windows::UI::Core::CoreWindow^ window); + virtual void Load(Platform::String^ entryPoint); + virtual void Run(); + virtual void Uninitialize(); + + private: + void RecreateRenderer(); + + // Application lifecycle event handlers. + void OnActivated(Windows::ApplicationModel::Core::CoreApplicationView^ applicationView, Windows::ApplicationModel::Activation::IActivatedEventArgs^ args); + + // Window event handlers. + void OnWindowSizeChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::WindowSizeChangedEventArgs^ args); + void OnVisibilityChanged(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::VisibilityChangedEventArgs^ args); + void OnWindowClosed(Windows::UI::Core::CoreWindow^ sender, Windows::UI::Core::CoreWindowEventArgs^ args); + + void UpdateWindowSize(Windows::Foundation::Size size); + void InitializeEGL(Windows::UI::Core::CoreWindow^ window); + void CleanupEGL(); + + bool mWindowClosed; + bool mWindowVisible; + GLsizei mWindowWidth; + GLsizei mWindowHeight; + + EGLDisplay mEglDisplay; + EGLContext mEglContext; + EGLSurface mEglSurface; + + OSWinrt* os; + }; + +} diff --git a/platform/winrt/detect.py b/platform/winrt/detect.py index d09688b71cf4..00913b0ade4c 100644 --- a/platform/winrt/detect.py +++ b/platform/winrt/detect.py @@ -57,13 +57,13 @@ def configure(env): env.Append(CCFLAGS=['-g','-pg']) env.Append(LINKFLAGS=['-pg']) - env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/ZW', '/EHsc']) - env.Append(CXXFLAGS=['/TP']) + env.Append(CCFLAGS=['/Gd','/GR','/nologo', '/EHsc']) + env.Append(CXXFLAGS=['/TP', '/ZW']) env.Append(CPPFLAGS=['/DMSVC', '/GR', ]) #env.Append(CCFLAGS=['/I'+os.getenv("WindowsSdkDir")+"/Include"]) env.Append(CCFLAGS=['/DWINRT_ENABLED']) env.Append(CCFLAGS=['/DWINDOWS_ENABLED']) - env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP']) + env.Append(CCFLAGS=['/DWINAPI_FAMILY=WINAPI_FAMILY_APP', '/D_WIN32_WINNT=0x0603', '/DNTDDI_VERSION=0x06030000']) env.Append(CCFLAGS=['/DRTAUDIO_ENABLED']) #env.Append(CCFLAGS=['/DWIN32']) env.Append(CCFLAGS=['/DTYPED_METHOD_BIND']) diff --git a/platform/winrt/gl_context_egl.cpp b/platform/winrt/gl_context_egl.cpp new file mode 100644 index 000000000000..ca592c5d19f7 --- /dev/null +++ b/platform/winrt/gl_context_egl.cpp @@ -0,0 +1,151 @@ +#include "gl_context_egl.h" + +using namespace Platform; + +void ContextEGL::release_current() { + + eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEglContext); +}; + +void ContextEGL::make_current() { + + eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext); +}; + +int ContextEGL::get_window_width() { + + return width; +}; + +int ContextEGL::get_window_height() { + + return height; +}; + +void ContextEGL::swap_buffers() { + + if (eglSwapBuffers(mEglDisplay, mEglSurface) != EGL_TRUE) + { + cleanup(); + + window = CoreWindow::GetForCurrentThread(); + initialize(); + + // tell rasterizer to reload textures and stuff? + } +}; + +Error ContextEGL::initialize() { + + EGLint configAttribList[] = { + EGL_RED_SIZE, 8, + EGL_GREEN_SIZE, 8, + EGL_BLUE_SIZE, 8, + EGL_ALPHA_SIZE, 8, + EGL_DEPTH_SIZE, 8, + EGL_STENCIL_SIZE, 8, + EGL_SAMPLE_BUFFERS, 0, + EGL_NONE + }; + + EGLint surfaceAttribList[] = { + EGL_NONE, EGL_NONE + }; + + EGLint numConfigs = 0; + EGLint majorVersion = 1; + EGLint minorVersion = 0; + EGLDisplay display = EGL_NO_DISPLAY; + EGLContext context = EGL_NO_CONTEXT; + EGLSurface surface = EGL_NO_SURFACE; + EGLConfig config = nullptr; + EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE }; + + try { + + display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + if (display == EGL_NO_DISPLAY) + { + throw Exception::CreateException(E_FAIL, L"Failed to get default EGL display"); + } + + if (eglInitialize(display, &majorVersion, &minorVersion) == EGL_FALSE) + { + throw Exception::CreateException(E_FAIL, L"Failed to initialize EGL"); + } + + if (eglGetConfigs(display, NULL, 0, &numConfigs) == EGL_FALSE) + { + throw Exception::CreateException(E_FAIL, L"Failed to get EGLConfig count"); + } + + if (eglChooseConfig(display, configAttribList, &config, 1, &numConfigs) == EGL_FALSE) + { + throw Exception::CreateException(E_FAIL, L"Failed to choose first EGLConfig count"); + } + + surface = eglCreateWindowSurface(display, config, reinterpret_cast(window), surfaceAttribList); + if (surface == EGL_NO_SURFACE) + { + throw Exception::CreateException(E_FAIL, L"Failed to create EGL fullscreen surface"); + } + + context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs); + if (context == EGL_NO_CONTEXT) + { + throw Exception::CreateException(E_FAIL, L"Failed to create EGL context"); + } + + if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) + { + throw Exception::CreateException(E_FAIL, L"Failed to make fullscreen EGLSurface current"); + } + } catch (...) { + return FAILED; + }; + + mEglDisplay = display; + mEglSurface = surface; + mEglContext = context; + + eglQuerySurface(display,surface,EGL_WIDTH,&width); + eglQuerySurface(display,surface,EGL_HEIGHT,&height); + + return OK; +}; + +void ContextEGL::cleanup() { + + if (mEglDisplay != EGL_NO_DISPLAY && mEglSurface != EGL_NO_SURFACE) + { + eglDestroySurface(mEglDisplay, mEglSurface); + mEglSurface = EGL_NO_SURFACE; + } + + if (mEglDisplay != EGL_NO_DISPLAY && mEglContext != EGL_NO_CONTEXT) + { + eglDestroyContext(mEglDisplay, mEglContext); + mEglContext = EGL_NO_CONTEXT; + } + + if (mEglDisplay != EGL_NO_DISPLAY) + { + eglTerminate(mEglDisplay); + mEglDisplay = EGL_NO_DISPLAY; + } +}; + +ContextEGL::ContextEGL(CoreWindow^ p_window) : + mEglDisplay(EGL_NO_DISPLAY), + mEglContext(EGL_NO_CONTEXT), + mEglSurface(EGL_NO_SURFACE) + { + + window = p_window; +}; + +ContextEGL::~ContextEGL() { + + cleanup(); +}; + diff --git a/platform/winrt/gl_context_egl.h b/platform/winrt/gl_context_egl.h new file mode 100644 index 000000000000..56bf654ee5f4 --- /dev/null +++ b/platform/winrt/gl_context_egl.h @@ -0,0 +1,44 @@ +#ifndef CONTEXT_EGL_H +#define CONTEXT_EGL_H + +#include + +#include "os/os.h" +#include "EGL/egl.h" +#include "error_list.h" +#include "drivers/gl_context/context_gl.h" + +using namespace Windows::UI::Core; + +class ContextEGL : public ContextGL { + + CoreWindow^ window; + + EGLDisplay mEglDisplay; + EGLContext mEglContext; + EGLSurface mEglSurface; + + EGLint width; + EGLint height; + +public: + + virtual void release_current(); + + virtual void make_current(); + + virtual int get_window_width(); + virtual int get_window_height(); + virtual void swap_buffers(); + + virtual Error initialize(); + + void cleanup(); + + ContextEGL(CoreWindow^ p_window); + ~ContextEGL(); + +}; + +#endif + diff --git a/platform/winrt/os_winrt.cpp b/platform/winrt/os_winrt.cpp index 16a74c877ce0..99c4ad968efe 100644 --- a/platform/winrt/os_winrt.cpp +++ b/platform/winrt/os_winrt.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* os_windows.cpp */ +/* os_winrt.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -28,12 +28,12 @@ /*************************************************************************/ #include "drivers/gles2/rasterizer_gles2.h" #include "drivers/gles1/rasterizer_gles1.h" -#include "os_windows.h" +#include "os_winrt.h" #include "drivers/nedmalloc/memory_pool_static_nedmalloc.h" #include "drivers/unix/memory_pool_static_malloc.h" #include "os/memory_pool_dynamic_static.h" -#include "drivers/windows/thread_windows.h" -#include "drivers/windows/semaphore_windows.h" +#include "thread_winrt.h" +//#include "drivers/windows/semaphore_windows.h" #include "drivers/windows/mutex_windows.h" #include "main/main.h" #include "drivers/windows/file_access_windows.h" @@ -44,14 +44,22 @@ #include "servers/audio/audio_server_sw.h" #include "servers/visual/visual_server_wrap_mt.h" -#include "tcp_server_winsock.h" -#include "stream_peer_winsock.h" #include "os/pc_joystick_map.h" -#include "lang_table.h" #include "os/memory_pool_dynamic_prealloc.h" #include "globals.h" #include "io/marshalls.h" +#include + +using namespace Windows::ApplicationModel::Core; +using namespace Windows::ApplicationModel::Activation; +using namespace Windows::UI::Core; +using namespace Windows::UI::Input; +using namespace Windows::Foundation; +using namespace Windows::Graphics::Display; +using namespace Microsoft::WRL; + + int OSWinrt::get_video_driver_count() const { return 2; @@ -129,59 +137,18 @@ bool OSWinrt::can_draw() const { }; -void OSWinrt::_touch_event(int idx, UINT uMsg, WPARAM wParam, LPARAM lParam) { +void OSWinrt::set_gl_context(ContextEGL* p_context) { - InputEvent event; - event.type = InputEvent::SCREEN_TOUCH; - event.ID=++last_id; - event.screen_touch.index = idx; - - switch (uMsg) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: { - - event.screen_touch.pressed = true; - } break; - - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: { - event.screen_touch.pressed = false; - } break; - }; - - event.screen_touch.x=GET_X_LPARAM(lParam); - event.screen_touch.y=GET_Y_LPARAM(lParam); - - if (main_loop) { - input->parse_input_event(event); - } + gl_context = p_context; }; -void OSWinrt::_drag_event(int idx,UINT uMsg, WPARAM wParam, LPARAM lParam) { - - InputEvent event; - event.type = InputEvent::SCREEN_DRAG; - event.ID=++last_id; - event.screen_drag.index = idx; - - event.screen_drag.x=GET_X_LPARAM(lParam); - event.screen_drag.y=GET_Y_LPARAM(lParam); - - if (main_loop) - input->parse_input_event(event); -}; - - void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { - - main_loop=NULL; outside=true; - + gl_context->initialize(); + visual_server = memnew( VisualServerRaster(rasterizer) ); if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) { @@ -222,6 +189,7 @@ void OSWinrt::initialize(const VideoMode& p_desired,int p_video_driver,int p_aud void OSWinrt::set_clipboard(const String& p_text) { + /* if (!OpenClipboard(hWnd)) { ERR_EXPLAIN("Unable to open clipboard."); ERR_FAIL(); @@ -255,10 +223,12 @@ void OSWinrt::set_clipboard(const String& p_text) { SetClipboardData(CF_TEXT, mem); CloseClipboard(); + */ }; String OSWinrt::get_clipboard() const { + /* String ret; if (!OpenClipboard(hWnd)) { ERR_EXPLAIN("Unable to open clipboard."); @@ -295,6 +265,8 @@ String OSWinrt::get_clipboard() const { CloseClipboard(); return ret; + */ + return ""; }; @@ -327,10 +299,6 @@ void OSWinrt::finalize() { if (rasterizer) memdelete(rasterizer); - if (user_proc) { - SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR)user_proc); - }; - spatial_sound_server->finish(); memdelete(spatial_sound_server); spatial_sound_2d_server->finish(); @@ -355,16 +323,11 @@ void OSWinrt::finalize() { } void OSWinrt::finalize_core() { - memdelete(process_map); - if (mempool_dynamic) memdelete( mempool_dynamic ); if (mempool_static) delete mempool_static; - - TCPServerWinsock::cleanup(); - StreamPeerWinsock::cleanup(); } void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) { @@ -399,10 +362,7 @@ void OSWinrt::vprint(const char* p_format, va_list p_list, bool p_stderr) { void OSWinrt::alert(const String& p_alert,const String& p_title) { - if (!is_no_window_mode_enabled()) - MessageBoxW(NULL,p_alert.c_str(),p_title.c_str(),MB_OK|MB_ICONEXCLAMATION); - else - print_line("ALERT: "+p_alert); + print_line("ALERT: "+p_alert); } void OSWinrt::set_mouse_mode(MouseMode p_mode) { @@ -445,71 +405,16 @@ void OSWinrt::get_fullscreen_mode_list(List *p_list,int p_screen) con void OSWinrt::print_error(const char* p_function,const char* p_file,int p_line,const char *p_code,const char*p_rationale,ErrorType p_type) { - HANDLE hCon=GetStdHandle(STD_OUTPUT_HANDLE); - if (!hCon || hCon==INVALID_HANDLE_VALUE) { - if (p_rationale && p_rationale[0]) { + if (p_rationale && p_rationale[0]) { - print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale); - print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line); + print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_rationale); + print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line); - } else { - print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code); - print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line); - - } } else { + print("\E[1;31;40mERROR: %s: \E[1;37;40m%s\n",p_function,p_code); + print("\E[0;31;40m At: %s:%i.\E[0;0;37m\n",p_file,p_line); - CONSOLE_SCREEN_BUFFER_INFO sbi; //original - GetConsoleScreenBufferInfo(hCon,&sbi); - - SetConsoleTextAttribute(hCon,sbi.wAttributes); - - - - uint32_t basecol=0; - switch(p_type) { - case ERR_ERROR: basecol = FOREGROUND_RED; break; - case ERR_WARNING: basecol = FOREGROUND_RED|FOREGROUND_GREEN; break; - case ERR_SCRIPT: basecol = FOREGROUND_GREEN; break; - } - - if (p_rationale && p_rationale[0]) { - - SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY); - - - switch(p_type) { - case ERR_ERROR: print("ERROR: "); break; - case ERR_WARNING: print("WARNING: "); break; - case ERR_SCRIPT: print("SCRIPT ERROR: "); break; - } - - SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY); - print(" %s\n",p_rationale); - SetConsoleTextAttribute(hCon,basecol); - print("At: "); - SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN); - print(" %s:%i\n",p_file,p_line); - - - } else { - SetConsoleTextAttribute(hCon,basecol|FOREGROUND_INTENSITY); - switch(p_type) { - case ERR_ERROR: print("ERROR: %s: ",p_function); break; - case ERR_WARNING: print("WARNING: %s: ",p_function); break; - case ERR_SCRIPT: print("SCRIPT ERROR: %s: ",p_function); break; - } - SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_INTENSITY); - print(" %s\n",p_code); - SetConsoleTextAttribute(hCon,basecol); - print("At: "); - SetConsoleTextAttribute(hCon,FOREGROUND_RED|FOREGROUND_BLUE|FOREGROUND_GREEN); - print(" %s:%i\n",p_file,p_line); - } - - SetConsoleTextAttribute(hCon,sbi.wAttributes); } - } @@ -566,10 +471,10 @@ uint64_t OSWinrt::get_unix_time() const { void OSWinrt::delay_usec(uint32_t p_usec) const { - if (p_usec < 1000) - Sleep(1); - else - Sleep(p_usec / 1000); + int msec = p_usec < 1000 ? 1 : p_usec / 1000; + + // no Sleep() + WaitForSingleObjectEx(GetCurrentThread(), msec, false); } uint64_t OSWinrt::get_ticks_usec() const { @@ -607,19 +512,12 @@ Error OSWinrt::kill(const ProcessID& p_pid) { Error OSWinrt::set_cwd(const String& p_cwd) { - if (_wchdir(p_cwd.c_str())!=0) - return ERR_CANT_OPEN; - return OK; } String OSWinrt::get_executable_path() const { - wchar_t bufname[4096]; - GetModuleFileNameW(NULL,bufname,4096); - String s= bufname; - print_line("EXEC PATHPó: "+s); - return s; + return ""; } void OSWinrt::set_icon(const Image& p_icon) { @@ -629,25 +527,16 @@ void OSWinrt::set_icon(const Image& p_icon) { bool OSWinrt::has_environment(const String& p_var) const { - return getenv(p_var.utf8().get_data()) != NULL; + return false; }; String OSWinrt::get_environment(const String& p_var) const { - char* val = getenv(p_var.utf8().get_data()); - if (val) - return val; - return ""; }; String OSWinrt::get_stdin_string(bool p_block) { - if (p_block) { - char buff[1024]; - return fgets(buff,1024,stdin); - }; - return String(); } @@ -665,23 +554,22 @@ Error OSWinrt::shell_open(String p_uri) { String OSWinrt::get_locale() const { Platform::String ^language = Windows::Globalization::Language::CurrentInputMethodLanguageTag; - return language.Data(); + return language->Data(); } void OSWinrt::release_rendering_thread() { - //gl_context->release_current(); - + gl_context->release_current(); } void OSWinrt::make_rendering_thread() { - //gl_context->make_current(); + gl_context->make_current(); } void OSWinrt::swap_buffers() { - //gl_context->swap_buffers(); + gl_context->swap_buffers(); } @@ -699,6 +587,7 @@ void OSWinrt::run() { while (!force_quit) { + CoreWindow::GetForCurrentThread()->Dispatcher->ProcessEvents(CoreProcessEventsOption::ProcessAllIfPresent); process_events(); // get rid of pending events if (Main::iteration()==true) break; @@ -724,7 +613,7 @@ String OSWinrt::get_data_dir() const { } -OSWinrt::OSWinrt(HINSTANCE _hInstance) { +OSWinrt::OSWinrt() { key_event_pos=0; force_quit=false; @@ -743,6 +632,8 @@ OSWinrt::OSWinrt(HINSTANCE _hInstance) { stdo=fopen("stdout.txt","wb"); #endif + gl_context = NULL; + } diff --git a/platform/winrt/os_winrt.h b/platform/winrt/os_winrt.h index bc7e188c20e2..c309239af1d8 100644 --- a/platform/winrt/os_winrt.h +++ b/platform/winrt/os_winrt.h @@ -41,11 +41,10 @@ #include "servers/spatial_sound_2d/spatial_sound_2d_server_sw.h" #include "servers/physics_2d/physics_2d_server_sw.h" +#include "gl_context_egl.h" #include -#include "key_mapping_win.h" -#include #include #include @@ -93,6 +92,8 @@ class OSWinrt : public OS { Physics2DServer *physics_2d_server; int pressrc; + ContextEGL* gl_context; + struct Joystick { int id; @@ -224,6 +225,8 @@ public: virtual void move_window_to_foreground(); virtual String get_data_dir() const; + void set_gl_context(ContextEGL* p_context); + virtual void release_rendering_thread(); virtual void make_rendering_thread(); virtual void swap_buffers(); diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 64034545882f..8b72308afbea 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -106,9 +106,9 @@ Ref TileMap::get_tileset() const { return tile_set; } -void TileMap::set_cell_size(int p_size) { +void TileMap::set_cell_size(Size2 p_size) { - ERR_FAIL_COND(p_size<1); + ERR_FAIL_COND(p_size.x<1 || p_size.y<1); _clear_quadrants(); cell_size=p_size; @@ -117,7 +117,7 @@ void TileMap::set_cell_size(int p_size) { } -int TileMap::get_cell_size() const { +Size2 TileMap::get_cell_size() const { return cell_size; } @@ -171,6 +171,7 @@ void TileMap::_update_dirty_quadrants() { VisualServer *vs = VisualServer::get_singleton(); Physics2DServer *ps = Physics2DServer::get_singleton(); + Vector2 tofs = get_cell_draw_offset(); while (dirty_quadrant_list.first()) { @@ -189,7 +190,7 @@ void TileMap::_update_dirty_quadrants() { Ref tex = tile_set->tile_get_texture(c.id); Vector2 tile_ofs = tile_set->tile_get_texture_offset(c.id); - Vector2 offset = Point2( E->key().x, E->key().y )*cell_size - q.pos; + Vector2 offset = _map_to_world(E->key().x, E->key().y) - q.pos + tofs; if (!tex.is_valid()) continue; @@ -299,7 +300,11 @@ void TileMap::_recompute_rect_cache() { for (Map::Element *E=quadrant_map.front();E;E=E->next()) { - Rect2 r( Point2(E->key().x, E->key().y)*cell_size*quadrant_size, Size2(1,1)*cell_size*quadrant_size ); + Rect2 r; + r.pos=_map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size); + r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size) ); + r.expand_to( _map_to_world(E->key().x*quadrant_size+quadrant_size, E->key().y*quadrant_size+quadrant_size) ); + r.expand_to( _map_to_world(E->key().x*quadrant_size, E->key().y*quadrant_size+quadrant_size) ); if (E==quadrant_map.front()) r_total=r; else @@ -323,8 +328,10 @@ void TileMap::_recompute_rect_cache() { Map::Element *TileMap::_create_quadrant(const PosKey& p_qk) { Matrix32 xform; - xform.set_origin(Point2(p_qk.x,p_qk.y)*quadrant_size*cell_size); + //xform.set_origin(Point2(p_qk.x,p_qk.y)*cell_size*quadrant_size); Quadrant q; + q.pos = _map_to_world(p_qk.x*quadrant_size,p_qk.y*quadrant_size); + xform.set_origin( q.pos ); q.canvas_item = VisualServer::get_singleton()->canvas_item_create(); VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); @@ -341,7 +348,6 @@ Map::Element *TileMap::_create_quadrant(const } Physics2DServer::get_singleton()->body_set_state(q.static_body,Physics2DServer::BODY_STATE_TRANSFORM,xform); - q.pos=Vector2(p_qk.x,p_qk.y)*quadrant_size*cell_size; rect_cache_dirty=true; quadrant_order_dirty=true; @@ -478,8 +484,11 @@ void TileMap::_recreate_quadrants() { } Q->get().cells.insert(E->key()); - + _make_quadrant_dirty(Q); } + + + } void TileMap::_clear_quadrants() { @@ -614,6 +623,152 @@ uint32_t TileMap::get_collision_layer_mask() const { return collision_layer; } +void TileMap::set_mode(Mode p_mode) { + + _clear_quadrants(); + mode=p_mode; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +TileMap::Mode TileMap::get_mode() const { + return mode; +} + +void TileMap::set_half_offset(HalfOffset p_half_offset) { + + _clear_quadrants(); + half_offset=p_half_offset; + _recreate_quadrants(); + emit_signal("settings_changed"); +} + +Vector2 TileMap::get_cell_draw_offset() const { + + switch(mode) { + + case MODE_SQUARE: { + + return Vector2(); + } break; + case MODE_ISOMETRIC: { + + return Vector2(-cell_size.x*0.5,0); + + } break; + case MODE_CUSTOM: { + + Vector2 min; + min.x = MIN(custom_transform[0].x,min.x); + min.y = MIN(custom_transform[0].y,min.y); + min.x = MIN(custom_transform[1].x,min.x); + min.y = MIN(custom_transform[1].y,min.y); + return min; + } break; + } + + return Vector2(); + +} + +TileMap::HalfOffset TileMap::get_half_offset() const { + return half_offset; +} + +Matrix32 TileMap::get_cell_transform() const { + + switch(mode) { + + case MODE_SQUARE: { + + Matrix32 m; + m[0]*=cell_size.x; + m[1]*=cell_size.y; + return m; + } break; + case MODE_ISOMETRIC: { + + //isometric only makes sense when y is positive in both x and y vectors, otherwise + //the drawing of tiles will overlap + Matrix32 m; + m[0]=Vector2(cell_size.x*0.5,cell_size.y*0.5); + m[1]=Vector2(-cell_size.x*0.5,cell_size.y*0.5); + return m; + + } break; + case MODE_CUSTOM: { + + return custom_transform; + } break; + } + + return Matrix32(); +} + +void TileMap::set_custom_transform(const Matrix32& p_xform) { + + _clear_quadrants(); + custom_transform=p_xform; + _recreate_quadrants(); + emit_signal("settings_changed"); + +} + +Matrix32 TileMap::get_custom_transform() const{ + + return custom_transform; +} + +Vector2 TileMap::_map_to_world(int x,int y,bool p_ignore_ofs) const { + + Vector2 ret = get_cell_transform().xform(Vector2(x,y)); + if (!p_ignore_ofs) { + switch(half_offset) { + + case HALF_OFFSET_X: { + if (ABS(y)&1) { + + ret+=get_cell_transform()[0]*0.5; + } + } break; + case HALF_OFFSET_Y: { + if (ABS(x)&1) { + ret+=get_cell_transform()[1]*0.5; + } + } break; + default: {} + } + } + return ret; +} +Vector2 TileMap::map_to_world(const Vector2& p_pos,bool p_ignore_ofs) const { + + return _map_to_world(p_pos.x,p_pos.y,p_ignore_ofs); +} +Vector2 TileMap::world_to_map(const Vector2& p_pos) const{ + + Vector2 ret = get_cell_transform().affine_inverse().xform(p_pos); + + + switch(half_offset) { + + case HALF_OFFSET_X: { + if (int(ret.y)&1) { + + ret.x-=0.5; + } + } break; + case HALF_OFFSET_Y: { + if (int(ret.x)&1) { + ret.y-=0.5; + } + } break; + default: {} + } + + return ret.floor(); +} + void TileMap::_bind_methods() { @@ -621,10 +776,21 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_tileset","tileset:TileSet"),&TileMap::set_tileset); ObjectTypeDB::bind_method(_MD("get_tileset:TileSet"),&TileMap::get_tileset); + ObjectTypeDB::bind_method(_MD("set_mode","mode"),&TileMap::set_mode); + ObjectTypeDB::bind_method(_MD("get_mode"),&TileMap::get_mode); + + ObjectTypeDB::bind_method(_MD("set_half_offset","half_offset"),&TileMap::set_half_offset); + ObjectTypeDB::bind_method(_MD("get_half_offset"),&TileMap::get_half_offset); + + ObjectTypeDB::bind_method(_MD("set_custom_transform","custom_transform"),&TileMap::set_custom_transform); + ObjectTypeDB::bind_method(_MD("get_custom_transform"),&TileMap::get_custom_transform); ObjectTypeDB::bind_method(_MD("set_cell_size","size"),&TileMap::set_cell_size); ObjectTypeDB::bind_method(_MD("get_cell_size"),&TileMap::get_cell_size); + ObjectTypeDB::bind_method(_MD("_set_old_cell_size","size"),&TileMap::_set_old_cell_size); + ObjectTypeDB::bind_method(_MD("_get_old_cell_size"),&TileMap::_get_old_cell_size); + ObjectTypeDB::bind_method(_MD("set_quadrant_size","size"),&TileMap::set_quadrant_size); ObjectTypeDB::bind_method(_MD("get_quadrant_size"),&TileMap::get_quadrant_size); @@ -650,6 +816,9 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear"),&TileMap::clear); + ObjectTypeDB::bind_method(_MD("map_to_world","mappos","ignore_half_ofs"),&TileMap::map_to_world,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("world_to_map","worldpos"),&TileMap::world_to_map); + ObjectTypeDB::bind_method(_MD("_clear_quadrants"),&TileMap::_clear_quadrants); ObjectTypeDB::bind_method(_MD("_recreate_quadrants"),&TileMap::_recreate_quadrants); ObjectTypeDB::bind_method(_MD("_update_dirty_quadrants"),&TileMap::_update_dirty_quadrants); @@ -657,17 +826,28 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("_set_tile_data"),&TileMap::_set_tile_data); ObjectTypeDB::bind_method(_MD("_get_tile_data"),&TileMap::_get_tile_data); - ADD_PROPERTY( PropertyInfo(Variant::INT,"cell_size",PROPERTY_HINT_RANGE,"1,8192,1"),_SCS("set_cell_size"),_SCS("get_cell_size")); - ADD_PROPERTY( PropertyInfo(Variant::INT,"quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Square,Isometric,Custom"),_SCS("set_mode"),_SCS("get_mode")); ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_set",PROPERTY_HINT_RESOURCE_TYPE,"TileSet"),_SCS("set_tileset"),_SCS("get_tileset")); - ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell_size",PROPERTY_HINT_RANGE,"1,8192,1",0),_SCS("_set_old_cell_size"),_SCS("_get_old_cell_size")); + ADD_PROPERTY( PropertyInfo(Variant::VECTOR2,"cell/size",PROPERTY_HINT_RANGE,"1,8192,1"),_SCS("set_cell_size"),_SCS("get_cell_size")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/quadrant_size",PROPERTY_HINT_RANGE,"1,128,1"),_SCS("set_quadrant_size"),_SCS("get_quadrant_size")); + ADD_PROPERTY( PropertyInfo(Variant::MATRIX32,"cell/custom_transform"),_SCS("set_custom_transform"),_SCS("get_custom_transform")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"cell/half_offset",PROPERTY_HINT_ENUM,"Offset X,Offset Y,Disabled"),_SCS("set_half_offset"),_SCS("get_half_offset")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/friction",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_friction"),_SCS("get_collision_friction")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"collision/bounce",PROPERTY_HINT_RANGE,"0,1,0.01"),_SCS("set_collision_bounce"),_SCS("get_collision_bounce")); ADD_PROPERTY( PropertyInfo(Variant::INT,"collision/layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); + ADD_PROPERTY( PropertyInfo(Variant::OBJECT,"tile_data",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR),_SCS("_set_tile_data"),_SCS("_get_tile_data")); ADD_SIGNAL(MethodInfo("settings_changed")); BIND_CONSTANT( INVALID_CELL ); + BIND_CONSTANT( MODE_SQUARE ); + BIND_CONSTANT( MODE_ISOMETRIC ); + BIND_CONSTANT( MODE_CUSTOM ); + BIND_CONSTANT( HALF_OFFSET_X ); + BIND_CONSTANT( HALF_OFFSET_Y ); + BIND_CONSTANT( HALF_OFFSET_DISABLED ); + } TileMap::TileMap() { @@ -678,12 +858,14 @@ TileMap::TileMap() { pending_update=false; quadrant_order_dirty=false; quadrant_size=16; - cell_size=64; + cell_size=Size2(64,64); center_x=false; center_y=false; collision_layer=1; friction=1; bounce=0; + mode=MODE_SQUARE; + half_offset=HALF_OFFSET_DISABLED; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index d21437e30f95..4e9e2e7e9797 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -37,12 +37,30 @@ class TileMap : public Node2D { OBJ_TYPE( TileMap, Node2D ); +public: + enum Mode { + MODE_SQUARE, + MODE_ISOMETRIC, + MODE_CUSTOM + }; + + enum HalfOffset { + HALF_OFFSET_X, + HALF_OFFSET_Y, + HALF_OFFSET_DISABLED, + }; + +private: Ref tile_set; - int cell_size; + Size2i cell_size; int quadrant_size; bool center_x,center_y; + Mode mode; + Matrix32 custom_transform; + HalfOffset half_offset; + union PosKey { @@ -117,6 +135,12 @@ class TileMap : public Node2D { void _set_tile_data(const DVector& p_data); DVector _get_tile_data() const; + + void _set_old_cell_size(int p_size) { set_cell_size(Size2(p_size,p_size)); } + int _get_old_cell_size() const { return cell_size.x; } + + _FORCE_INLINE_ Vector2 _map_to_world(int p_x,int p_y,bool p_ignore_ofs=false) const; + protected: @@ -132,8 +156,8 @@ public: void set_tileset(const Ref& p_tileset); Ref get_tileset() const; - void set_cell_size(int p_size); - int get_cell_size() const; + void set_cell_size(Size2 p_size); + Size2 get_cell_size() const; void set_quadrant_size(int p_size); int get_quadrant_size() const; @@ -159,10 +183,28 @@ public: void set_collision_bounce(float p_bounce); float get_collision_bounce() const; + void set_mode(Mode p_mode); + Mode get_mode() const; + + void set_half_offset(HalfOffset p_half_offset); + HalfOffset get_half_offset() const; + + void set_custom_transform(const Matrix32& p_xform); + Matrix32 get_custom_transform() const; + + Matrix32 get_cell_transform() const; + Vector2 get_cell_draw_offset() const; + + Vector2 map_to_world(const Vector2& p_pos, bool p_ignore_ofs=false) const; + Vector2 world_to_map(const Vector2& p_pos) const; + void clear(); TileMap(); ~TileMap(); }; +VARIANT_ENUM_CAST(TileMap::Mode); +VARIANT_ENUM_CAST(TileMap::HalfOffset); + #endif // TILE_MAP_H diff --git a/scene/2d/y_sort.cpp b/scene/2d/y_sort.cpp new file mode 100644 index 000000000000..d441abfaf102 --- /dev/null +++ b/scene/2d/y_sort.cpp @@ -0,0 +1,29 @@ +#include "y_sort.h" + + + +void YSort::set_sort_enabled(bool p_enabled) { + + sort_enabled=p_enabled; + VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),sort_enabled); +} + +bool YSort::is_sort_enabled() const { + + return sort_enabled; +} + +void YSort::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_sort_enabled","enabled"),&YSort::set_sort_enabled); + ObjectTypeDB::bind_method(_MD("is_sort_enabled"),&YSort::is_sort_enabled); + + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"sort/enabled"),_SCS("set_sort_enabled"),_SCS("is_sort_enabled")); +} + + +YSort::YSort() { + + sort_enabled=true; + VS::get_singleton()->canvas_item_set_sort_children_by_y(get_canvas_item(),true); +} diff --git a/scene/2d/y_sort.h b/scene/2d/y_sort.h new file mode 100644 index 000000000000..6d04a67e4244 --- /dev/null +++ b/scene/2d/y_sort.h @@ -0,0 +1,17 @@ +#ifndef Y_SORT_H +#define Y_SORT_H + +#include "scene/2d/node_2d.h" + +class YSort : public Node2D { + OBJ_TYPE(YSort,Node2D); + bool sort_enabled; + static void _bind_methods(); +public: + + void set_sort_enabled(bool p_enabled); + bool is_sort_enabled() const; + YSort(); +}; + +#endif // Y_SORT_H diff --git a/scene/3d/area.cpp b/scene/3d/area.cpp index f5895453cc11..7370c36eb790 100644 --- a/scene/3d/area.cpp +++ b/scene/3d/area.cpp @@ -255,16 +255,6 @@ bool Area::is_monitoring_enabled() const { } -void Area::set_ray_pickable(bool p_ray_pickable) { - - ray_pickable=p_ray_pickable; - PhysicsServer::get_singleton()->area_set_ray_pickable(get_rid(),p_ray_pickable); -} - -bool Area::is_ray_pickable() const { - - return ray_pickable; -} void Area::_bind_methods() { @@ -289,8 +279,6 @@ void Area::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_priority","priority"),&Area::set_priority); ObjectTypeDB::bind_method(_MD("get_priority"),&Area::get_priority); - ObjectTypeDB::bind_method(_MD("set_ray_pickable","ray_pickable"),&Area::set_ray_pickable); - ObjectTypeDB::bind_method(_MD("is_ray_pickable"),&Area::is_ray_pickable); ObjectTypeDB::bind_method(_MD("set_enable_monitoring","enable"),&Area::set_enable_monitoring); ObjectTypeDB::bind_method(_MD("is_monitoring_enabled"),&Area::is_monitoring_enabled); @@ -310,7 +298,6 @@ void Area::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::REAL,"density",PROPERTY_HINT_RANGE,"0,1024,0.001"),_SCS("set_density"),_SCS("get_density")); ADD_PROPERTY( PropertyInfo(Variant::INT,"priority",PROPERTY_HINT_RANGE,"0,128,1"),_SCS("set_priority"),_SCS("get_priority")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"monitoring"),_SCS("set_enable_monitoring"),_SCS("is_monitoring_enabled")); - ADD_PROPERTY( PropertyInfo(Variant::BOOL,"ray_pickable"),_SCS("set_ray_pickable"),_SCS("is_ray_pickable")); } @@ -323,7 +310,7 @@ Area::Area() : CollisionObject(PhysicsServer::get_singleton()->area_create(),tru density=0.1; priority=0; monitoring=false; - ray_pickable=false; + set_ray_pickable(false); set_enable_monitoring(true); } diff --git a/scene/3d/area.h b/scene/3d/area.h index 92b5d39f590f..5558e2c71978 100644 --- a/scene/3d/area.h +++ b/scene/3d/area.h @@ -52,7 +52,7 @@ private: real_t density; int priority; bool monitoring; - bool ray_pickable; + void _body_inout(int p_status,const RID& p_body, int p_instance, int p_body_shape,int p_area_shape); @@ -109,9 +109,6 @@ public: void set_priority(real_t p_priority); real_t get_priority() const; - void set_ray_pickable(bool p_ray_pickable); - bool is_ray_pickable() const; - void set_enable_monitoring(bool p_enable); bool is_monitoring_enabled() const; diff --git a/scene/3d/camera.cpp b/scene/3d/camera.cpp index 4245bfa2c92f..c85ad70c6353 100644 --- a/scene/3d/camera.cpp +++ b/scene/3d/camera.cpp @@ -262,7 +262,7 @@ void Camera::_notification(int p_what) { Transform Camera::get_camera_transform() const { - return get_global_transform(); + return get_global_transform().orthonormalized(); } void Camera::set_perspective(float p_fovy_degrees, float p_z_near, float p_z_far) { @@ -695,7 +695,7 @@ Vector Camera::get_frustum() const { else cm.set_orthogonal(size,viewport_size.get_aspect(),near,far,keep_aspect==KEEP_WIDTH); - return cm.get_projection_planes(get_global_transform()); + return cm.get_projection_planes(get_camera_transform()); } @@ -704,7 +704,7 @@ Vector Camera::get_frustum() const { void Camera::look_at(const Vector3& p_target, const Vector3& p_up_normal) { Transform lookat; - lookat.origin=get_global_transform().origin; + lookat.origin=get_camera_transform().origin; lookat=lookat.looking_at(p_target,p_up_normal); set_global_transform(lookat); } diff --git a/scene/3d/collision_object.cpp b/scene/3d/collision_object.cpp index 06564f5c49ab..e9d3e739060f 100644 --- a/scene/3d/collision_object.cpp +++ b/scene/3d/collision_object.cpp @@ -53,8 +53,9 @@ void CollisionObject::_notification(int p_what) { } else PhysicsServer::get_singleton()->body_set_space(rid,space); + _update_pickable(); //get space - } + }; case NOTIFICATION_TRANSFORM_CHANGED: { @@ -63,6 +64,11 @@ void CollisionObject::_notification(int p_what) { else PhysicsServer::get_singleton()->body_set_state(rid,PhysicsServer::BODY_STATE_TRANSFORM,get_global_transform()); + } break; + case NOTIFICATION_VISIBILITY_CHANGED: { + + _update_pickable(); + } break; case NOTIFICATION_EXIT_WORLD: { @@ -91,11 +97,11 @@ void CollisionObject::_update_shapes() { continue; if (area) PhysicsServer::get_singleton()->area_add_shape(rid,shapes[i].shape->get_rid(),shapes[i].xform); - else { + else { PhysicsServer::get_singleton()->body_add_shape(rid,shapes[i].shape->get_rid(),shapes[i].xform); - if (shapes[i].trigger) - PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid,i,shapes[i].trigger); - } + if (shapes[i].trigger) + PhysicsServer::get_singleton()->body_set_shape_as_trigger(rid,i,shapes[i].trigger); + } } } @@ -160,18 +166,18 @@ void CollisionObject::_get_property_list( List *p_list) const { String path="shapes/"+itos(i)+"/"; p_list->push_back( PropertyInfo(Variant::OBJECT,path+"shape",PROPERTY_HINT_RESOURCE_TYPE,"Shape",PROPERTY_USAGE_NOEDITOR) ); p_list->push_back( PropertyInfo(Variant::TRANSFORM,path+"transform",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) ); - p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) ); + p_list->push_back( PropertyInfo(Variant::BOOL,path+"trigger",PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR) ); } } -void CollisionObject::_input_event(const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape) { +void CollisionObject::_input_event(Node *p_camera, const InputEvent& p_input_event, const Vector3& p_pos, const Vector3& p_normal, int p_shape) { if (get_script_instance()) { - get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_input_event,p_pos,p_normal,p_shape); + get_script_instance()->call(SceneStringNames::get_singleton()->_input_event,p_camera,p_input_event,p_pos,p_normal,p_shape); } - emit_signal(SceneStringNames::get_singleton()->input_event,p_input_event,p_pos,p_normal,p_shape); + emit_signal(SceneStringNames::get_singleton()->input_event,p_camera,p_input_event,p_pos,p_normal,p_shape); } void CollisionObject::_mouse_enter() { @@ -192,6 +198,28 @@ void CollisionObject::_mouse_exit() { } +void CollisionObject::_update_pickable() { + if (!is_inside_scene()) + return; + bool pickable = ray_pickable && is_inside_scene() && is_visible(); + if (area) + PhysicsServer::get_singleton()->area_set_ray_pickable(rid,pickable); + else + PhysicsServer::get_singleton()->body_set_ray_pickable(rid,pickable); +} + +void CollisionObject::set_ray_pickable(bool p_ray_pickable) { + + ray_pickable=p_ray_pickable; + _update_pickable(); + +} + +bool CollisionObject::is_ray_pickable() const { + + return ray_pickable; +} + void CollisionObject::_bind_methods() { @@ -206,15 +234,18 @@ void CollisionObject::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_shape_transform","shape_idx"),&CollisionObject::get_shape_transform); ObjectTypeDB::bind_method(_MD("remove_shape","shape_idx"),&CollisionObject::remove_shape); ObjectTypeDB::bind_method(_MD("clear_shapes"),&CollisionObject::clear_shapes); + ObjectTypeDB::bind_method(_MD("set_ray_pickable","ray_pickable"),&CollisionObject::set_ray_pickable); + ObjectTypeDB::bind_method(_MD("is_ray_pickable"),&CollisionObject::is_ray_pickable); ObjectTypeDB::bind_method(_MD("set_capture_input_on_drag","enable"),&CollisionObject::set_capture_input_on_drag); ObjectTypeDB::bind_method(_MD("get_capture_input_on_drag"),&CollisionObject::get_capture_input_on_drag); ObjectTypeDB::bind_method(_MD("get_rid"),&CollisionObject::get_rid); - BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx"))); + BIND_VMETHOD( MethodInfo("_input_event",PropertyInfo(Variant::OBJECT,"camera"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx"))); - ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx"))); + ADD_SIGNAL( MethodInfo("input_event",PropertyInfo(Variant::OBJECT,"camera"),PropertyInfo(Variant::INPUT_EVENT,"event"),PropertyInfo(Variant::VECTOR3,"click_pos"),PropertyInfo(Variant::VECTOR3,"click_normal"),PropertyInfo(Variant::INT,"shape_idx"))); ADD_SIGNAL( MethodInfo("mouse_enter")); ADD_SIGNAL( MethodInfo("mouse_exit")); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"input/ray_pickable"),_SCS("set_ray_pickable"),_SCS("is_ray_pickable")); ADD_PROPERTY(PropertyInfo(Variant::BOOL,"input/capture_on_drag"),_SCS("set_capture_input_on_drag"),_SCS("get_capture_input_on_drag")); } @@ -296,6 +327,8 @@ CollisionObject::CollisionObject(RID p_rid, bool p_area) { rid=p_rid; area=p_area; + capture_input_on_drag=false; + ray_pickable=true; if (p_area) { PhysicsServer::get_singleton()->area_attach_object_instance_ID(rid,get_instance_ID()); } else { @@ -321,6 +354,7 @@ CollisionObject::CollisionObject() { capture_input_on_drag=false; + ray_pickable=true; //owner= diff --git a/scene/3d/collision_object.h b/scene/3d/collision_object.h index afd73aa9cccf..eafce2c82c9b 100644 --- a/scene/3d/collision_object.h +++ b/scene/3d/collision_object.h @@ -51,9 +51,10 @@ class CollisionObject : public Spatial { }; bool capture_input_on_drag; - + bool ray_pickable; Vector shapes; + void _update_pickable(); void _update_shapes(); friend class CollisionShape; @@ -69,7 +70,7 @@ protected: void _get_property_list( List *p_list) const; static void _bind_methods(); friend class Viewport; - virtual void _input_event(const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape); + virtual void _input_event(Node* p_camera,const InputEvent& p_input_event,const Vector3& p_pos, const Vector3& p_normal, int p_shape); virtual void _mouse_enter(); virtual void _mouse_exit(); @@ -87,9 +88,13 @@ public: void set_shape_as_trigger(int p_shape_idx, bool p_trigger); bool is_shape_set_as_trigger(int p_shape_idx) const; + void set_ray_pickable(bool p_ray_pickable); + bool is_ray_pickable() const; + void set_capture_input_on_drag(bool p_capture); bool get_capture_input_on_drag() const; + _FORCE_INLINE_ RID get_rid() const { return rid; } CollisionObject(); diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 1efc74e67225..0d571b77cda1 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -622,7 +622,7 @@ void SpotLight::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION ); ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_angle", PROPERTY_HINT_RANGE, "0.01,89.9,0.01"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ANGLE ); - ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_ATTENUATION ); + ADD_PROPERTYI( PropertyInfo( Variant::REAL, "params/spot_attenuation", PROPERTY_HINT_EXP_EASING, "attenuation"), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPOT_ATTENUATION ); } diff --git a/scene/3d/navigation.cpp b/scene/3d/navigation.cpp index d2abdad07997..d22198d47e4a 100644 --- a/scene/3d/navigation.cpp +++ b/scene/3d/navigation.cpp @@ -21,6 +21,7 @@ void Navigation::_navmesh_link(int p_id) { List::Element *P=nm.polygons.push_back(Polygon()); Polygon &p=P->get(); + p.owner=&nm; Vector poly = nm.navmesh->get_polygon(i); int plen=poly.size(); @@ -145,13 +146,14 @@ void Navigation::_navmesh_unlink(int p_id) { } -int Navigation::navmesh_create(const Ref& p_mesh,const Transform& p_xform) { +int Navigation::navmesh_create(const Ref& p_mesh, const Transform& p_xform, Object *p_owner) { int id = last_id++; NavMesh nm; nm.linked=false; nm.navmesh=p_mesh; nm.xform=p_xform; + nm.owner=p_owner; navmesh_map[id]=nm; _navmesh_link(id); @@ -453,6 +455,7 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec bool use_collision=false; Vector3 closest_point; float closest_point_d=1e20; + NavMesh *closest_navmesh=NULL; for (Map::Element*E=navmesh_map.front();E;E=E->next()) { @@ -471,10 +474,12 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec closest_point=inters; use_collision=true; closest_point_d=p_from.distance_to(inters); + closest_navmesh=p.owner; } else if (closest_point_d > inters.distance_to(p_from)){ closest_point=inters; closest_point_d=p_from.distance_to(inters); + closest_navmesh=p.owner; } } } @@ -492,6 +497,7 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec closest_point_d=d; closest_point=b; + closest_navmesh=p.owner; } } @@ -499,6 +505,10 @@ Vector3 Navigation::get_closest_point_to_segment(const Vector3& p_from,const Vec } } + if (closest_navmesh && closest_navmesh->owner) { + //print_line("navmesh is: "+closest_navmesh->owner->cast_to()->get_name()); + } + return closest_point; } @@ -577,7 +587,7 @@ Vector3 Navigation::get_up_vector() const{ void Navigation::_bind_methods() { - ObjectTypeDB::bind_method(_MD("navmesh_create","mesh:NavigationMesh","xform"),&Navigation::navmesh_create); + ObjectTypeDB::bind_method(_MD("navmesh_create","mesh:NavigationMesh","xform","owner"),&Navigation::navmesh_create,DEFVAL(Variant())); ObjectTypeDB::bind_method(_MD("navmesh_set_transform","id","xform"),&Navigation::navmesh_set_transform); ObjectTypeDB::bind_method(_MD("navmesh_remove","id"),&Navigation::navmesh_remove); diff --git a/scene/3d/navigation.h b/scene/3d/navigation.h index e8a97a65911f..9b6cf5fbc4d5 100644 --- a/scene/3d/navigation.h +++ b/scene/3d/navigation.h @@ -41,6 +41,8 @@ class Navigation : public Spatial { }; + struct NavMesh; + struct Polygon { @@ -57,6 +59,8 @@ class Navigation : public Spatial { float distance; int prev_edge; + + NavMesh *owner; }; @@ -74,6 +78,7 @@ class Navigation : public Spatial { struct NavMesh { + Object *owner; Transform xform; bool linked; Ref navmesh; @@ -124,7 +129,7 @@ public: Vector3 get_up_vector() const; //API should be as dynamic as possible - int navmesh_create(const Ref& p_mesh,const Transform& p_xform); + int navmesh_create(const Ref& p_mesh,const Transform& p_xform,Object* p_owner=NULL); void navmesh_set_transform(int p_id, const Transform& p_xform); void navmesh_remove(int p_id); diff --git a/scene/3d/navigation_mesh.cpp b/scene/3d/navigation_mesh.cpp index cf2e22a57370..db416f24dd0e 100644 --- a/scene/3d/navigation_mesh.cpp +++ b/scene/3d/navigation_mesh.cpp @@ -129,7 +129,7 @@ void NavigationMeshInstance::set_enabled(bool p_enabled) { if (navmesh.is_valid()) { - nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation)); + nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this); } } @@ -162,7 +162,7 @@ void NavigationMeshInstance::_notification(int p_what) { if (enabled && navmesh.is_valid()) { - nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation)); + nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this); } break; } @@ -205,7 +205,7 @@ void NavigationMeshInstance::set_navigation_mesh(const Ref& p_na navmesh=p_navmesh; if (navigation && navmesh.is_valid() && enabled) { - nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation)); + nav_id = navigation->navmesh_create(navmesh,get_relative_transform(navigation),this); } update_gizmo(); diff --git a/scene/3d/physics_joint.cpp b/scene/3d/physics_joint.cpp index 341b02314dd8..8a79e17d8788 100644 --- a/scene/3d/physics_joint.cpp +++ b/scene/3d/physics_joint.cpp @@ -66,6 +66,9 @@ void Joint::_update_joint(bool p_only_free) { joint = _configure_joint(body_a,body_b); + if (joint.is_valid()) + PhysicsServer::get_singleton()->joint_set_solver_priority(joint,solver_priority); + if (body_b && joint.is_valid()) { ba=body_a->get_rid(); @@ -107,6 +110,20 @@ NodePath Joint::get_node_b() const{ } +void Joint::set_solver_priority(int p_priority) { + + solver_priority=p_priority; + if (joint.is_valid()) + PhysicsServer::get_singleton()->joint_set_solver_priority(joint,solver_priority); + +} + +int Joint::get_solver_priority() const { + + return solver_priority; +} + + void Joint::_notification(int p_what) { switch(p_what) { @@ -117,8 +134,6 @@ void Joint::_notification(int p_what) { case NOTIFICATION_EXIT_SCENE: { if (joint.is_valid()) { _update_joint(true); - - PhysicsServer::get_singleton()->free(joint); joint=RID(); } @@ -138,9 +153,13 @@ void Joint::_bind_methods() { ObjectTypeDB::bind_method( _MD("set_node_b","node"), &Joint::set_node_b ); ObjectTypeDB::bind_method( _MD("get_node_b"), &Joint::get_node_b ); + ObjectTypeDB::bind_method( _MD("set_solver_priority","priority"), &Joint::set_solver_priority ); + ObjectTypeDB::bind_method( _MD("get_solver_priority"), &Joint::get_solver_priority ); ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_a"), _SCS("set_node_a"),_SCS("get_node_a") ); ADD_PROPERTY( PropertyInfo( Variant::NODE_PATH, "nodes/node_b"), _SCS("set_node_b"),_SCS("get_node_b") ); + ADD_PROPERTY( PropertyInfo( Variant::INT, "solver/priority",PROPERTY_HINT_RANGE,"1,8,1"), _SCS("set_solver_priority"),_SCS("get_solver_priority") ); + } @@ -148,7 +167,7 @@ void Joint::_bind_methods() { Joint::Joint() { - + solver_priority=1; } diff --git a/scene/3d/physics_joint.h b/scene/3d/physics_joint.h index 6daa06da2b95..32bec1bd6f1d 100644 --- a/scene/3d/physics_joint.h +++ b/scene/3d/physics_joint.h @@ -44,6 +44,8 @@ class Joint : public Spatial { NodePath a; NodePath b; + int solver_priority; + protected: @@ -62,6 +64,9 @@ public: void set_node_b(const NodePath& p_node_b); NodePath get_node_b() const; + void set_solver_priority(int p_priority); + int get_solver_priority() const; + RID get_joint() const { return joint; } Joint(); diff --git a/scene/3d/vehicle_body.cpp b/scene/3d/vehicle_body.cpp index 07abd1dcd298..4cf905e4eebe 100644 --- a/scene/3d/vehicle_body.cpp +++ b/scene/3d/vehicle_body.cpp @@ -179,7 +179,7 @@ void VehicleWheel::set_damping_compression(float p_value){ } float VehicleWheel::get_damping_compression() const{ - return m_wheelsDampingRelaxation; + return m_wheelsDampingCompression; } void VehicleWheel::set_damping_relaxation(float p_value){ @@ -745,11 +745,12 @@ void VehicleBody::_update_friction(PhysicsDirectBodyState *s) { { if (engine_force != 0.f) { - rollingFriction = engine_force* s->get_step(); + rollingFriction = -engine_force* s->get_step(); } else { real_t defaultRollingFrictionImpulse = 0.f; - real_t maxImpulse = wheelInfo.m_brake ? wheelInfo.m_brake : defaultRollingFrictionImpulse; + float cbrake = MAX(wheelInfo.m_brake,brake); + real_t maxImpulse = cbrake ? cbrake : defaultRollingFrictionImpulse; btVehicleWheelContactPoint contactPt(s,wheelInfo.m_raycastInfo.m_groundObject,wheelInfo.m_raycastInfo.m_contactPointWS,m_forwardWS[wheel],maxImpulse); rollingFriction = _calc_rolling_friction(contactPt); } @@ -1009,9 +1010,9 @@ void VehicleBody::_bind_methods(){ ObjectTypeDB::bind_method(_MD("_direct_state_changed"),&VehicleBody::_direct_state_changed); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/engine_force",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_engine_force"),_SCS("get_engine_force")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/brake",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_brake"),_SCS("get_brake")); - ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/steering",PROPERTY_HINT_RANGE,"0.01,1024.0,0.01"),_SCS("set_steering"),_SCS("get_steering")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/engine_force",PROPERTY_HINT_RANGE,"0.00,1024.0,0.01"),_SCS("set_engine_force"),_SCS("get_engine_force")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/brake",PROPERTY_HINT_RANGE,"0.0,1.0,0.01"),_SCS("set_brake"),_SCS("get_brake")); + ADD_PROPERTY( PropertyInfo(Variant::REAL,"motion/steering",PROPERTY_HINT_RANGE,"-180,180.0,0.01"),_SCS("set_steering"),_SCS("get_steering")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"body/mass",PROPERTY_HINT_RANGE,"0.01,65536,0.01"),_SCS("set_mass"),_SCS("get_mass")); ADD_PROPERTY( PropertyInfo(Variant::REAL,"body/friction",PROPERTY_HINT_RANGE,"0.01,1,0.01"),_SCS("set_friction"),_SCS("get_friction")); diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index 030f3f27e0f5..88fabb3489df 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -180,6 +180,10 @@ void AnimationPlayer::_get_property_list( List *p_list) const { } +void AnimationPlayer::advance(float p_time) { + + _animation_process( p_time ); +} void AnimationPlayer::_notification(int p_what) { @@ -1227,6 +1231,8 @@ void AnimationPlayer::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_current_animation_pos"),&AnimationPlayer::get_current_animation_pos); ObjectTypeDB::bind_method(_MD("get_current_animation_length"),&AnimationPlayer::get_current_animation_length); + ObjectTypeDB::bind_method(_MD("advance","delta"),&AnimationPlayer::advance); + ADD_PROPERTY( PropertyInfo( Variant::INT, "playback/process_mode", PROPERTY_HINT_ENUM, "Fixed,Idle"), _SCS("set_animation_process_mode"), _SCS("get_animation_process_mode")); ADD_PROPERTY( PropertyInfo( Variant::REAL, "playback/default_blend_time", PROPERTY_HINT_RANGE, "0,4096,0.01"), _SCS("set_default_blend_time"), _SCS("get_default_blend_time")); diff --git a/scene/animation/animation_player.h b/scene/animation/animation_player.h index 51c000d4d8fd..038c43d5697e 100644 --- a/scene/animation/animation_player.h +++ b/scene/animation/animation_player.h @@ -283,6 +283,8 @@ public: float get_current_animation_pos() const; float get_current_animation_length() const; + void advance(float p_time); + void set_root(const NodePath& p_root); NodePath get_root() const; diff --git a/scene/audio/event_player.cpp b/scene/audio/event_player.cpp index 6bad94bf0ec8..e5b2be53ca12 100644 --- a/scene/audio/event_player.cpp +++ b/scene/audio/event_player.cpp @@ -280,8 +280,8 @@ float EventPlayer::get_channel_last_note_time(int p_channel) const { void EventPlayer::_bind_methods() { - ObjectTypeDB::bind_method(_MD("set_stream","stream:Stream"),&EventPlayer::set_stream); - ObjectTypeDB::bind_method(_MD("get_stream:Stream"),&EventPlayer::get_stream); + ObjectTypeDB::bind_method(_MD("set_stream","stream:EventStream"),&EventPlayer::set_stream); + ObjectTypeDB::bind_method(_MD("get_stream:EventStream"),&EventPlayer::get_stream); ObjectTypeDB::bind_method(_MD("play"),&EventPlayer::play); ObjectTypeDB::bind_method(_MD("stop"),&EventPlayer::stop); diff --git a/scene/gui/button_group.cpp b/scene/gui/button_group.cpp index 65cfd0350541..58b323c24dba 100644 --- a/scene/gui/button_group.cpp +++ b/scene/gui/button_group.cpp @@ -67,6 +67,9 @@ Array ButtonGroup::_get_button_list() const { List b; get_button_list(&b); + + b.sort_custom(); + Array arr; arr.resize(b.size()); diff --git a/scene/gui/label.cpp b/scene/gui/label.cpp index b7918994d88b..36940655d4cd 100644 --- a/scene/gui/label.cpp +++ b/scene/gui/label.cpp @@ -397,6 +397,7 @@ void Label::regenerate_word_cache() { } + if (current=='\n') { insert_newline=true; } else { @@ -446,7 +447,7 @@ void Label::regenerate_word_cache() { } - total_char_cache -= line_count + 1; // do not count new lines (including the first one) + //total_char_cache -= line_count + 1; // do not count new lines (including the first one) if (!autowrap) { @@ -535,7 +536,7 @@ void Label::set_percent_visible(float p_percent) { if (p_percent<0) set_visible_characters(-1); else - set_visible_characters(get_total_character_count()*p_percent); + set_visible_characters(get_total_character_count()*p_percent); percent_visible=p_percent; } diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 92dcef803c9e..bd39fafc8b7f 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -164,6 +164,9 @@ void Viewport::_parent_visibility_changed() { Control *c = parent->cast_to(); VisualServer::get_singleton()->canvas_item_set_visible(canvas_item,c->is_visible()); + + _update_listener(); + _update_listener_2d(); } @@ -394,7 +397,7 @@ void Viewport::_notification(int p_what) { if (obj) { CollisionObject *co = obj->cast_to(); if (co) { - co->_input_event(ev,Vector3(),Vector3(),0); + co->_input_event(camera,ev,Vector3(),Vector3(),0); captured=true; if (ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && !ev.mouse_button.pressed) { physics_object_capture=0; @@ -416,7 +419,7 @@ void Viewport::_notification(int p_what) { if (last_id) { if (ObjectDB::get_instance(last_id)) { //good, exists - last_object->_input_event(ev,result.position,result.normal,result.shape); + last_object->_input_event(camera,ev,result.position,result.normal,result.shape); if (last_object->get_capture_input_on_drag() && ev.type==InputEvent::MOUSE_BUTTON && ev.mouse_button.button_index==1 && ev.mouse_button.pressed) { physics_object_capture=last_id; } @@ -440,10 +443,13 @@ void Viewport::_notification(int p_what) { bool col = space->intersect_ray(from,from+dir*10000,result,Set(),0xFFFFFFFF,0xFFFFFFFF); ObjectID new_collider=0; if (col) { + if (result.collider) { + CollisionObject *co = result.collider->cast_to(); if (co) { - co->_input_event(ev,result.position,result.normal,result.shape); + + co->_input_event(camera,ev,result.position,result.normal,result.shape); last_object=co; last_id=result.collider_id; new_collider=last_id; @@ -541,7 +547,7 @@ Rect2 Viewport::get_rect() const { void Viewport::_update_listener() { - if (is_inside_scene() && audio_listener && camera) { + if (is_inside_scene() && audio_listener && camera && (!get_parent() || (get_parent()->cast_to() && get_parent()->cast_to()->is_visible()))) { SpatialSoundServer::get_singleton()->listener_set_space(listener,find_world()->get_sound_space()); } else { SpatialSoundServer::get_singleton()->listener_set_space(listener,RID()); @@ -552,7 +558,7 @@ void Viewport::_update_listener() { void Viewport::_update_listener_2d() { - if (is_inside_scene() && audio_listener_2d) + if (is_inside_scene() && audio_listener && camera && (!get_parent() || (get_parent()->cast_to() && get_parent()->cast_to()->is_visible()))) SpatialSound2DServer::get_singleton()->listener_set_space(listener_2d,find_world_2d()->get_sound_space()); else SpatialSound2DServer::get_singleton()->listener_set_space(listener_2d,RID()); diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 2a1cca6a3ab3..1902ff686b2e 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -100,6 +100,7 @@ #include "scene/2d/sample_player_2d.h" #include "scene/2d/screen_button.h" #include "scene/2d/remote_transform_2d.h" +#include "scene/2d/y_sort.h" #include "scene/2d/position_2d.h" #include "scene/2d/tile_map.h" @@ -491,6 +492,7 @@ void register_scene_types() { ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::set_type_enabled("CollisionShape2D",false); ObjectTypeDB::set_type_enabled("CollisionPolygon2D",false); diff --git a/scene/resources/animation.cpp b/scene/resources/animation.cpp index 67f45ced2b6f..e6359f920b22 100644 --- a/scene/resources/animation.cpp +++ b/scene/resources/animation.cpp @@ -1716,7 +1716,7 @@ void Animation::clear() { } -void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,float p_alowed_angular_err) { +void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,float p_alowed_angular_err,float p_max_optimizable_angle) { ERR_FAIL_INDEX(p_idx,tracks.size()); ERR_FAIL_COND(tracks[p_idx]->type!=TYPE_TRANSFORM); @@ -1779,6 +1779,7 @@ void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,fl } else { + Quat r02 = (q0.inverse() * q2).normalized(); Quat r01 = (q0.inverse() * q1).normalized(); @@ -1788,6 +1789,9 @@ void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,fl r02.get_axis_and_angle(v02,a02); r01.get_axis_and_angle(v01,a01); + if (Math::abs(a02)>p_max_optimizable_angle) + continue; + if (v01.dot(v02)<0) { //make sure both rotations go the same way to compare v02=-v02; @@ -1905,7 +1909,7 @@ void Animation::_transform_track_optimize(int p_idx,float p_alowed_linear_err,fl } -void Animation::optimize(float p_allowed_linear_err,float p_allowed_angular_err) { +void Animation::optimize(float p_allowed_linear_err,float p_allowed_angular_err,float p_angle_max) { int total_tt=0; @@ -1913,7 +1917,7 @@ void Animation::optimize(float p_allowed_linear_err,float p_allowed_angular_err) for(int i=0;itype==TYPE_TRANSFORM) - _transform_track_optimize(i,p_allowed_linear_err,p_allowed_angular_err); + _transform_track_optimize(i,p_allowed_linear_err,p_allowed_angular_err,p_angle_max); } diff --git a/scene/resources/animation.h b/scene/resources/animation.h index 4c4e2f02752c..0c0290295ad3 100644 --- a/scene/resources/animation.h +++ b/scene/resources/animation.h @@ -204,7 +204,7 @@ private: return idxr; } - void _transform_track_optimize(int p_idx, float p_allowed_err=0.05, float p_alowed_angular_err=0.01); + void _transform_track_optimize(int p_idx, float p_allowed_err=0.05, float p_alowed_angular_err=0.01,float p_max_optimizable_angle=Math_PI*0.125); protected: @@ -271,7 +271,7 @@ public: void clear(); - void optimize(float p_allowed_linear_err=0.05,float p_allowed_angular_err=0.01); + void optimize(float p_allowed_linear_err=0.05,float p_allowed_angular_err=0.01,float p_max_optimizable_angle=Math_PI*0.125); Animation(); ~Animation(); diff --git a/scene/resources/packed_scene.cpp b/scene/resources/packed_scene.cpp index 3bd7314778ff..3109556922a5 100644 --- a/scene/resources/packed_scene.cpp +++ b/scene/resources/packed_scene.cpp @@ -225,22 +225,34 @@ Error PackedScene::_parse_node(Node *p_owner,Node *p_node,int p_parent_idx, Map< p_node->get_property_list(&plist); for (List::Element *E=plist.front();E;E=E->next()) { - if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) + + if (!(E->get().usage & PROPERTY_USAGE_STORAGE)) { continue; + } String name = E->get().name; Variant value = p_node->get( E->get().name ); - if (E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero()) + if (E->get().usage & PROPERTY_USAGE_STORE_IF_NONZERO && value.is_zero()) { continue; + } if (nd.instance>=0) { //only save changed properties in instance - if (!instance_state.has(name)) + /* + // this was commented because it would not save properties created from within script + // done with _get_property_list, that are not in the original node. + // if some property is not saved, check again + + if (!instance_state.has(name)) { + print_line("skip not in instance"); continue; - if (instance_state[name]==value) + }*/ + + if (instance_state[name]==value) { continue; + } } diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp index 4a303d3fddda..5938e716e955 100644 --- a/servers/physics/area_pair_sw.cpp +++ b/servers/physics/area_pair_sw.cpp @@ -67,7 +67,6 @@ void AreaPairSW::solve(float p_step) { AreaPairSW::AreaPairSW(BodySW *p_body,int p_body_shape, AreaSW *p_area,int p_area_shape) { - body=p_body; area=p_area; body_shape=p_body_shape; @@ -75,6 +74,8 @@ AreaPairSW::AreaPairSW(BodySW *p_body,int p_body_shape, AreaSW *p_area,int p_are colliding=false; body->add_constraint(this,0); area->add_constraint(this); + if (p_body->get_mode()==PhysicsServer::BODY_MODE_KINEMATIC) + p_body->set_active(true); } diff --git a/servers/physics/area_sw.cpp b/servers/physics/area_sw.cpp index 8192a984000c..4c9ac814bea9 100644 --- a/servers/physics/area_sw.cpp +++ b/servers/physics/area_sw.cpp @@ -148,8 +148,6 @@ void AreaSW::call_queries() { return; } - - for (Map::Element *E=monitored_bodies.front();E;E=E->next()) { if (E->get().state==0) @@ -182,8 +180,8 @@ AreaSW::AreaSW() : CollisionObjectSW(TYPE_AREA), monitor_query_list(this), move point_attenuation=1; density=0.1; priority=0; - ray_pickable=false; - + set_ray_pickable(false); + monitor_callback_id=0; } diff --git a/servers/physics/area_sw.h b/servers/physics/area_sw.h index a864055d172a..c0c6e5c2aefd 100644 --- a/servers/physics/area_sw.h +++ b/servers/physics/area_sw.h @@ -48,7 +48,6 @@ class AreaSW : public CollisionObjectSW{ float point_attenuation; float density; int priority; - bool ray_pickable; ObjectID monitor_callback_id; StringName monitor_callback_method; @@ -139,8 +138,6 @@ public: _FORCE_INLINE_ void remove_constraint( ConstraintSW* p_constraint) { constraints.erase(p_constraint); } _FORCE_INLINE_ const Set& get_constraints() const { return constraints; } - _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; } - _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; } diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index f34aa19cae58..c8e1fc4022da 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -217,4 +217,5 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) { space=NULL; instance_id=0; layer_mask=1; + ray_pickable=true; } diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index e717cc257c9d..98d05538a851 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -94,6 +94,9 @@ protected: virtual void _shapes_changed()=0; void _set_space(SpaceSW *space); + bool ray_pickable; + + CollisionObjectSW(Type p_type); public: @@ -119,6 +122,9 @@ public: _FORCE_INLINE_ Transform get_inv_transform() const { return inv_transform; } _FORCE_INLINE_ SpaceSW* get_space() const { return space; } + _FORCE_INLINE_ void set_ray_pickable(bool p_enable) { ray_pickable=p_enable; } + _FORCE_INLINE_ bool is_ray_pickable() const { return ray_pickable; } + _FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask=p_mask; } _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; } diff --git a/servers/physics/constraint_sw.h b/servers/physics/constraint_sw.h index 1be96422e14d..5e79c4b54c88 100644 --- a/servers/physics/constraint_sw.h +++ b/servers/physics/constraint_sw.h @@ -38,12 +38,13 @@ class ConstraintSW { uint64_t island_step; ConstraintSW *island_next; ConstraintSW *island_list_next; + int priority; RID self; protected: - ConstraintSW(BodySW **p_body_ptr=NULL,int p_body_count=0) { _body_ptr=p_body_ptr; _body_count=p_body_count; island_step=0; } + ConstraintSW(BodySW **p_body_ptr=NULL,int p_body_count=0) { _body_ptr=p_body_ptr; _body_count=p_body_count; island_step=0; priority=1; } public: _FORCE_INLINE_ void set_self(const RID& p_self) { self=p_self; } @@ -62,6 +63,9 @@ public: _FORCE_INLINE_ BodySW **get_body_ptr() const { return _body_ptr; } _FORCE_INLINE_ int get_body_count() const { return _body_count; } + _FORCE_INLINE_ void set_priority(int p_priority) { priority=p_priority; } + _FORCE_INLINE_ int get_priority() const { return priority; } + virtual bool setup(float p_step)=0; virtual void solve(float p_step)=0; diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 043d2149fe79..31c4d8f12165 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -836,6 +836,22 @@ void PhysicsServerSW::body_set_force_integration_callback(RID p_body,Object *p_r } +void PhysicsServerSW::body_set_ray_pickable(RID p_body,bool p_enable) { + + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + body->set_ray_pickable(p_enable); + +} + +bool PhysicsServerSW::body_is_ray_pickable(RID p_body) const{ + + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body,false); + return body->is_ray_pickable(); + +} + /* JOINT API */ @@ -1000,6 +1016,21 @@ bool PhysicsServerSW::hinge_joint_get_flag(RID p_joint,HingeJointFlag p_flag) co return hinge_joint->get_flag(p_flag); } +void PhysicsServerSW::joint_set_solver_priority(RID p_joint,int p_priority) { + + JointSW *joint = joint_owner.get(p_joint); + ERR_FAIL_COND(!joint); + joint->set_priority(p_priority); +} + +int PhysicsServerSW::joint_get_solver_priority(RID p_joint) const{ + + JointSW *joint = joint_owner.get(p_joint); + ERR_FAIL_COND_V(!joint,0); + return joint->get_priority(); + +} + PhysicsServerSW::JointType PhysicsServerSW::joint_get_type(RID p_joint) const { JointSW *joint = joint_owner.get(p_joint); diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 76e5aecf555a..6609a7866264 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -201,6 +201,9 @@ public: virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant()); + virtual void body_set_ray_pickable(RID p_body,bool p_enable); + virtual bool body_is_ray_pickable(RID p_body) const; + /* JOINT API */ virtual RID joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B); @@ -244,6 +247,9 @@ public: virtual JointType joint_get_type(RID p_joint) const; + virtual void joint_set_solver_priority(RID p_joint,int p_priority); + virtual int joint_get_solver_priority(RID p_joint) const; + #if 0 virtual void joint_set_param(RID p_joint, JointParam p_param, real_t p_value); virtual real_t joint_get_param(RID p_joint,JointParam p_param) const; diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 68d6b464ab2d..4e8b60b86bc3 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -71,12 +71,13 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto real_t min_d=1e10; + for(int i=0;iintersection_query_results[i],p_layer_mask,p_object_type_mask)) continue; - if (space->intersection_query_results[i]->get_type()==CollisionObjectSW::TYPE_AREA && !(static_cast(space->intersection_query_results[i])->is_ray_pickable())) + if (!(static_cast(space->intersection_query_results[i])->is_ray_pickable())) continue; if (p_exclude.has( space->intersection_query_results[i]->get_self())) @@ -97,6 +98,8 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) { + + Transform xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); shape_point=xform.xform(shape_point); diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp index 6d958048754e..b7d06d207b6b 100644 --- a/servers/physics/step_sw.cpp +++ b/servers/physics/step_sw.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "step_sw.h" - +#include "joints_sw.h" void StepSW::_populate_island(BodySW* p_body,BodySW** p_island,ConstraintSW **p_constraint_island) { @@ -68,14 +68,41 @@ void StepSW::_setup_island(ConstraintSW *p_island,float p_delta) { void StepSW::_solve_island(ConstraintSW *p_island,int p_iterations,float p_delta){ - for(int i=0;isolve(p_delta); - ci=ci->get_island_next(); + while(p_island) { + + for(int i=0;isolve(p_delta); + ci=ci->get_island_next(); + } + } + + at_priority++; + + { + ConstraintSW *ci=p_island; + ConstraintSW *prev=NULL; + while(ci) { + if (ci->get_priority()set_island_next(ci->get_island_next()); //remove + } else { + p_island=ci->get_island_next(); + } + } else { + + prev=ci; + } + + ci=ci->get_island_next(); + } } } + } void StepSW::_check_suspend(BodySW *p_island,float p_delta) { diff --git a/servers/physics_2d/area_2d_sw.cpp b/servers/physics_2d/area_2d_sw.cpp index 58035eb656b0..8be583c2356d 100644 --- a/servers/physics_2d/area_2d_sw.cpp +++ b/servers/physics_2d/area_2d_sw.cpp @@ -180,6 +180,7 @@ Area2DSW::Area2DSW() : CollisionObject2DSW(TYPE_AREA), monitor_query_list(this), gravity_vector=Vector2(0,-1); gravity_is_point=false; point_attenuation=1; + density=0.1; priority=0; monitor_callback_id=0; diff --git a/servers/physics_2d/area_pair_2d_sw.cpp b/servers/physics_2d/area_pair_2d_sw.cpp index 35286bdb67f0..1c7f73db5e46 100644 --- a/servers/physics_2d/area_pair_2d_sw.cpp +++ b/servers/physics_2d/area_pair_2d_sw.cpp @@ -75,6 +75,8 @@ AreaPair2DSW::AreaPair2DSW(Body2DSW *p_body,int p_body_shape, Area2DSW *p_area,i colliding=false; body->add_constraint(this,0); area->add_constraint(this); + if (p_body->get_mode()==Physics2DServer::BODY_MODE_KINEMATIC) //need to be active to process pair + p_body->set_active(true); } diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index dc8e4cc298f0..fbed5779ffc7 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -520,6 +520,9 @@ void PhysicsServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("body_set_force_integration_callback","body","receiver","method","userdata"),&PhysicsServer::body_set_force_integration_callback,DEFVAL(Variant())); + ObjectTypeDB::bind_method(_MD("body_set_ray_pickable","body","enable"),&PhysicsServer::body_set_ray_pickable); + ObjectTypeDB::bind_method(_MD("body_is_ray_pickable","body"),&PhysicsServer::body_is_ray_pickable); + /* JOINT API */ BIND_CONSTANT( JOINT_PIN ); @@ -627,6 +630,9 @@ void PhysicsServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("joint_get_type","joint"),&PhysicsServer::joint_get_type); + ObjectTypeDB::bind_method(_MD("joint_set_solver_priority","joint","priority"),&PhysicsServer::joint_set_solver_priority); + ObjectTypeDB::bind_method(_MD("joint_get_solver_priority","joint"),&PhysicsServer::joint_get_solver_priority); + ObjectTypeDB::bind_method(_MD("joint_create_generic_6dof","body_A","local_ref_A","body_B","local_ref_B"),&PhysicsServer::joint_create_generic_6dof); ObjectTypeDB::bind_method(_MD("generic_6dof_joint_set_param","joint","axis","param","value"),&PhysicsServer::generic_6dof_joint_set_param); diff --git a/servers/physics_server.h b/servers/physics_server.h index 25a89775a8b4..0c2542a66caa 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -450,6 +450,10 @@ public: virtual void body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant())=0; + virtual void body_set_ray_pickable(RID p_body,bool p_enable)=0; + virtual bool body_is_ray_pickable(RID p_body) const=0; + + /* JOINT API */ enum JointType { @@ -464,6 +468,8 @@ public: virtual JointType joint_get_type(RID p_joint) const=0; + virtual void joint_set_solver_priority(RID p_joint,int p_priority)=0; + virtual int joint_get_solver_priority(RID p_joint) const=0; virtual RID joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B)=0; diff --git a/servers/register_server_types.cpp b/servers/register_server_types.cpp index f8d38d15c021..a2b1b71f9912 100644 --- a/servers/register_server_types.cpp +++ b/servers/register_server_types.cpp @@ -57,6 +57,7 @@ void register_server_types() { ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_type(); + ObjectTypeDB::register_type(); ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_virtual_type(); ObjectTypeDB::register_virtual_type(); diff --git a/servers/spatial_sound/spatial_sound_server_sw.cpp b/servers/spatial_sound/spatial_sound_server_sw.cpp index 7ec29d32cbd9..d00deb391247 100644 --- a/servers/spatial_sound/spatial_sound_server_sw.cpp +++ b/servers/spatial_sound/spatial_sound_server_sw.cpp @@ -879,10 +879,13 @@ void SpatialSoundServerSW::update(float p_delta) { float volume_attenuation = 0.0; float air_absorption_hf_cutoff = 0.0; float air_absorption = 0.0; - float pitch_scale=0.0; + float pitch_scale=1.0; Vector3 panning; + //print_line("listeners: "+itos(space->listeners.size())); + + for(Set::Element *L=space->listeners.front();L;L=L->next()) { Listener *listener=listener_owner.get(L->get()); @@ -899,9 +902,11 @@ void SpatialSoundServerSW::update(float p_delta) { float attenuation_exp=source->params[SOURCE_PARAM_ATTENUATION_DISTANCE_EXP]; float attenuation=1; + //print_line("DIST MIN: "+rtos(distance_min)); + //print_line("DIST MAX: "+rtos(distance_max)); if (distance_max>0) { distance = CLAMP(distance,distance_min,distance_max); - attenuation = Math::pow(1.0 - ((distance - distance_min)/distance_max),CLAMP(attenuation_exp,0.001,16)); + attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16)); } float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]; @@ -945,7 +950,7 @@ void SpatialSoundServerSW::update(float p_delta) { air_absorption+=weight*absorption; air_absorption_hf_cutoff+=weight*hf_attenuation_cutoff; panning+=vpanning*weight; - pitch_scale+=pscale*weight; + //pitch_scale+=pscale*weight; } @@ -991,8 +996,8 @@ void SpatialSoundServerSW::update(float p_delta) { reverb_send*=volume_scale; int mix_rate = v.sample_mix_rate*v.pitch_scale*pitch_scale*source->params[SOURCE_PARAM_PITCH_SCALE]; - if (mix_rate<=0) { + if (mix_rate<=0) { ERR_PRINT("Invalid mix rate for voice (0) check for invalid pitch_scale param."); to_disable.push_back(ActiveVoice(source,voice)); // oh well.. continue; //invalid mix rate, disabling diff --git a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp index e3c8aba75803..2aab0e7dc943 100644 --- a/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp +++ b/servers/spatial_sound_2d/spatial_sound_2d_server_sw.cpp @@ -904,7 +904,7 @@ void SpatialSound2DServerSW::update(float p_delta) { if (distance_max>0) { distance = CLAMP(distance,distance_min,distance_max); - attenuation = Math::pow(1.0 - ((distance - distance_min)/distance_max),CLAMP(attenuation_exp,0.001,16)); + attenuation = Math::pow(1.0 - ((distance - distance_min)/(distance_max-distance_min)),CLAMP(attenuation_exp,0.001,16)); } float hf_attenuation_cutoff = room->params[ROOM_PARAM_ATTENUATION_HF_CUTOFF]; diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 21ecd4030df4..6d5627877bbf 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -1202,7 +1202,7 @@ RID VisualServerRaster::camera_create() { } void VisualServerRaster::camera_set_perspective(RID p_camera,float p_fovy_degrees, float p_z_near, float p_z_far) { - VS_CHANGED; + VS_CHANGED Camera *camera = camera_owner.get( p_camera ); ERR_FAIL_COND(!camera); camera->type=Camera::PERSPECTIVE; @@ -1226,7 +1226,7 @@ void VisualServerRaster::camera_set_transform(RID p_camera,const Transform& p_tr VS_CHANGED; Camera *camera = camera_owner.get( p_camera ); ERR_FAIL_COND(!camera); - camera->transform=p_transform; + camera->transform=p_transform.orthonormalized(); } @@ -3531,6 +3531,15 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen canvas_item->commands.push_back(bm); }; +void VisualServerRaster::canvas_item_set_sort_children_by_y(RID p_item, bool p_enable) { + + VS_CHANGED; + CanvasItem *canvas_item = canvas_item_owner.get( p_item ); + ERR_FAIL_COND(!canvas_item); + canvas_item->sort_y=p_enable; +} + + void VisualServerRaster::canvas_item_add_clip_ignore(RID p_item, bool p_ignore) { VS_CHANGED; @@ -5591,26 +5600,30 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat float opacity = ci->opacity * p_opacity; -#ifndef ONTOP_DISABLED - CanvasItem **child_items = ci->child_items.ptr(); + int child_item_count=ci->child_items.size(); - int top_item_count=0; - CanvasItem **top_items=(CanvasItem**)alloca(child_item_count*sizeof(CanvasItem*)); + CanvasItem **child_items=(CanvasItem**)alloca(child_item_count*sizeof(CanvasItem*)); + copymem(child_items,ci->child_items.ptr(),child_item_count*sizeof(CanvasItem*)); if (ci->clip) { rasterizer->canvas_set_clip(true,global_rect); canvas_clip=global_rect; } + if (ci->sort_y) { + + SortArray sorter; + sorter.sort(child_items,child_item_count); + } + + for(int i=0;iontop) - top_items[top_item_count++]=child_items[i]; - else { - _render_canvas_item(child_items[i],xform,p_clip_rect,opacity); - } + continue; + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity); } -#endif + if (s!=0) { @@ -5746,20 +5759,13 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat rasterizer->canvas_set_clip(true,canvas_clip); } -#ifndef ONTOP_DISABLED + for(int i=0;iontop) + continue; + _render_canvas_item(child_items[i],xform,p_clip_rect,opacity); } -#else - for(int i=0;ichild_items.size();i++) { - - _render_canvas_item(p_canvas_item->child_items[i],xform,p_clip_rect,opacity); - } -#endif - if (ci->clip) { rasterizer->canvas_set_clip(false,Rect2()); diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 49e7996c59ab..41ad3aab1542 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -328,7 +328,7 @@ class VisualServerRaster : public VisualServer { - + struct CanvasItem { @@ -446,13 +446,14 @@ class VisualServerRaster : public VisualServer { bool clip; bool visible; bool ontop; + bool sort_y; float opacity; float self_opacity; MaterialBlendMode blend_mode; RID viewport; mutable bool custom_rect; - mutable bool rect_dirty; + mutable bool rect_dirty; mutable Rect2 rect; Vector commands; @@ -460,11 +461,18 @@ class VisualServerRaster : public VisualServer { const Rect2& get_rect() const; void clear() { for (int i=0;ixform.elements[2].y < p_right->xform.elements[2].y; + } + }; struct Canvas { @@ -1135,6 +1143,7 @@ public: virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform); virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend); virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore); + virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable); virtual void canvas_item_clear(RID p_item); virtual void canvas_item_raise(RID p_item); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index f1ba4c453ba9..73e736f68476 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -1107,6 +1107,8 @@ public: FUNC2(canvas_item_add_set_blend_mode,RID, MaterialBlendMode ); FUNC2(canvas_item_add_clip_ignore,RID, bool ); + FUNC2(canvas_item_set_sort_children_by_y,RID,bool); + FUNC1(canvas_item_clear,RID); FUNC1(canvas_item_raise,RID); diff --git a/servers/visual_server.h b/servers/visual_server.h index 8934fa790346..166e4907b506 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -944,6 +944,7 @@ public: virtual void canvas_item_add_set_transform(RID p_item,const Matrix32& p_transform)=0; virtual void canvas_item_add_set_blend_mode(RID p_item, MaterialBlendMode p_blend)=0; virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore)=0; + virtual void canvas_item_set_sort_children_by_y(RID p_item, bool p_enable)=0; virtual void canvas_item_clear(RID p_item)=0; virtual void canvas_item_raise(RID p_item)=0; diff --git a/tools/collada/collada.cpp b/tools/collada/collada.cpp index e29888b433b8..16b15426dffa 100644 --- a/tools/collada/collada.cpp +++ b/tools/collada/collada.cpp @@ -2144,6 +2144,7 @@ void Collada::_parse_scene(XMLParser& parser) { if (name=="instance_visual_scene") { state.root_visual_scene=_uri_to_id(parser.get_attribute_value("url")); + print_line("***ROOT VISUAL SCENE: "+state.root_visual_scene); } if (name=="instance_physics_scene") { state.root_physics_scene=_uri_to_id(parser.get_attribute_value("url")); @@ -2513,6 +2514,9 @@ bool Collada::_move_geometry_to_skeletons(VisualScene *p_vscene,Node *p_node,Lis ERR_FAIL_COND_V( !state.scene_map.has( nodeid ), false); //weird, it should have it... NodeJoint *nj = SAFE_CAST(state.scene_map[nodeid]); ERR_FAIL_COND_V(!nj,false); + if (!nj->owner) { + print_line("Has no owner: "+nj->name); + } ERR_FAIL_COND_V( !nj->owner,false ); //weird, node should have a skeleton owner NodeSkeleton *sk = nj->owner; diff --git a/tools/editor/io_plugins/editor_font_import_plugin.cpp b/tools/editor/io_plugins/editor_font_import_plugin.cpp index 4b3e0529078e..6a6ee8c61428 100644 --- a/tools/editor/io_plugins/editor_font_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_font_import_plugin.cpp @@ -92,6 +92,7 @@ public: String gradient_image; + bool disable_filter; bool round_advance; @@ -153,6 +154,8 @@ public: color_use_monochrome=p_value; else if (n=="advanced/round_advance") round_advance=p_value; + else if (n=="advanced/disable_filter") + disable_filter=p_value; else return false; @@ -217,6 +220,8 @@ public: r_ret=color_use_monochrome; else if (n=="advanced/round_advance") r_ret=round_advance; + else if (n=="advanced/disable_filter") + r_ret=disable_filter; else return false; @@ -265,6 +270,7 @@ public: } p_list->push_back(PropertyInfo(Variant::BOOL,"color/monochrome")); p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/round_advance")); + p_list->push_back(PropertyInfo(Variant::BOOL,"advanced/disable_filter")); } @@ -302,6 +308,7 @@ public: color_use_monochrome=false; round_advance=true; + disable_filter=false; } @@ -331,6 +338,7 @@ public: color_use_monochrome=false; round_advance=true; + disable_filter=false; } @@ -1260,6 +1268,7 @@ Ref EditorFontImportPlugin::generate_font(const Refget_option("extra_space/space"); int top_space = from->get_option("extra_space/top"); int bottom_space = from->get_option("extra_space/bottom"); + bool disable_filter = from->get_option("advanced/disable_filter"); Ref font; @@ -1279,7 +1288,12 @@ Ref EditorFontImportPlugin::generate_font(const Ref t = memnew(ImageTexture); - t->create_from_image(atlas); + int flags; + if (disable_filter) + flags=0; + else + flags=Texture::FLAG_FILTER; + t->create_from_image(atlas,flags); t->set_storage( ImageTexture::STORAGE_COMPRESS_LOSSLESS ); font->add_texture(t); diff --git a/tools/editor/io_plugins/editor_import_collada.cpp b/tools/editor/io_plugins/editor_import_collada.cpp index 9bee47ca66ea..95ee1f92e2dd 100644 --- a/tools/editor/io_plugins/editor_import_collada.cpp +++ b/tools/editor/io_plugins/editor_import_collada.cpp @@ -1829,9 +1829,9 @@ void ColladaImport::create_animation(int p_clip, bool p_make_tracks_in_all_bones if (p_clip>=0 && collada.state.animation_clips[p_clip].end) anim_length=collada.state.animation_clips[p_clip].end; - while(f=collada.state.animation_length) - f=collada.state.animation_length; + while(f=anim_length) + f=anim_length; base_snapshots.push_back(f); f+=snapshot_interval; diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.cpp b/tools/editor/io_plugins/editor_scene_import_plugin.cpp index 2482728c87bb..c2cd5ff525fb 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_scene_import_plugin.cpp @@ -40,6 +40,7 @@ #include "scene/3d/body_shape.h" #include "scene/3d/physics_body.h" #include "scene/3d/portal.h" +#include "scene/3d/vehicle_body.h" #include "os/os.h" @@ -649,9 +650,10 @@ const EditorSceneImportDialog::FlagInfo EditorSceneImportDialog::scene_flag_name {EditorSceneImportPlugin::SCENE_FLAG_CREATE_BILLBOARDS,"Create","Create Billboards (-bb)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_IMPOSTORS,"Create","Create Impostors (-imp:dist)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_LODS,"Create","Create LODs (-lod:dist)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Cars (-car)",true}, - {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Car Wheels (-wheel)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_CARS,"Create","Create Vehicles (-vehicle)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_CREATE_WHEELS,"Create","Create Vehicle Wheels (-wheel)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_NAVMESH,"Create","Create Navigation Meshes (-navmesh)",true}, + {EditorSceneImportPlugin::SCENE_FLAG_DETECT_LIGHTMAP_LAYER,"Create","Detect LightMap Layer (-lm:).",true}, {-1,NULL,NULL,false} }; @@ -1199,6 +1201,17 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map } } } + + + if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to()) { + + MeshInstance *mi = p_node->cast_to(); + + String str=name; + int layer = str.substr(str.find("lm")+3,str.length()).to_int(); + mi->set_baked_light_texture_id(layer); + } + if (p_flags&SCENE_FLAG_CREATE_COLLISIONS && _teststr(name,"colonly") && p_node->cast_to()) { if (isroot) @@ -1262,6 +1275,46 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map p_node->replace_by(nmi); memdelete(p_node); p_node=nmi; + } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"vehicle")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to(); + VehicleBody *bv = memnew( VehicleBody ); + String n = _fixstr(p_node->get_name(),"vehicle"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; + + + } else if (p_flags&SCENE_FLAG_CREATE_CARS &&_teststr(name,"wheel")) { + + if (isroot) + return p_node; + + Node *owner = p_node->get_owner(); + Spatial *s = p_node->cast_to(); + VehicleWheel *bv = memnew( VehicleWheel ); + String n = _fixstr(p_node->get_name(),"wheel"); + bv->set_name(n); + p_node->replace_by(bv); + p_node->set_name(n); + bv->add_child(p_node); + bv->set_owner(owner); + p_node->set_owner(owner); + bv->set_transform(s->get_transform()); + s->set_transform(Transform()); + + p_node=bv; } else if (p_flags&SCENE_FLAG_CREATE_ROOMS && _teststr(name,"room") && p_node->cast_to()) { diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index 3b39f0c96276..6095ecf387d7 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -125,6 +125,7 @@ public: SCENE_FLAG_DETECT_ALPHA=1<<15, SCENE_FLAG_DETECT_VCOLOR=1<<16, SCENE_FLAG_CREATE_NAVMESH=1<<17, + SCENE_FLAG_DETECT_LIGHTMAP_LAYER=1<<18, SCENE_FLAG_REMOVE_NOIMP=1<<24, SCENE_FLAG_IMPORT_ANIMATIONS=1<<25, diff --git a/tools/editor/plugins/sample_player_editor_plugin.cpp b/tools/editor/plugins/sample_player_editor_plugin.cpp index fa8a285e4eec..f3d6fe65da55 100644 --- a/tools/editor/plugins/sample_player_editor_plugin.cpp +++ b/tools/editor/plugins/sample_player_editor_plugin.cpp @@ -64,6 +64,8 @@ void SamplePlayerEditor::_play() { return; node->call("play",samples->get_item_text( samples->get_selected() )); + stop->set_pressed(false); + play->set_pressed(true); } void SamplePlayerEditor::_stop() { @@ -74,6 +76,9 @@ void SamplePlayerEditor::_stop() { return; node->call("stop_all"); + print_line("STOP ALL!!"); + stop->set_pressed(true); + play->set_pressed(false); } diff --git a/tools/editor/plugins/spatial_editor_plugin.cpp b/tools/editor/plugins/spatial_editor_plugin.cpp index a5cddc20e6a7..b87b250b223f 100644 --- a/tools/editor/plugins/spatial_editor_plugin.cpp +++ b/tools/editor/plugins/spatial_editor_plugin.cpp @@ -1925,6 +1925,15 @@ void SpatialEditorViewport::_menu_option(int p_option) { call_deferred("update_transform_gizmo_view"); } break; + case VIEW_AUDIO_LISTENER: { + + int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); + bool current = view_menu->get_popup()->is_item_checked( idx ); + current=!current; + viewport->set_as_audio_listener(current); + view_menu->get_popup()->set_item_checked( idx, current ); + + } break; } @@ -2055,6 +2064,13 @@ void SpatialEditorViewport::set_state(const Dictionary& p_state) { _menu_option(VIEW_PERSPECTIVE); if (env != camera->get_environment().is_valid()) _menu_option(VIEW_ENVIRONMENT); + if (p_state.has("listener")) { + bool listener = p_state["listener"]; + + int idx = view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER); + viewport->set_as_audio_listener(listener); + view_menu->get_popup()->set_item_checked( idx, listener ); + } } @@ -2068,6 +2084,7 @@ Dictionary SpatialEditorViewport::get_state() const { d["distance"]=cursor.distance; d["use_environment"]=camera->get_environment().is_valid(); d["use_orthogonal"]=camera->get_projection()==Camera::PROJECTION_ORTHOGONAL; + d["listener"]=viewport->is_audio_listener(); return d; } @@ -2147,6 +2164,9 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_check_item("Environment",VIEW_ENVIRONMENT); view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(VIEW_ENVIRONMENT),true); + view_menu->get_popup()->add_separator(); + view_menu->get_popup()->add_check_item("Audio Listener",VIEW_AUDIO_LISTENER); + view_menu->get_popup()->add_separator(); view_menu->get_popup()->add_item("Selection (F)",VIEW_CENTER_TO_SELECTION); view_menu->get_popup()->add_item("Align with view (Ctrl+Shift+F)",VIEW_ALIGN_SELECTION_WITH_VIEW); @@ -2163,6 +2183,12 @@ SpatialEditorViewport::SpatialEditorViewport(SpatialEditor *p_spatial_editor, Ed previewing=NULL; preview=NULL; gizmo_scale=1.0; + + if (p_index==0) { + view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(VIEW_AUDIO_LISTENER),true); + viewport->set_as_audio_listener(true); + } + EditorSettings::get_singleton()->connect("settings_changed",this,"update_transform_gizmo_view"); } @@ -3307,6 +3333,11 @@ void SpatialEditor::clear() { } } + for(int i=0;i<4;i++) { + + viewports[i]->view_menu->get_popup()->set_item_checked(view_menu->get_popup()->get_item_index(SpatialEditorViewport::VIEW_AUDIO_LISTENER),i==0); + viewports[i]->viewport->set_as_audio_listener(i==0); + } view_menu->get_popup()->set_item_checked( view_menu->get_popup()->get_item_index(MENU_VIEW_GRID), true ); diff --git a/tools/editor/plugins/spatial_editor_plugin.h b/tools/editor/plugins/spatial_editor_plugin.h index 4bbddbac58a9..0cfdbfaf470e 100644 --- a/tools/editor/plugins/spatial_editor_plugin.h +++ b/tools/editor/plugins/spatial_editor_plugin.h @@ -65,7 +65,7 @@ public: class SpatialEditorViewport : public Control { OBJ_TYPE( SpatialEditorViewport, Control ); - +friend class SpatialEditor; enum { VIEW_TOP, @@ -78,7 +78,8 @@ class SpatialEditorViewport : public Control { VIEW_ALIGN_SELECTION_WITH_VIEW, VIEW_PERSPECTIVE, VIEW_ENVIRONMENT, - VIEW_ORTHOGONAL + VIEW_ORTHOGONAL, + VIEW_AUDIO_LISTENER, }; enum { GIZMO_BASE_LAYER=25 diff --git a/tools/editor/plugins/tile_map_editor_plugin.cpp b/tools/editor/plugins/tile_map_editor_plugin.cpp index 09f26c8ca08d..a25997108b16 100644 --- a/tools/editor/plugins/tile_map_editor_plugin.cpp +++ b/tools/editor/plugins/tile_map_editor_plugin.cpp @@ -166,7 +166,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); Matrix32 xform_inv = xform.affine_inverse(); - Vector2 snap = Vector2(1,1)*node->get_cell_size(); + Vector2 snap = node->get_cell_size(); switch(p_event.type) { @@ -218,7 +218,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { if (mb.mod.shift) { tool=TOOL_SELECTING; - selection_begin =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor(); + selection_begin =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); selection.pos=selection_begin; selection.size=Point2(0,0); selection_active=true; @@ -229,7 +229,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { int id = get_selected_tile(); if (id!=TileMap::INVALID_CELL) { tool=TOOL_PAINTING; - Point2i local =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor(); + Point2i local =node->world_to_map((xform_inv.xform(Point2(mb.x,mb.y)))); paint_undo.clear(); CellOp op; op.idx = node->get_cell(local.x,local.y); @@ -278,7 +278,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { } else if (mb.pressed && tool==TOOL_NONE) { tool=TOOL_ERASING; - Point2i local =(xform_inv.xform(Point2(mb.x,mb.y))/snap).floor(); + Point2i local =node->world_to_map(xform_inv.xform(Point2(mb.x,mb.y))); paint_undo.clear(); CellOp op; op.idx = node->get_cell(local.x,local.y); @@ -322,7 +322,7 @@ bool TileMapEditor::forward_input_event(const InputEvent& p_event) { const InputEventMouseMotion &mm=p_event.mouse_motion; - Point2i new_over_tile = (xform_inv.xform(Point2(mm.x,mm.y))/snap).floor(); + Point2i new_over_tile = node->world_to_map(xform_inv.xform(Point2(mm.x,mm.y)));//(xform_inv.xform(Point2(mm.x,mm.y))/snap).floor(); if (new_over_tile!=over_tile) { over_tile=new_over_tile; @@ -469,44 +469,104 @@ void TileMapEditor::_canvas_draw() { if (!node) return; - int cell_size=node->get_cell_size(); + Size2 cell_size=node->get_cell_size(); + Matrix32 cell_xf = node->get_cell_transform(); Matrix32 xform = CanvasItemEditor::get_singleton()->get_canvas_transform() * node->get_global_transform(); Matrix32 xform_inv = xform.affine_inverse(); Size2 screen_size=canvas_item_editor->get_size(); - Rect2 aabb; - aabb.pos=xform_inv.xform(Vector2()); - aabb.expand_to(xform_inv.xform(Vector2(0,screen_size.height))); - aabb.expand_to(xform_inv.xform(Vector2(screen_size.width,0))); - aabb.expand_to(xform_inv.xform(screen_size)); - Rect2i si=aabb; + { + Rect2 aabb; + aabb.pos=node->world_to_map(xform_inv.xform(Vector2())); + aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(0,screen_size.height)))); + aabb.expand_to(node->world_to_map(xform_inv.xform(Vector2(screen_size.width,0)))); + aabb.expand_to(node->world_to_map(xform_inv.xform(screen_size))); + Rect2i si=aabb.grow(1.0); - for(int i=(si.pos.x/cell_size)-1;i<=(si.pos.x+si.size.x)/cell_size;i++) { + if (node->get_half_offset()!=TileMap::HALF_OFFSET_X) { - int ofs = i*cell_size; + for(int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { + Vector2 from = xform.xform(node->map_to_world(Vector2(i,si.pos.y))); + Vector2 to = xform.xform(node->map_to_world(Vector2(i,si.pos.y+si.size.y+1))); + + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + } + } else { + + + for(int i=(si.pos.x)-1;i<=(si.pos.x+si.size.x);i++) { + + for(int j=(si.pos.y)-1;j<=(si.pos.y+si.size.y);j++) { + + Vector2 ofs; + if (ABS(j)&1) { + ofs=cell_xf[0]*0.5; + } + + Vector2 from = xform.xform(node->map_to_world(Vector2(i,j),true)+ofs); + Vector2 to = xform.xform(node->map_to_world(Vector2(i,j+1),true)+ofs); + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + } + + } + } + + if (node->get_half_offset()!=TileMap::HALF_OFFSET_Y) { + + for(int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { + + Vector2 from = xform.xform(node->map_to_world(Vector2(si.pos.x,i))); + Vector2 to = xform.xform(node->map_to_world(Vector2(si.pos.x+si.size.x+1,i))); + + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + + } + } else { + + + for(int i=(si.pos.y)-1;i<=(si.pos.y+si.size.y);i++) { + + for(int j=(si.pos.x)-1;j<=(si.pos.x+si.size.x);j++) { + + Vector2 ofs; + if (ABS(j)&1) { + ofs=cell_xf[1]*0.5; + } + + Vector2 from = xform.xform(node->map_to_world(Vector2(j,i),true)+ofs); + Vector2 to = xform.xform(node->map_to_world(Vector2(j+1,i),true)+ofs); + Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); + canvas_item_editor->draw_line(from,to,col,1); + } + + } + + + + } +/* + for(int i=(si.pos.y/cell_size.y)-1;i<=(si.pos.y+si.size.y)/cell_size.y;i++) { + + int ofs = i*cell_size.y; Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(xform.xform(Point2(ofs,si.pos.y)),xform.xform(Point2(ofs,si.pos.y+si.size.y)),col,1); - - } - - for(int i=(si.pos.y/cell_size)-1;i<=(si.pos.y+si.size.y)/cell_size;i++) { - - int ofs = i*cell_size; - Color col=i==0?Color(1,0.8,0.2,0.5):Color(1,0.3,0.1,0.2); - canvas_item_editor->draw_line(xform.xform(Point2(si.pos.x,ofs)),xform.xform(Point2(si.pos.x+si.size.x,ofs)),col,1); + canvas_item_editor->draw_line(xform.xform(Point2(si.pos.x,ofs)),xform.xform(Point2(si.pos.x+si.size.x,ofs)),col,1);*/ } if (selection_active) { Vector points; - points.push_back( xform.xform( selection.pos * cell_size) ); - points.push_back( xform.xform( (selection.pos+Point2(selection.size.x+1,0)) * cell_size) ); - points.push_back( xform.xform( (selection.pos+Point2(selection.size.x+1,selection.size.y+1)) * cell_size) ); - points.push_back( xform.xform( (selection.pos+Point2(0,selection.size.y+1)) * cell_size) ); + points.push_back( xform.xform( node->map_to_world(( selection.pos ) ))); + points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(selection.size.x+1,0)) ) )); + points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(selection.size.x+1,selection.size.y+1)) ) )); + points.push_back( xform.xform( node->map_to_world((selection.pos+Point2(0,selection.size.y+1)) ) )); Color col=Color(0.2,0.8,1,0.4); canvas_item_editor->draw_colored_polygon(points,col); @@ -515,15 +575,22 @@ void TileMapEditor::_canvas_draw() { if (mouse_over){ - const Vector2 endpoints[4]={ - - xform.xform( over_tile * cell_size) , - xform.xform( (over_tile+Point2(1,0)) * cell_size) , - xform.xform( (over_tile+Point2(1,1)) * cell_size) , - xform.xform( (over_tile+Point2(0,1)) * cell_size) , + Vector2 endpoints[4]={ + ( node->map_to_world(over_tile,true) ) , + ( node->map_to_world((over_tile+Point2(1,0)),true ) ), + ( node->map_to_world((over_tile+Point2(1,1)),true ) ), + ( node->map_to_world((over_tile+Point2(0,1)),true ) ) }; + + for(int i=0;i<4;i++) { + if (node->get_half_offset()==TileMap::HALF_OFFSET_X && ABS(over_tile.y)&1) + endpoints[i]+=cell_xf[0]*0.5; + if (node->get_half_offset()==TileMap::HALF_OFFSET_Y && ABS(over_tile.x)&1) + endpoints[i]+=cell_xf[1]*0.5; + endpoints[i]=xform.xform(endpoints[i]); + } Color col; if (node->get_cell(over_tile.x,over_tile.y)!=TileMap::INVALID_CELL) col=Color(0.2,0.8,1.0,0.8); @@ -542,10 +609,10 @@ void TileMapEditor::_canvas_draw() { Vector points; - points.push_back( xform.xform( duplicate.pos * cell_size) ); - points.push_back( xform.xform( (duplicate.pos+Point2(duplicate.size.x+1,0)) * cell_size) ); - points.push_back( xform.xform( (duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1)) * cell_size) ); - points.push_back( xform.xform( (duplicate.pos+Point2(0,duplicate.size.y+1)) * cell_size) ); + points.push_back( xform.xform( node->map_to_world(duplicate.pos ) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,0)) ) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(duplicate.size.x+1,duplicate.size.y+1))) )); + points.push_back( xform.xform( node->map_to_world((duplicate.pos+Point2(0,duplicate.size.y+1))) )); Color col=Color(0.2,1.0,0.8,0.4); canvas_item_editor->draw_colored_polygon(points,col); @@ -562,18 +629,19 @@ void TileMapEditor::_canvas_draw() { Ref t = ts->tile_get_texture(st); if (t.is_valid()) { - Rect2 r = ts->tile_get_region(st); - Size2 sc = (endpoints[2]-endpoints[0])/cell_size; + Vector2 from = xform.xform(ts->tile_get_texture_offset(st)+node->map_to_world(over_tile)+node->get_cell_draw_offset()); + Rect2 r = ts->tile_get_region(st); + Size2 sc = xform.get_scale(); if (mirror_x->is_pressed()) sc.x*=-1.0; if (mirror_y->is_pressed()) sc.y*=-1.0; if (r==Rect2()) { - canvas_item_editor->draw_texture_rect(t,Rect2(endpoints[0],t->get_size()*sc),false,Color(1,1,1,0.5)); + canvas_item_editor->draw_texture_rect(t,Rect2(from,t->get_size()*sc),false,Color(1,1,1,0.5)); } else { - canvas_item_editor->draw_texture_rect_region(t,Rect2(endpoints[0],r.get_size()*sc),r,Color(1,1,1,0.5)); + canvas_item_editor->draw_texture_rect_region(t,Rect2(from,r.get_size()*sc),r,Color(1,1,1,0.5)); } } } diff --git a/tools/editor/plugins/tile_set_editor_plugin.cpp b/tools/editor/plugins/tile_set_editor_plugin.cpp index 6026cda4dcc3..a51caf7d54a1 100644 --- a/tools/editor/plugins/tile_set_editor_plugin.cpp +++ b/tools/editor/plugins/tile_set_editor_plugin.cpp @@ -44,6 +44,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref p_library, bool p_me Node *child = scene->get_child(i); + if (!child->cast_to()) { if (child->get_child_count()>0) { child=child->get_child(0); @@ -72,7 +73,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref p_library, bool p_me p_library->tile_set_texture(id,texture); - Vector2 phys_offset = mi->get_offset(); + Vector2 phys_offset; if (mi->is_centered()) { Size2 s; @@ -112,7 +113,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref p_library, bool p_me } - p_library->tile_set_texture_offset(id,Vector2()); + p_library->tile_set_texture_offset(id,mi->get_offset()); } } diff --git a/tools/export/blender25/io_scene_dae/__init__.py b/tools/export/blender25/io_scene_dae/__init__.py index fe8a383383b4..29fa6ed1143a 100644 --- a/tools/export/blender25/io_scene_dae/__init__.py +++ b/tools/export/blender25/io_scene_dae/__init__.py @@ -108,6 +108,11 @@ class ExportDAE(bpy.types.Operator, ExportHelper): description=("Export all actions for the first armature found in separate DAE files"), default=False, ) + use_anim_skip_noexp = BoolProperty( + name="Skip (-noexp) Actions", + description="Skip exporting of actions whose name end in (-noexp). Useful to skip control animations.", + default=True, + ) use_anim_optimize = BoolProperty( name="Optimize Keyframes", description="Remove double keyframes", diff --git a/tools/export/blender25/io_scene_dae/export_dae.py b/tools/export/blender25/io_scene_dae/export_dae.py index 867b0a00e7c9..801eb7ae4c21 100644 --- a/tools/export/blender25/io_scene_dae/export_dae.py +++ b/tools/export/blender25/io_scene_dae/export_dae.py @@ -317,6 +317,7 @@ class DaeExporter: def export_mesh(self,node,armature=None,shapename=None): + mesh = node.data if (node.data in self.mesh_cache) and shapename==None: return self.mesh_cache[mesh] @@ -475,7 +476,12 @@ class DaeExporter: self.writel(S_GEOM,3,'') float_values="" for v in vertices: - float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y) + try: + float_values+=" "+str(v.uv[uvi].x)+" "+str(v.uv[uvi].y) + except: + # I don't understand this weird multi-uv-layer API, but with this it seems to works + float_values+=" 0 0 " + self.writel(S_GEOM,4,''+float_values+'') self.writel(S_GEOM,4,'') self.writel(S_GEOM,4,'') @@ -1156,6 +1162,8 @@ class DaeExporter: for x in bpy.data.actions[:]: if x.users==0 or x in self.action_constraints: continue + if (self.config["use_anim_skip_noexp"] and x.name.endswith("-noexp")): + continue bones=[] #find bones used