Merge remote-tracking branch 'upstream/master' into x11-window-management

Conflicts:
	platform/x11/detect.py
This commit is contained in:
hurikhan 2015-01-14 13:31:16 +08:00
commit 8a30feebbe
34 changed files with 1049 additions and 94 deletions

View file

@ -847,8 +847,15 @@ void ObjectTypeDB::set_type_enabled(StringName p_type,bool p_enable) {
bool ObjectTypeDB::is_type_enabled(StringName p_type) { bool ObjectTypeDB::is_type_enabled(StringName p_type) {
ERR_FAIL_COND_V(!types.has(p_type),false); TypeInfo *ti=types.getptr(p_type);
return !types[p_type].disabled; if (!ti || !ti->creation_func) {
if (compat_types.has(p_type)) {
ti=types.getptr(compat_types[p_type]);
}
}
ERR_FAIL_COND_V(!ti,false);
return !ti->disabled;
} }
StringName ObjectTypeDB::get_category(const StringName& p_node) { StringName ObjectTypeDB::get_category(const StringName& p_node) {

Binary file not shown.

View file

@ -15,6 +15,7 @@ const GRAVITY = 500.0
#consider "floor". #consider "floor".
const FLOOR_ANGLE_TOLERANCE = 40 const FLOOR_ANGLE_TOLERANCE = 40
const WALK_FORCE = 600 const WALK_FORCE = 600
const WALK_MIN_SPEED=10
const WALK_MAX_SPEED = 200 const WALK_MAX_SPEED = 200
const STOP_FORCE = 1300 const STOP_FORCE = 1300
const JUMP_SPEED = 200 const JUMP_SPEED = 200
@ -40,12 +41,12 @@ func _fixed_process(delta):
var stop=true var stop=true
if (walk_left): if (walk_left):
if (velocity.x<=0 and velocity.x > -WALK_MAX_SPEED): if (velocity.x<=WALK_MIN_SPEED and velocity.x > -WALK_MAX_SPEED):
force.x-=WALK_FORCE force.x-=WALK_FORCE
stop=false stop=false
elif (walk_right): elif (walk_right):
if (velocity.x>=0 and velocity.x < WALK_MAX_SPEED): if (velocity.x>=-WALK_MIN_SPEED and velocity.x < WALK_MAX_SPEED):
force.x+=WALK_FORCE force.x+=WALK_FORCE
stop=false stop=false

Binary file not shown.

File diff suppressed because one or more lines are too long

View file

@ -5141,6 +5141,7 @@ bool RasterizerGLES2::_setup_material(const Geometry *p_geometry,const Material
if (p_material->shader_cache->has_texscreen && framebuffer.active) { if (p_material->shader_cache->has_texscreen && framebuffer.active) {
material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(0,0,float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_TEX,texcoord); material_shader.set_uniform(MaterialShaderGLES2::TEXSCREEN_TEX,texcoord);
glActiveTexture(GL_TEXTURE0+texcoord); glActiveTexture(GL_TEXTURE0+texcoord);
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
@ -8387,11 +8388,32 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
if (shader->has_texscreen && framebuffer.active) { if (shader->has_texscreen && framebuffer.active) {
int x = viewport.x;
int y = window_size.height-(viewport.height+viewport.y);
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height)); canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_MULT,Vector2(float(viewport.width)/framebuffer.width,float(viewport.height)/framebuffer.height));
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_SCREEN_CLAMP,Color(float(x)/framebuffer.width,float(y)/framebuffer.height,float(x+viewport.width)/framebuffer.width,float(y+viewport.height)/framebuffer.height));
canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,tex_id); canvas_shader.set_uniform(CanvasShaderGLES2::TEXSCREEN_TEX,tex_id);
glActiveTexture(GL_TEXTURE0+tex_id); glActiveTexture(GL_TEXTURE0+tex_id);
glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color); glBindTexture(GL_TEXTURE_2D,framebuffer.sample_color);
if (framebuffer.scale==1 && !canvas_texscreen_used) {
#ifdef GLEW_ENABLED
glReadBuffer(GL_COLOR_ATTACHMENT0);
#endif
glCopyTexSubImage2D(GL_TEXTURE_2D,0,x,y,x,y,viewport.width,viewport.height);
if (current_clip) {
print_line(" a clip ");
}
canvas_texscreen_used=true;
}
tex_id++;
}
if (tex_id>1) {
glActiveTexture(GL_TEXTURE0);
} }
if (shader->has_screen_uv) { if (shader->has_screen_uv) {
canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height)); canvas_shader.set_uniform(CanvasShaderGLES2::SCREEN_UV_MULT,Vector2(1.0/viewport.width,1.0/viewport.height));
@ -8412,6 +8434,7 @@ void RasterizerGLES2::canvas_render_items(CanvasItem *p_item_list) {
} }
canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform); canvas_shader.set_uniform(CanvasShaderGLES2::PROJECTION_MATRIX,canvas_transform);
canvas_last_shader=shader_owner->shader; canvas_last_shader=shader_owner->shader;
} }

View file

@ -404,7 +404,7 @@ String ShaderCompilerGLES2::dump_node_code(SL::Node *p_node,int p_level,bool p_a
} else if (callfunc=="texscreen") { } else if (callfunc=="texscreen") {
//create the call to sample the screen, and clamp it //create the call to sample the screen, and clamp it
uses_texscreen=true; uses_texscreen=true;
code="(texture2D( texscreen_tex, min(("+dump_node_code(onode->arguments[1],p_level)+").xy*texscreen_screen_mult,texscreen_screen_mult))).rgb"; code="(texture2D( texscreen_tex, clamp(("+dump_node_code(onode->arguments[1],p_level)+").xy*texscreen_screen_mult,texscreen_screen_clamp.xy,texscreen_screen_clamp.zw))).rgb";
//code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb"; //code="(texture2D( screen_texture, ("+dump_node_code(onode->arguments[1],p_level)+").xy).rgb";
break; break;
} else if (callfunc=="texpos") { } else if (callfunc=="texpos") {
@ -690,6 +690,7 @@ ShaderCompilerGLES2::ShaderCompilerGLES2() {
replace_table["cross" ]="cross"; replace_table["cross" ]="cross";
replace_table["normalize"]= "normalize"; replace_table["normalize"]= "normalize";
replace_table["reflect"]= "reflect"; replace_table["reflect"]= "reflect";
replace_table["refract"]= "refract";
replace_table["tex"]= "tex"; replace_table["tex"]= "tex";
replace_table["texa"]= "texa"; replace_table["texa"]= "texa";
replace_table["tex2"]= "tex2"; replace_table["tex2"]= "tex2";

View file

@ -100,6 +100,7 @@ uniform vec2 screen_uv_mult;
#if defined(ENABLE_TEXSCREEN) #if defined(ENABLE_TEXSCREEN)
uniform vec2 texscreen_screen_mult; uniform vec2 texscreen_screen_mult;
uniform vec4 texscreen_screen_clamp;
uniform sampler2D texscreen_tex; uniform sampler2D texscreen_tex;
#endif #endif

View file

@ -779,6 +779,7 @@ uniform highp mat4 camera_inverse_transform;
#if defined(ENABLE_TEXSCREEN) #if defined(ENABLE_TEXSCREEN)
uniform vec2 texscreen_screen_mult; uniform vec2 texscreen_screen_mult;
uniform vec4 texscreen_screen_clamp;
uniform sampler2D texscreen_tex; uniform sampler2D texscreen_tex;
#endif #endif

View file

@ -1661,7 +1661,7 @@ Error GDScriptLanguage::complete_code(const String& p_code, const String& p_base
//print_line( p_code.replace(String::chr(0xFFFF),"<cursor>")); //print_line( p_code.replace(String::chr(0xFFFF),"<cursor>"));
GDParser p; GDParser p;
Error err = p.parse(p_code,p_base_path); Error err = p.parse(p_code,p_base_path,true);
bool isfunction=false; bool isfunction=false;
Set<String> options; Set<String> options;

View file

@ -205,6 +205,7 @@ Variant _jobject_to_variant(JNIEnv * env, jobject obj) {
String name = _get_class_name(env, c, &array); String name = _get_class_name(env, c, &array);
//print_line("name is " + name + ", array "+Variant(array)); //print_line("name is " + name + ", array "+Variant(array));
print_line("ARGNAME: "+name);
if (name == "java.lang.String") { if (name == "java.lang.String") {
return String::utf8(env->GetStringUTFChars( (jstring)obj, NULL )); return String::utf8(env->GetStringUTFChars( (jstring)obj, NULL ));

View file

@ -52,6 +52,7 @@ def get_opts():
return [ return [
('use_llvm','Use llvm compiler','no'), ('use_llvm','Use llvm compiler','no'),
('use_sanitizer','Use llvm compiler sanitize address','no'), ('use_sanitizer','Use llvm compiler sanitize address','no'),
('pulseaudio','Detect & Use pulseaudio','yes'),
('experimental_wm_api', 'Use experimental window management API','no'), ('experimental_wm_api', 'Use experimental window management API','no'),
] ]
@ -121,12 +122,13 @@ def configure(env):
env.Append(CPPFLAGS=['-DOPENGL_ENABLED','-DGLEW_ENABLED']) env.Append(CPPFLAGS=['-DOPENGL_ENABLED','-DGLEW_ENABLED'])
env.Append(CPPFLAGS=["-DALSA_ENABLED"]) env.Append(CPPFLAGS=["-DALSA_ENABLED"])
if not os.system("pkg-config --exists libpulse-simple"): if (env["pulseaudio"]=="yes"):
print("Enabling PulseAudio") if not os.system("pkg-config --exists libpulse-simple"):
env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"]) print("Enabling PulseAudio")
env.ParseConfig('pkg-config --cflags --libs libpulse-simple') env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"])
else: env.ParseConfig('pkg-config --cflags --libs libpulse-simple')
print("PulseAudio development libraries not found, disabling driver") else:
print("PulseAudio development libraries not found, disabling driver")
env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL']) env.Append(CPPFLAGS=['-DX11_ENABLED','-DUNIX_ENABLED','-DGLES2_ENABLED','-DGLES_OVER_GL'])
env.Append(LIBS=['GL', 'GLU', 'pthread','asound','z']) #TODO detect linux/BSD! env.Append(LIBS=['GL', 'GLU', 'pthread','asound','z']) #TODO detect linux/BSD!

View file

@ -291,13 +291,27 @@ void Node2D::set_global_transform(const Matrix32& p_transform) {
void Node2D::set_z(int p_z) { void Node2D::set_z(int p_z) {
ERR_FAIL_COND(p_z<-VS::CANVAS_ITEM_Z_DEFAULT); ERR_FAIL_COND(p_z<VS::CANVAS_ITEM_Z_MIN);
ERR_FAIL_COND(p_z>=VS::CANVAS_ITEM_Z_DEFAULT); ERR_FAIL_COND(p_z>VS::CANVAS_ITEM_Z_MAX);
z=p_z; z=p_z;
VS::get_singleton()->canvas_item_set_z(get_canvas_item(),z+VS::CANVAS_ITEM_Z_DEFAULT); VS::get_singleton()->canvas_item_set_z(get_canvas_item(),z);
} }
void Node2D::set_z_as_relative(bool p_enabled) {
if (z_relative==p_enabled)
return;
z_relative=p_enabled;
VS::get_singleton()->canvas_item_set_z_as_relative_to_parent(get_canvas_item(),p_enabled);
}
bool Node2D::is_z_relative() const {
return z_relative;
}
int Node2D::get_z() const{ int Node2D::get_z() const{
return z; return z;
@ -332,13 +346,16 @@ void Node2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_z","z"),&Node2D::set_z); ObjectTypeDB::bind_method(_MD("set_z","z"),&Node2D::set_z);
ObjectTypeDB::bind_method(_MD("get_z"),&Node2D::get_z); ObjectTypeDB::bind_method(_MD("get_z"),&Node2D::get_z);
ObjectTypeDB::bind_method(_MD("set_z_as_relative","enable"),&Node2D::set_z_as_relative);
ObjectTypeDB::bind_method(_MD("is_z_relative"),&Node2D::is_z_relative);
ObjectTypeDB::bind_method(_MD("edit_set_pivot"),&Node2D::edit_set_pivot); ObjectTypeDB::bind_method(_MD("edit_set_pivot"),&Node2D::edit_set_pivot);
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos")); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/pos"),_SCS("set_pos"),_SCS("get_pos"));
ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd")); ADD_PROPERTY(PropertyInfo(Variant::REAL,"transform/rot",PROPERTY_HINT_RANGE,"-1440,1440,0.1"),_SCS("_set_rotd"),_SCS("_get_rotd"));
ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale")); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"transform/scale"),_SCS("set_scale"),_SCS("get_scale"));
ADD_PROPERTY(PropertyInfo(Variant::INT,"visibility/z",PROPERTY_HINT_RANGE,"-512,511,1"),_SCS("set_z"),_SCS("get_z")); ADD_PROPERTY(PropertyInfo(Variant::INT,"z/z",PROPERTY_HINT_RANGE,itos(VS::CANVAS_ITEM_Z_MIN)+","+itos(VS::CANVAS_ITEM_Z_MAX)+",1"),_SCS("set_z"),_SCS("get_z"));
ADD_PROPERTY(PropertyInfo(Variant::BOOL,"z/relative"),_SCS("set_z_as_relative"),_SCS("is_z_relative"));
} }
@ -351,6 +368,7 @@ Node2D::Node2D() {
scale=Vector2(1,1); scale=Vector2(1,1);
_xform_dirty=false; _xform_dirty=false;
z=0; z=0;
z_relative=true;
} }

View file

@ -39,6 +39,7 @@ class Node2D : public CanvasItem {
float angle; float angle;
Size2 scale; Size2 scale;
int z; int z;
bool z_relative;
Matrix32 _mat; Matrix32 _mat;
@ -89,6 +90,8 @@ public:
void set_z(int p_z); void set_z(int p_z);
int get_z() const; int get_z() const;
void set_z_as_relative(bool p_enabled);
bool is_z_relative() const;
Matrix32 get_transform() const; Matrix32 get_transform() const;

View file

@ -43,13 +43,44 @@ void PhysicsBody2D::_notification(int p_what) {
*/ */
} }
void PhysicsBody2D::set_one_way_collision_direction(const Vector2& p_dir) {
one_way_collision_direction=p_dir;
Physics2DServer::get_singleton()->body_set_one_way_collision_direction(get_rid(),p_dir);
}
Vector2 PhysicsBody2D::get_one_way_collision_direction() const{
return one_way_collision_direction;
}
void PhysicsBody2D::set_one_way_collision_max_depth(float p_depth) {
one_way_collision_max_depth=p_depth;
Physics2DServer::get_singleton()->body_set_one_way_collision_max_depth(get_rid(),p_depth);
}
float PhysicsBody2D::get_one_way_collision_max_depth() const{
return one_way_collision_max_depth;
}
void PhysicsBody2D::_bind_methods() { void PhysicsBody2D::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_direction","dir"),&PhysicsBody2D::set_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_direction"),&PhysicsBody2D::get_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("set_one_way_collision_max_depth","depth"),&PhysicsBody2D::set_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("get_one_way_collision_max_depth"),&PhysicsBody2D::get_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with); ObjectTypeDB::bind_method(_MD("add_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::add_collision_exception_with);
ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with); ObjectTypeDB::bind_method(_MD("remove_collision_exception_with","body:PhysicsBody2D"),&PhysicsBody2D::remove_collision_exception_with);
ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask"));
ADD_PROPERTYNZ(PropertyInfo(Variant::VECTOR2,"one_way_collision/direction"),_SCS("set_one_way_collision_direction"),_SCS("get_one_way_collision_direction"));
ADD_PROPERTYNZ(PropertyInfo(Variant::REAL,"one_way_collision/max_depth"),_SCS("set_one_way_collision_max_depth"),_SCS("get_one_way_collision_max_depth"));
} }
void PhysicsBody2D::set_layer_mask(uint32_t p_mask) { void PhysicsBody2D::set_layer_mask(uint32_t p_mask) {
@ -66,6 +97,7 @@ uint32_t PhysicsBody2D::get_layer_mask() const {
PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) {
mask=1; mask=1;
set_one_way_collision_max_depth(0);
} }
@ -932,7 +964,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
//if (d<margin) //if (d<margin)
/// continue; /// continue;
recover_motion+=(b-a)*0.2; recover_motion+=(b-a)*0.4;
} }
if (recover_motion==Vector2()) { if (recover_motion==Vector2()) {
@ -963,6 +995,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask); bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,get_layer_mask(),mask);
//print_line("shape: "+itos(i)+" travel:"+rtos(ltravel)); //print_line("shape: "+itos(i)+" travel:"+rtos(ltravel));
if (!valid) { if (!valid) {
safe=0; safe=0;
unsafe=0; unsafe=0;
best_shape=i; //sadly it's the best best_shape=i; //sadly it's the best
@ -994,9 +1027,11 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask); bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,get_layer_mask(),mask);
if (!c2) { if (!c2) {
//should not happen, but floating point precision is so weird.. //should not happen, but floating point precision is so weird..
colliding=false; colliding=false;
} else { } else {
//print_line("Travel: "+rtos(travel)); //print_line("Travel: "+rtos(travel));
colliding=true; colliding=true;
collision=rest_info.point; collision=rest_info.point;

View file

@ -39,6 +39,8 @@ class PhysicsBody2D : public CollisionObject2D {
OBJ_TYPE(PhysicsBody2D,CollisionObject2D); OBJ_TYPE(PhysicsBody2D,CollisionObject2D);
uint32_t mask; uint32_t mask;
Vector2 one_way_collision_direction;
float one_way_collision_max_depth;
protected: protected:
void _notification(int p_what); void _notification(int p_what);
@ -53,6 +55,12 @@ public:
void add_collision_exception_with(Node* p_node); //must be physicsbody void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node); void remove_collision_exception_with(Node* p_node);
void set_one_way_collision_direction(const Vector2& p_dir);
Vector2 get_one_way_collision_direction() const;
void set_one_way_collision_max_depth(float p_dir);
float get_one_way_collision_max_depth() const;
PhysicsBody2D(); PhysicsBody2D();
}; };

View file

@ -92,6 +92,7 @@ void PhysicsBody::remove_collision_exception_with(Node* p_node) {
PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(),physics_body->get_rid()); PhysicsServer::get_singleton()->body_remove_collision_exception(get_rid(),physics_body->get_rid());
} }
void PhysicsBody::_bind_methods() { void PhysicsBody::_bind_methods() {
ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody::set_layer_mask); ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody::set_layer_mask);
ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody::get_layer_mask); ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody::get_layer_mask);

View file

@ -56,6 +56,8 @@ public:
void add_collision_exception_with(Node* p_node); //must be physicsbody void add_collision_exception_with(Node* p_node); //must be physicsbody
void remove_collision_exception_with(Node* p_node); void remove_collision_exception_with(Node* p_node);
PhysicsBody(); PhysicsBody();
}; };

View file

@ -298,7 +298,7 @@ void TextEdit::_update_scrollbars() {
int hscroll_rows = ((hmin.height-1)/get_row_height())+1; int hscroll_rows = ((hmin.height-1)/get_row_height())+1;
int visible_rows = get_visible_rows(); int visible_rows = get_visible_rows();
int total_rows = text.size() * cache.line_spacing; int total_rows = text.size();
int vscroll_pixels = v_scroll->get_combined_minimum_size().width; int vscroll_pixels = v_scroll->get_combined_minimum_size().width;
int visible_width = size.width - cache.style_normal->get_minimum_size().width; int visible_width = size.width - cache.style_normal->get_minimum_size().width;

View file

@ -272,7 +272,7 @@ void register_scene_types() {
ObjectTypeDB::register_type<Control>(); ObjectTypeDB::register_type<Control>();
// ObjectTypeDB::register_type<EmptyControl>(); // ObjectTypeDB::register_type<EmptyControl>();
ObjectTypeDB::add_compatibility_type("EmptyControl","control"); ObjectTypeDB::add_compatibility_type("EmptyControl","Control");
ObjectTypeDB::register_type<Button>(); ObjectTypeDB::register_type<Button>();
ObjectTypeDB::register_type<Label>(); ObjectTypeDB::register_type<Label>();
ObjectTypeDB::register_type<HScrollBar>(); ObjectTypeDB::register_type<HScrollBar>();

View file

@ -647,6 +647,7 @@ Body2DSW::Body2DSW() : CollisionObject2DSW(TYPE_BODY), active_list(this), inerti
area_linear_damp=0; area_linear_damp=0;
contact_count=0; contact_count=0;
gravity_scale=1.0; gravity_scale=1.0;
one_way_collision_max_depth=0.1;
still_time=0; still_time=0;
continuous_cd_mode=Physics2DServer::CCD_MODE_DISABLED; continuous_cd_mode=Physics2DServer::CCD_MODE_DISABLED;

View file

@ -67,6 +67,9 @@ class Body2DSW : public CollisionObject2DSW {
Vector2 applied_force; Vector2 applied_force;
real_t applied_torque; real_t applied_torque;
Vector2 one_way_collision_direction;
float one_way_collision_max_depth;
SelfList<Body2DSW> active_list; SelfList<Body2DSW> active_list;
SelfList<Body2DSW> inertia_update_list; SelfList<Body2DSW> inertia_update_list;
@ -216,6 +219,12 @@ public:
_FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode=p_mode; } _FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode=p_mode; }
_FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; } _FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; }
void set_one_way_collision_direction(const Vector2& p_dir) { one_way_collision_direction=p_dir; }
Vector2 get_one_way_collision_direction() const { return one_way_collision_direction; }
void set_one_way_collision_max_depth(float p_depth) { one_way_collision_max_depth=p_depth; }
float get_one_way_collision_max_depth() const { return one_way_collision_max_depth; }
void set_space(Space2DSW *p_space); void set_space(Space2DSW *p_space);
void update_inertias(); void update_inertias();

View file

@ -138,6 +138,21 @@ void Physics2DServerSW::_shape_col_cbk(const Vector2& p_point_A,const Vector2& p
if (cbk->max==0) if (cbk->max==0)
return; return;
if (cbk->valid_dir!=Vector2()) {
if (p_point_A.distance_squared_to(p_point_B)>cbk->valid_depth*cbk->valid_depth) {
return;
}
if (cbk->valid_dir.dot((p_point_A-p_point_B).normalized())<0.7071) {
/* print_line("A: "+p_point_A);
print_line("B: "+p_point_B);
print_line("discard too angled "+rtos(cbk->valid_dir.dot((p_point_A-p_point_B))));
print_line("resnorm: "+(p_point_A-p_point_B).normalized());
print_line("distance: "+rtos(p_point_A.distance_to(p_point_B)));
*/
return;
}
}
if (cbk->amount == cbk->max) { if (cbk->amount == cbk->max) {
//find least deep //find least deep
float min_depth=1e20; float min_depth=1e20;
@ -860,6 +875,37 @@ int Physics2DServerSW::body_get_max_contacts_reported(RID p_body) const {
return body->get_max_contacts_reported(); return body->get_max_contacts_reported();
} }
void Physics2DServerSW::body_set_one_way_collision_direction(RID p_body,const Vector2& p_direction) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
body->set_one_way_collision_direction(p_direction);
}
Vector2 Physics2DServerSW::body_get_one_way_collision_direction(RID p_body) const{
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body,Vector2());
return body->get_one_way_collision_direction();
}
void Physics2DServerSW::body_set_one_way_collision_max_depth(RID p_body,float p_max_depth) {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND(!body);
body->set_one_way_collision_max_depth(p_max_depth);
}
float Physics2DServerSW::body_get_one_way_collision_max_depth(RID p_body) const {
Body2DSW *body = body_owner.get(p_body);
ERR_FAIL_COND_V(!body,0);
return body->get_one_way_collision_max_depth();
}
void Physics2DServerSW::body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata) { void Physics2DServerSW::body_set_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata) {

View file

@ -71,6 +71,8 @@ public:
struct CollCbkData { struct CollCbkData {
Vector2 valid_dir;
float valid_depth;
int max; int max;
int amount; int amount;
Vector2 *ptr; Vector2 *ptr;
@ -205,6 +207,13 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts); virtual void body_set_max_contacts_reported(RID p_body, int p_contacts);
virtual int body_get_max_contacts_reported(RID p_body) const; virtual int body_get_max_contacts_reported(RID p_body) const;
virtual void body_set_one_way_collision_direction(RID p_body,const Vector2& p_direction);
virtual Vector2 body_get_one_way_collision_direction(RID p_body) const;
virtual void body_set_one_way_collision_max_depth(RID p_body,float p_max_depth);
virtual float body_get_one_way_collision_max_depth(RID p_body) const;
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_force_integration_callback(RID p_body,Object *p_receiver,const StringName& p_method,const Variant& p_udata=Variant());
virtual bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count); virtual bool body_collide_shape(RID p_body, int p_body_shape,RID p_shape, const Matrix32& p_shape_xform,const Vector2& p_motion,Vector2 *r_results,int p_result_max,int &r_result_count);

View file

@ -98,7 +98,7 @@ bool Physics2DDirectSpaceStateSW::intersect_ray(const Vector2& p_from, const Vec
if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) { if (shape->intersect_segment(local_from,local_to,shape_point,shape_normal)) {
//print_line("inters sgment!");
Matrix32 xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); Matrix32 xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
shape_point=xform.xform(shape_point); shape_point=xform.xform(shape_point);
@ -217,6 +217,16 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32
int shape_idx=space->intersection_query_subindex_results[i]; int shape_idx=space->intersection_query_subindex_results[i];
/*if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
if (body->get_one_way_collision_direction()!=Vector2() && p_motion.dot(body->get_one_way_collision_direction())<=CMP_EPSILON) {
print_line("failed in motion dir");
continue;
}
}*/
Matrix32 col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx); Matrix32 col_obj_xform = col_obj->get_transform() * col_obj->get_shape_transform(shape_idx);
//test initial overlap, does it collide if going all the way? //test initial overlap, does it collide if going all the way?
if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) { if (!CollisionSolver2DSW::solve(shape,p_xform,p_motion,col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) {
@ -227,6 +237,14 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32
//test initial overlap //test initial overlap
if (CollisionSolver2DSW::solve(shape,p_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) { if (CollisionSolver2DSW::solve(shape,p_xform,Vector2(),col_obj->get_shape(shape_idx),col_obj_xform,Vector2() ,NULL,NULL,NULL,p_margin)) {
if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
//if one way collision direction ignore initial overlap
const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
if (body->get_one_way_collision_direction()!=Vector2()) {
continue;
}
}
return false; return false;
} }
@ -253,6 +271,29 @@ bool Physics2DDirectSpaceStateSW::cast_motion(const RID& p_shape, const Matrix32
} }
} }
if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
if (body->get_one_way_collision_direction()!=Vector2()) {
Vector2 cd[2];
Physics2DServerSW::CollCbkData cbk;
cbk.max=1;
cbk.amount=0;
cbk.ptr=cd;
cbk.valid_dir=body->get_one_way_collision_direction();
cbk.valid_depth=body->get_one_way_collision_max_depth();
Vector2 sep=mnormal; //important optimization for this to work fast enough
bool collided = CollisionSolver2DSW::solve(shape,p_xform,p_motion*(hi+space->contact_max_allowed_penetration),col_obj->get_shape(shape_idx),col_obj_xform,Vector2(),Physics2DServerSW::_shape_col_cbk,&cbk,&sep,p_margin);
if (!collided || cbk.amount==0) {
continue;
}
}
}
if (low<best_safe) { if (low<best_safe) {
best_safe=low; best_safe=low;
best_unsafe=hi; best_unsafe=hi;
@ -311,14 +352,23 @@ bool Physics2DDirectSpaceStateSW::collide_shape(RID p_shape, const Matrix32& p_s
if (p_exclude.has( col_obj->get_self() )) if (p_exclude.has( col_obj->get_self() ))
continue; continue;
if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
cbk.valid_dir=body->get_one_way_collision_direction();
cbk.valid_depth=body->get_one_way_collision_max_depth();
} else {
cbk.valid_dir=Vector2();
cbk.valid_depth=0;
}
if (CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),cbkres,cbkptr,NULL,p_margin)) { if (CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2(),cbkres,cbkptr,NULL,p_margin)) {
collided=true; collided=p_result_max==0 || cbk.amount>0;
} }
} }
r_result_count=cbk.amount; r_result_count=cbk.amount;
return collided; return collided;
@ -334,6 +384,8 @@ struct _RestCallbackData2D {
Vector2 best_contact; Vector2 best_contact;
Vector2 best_normal; Vector2 best_normal;
float best_len; float best_len;
Vector2 valid_dir;
float valid_depth;
}; };
static void _rest_cbk_result(const Vector2& p_point_A,const Vector2& p_point_B,void *p_userdata) { static void _rest_cbk_result(const Vector2& p_point_A,const Vector2& p_point_B,void *p_userdata) {
@ -341,11 +393,23 @@ static void _rest_cbk_result(const Vector2& p_point_A,const Vector2& p_point_B,v
_RestCallbackData2D *rd=(_RestCallbackData2D*)p_userdata; _RestCallbackData2D *rd=(_RestCallbackData2D*)p_userdata;
if (rd->valid_dir!=Vector2()) {
if (rd->valid_dir!=Vector2()) {
if (p_point_A.distance_squared_to(p_point_B)>rd->valid_depth*rd->valid_depth)
return;
if (rd->valid_dir.dot((p_point_A-p_point_B).normalized())<Math_PI*0.25)
return;
}
}
Vector2 contact_rel = p_point_B - p_point_A; Vector2 contact_rel = p_point_B - p_point_A;
float len = contact_rel.length(); float len = contact_rel.length();
if (len <= rd->best_len) if (len <= rd->best_len)
return; return;
rd->best_len=len; rd->best_len=len;
rd->best_contact=p_point_B; rd->best_contact=p_point_B;
rd->best_normal=contact_rel/len; rd->best_normal=contact_rel/len;
@ -385,6 +449,17 @@ bool Physics2DDirectSpaceStateSW::rest_info(RID p_shape, const Matrix32& p_shape
if (p_exclude.has( col_obj->get_self() )) if (p_exclude.has( col_obj->get_self() ))
continue; continue;
if (col_obj->get_type()==CollisionObject2DSW::TYPE_BODY) {
const Body2DSW *body=static_cast<const Body2DSW*>(col_obj);
rcd.valid_dir=body->get_one_way_collision_direction();
rcd.valid_depth=body->get_one_way_collision_max_depth();
} else {
rcd.valid_dir=Vector2();
rcd.valid_depth=0;
}
rcd.object=col_obj; rcd.object=col_obj;
rcd.shape=shape_idx; rcd.shape=shape_idx;
bool sc = CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2() ,_rest_cbk_result,&rcd,NULL,p_margin); bool sc = CollisionSolver2DSW::solve(shape,p_shape_xform,p_motion,col_obj->get_shape(shape_idx),col_obj->get_transform() * col_obj->get_shape_transform(shape_idx),Vector2() ,_rest_cbk_result,&rcd,NULL,p_margin);

View file

@ -500,6 +500,13 @@ void Physics2DServer::_bind_methods() {
ObjectTypeDB::bind_method(_MD("body_set_max_contacts_reported","body","amount"),&Physics2DServer::body_set_max_contacts_reported); ObjectTypeDB::bind_method(_MD("body_set_max_contacts_reported","body","amount"),&Physics2DServer::body_set_max_contacts_reported);
ObjectTypeDB::bind_method(_MD("body_get_max_contacts_reported","body"),&Physics2DServer::body_get_max_contacts_reported); ObjectTypeDB::bind_method(_MD("body_get_max_contacts_reported","body"),&Physics2DServer::body_get_max_contacts_reported);
ObjectTypeDB::bind_method(_MD("body_set_one_way_collision_direction","normal"),&Physics2DServer::body_set_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("body_get_one_way_collision_direction"),&Physics2DServer::body_get_one_way_collision_direction);
ObjectTypeDB::bind_method(_MD("body_set_one_way_collision_max_depth","normal"),&Physics2DServer::body_set_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("body_get_one_way_collision_max_depth"),&Physics2DServer::body_get_one_way_collision_max_depth);
ObjectTypeDB::bind_method(_MD("body_set_omit_force_integration","body","enable"),&Physics2DServer::body_set_omit_force_integration); ObjectTypeDB::bind_method(_MD("body_set_omit_force_integration","body","enable"),&Physics2DServer::body_set_omit_force_integration);
ObjectTypeDB::bind_method(_MD("body_is_omitting_force_integration","body"),&Physics2DServer::body_is_omitting_force_integration); ObjectTypeDB::bind_method(_MD("body_is_omitting_force_integration","body"),&Physics2DServer::body_is_omitting_force_integration);

View file

@ -442,6 +442,12 @@ public:
virtual void body_set_max_contacts_reported(RID p_body, int p_contacts)=0; virtual void body_set_max_contacts_reported(RID p_body, int p_contacts)=0;
virtual int body_get_max_contacts_reported(RID p_body) const=0; virtual int body_get_max_contacts_reported(RID p_body) const=0;
virtual void body_set_one_way_collision_direction(RID p_body,const Vector2& p_direction)=0;
virtual Vector2 body_get_one_way_collision_direction(RID p_body) const=0;
virtual void body_set_one_way_collision_max_depth(RID p_body,float p_max_depth)=0;
virtual float body_get_one_way_collision_max_depth(RID p_body) const=0;
//missing remove //missing remove
virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold)=0; virtual void body_set_contacts_reported_depth_treshold(RID p_body, float p_treshold)=0;
virtual float body_get_contacts_reported_depth_treshold(RID p_body) const=0; virtual float body_get_contacts_reported_depth_treshold(RID p_body) const=0;

View file

@ -900,6 +900,7 @@ const ShaderLanguage::IntrinsicFuncDef ShaderLanguage::intrinsic_func_defs[]={
{"normalize",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}}, {"normalize",TYPE_VEC3,{TYPE_VEC3,TYPE_VOID}},
{"normalize",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}}, {"normalize",TYPE_VEC4,{TYPE_VEC4,TYPE_VOID}},
{"reflect",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}}, {"reflect",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_VOID}},
{"refract",TYPE_VEC3,{TYPE_VEC3,TYPE_VEC3,TYPE_FLOAT,TYPE_VOID}},
//intrinsics - texture //intrinsics - texture
{"tex",TYPE_VEC4,{TYPE_TEXTURE,TYPE_VEC2,TYPE_VOID}}, {"tex",TYPE_VEC4,{TYPE_TEXTURE,TYPE_VEC2,TYPE_VOID}},
{"texcube",TYPE_VEC4,{TYPE_CUBEMAP,TYPE_VEC3,TYPE_VOID}}, {"texcube",TYPE_VEC4,{TYPE_CUBEMAP,TYPE_VEC3,TYPE_VOID}},

View file

@ -3691,7 +3691,7 @@ void VisualServerRaster::canvas_item_add_set_blend_mode(RID p_item, MaterialBlen
void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) { void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) {
ERR_FAIL_COND(p_z<0 || p_z>=CANVAS_ITEM_Z_MAX); ERR_FAIL_COND(p_z<CANVAS_ITEM_Z_MIN || p_z>CANVAS_ITEM_Z_MAX);
VS_CHANGED; VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item ); CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item); ERR_FAIL_COND(!canvas_item);
@ -3699,6 +3699,15 @@ void VisualServerRaster::canvas_item_set_z(RID p_item, int p_z) {
} }
void VisualServerRaster::canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable) {
VS_CHANGED;
CanvasItem *canvas_item = canvas_item_owner.get( p_item );
ERR_FAIL_COND(!canvas_item);
canvas_item->z_relative=p_enable;
}
void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) { void VisualServerRaster::canvas_item_set_use_parent_shader(RID p_item, bool p_enable) {
VS_CHANGED; VS_CHANGED;
@ -6139,18 +6148,20 @@ void VisualServerRaster::_render_camera(Viewport *p_viewport,Camera *p_camera, S
void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) { void VisualServerRaster::_render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect) {
Rasterizer::CanvasItem *z_list[CANVAS_ITEM_Z_MAX];
Rasterizer::CanvasItem *z_last_list[CANVAS_ITEM_Z_MAX];
for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) { static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1;
Rasterizer::CanvasItem *z_list[z_range];
Rasterizer::CanvasItem *z_last_list[z_range];
for(int i=0;i<z_range;i++) {
z_list[i]=NULL; z_list[i]=NULL;
z_last_list[i]=NULL; z_last_list[i]=NULL;
} }
_render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,z_list,z_last_list,NULL,NULL); _render_canvas_item(p_canvas_item,p_transform,p_clip_rect,1.0,0,z_list,z_last_list,NULL,NULL);
for(int i=0;i<CANVAS_ITEM_Z_MAX;i++) { for(int i=0;i<z_range;i++) {
if (!z_list[i]) if (!z_list[i])
continue; continue;
rasterizer->canvas_render_items(z_list[i]); rasterizer->canvas_render_items(z_list[i]);
@ -6168,7 +6179,7 @@ void VisualServerRaster::_render_canvas_item_viewport(VisualServer* p_self,void
} }
void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) { void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner) {
CanvasItem *ci = p_canvas_item; CanvasItem *ci = p_canvas_item;
@ -6247,7 +6258,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (child_items[i]->ontop) if (child_items[i]->ontop)
continue; continue;
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
} }
@ -6256,13 +6267,20 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
ci->final_transform=xform; ci->final_transform=xform;
ci->final_opacity=opacity * ci->self_opacity; ci->final_opacity=opacity * ci->self_opacity;
if (z_last_list[ci->z]) { if (ci->z_relative)
z_last_list[ci->z]->next=ci; p_z=CLAMP(p_z+ci->z,CANVAS_ITEM_Z_MIN,CANVAS_ITEM_Z_MAX);
z_last_list[ci->z]=ci; else
p_z=ci->z;
int zidx = p_z-CANVAS_ITEM_Z_MIN;
if (z_last_list[zidx]) {
z_last_list[zidx]->next=ci;
z_last_list[zidx]=ci;
} else { } else {
z_list[ci->z]=ci; z_list[zidx]=ci;
z_last_list[ci->z]=ci; z_last_list[zidx]=ci;
} }
ci->next=NULL; ci->next=NULL;
@ -6273,7 +6291,7 @@ void VisualServerRaster::_render_canvas_item(CanvasItem *p_canvas_item,const Mat
if (!child_items[i]->ontop) if (!child_items[i]->ontop)
continue; continue;
_render_canvas_item(child_items[i],xform,p_clip_rect,opacity,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner); _render_canvas_item(child_items[i],xform,p_clip_rect,opacity,p_z,z_list,z_last_list,(CanvasItem*)ci->final_clip_owner,p_shader_owner);
} }
} }
@ -6282,31 +6300,62 @@ void VisualServerRaster::_render_canvas(Canvas *p_canvas,const Matrix32 &p_trans
rasterizer->canvas_begin(); rasterizer->canvas_begin();
int l = p_canvas->child_items.size(); int l = p_canvas->child_items.size();
Canvas::ChildItem *ci=p_canvas->child_items.ptr();
bool has_mirror=false;
for(int i=0;i<l;i++) { for(int i=0;i<l;i++) {
if (ci[i].mirror.x || ci[i].mirror.y) {
Canvas::ChildItem& ci=p_canvas->child_items[i]; has_mirror=true;
_render_canvas_item_tree(ci.item,p_transform,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height)); break;
//mirroring (useful for scrolling backgrounds)
if (ci.mirror.x!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
} }
if (ci.mirror.y!=0) { }
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y)); Rect2 clip_rect(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height);
_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height)); if (!has_mirror) {
static const int z_range = CANVAS_ITEM_Z_MAX-CANVAS_ITEM_Z_MIN+1;
Rasterizer::CanvasItem *z_list[z_range];
Rasterizer::CanvasItem *z_last_list[z_range];
for(int i=0;i<z_range;i++) {
z_list[i]=NULL;
z_last_list[i]=NULL;
} }
if (ci.mirror.y!=0 && ci.mirror.x!=0) { for(int i=0;i<l;i++) {
_render_canvas_item(ci[i].item,p_transform,clip_rect,1.0,0,z_list,z_last_list,NULL,NULL);
Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
_render_canvas_item_tree(ci.item,xform2,Rect2(viewport_rect.x,viewport_rect.y,viewport_rect.width,viewport_rect.height));
} }
for(int i=0;i<z_range;i++) {
if (!z_list[i])
continue;
rasterizer->canvas_render_items(z_list[i]);
}
} else {
for(int i=0;i<l;i++) {
Canvas::ChildItem& ci=p_canvas->child_items[i];
_render_canvas_item_tree(ci.item,p_transform,clip_rect);
//mirroring (useful for scrolling backgrounds)
if (ci.mirror.x!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(ci.mirror.x,0));
_render_canvas_item_tree(ci.item,xform2,clip_rect);
}
if (ci.mirror.y!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,Vector2(0,ci.mirror.y));
_render_canvas_item_tree(ci.item,xform2,clip_rect);
}
if (ci.mirror.y!=0 && ci.mirror.x!=0) {
Matrix32 xform2 = p_transform * Matrix32(0,ci.mirror);
_render_canvas_item_tree(ci.item,xform2,clip_rect);
}
}
} }
} }

View file

@ -380,6 +380,7 @@ class VisualServerRaster : public VisualServer {
List<CanvasItem*>::Element *E; List<CanvasItem*>::Element *E;
RID viewport; RID viewport;
int z; int z;
bool z_relative;
bool sort_y; bool sort_y;
float opacity; float opacity;
float self_opacity; float self_opacity;
@ -391,11 +392,12 @@ class VisualServerRaster : public VisualServer {
CanvasItem() { CanvasItem() {
E=NULL; E=NULL;
z=CANVAS_ITEM_Z_MAX/2; z=0;
opacity=1; opacity=1;
self_opacity=1; self_opacity=1;
sort_y=false; sort_y=false;
use_parent_shader=false; use_parent_shader=false;
z_relative=true;
} }
}; };
@ -600,7 +602,7 @@ class VisualServerRaster : public VisualServer {
void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario); void _render_camera(Viewport *p_viewport,Camera *p_camera, Scenario *p_scenario);
static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect); static void _render_canvas_item_viewport(VisualServer* p_self,void *p_vp,const Rect2& p_rect);
void _render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect); void _render_canvas_item_tree(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect);
void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect,float p_opacity,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner); void _render_canvas_item(CanvasItem *p_canvas_item,const Matrix32& p_transform,const Rect2& p_clip_rect, float p_opacity,int p_z,Rasterizer::CanvasItem **z_list,Rasterizer::CanvasItem **z_last_list,CanvasItem *p_canvas_clip,CanvasItem *p_shader_owner);
void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform); void _render_canvas(Canvas *p_canvas,const Matrix32 &p_transform);
Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); Vector<Vector3> _camera_generate_endpoints(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max); Vector<Plane> _camera_generate_orthogonal_planes(Instance *p_light,Camera *p_camera,float p_range_min, float p_range_max);
@ -1112,6 +1114,7 @@ public:
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore); 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_set_sort_children_by_y(RID p_item, bool p_enable);
virtual void canvas_item_set_z(RID p_item, int p_z); virtual void canvas_item_set_z(RID p_item, int p_z);
virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable);
virtual void canvas_item_set_shader(RID p_item, RID p_shader); virtual void canvas_item_set_shader(RID p_item, RID p_shader);
virtual RID canvas_item_get_shader(RID p_item) const; virtual RID canvas_item_get_shader(RID p_item) const;

View file

@ -1132,6 +1132,7 @@ public:
FUNC2(canvas_item_set_sort_children_by_y,RID,bool); FUNC2(canvas_item_set_sort_children_by_y,RID,bool);
FUNC2(canvas_item_set_z,RID,int); FUNC2(canvas_item_set_z,RID,int);
FUNC2(canvas_item_set_z_as_relative_to_parent,RID,bool);
FUNC2(canvas_item_set_shader,RID, RID ); FUNC2(canvas_item_set_shader,RID, RID );
FUNC1RC(RID,canvas_item_get_shader,RID ); FUNC1RC(RID,canvas_item_get_shader,RID );

View file

@ -86,8 +86,9 @@ public:
ARRAY_WEIGHTS_SIZE=4, ARRAY_WEIGHTS_SIZE=4,
MAX_PARTICLE_COLOR_PHASES=4, MAX_PARTICLE_COLOR_PHASES=4,
MAX_PARTICLE_ATTRACTORS=4, MAX_PARTICLE_ATTRACTORS=4,
CANVAS_ITEM_Z_MAX=1024, CANVAS_ITEM_Z_MIN=-4096,
CANVAS_ITEM_Z_DEFAULT=512, CANVAS_ITEM_Z_MAX=4096,
MAX_CURSORS = 8, MAX_CURSORS = 8,
@ -985,6 +986,7 @@ public:
virtual void canvas_item_add_clip_ignore(RID p_item, bool p_ignore)=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_set_sort_children_by_y(RID p_item, bool p_enable)=0;
virtual void canvas_item_set_z(RID p_item, int p_z)=0; virtual void canvas_item_set_z(RID p_item, int p_z)=0;
virtual void canvas_item_set_z_as_relative_to_parent(RID p_item, bool p_enable)=0;
virtual void canvas_item_clear(RID p_item)=0; virtual void canvas_item_clear(RID p_item)=0;
virtual void canvas_item_raise(RID p_item)=0; virtual void canvas_item_raise(RID p_item)=0;

View file

@ -411,7 +411,11 @@ void EditorTextureImportDialog::popup_import(const String& p_from) {
Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from); Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(p_from);
ERR_FAIL_COND(!rimd.is_valid()); ERR_FAIL_COND(!rimd.is_valid());
save_path->set_text(p_from.get_base_dir()); if (plugin->get_mode()==EditorTextureImportPlugin::MODE_ATLAS)
save_path->set_text(p_from);
else
save_path->set_text(p_from.get_base_dir());
texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("format")))); texture_options->set_format(EditorTextureImportPlugin::ImageFormat(int(rimd->get_option("format"))));
texture_options->set_flags(rimd->get_option("flags")); texture_options->set_flags(rimd->get_option("flags"));
texture_options->set_quality(rimd->get_option("quality")); texture_options->set_quality(rimd->get_option("quality"));

View file

@ -98,6 +98,7 @@ public:
IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear
}; };
Mode get_mode() const { return mode; }
virtual String get_name() const; virtual String get_name() const;
virtual String get_visible_name() const; virtual String get_visible_name() const;
virtual void import_dialog(const String& p_from=""); virtual void import_dialog(const String& p_from="");