mirror of
https://github.com/godotengine/godot
synced 2024-09-05 11:38:33 +00:00
Huge Amount of BugFix
-=-=-=-=-=-=-=-=-=-=- -Fixes to Collada Exporter (avoid crash situtions) -Fixed to Collada Importer (Fixed Animation Optimizer Bugs) -Fixes to RigidBody/RigidBody2D body_enter/body_exit, was buggy -Fixed ability for RigidBody/RigidBody2D to get contacts reported and bodyin/out in Kinematic mode. -Added proper trigger support for 3D Physics shapes -Changed proper value for Z-Offset in OmniLight -Fixed spot attenuation bug in SpotLight -Fixed some 3D and 2D spatial soudn bugs related to distance attenuation. -Fixed bugs in EventPlayer (channels were muted by default) -Fix in ButtonGroup (get nodes in group are now returned in order) -Fixed Linear->SRGB Conversion, previous algo sucked, new algo works OK -Changed SRGB->Linear conversion to use hardware if supported, improves texture quality a lot -Fixed options for Y-Fov and X-Fov in camera, should be more intuitive. -Fixed bugs related to viewports and transparency Huge Amount of New Stuff: -=-=-=-=-=-=-=-==-=-=-=- -Ability to manually advance an AnimationPlayer that is inactive (with advance() function) -More work in WinRT platform -Added XY normalmap support, imports on this format by default. Reduces normlmap size and enables much nice compression using LATC -Added Anisotropic filter support to textures, can be specified on import -Added support for Non-Square, Isometric and Hexagonal tilemaps in TileMap. -Added Isometric Dungeon demo. -Added simple hexagonal map demo. -Added Truck-Town demo. Shows how most types of joints and vehicles are used. Please somebody make a nicer town, this one is too hardcore. -Added an Object-Picking API to both RigidBody and Area! (and relevant demo)
This commit is contained in:
parent
870c075ebf
commit
b24fe3dd20
|
@ -856,6 +856,36 @@ Vector<int> _Geometry::triangulate_polygon(const Vector<Vector2>& p_polygon) {
|
|||
return Geometry::triangulate_polygon(p_polygon);
|
||||
}
|
||||
|
||||
Dictionary _Geometry::make_atlas(const Vector<Size2>& p_rects) {
|
||||
|
||||
Dictionary ret;
|
||||
|
||||
Vector<Size2i> rects;
|
||||
for (int i=0; i<p_rects.size(); i++) {
|
||||
|
||||
rects.push_back(p_rects[i]);
|
||||
};
|
||||
|
||||
Vector<Point2i> result;
|
||||
Size2i size;
|
||||
|
||||
Geometry::make_atlas(rects, result, size);
|
||||
|
||||
Size2 r_size = size;
|
||||
Vector<Point2> r_result;
|
||||
for (int i=0; i<result.size(); i++) {
|
||||
|
||||
r_result.push_back(result[i]);
|
||||
};
|
||||
|
||||
|
||||
ret["points"] = r_result;
|
||||
ret["size"] = r_size;
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
void _Geometry::_bind_methods() {
|
||||
|
||||
|
||||
|
@ -878,6 +908,7 @@ void _Geometry::_bind_methods() {
|
|||
|
||||
ObjectTypeDB::bind_method(_MD("triangulate_polygon","polygon"),&_Geometry::triangulate_polygon);
|
||||
|
||||
ObjectTypeDB::bind_method(_MD("make_atlas","sizes"),&_Geometry::make_atlas);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -236,6 +236,8 @@ public:
|
|||
|
||||
Vector<int> triangulate_polygon(const Vector<Vector2>& p_polygon);
|
||||
|
||||
Dictionary make_atlas(const Vector<Size2>& p_rects);
|
||||
|
||||
_Geometry();
|
||||
};
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -1004,3 +1004,134 @@ DVector<Plane> 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<Size2i>& p_rects,Vector<Point2i>& 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<p_rects.size();i++) {
|
||||
wrects[i].s=p_rects[i];
|
||||
wrects[i].idx=i;
|
||||
}
|
||||
wrects.sort();
|
||||
int widest = wrects[0].s.width;
|
||||
|
||||
Vector<_AtlasWorkRectResult> results;
|
||||
|
||||
for(int i=0;i<=12;i++) {
|
||||
|
||||
int w = 1<<i;
|
||||
int max_h=0;
|
||||
int max_w=0;
|
||||
if ( w < widest )
|
||||
continue;
|
||||
|
||||
Vector<int> hmax;
|
||||
hmax.resize(w);
|
||||
for(int j=0;j<w;j++)
|
||||
hmax[j]=0;
|
||||
|
||||
//place them
|
||||
int ofs=0;
|
||||
int limit_h=0;
|
||||
for(int j=0;j<wrects.size();j++) {
|
||||
|
||||
|
||||
if (ofs+wrects[j].s.width > w) {
|
||||
|
||||
ofs=0;
|
||||
}
|
||||
|
||||
int from_y=0;
|
||||
for(int k=0;k<wrects[j].s.width;k++) {
|
||||
|
||||
if (hmax[ofs+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<wrects[j].s.width;k++) {
|
||||
|
||||
hmax[ofs+k]=end_h;
|
||||
}
|
||||
|
||||
if (end_h > 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;i<results.size();i++) {
|
||||
|
||||
float h = nearest_power_of_2(results[i].max_h);
|
||||
float w = nearest_power_of_2(results[i].max_w);
|
||||
float aspect = h>w ? h/w : w/h;
|
||||
if (aspect < best_aspect) {
|
||||
best=i;
|
||||
best_aspect=aspect;
|
||||
}
|
||||
}
|
||||
|
||||
r_result.resize(p_rects.size());
|
||||
|
||||
for(int i=0;i<p_rects.size();i++) {
|
||||
|
||||
r_result[ results[best].result[i].idx ]=results[best].result[i].p;
|
||||
}
|
||||
|
||||
r_size=Size2(results[best].max_w,results[best].max_h );
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -826,7 +826,9 @@ public:
|
|||
static DVector<Plane> build_box_planes(const Vector3& p_extents);
|
||||
static DVector<Plane> build_cylinder_planes(float p_radius, float p_height, int p_sides, Vector3::Axis p_axis=Vector3::AXIS_Z);
|
||||
static DVector<Plane> 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<Size2i>& p_rects,Vector<Point2i>& r_result, Size2i& r_size);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -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<m_type*>(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<m_type*>(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<m_type*>(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<m_type*>(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<Matrix32*>(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<Matrix32*>(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());
|
||||
|
|
BIN
demos/3d/truck_town/car_base.scn
Normal file
BIN
demos/3d/truck_town/car_base.scn
Normal file
Binary file not shown.
BIN
demos/3d/truck_town/cement.tex
Normal file
BIN
demos/3d/truck_town/cement.tex
Normal file
Binary file not shown.
BIN
demos/3d/truck_town/crane.scn
Normal file
BIN
demos/3d/truck_town/crane.scn
Normal file
Binary file not shown.
7
demos/3d/truck_town/engine.cfg
Normal file
7
demos/3d/truck_town/engine.cfg
Normal file
|
@ -0,0 +1,7 @@
|
|||
[application]
|
||||
|
||||
main_scene="res://truck_scene.scn"
|
||||
|
||||
[rasterizer]
|
||||
|
||||
shadow_filter=3
|
69
demos/3d/truck_town/follow_camera.gd
Normal file
69
demos/3d/truck_town/follow_camera.gd
Normal file
|
@ -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)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
demos/3d/truck_town/grass.tex
Normal file
BIN
demos/3d/truck_town/grass.tex
Normal file
Binary file not shown.
BIN
demos/3d/truck_town/trailer_truck.scn
Normal file
BIN
demos/3d/truck_town/trailer_truck.scn
Normal file
Binary file not shown.
BIN
demos/3d/truck_town/truck_scene.scn
Normal file
BIN
demos/3d/truck_town/truck_scene.scn
Normal file
Binary file not shown.
BIN
demos/3d/truck_town/trucktown.scn
Normal file
BIN
demos/3d/truck_town/trucktown.scn
Normal file
Binary file not shown.
54
demos/3d/truck_town/vehicle.gd
Normal file
54
demos/3d/truck_town/vehicle.gd
Normal file
|
@ -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
|
||||
|
||||
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
162
platform/winrt/app.cpp
Normal file
162
platform/winrt/app.cpp
Normal file
|
@ -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<Platform::String^>^)
|
||||
{
|
||||
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<CoreApplicationView^, IActivatedEventArgs^>(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<CoreWindow^, VisibilityChangedEventArgs^>(this, &App::OnVisibilityChanged);
|
||||
|
||||
window->Closed +=
|
||||
ref new TypedEventHandler<CoreWindow^, CoreWindowEventArgs^>(this, &App::OnWindowClosed);
|
||||
|
||||
window->SizeChanged +=
|
||||
ref new TypedEventHandler<CoreWindow^, WindowSizeChangedEventArgs^>(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<GLsizei>(pixelSize.Width);
|
||||
mWindowHeight = static_cast<GLsizei>(pixelSize.Height);
|
||||
*/
|
||||
}
|
51
platform/winrt/app.h
Normal file
51
platform/winrt/app.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <wrl.h>
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
}
|
|
@ -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'])
|
||||
|
|
151
platform/winrt/gl_context_egl.cpp
Normal file
151
platform/winrt/gl_context_egl.cpp
Normal file
|
@ -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<IInspectable*>(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();
|
||||
};
|
||||
|
44
platform/winrt/gl_context_egl.h
Normal file
44
platform/winrt/gl_context_egl.h
Normal file
|
@ -0,0 +1,44 @@
|
|||
#ifndef CONTEXT_EGL_H
|
||||
#define CONTEXT_EGL_H
|
||||
|
||||
#include <wrl.h>
|
||||
|
||||
#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
|
||||
|
|
@ -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 <wrl.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;
|
||||
|
||||
|
||||
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<VideoMode> *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;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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 <windows.h>
|
||||
|
||||
#include "key_mapping_win.h"
|
||||
#include <windowsx.h>
|
||||
#include <io.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
|
@ -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();
|
||||
|
|
|
@ -106,9 +106,9 @@ Ref<TileSet> 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<Texture> 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<PosKey,Quadrant>::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<TileMap::PosKey,TileMap::Quadrant>::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<TileMap::PosKey,TileMap::Quadrant>::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;
|
||||
|
|
|
@ -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<TileSet> 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<int>& p_data);
|
||||
DVector<int> _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<TileSet>& p_tileset);
|
||||
Ref<TileSet> 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
|
||||
|
|
29
scene/2d/y_sort.cpp
Normal file
29
scene/2d/y_sort.cpp
Normal file
|
@ -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);
|
||||
}
|
17
scene/2d/y_sort.h
Normal file
17
scene/2d/y_sort.h
Normal file
|
@ -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
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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<Plane> 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<Plane> 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);
|
||||
}
|
||||
|
|
|
@ -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<PropertyInfo> *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=
|
||||
|
||||
|
|
|
@ -51,9 +51,10 @@ class CollisionObject : public Spatial {
|
|||
};
|
||||
|
||||
bool capture_input_on_drag;
|
||||
|
||||
bool ray_pickable;
|
||||
Vector<ShapeData> shapes;
|
||||
|
||||
void _update_pickable();
|
||||
void _update_shapes();
|
||||
|
||||
friend class CollisionShape;
|
||||
|
@ -69,7 +70,7 @@ protected:
|
|||
void _get_property_list( List<PropertyInfo> *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();
|
||||
|
|
|
@ -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 );
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ void Navigation::_navmesh_link(int p_id) {
|
|||
|
||||
List<Polygon>::Element *P=nm.polygons.push_back(Polygon());
|
||||
Polygon &p=P->get();
|
||||
p.owner=&nm;
|
||||
|
||||
Vector<int> 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<NavigationMesh>& p_mesh,const Transform& p_xform) {
|
||||
int Navigation::navmesh_create(const Ref<NavigationMesh>& 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<int,NavMesh>::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<Node>()->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);
|
||||
|
||||
|
|
|
@ -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<NavigationMesh> navmesh;
|
||||
|
@ -124,7 +129,7 @@ public:
|
|||
Vector3 get_up_vector() const;
|
||||
|
||||
//API should be as dynamic as possible
|
||||
int navmesh_create(const Ref<NavigationMesh>& p_mesh,const Transform& p_xform);
|
||||
int navmesh_create(const Ref<NavigationMesh>& 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);
|
||||
|
||||
|
|
|
@ -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<NavigationMesh>& 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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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"));
|
||||
|
||||
|
|
|
@ -180,6 +180,10 @@ void AnimationPlayer::_get_property_list( List<PropertyInfo> *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"));
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -67,6 +67,9 @@ Array ButtonGroup::_get_button_list() const {
|
|||
|
||||
List<BaseButton*> b;
|
||||
get_button_list(&b);
|
||||
|
||||
b.sort_custom<Node::Comparator>();
|
||||
|
||||
Array arr;
|
||||
arr.resize(b.size());
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -164,6 +164,9 @@ void Viewport::_parent_visibility_changed() {
|
|||
|
||||
Control *c = parent->cast_to<Control>();
|
||||
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<CollisionObject>();
|
||||
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<RID>(),0xFFFFFFFF,0xFFFFFFFF);
|
||||
ObjectID new_collider=0;
|
||||
if (col) {
|
||||
|
||||
if (result.collider) {
|
||||
|
||||
CollisionObject *co = result.collider->cast_to<CollisionObject>();
|
||||
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<Control>() && get_parent()->cast_to<Control>()->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<Control>() && get_parent()->cast_to<Control>()->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());
|
||||
|
|
|
@ -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<VisibilityNotifier2D>();
|
||||
ObjectTypeDB::register_type<VisibilityEnabler2D>();
|
||||
ObjectTypeDB::register_type<Polygon2D>();
|
||||
ObjectTypeDB::register_type<YSort>();
|
||||
|
||||
ObjectTypeDB::set_type_enabled("CollisionShape2D",false);
|
||||
ObjectTypeDB::set_type_enabled("CollisionPolygon2D",false);
|
||||
|
|
|
@ -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;i<tracks.size();i++) {
|
||||
|
||||
if (tracks[i]->type==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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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<PropertyInfo>::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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -148,8 +148,6 @@ void AreaSW::call_queries() {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
for (Map<BodyKey,BodyState>::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;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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<ConstraintSW*>& 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; }
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -217,4 +217,5 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) {
|
|||
space=NULL;
|
||||
instance_id=0;
|
||||
layer_mask=1;
|
||||
ray_pickable=true;
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -71,12 +71,13 @@ bool PhysicsDirectSpaceStateSW::intersect_ray(const Vector3& p_from, const Vecto
|
|||
real_t min_d=1e10;
|
||||
|
||||
|
||||
|
||||
for(int i=0;i<amount;i++) {
|
||||
|
||||
if (!_match_object_type_query(space->intersection_query_results[i],p_layer_mask,p_object_type_mask))
|
||||
continue;
|
||||
|
||||
if (space->intersection_query_results[i]->get_type()==CollisionObjectSW::TYPE_AREA && !(static_cast<AreaSW*>(space->intersection_query_results[i])->is_ray_pickable()))
|
||||
if (!(static_cast<AreaSW*>(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);
|
||||
|
||||
|
|
|
@ -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;i<p_iterations;i++) {
|
||||
int at_priority=1;
|
||||
|
||||
ConstraintSW *ci=p_island;
|
||||
while(ci) {
|
||||
ci->solve(p_delta);
|
||||
ci=ci->get_island_next();
|
||||
while(p_island) {
|
||||
|
||||
for(int i=0;i<p_iterations;i++) {
|
||||
|
||||
ConstraintSW *ci=p_island;
|
||||
while(ci) {
|
||||
ci->solve(p_delta);
|
||||
ci=ci->get_island_next();
|
||||
}
|
||||
}
|
||||
|
||||
at_priority++;
|
||||
|
||||
{
|
||||
ConstraintSW *ci=p_island;
|
||||
ConstraintSW *prev=NULL;
|
||||
while(ci) {
|
||||
if (ci->get_priority()<at_priority) {
|
||||
if (prev) {
|
||||
prev->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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -57,6 +57,7 @@ void register_server_types() {
|
|||
ObjectTypeDB::register_virtual_type<Physics2DShapeQueryResult>();
|
||||
ObjectTypeDB::register_type<Physics2DShapeQueryParameters>();
|
||||
|
||||
ObjectTypeDB::register_type<PhysicsShapeQueryParameters>();
|
||||
ObjectTypeDB::register_virtual_type<PhysicsDirectBodyState>();
|
||||
ObjectTypeDB::register_virtual_type<PhysicsDirectSpaceState>();
|
||||
ObjectTypeDB::register_virtual_type<PhysicsShapeQueryResult>();
|
||||
|
|
|
@ -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<RID>::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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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<CanvasItem*,CanvasItemPtrSort> sorter;
|
||||
sorter.sort(child_items,child_item_count);
|
||||
}
|
||||
|
||||
|
||||
for(int i=0;i<child_item_count;i++) {
|
||||
|
||||
if (child_items[i]->ontop)
|
||||
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;i<child_item_count;i++) {
|
||||
|
||||
for(int i=0;i<top_item_count;i++) {
|
||||
|
||||
_render_canvas_item(top_items[i],xform,p_clip_rect,opacity);
|
||||
if (!child_items[i]->ontop)
|
||||
continue;
|
||||
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity);
|
||||
}
|
||||
|
||||
#else
|
||||
for(int i=0;i<p_canvas_item->child_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());
|
||||
|
|
|
@ -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<Command*> commands;
|
||||
|
@ -460,11 +461,18 @@ class VisualServerRaster : public VisualServer {
|
|||
|
||||
const Rect2& get_rect() const;
|
||||
void clear() { for (int i=0;i<commands.size();i++) memdelete( commands[i] ); commands.clear(); clip=false; rect_dirty=true;};
|
||||
CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; }
|
||||
CanvasItem() { clip=false; E=NULL; opacity=1; self_opacity=1; blend_mode=MATERIAL_BLEND_MODE_MIX; visible=true; rect_dirty=true; custom_rect=false; ontop=true; sort_y=false;}
|
||||
~CanvasItem() { clear(); }
|
||||
};
|
||||
|
||||
|
||||
struct CanvasItemPtrSort {
|
||||
|
||||
_FORCE_INLINE_ bool operator()(const CanvasItem* p_left,const CanvasItem* p_right) const {
|
||||
|
||||
return p_left->xform.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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<NodeJoint*>(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;
|
||||
|
|
|
@ -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<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
int space_space = from->get_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> font;
|
||||
|
||||
|
@ -1279,7 +1288,12 @@ Ref<Font> EditorFontImportPlugin::generate_font(const Ref<ResourceImportMetadata
|
|||
//register texures
|
||||
{
|
||||
Ref<ImageTexture> 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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
if (f>=collada.state.animation_length)
|
||||
f=collada.state.animation_length;
|
||||
while(f<anim_length) {
|
||||
if (f>=anim_length)
|
||||
f=anim_length;
|
||||
|
||||
base_snapshots.push_back(f);
|
||||
f+=snapshot_interval;
|
||||
|
|
|
@ -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:<int>).",true},
|
||||
{-1,NULL,NULL,false}
|
||||
};
|
||||
|
||||
|
@ -1199,6 +1201,17 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (p_flags&SCENE_FLAG_DETECT_LIGHTMAP_LAYER && _teststr(name,"lm") && p_node->cast_to<MeshInstance>()) {
|
||||
|
||||
MeshInstance *mi = p_node->cast_to<MeshInstance>();
|
||||
|
||||
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<MeshInstance>()) {
|
||||
|
||||
if (isroot)
|
||||
|
@ -1262,6 +1275,46 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map<Ref<Mesh>
|
|||
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<Spatial>();
|
||||
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<Spatial>();
|
||||
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<MeshInstance>()) {
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<Vector2> 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<Vector2> 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<Texture> 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,6 +44,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> p_library, bool p_me
|
|||
|
||||
Node *child = scene->get_child(i);
|
||||
|
||||
|
||||
if (!child->cast_to<Sprite>()) {
|
||||
if (child->get_child_count()>0) {
|
||||
child=child->get_child(0);
|
||||
|
@ -72,7 +73,7 @@ void TileSetEditor::_import_scene(Node *scene, Ref<TileSet> 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<TileSet> p_library, bool p_me
|
|||
|
||||
}
|
||||
|
||||
p_library->tile_set_texture_offset(id,Vector2());
|
||||
p_library->tile_set_texture_offset(id,mi->get_offset());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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,'<source id="'+meshid+'-texcoord-'+str(uvi)+'">')
|
||||
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_array id="'+meshid+'-texcoord-'+str(uvi)+'-array" count="'+str(len(vertices)*2)+'">'+float_values+'</float_array>')
|
||||
self.writel(S_GEOM,4,'<technique_common>')
|
||||
self.writel(S_GEOM,4,'<accessor source="#'+meshid+'-texcoord-'+str(uvi)+'-array" count="'+str(len(vertices))+'" stride="2">')
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue