diff --git a/core/image.cpp b/core/image.cpp index d9ba6c15942..ae9fb0adc46 100644 --- a/core/image.cpp +++ b/core/image.cpp @@ -1998,6 +1998,26 @@ void Image::set_compress_bc_func(void (*p_compress_func)(Image *)) { +void Image::normalmap_to_xy() { + + convert(Image::FORMAT_RGBA); + + { + int len = data.size()/4; + DVector::Write wp = data.write(); + unsigned char *data_ptr=wp.ptr(); + + for(int i=0;itarget, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); } + if (use_anisotropic_filter) { + + if (texture->flags&VS::TEXTURE_FLAG_ANISOTROPIC_FILTER) { + + glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_level); + } else { + glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); + } + } + int mipmaps= (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && img.get_mipmaps()>0) ? img.get_mipmaps() +1 : 1; @@ -1047,6 +1096,16 @@ void RasterizerGLES2::texture_set_flags(RID p_texture,uint32_t p_flags) { } + if (use_anisotropic_filter) { + + if (texture->flags&VS::TEXTURE_FLAG_ANISOTROPIC_FILTER) { + + glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, anisotropic_level); + } else { + glTexParameterf(texture->target, _GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); + } + } + if (texture->flags&VS::TEXTURE_FLAG_MIPMAPS && !texture->ignore_mipmaps) glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,use_fast_texture_filter?GL_LINEAR_MIPMAP_NEAREST:GL_LINEAR_MIPMAP_LINEAR); else @@ -8617,6 +8676,12 @@ void RasterizerGLES2::init() { use_texture_instancing=false; use_attribute_instancing=true; full_float_fb_supported=true; + srgb_supported=true; + latc_supported=true; + s3tc_srgb_supported=true; + use_anisotropic_filter=true; + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level); + anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0))); #ifdef OSX_ENABLED use_rgba_shadowmaps=true; use_fp16_fb=false; @@ -8636,12 +8701,25 @@ void RasterizerGLES2::init() { use_rgba_shadowmaps=true; //no other way, go back to rgba } pvr_supported=extensions.has("GL_IMG_texture_compression_pvrtc"); + pvr_srgb_supported=extensions.has("GL_EXT_pvrtc_sRGB"); etc_supported=extensions.has("GL_OES_compressed_ETC1_RGB8_texture"); use_depth24 = extensions.has("GL_OES_depth24"); s3tc_supported = extensions.has("GL_EXT_texture_compression_dxt1") || extensions.has("GL_EXT_texture_compression_s3tc") || extensions.has("WEBGL_compressed_texture_s3tc"); use_half_float = extensions.has("GL_OES_vertex_half_float"); atitc_supported=extensions.has("GL_AMD_compressed_ATC_texture"); + + srgb_supported=extensions.has("GL_EXT_sRGB"); + s3tc_srgb_supported = s3tc_supported && extensions.has("GL_EXT_texture_compression_s3tc"); + latc_supported = extensions.has("GL_EXT_texture_compression_latc"); + anisotropic_level=1.0; + use_anisotropic_filter=extensions.has("GL_EXT_texture_filter_anisotropic"); + if (use_anisotropic_filter) { + glGetFloatv(_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT,&anisotropic_level); + anisotropic_level=MIN(anisotropic_level,float(GLOBAL_DEF("rasterizer/anisotropic_filter_level",4.0))); + } + + print_line("S3TC: "+itos(s3tc_supported)+" ATITC: "+itos(atitc_supported)); GLint vtf; diff --git a/drivers/gles2/rasterizer_gles2.h b/drivers/gles2/rasterizer_gles2.h index a9fa7994e50..4b56775b884 100644 --- a/drivers/gles2/rasterizer_gles2.h +++ b/drivers/gles2/rasterizer_gles2.h @@ -73,7 +73,10 @@ class RasterizerGLES2 : public Rasterizer { uint8_t *skinned_buffer; int skinned_buffer_size; bool pvr_supported; + bool pvr_srgb_supported; bool s3tc_supported; + bool s3tc_srgb_supported; + bool latc_supported; bool etc_supported; bool atitc_supported; bool npo2_textures_available; @@ -82,6 +85,8 @@ class RasterizerGLES2 : public Rasterizer { bool full_float_fb_supported; bool use_shadow_mapping; bool use_fp16_fb; + bool srgb_supported; + ShadowFilterTechnique shadow_filter; bool use_shadow_esm; @@ -91,6 +96,8 @@ class RasterizerGLES2 : public Rasterizer { bool use_texture_instancing; bool use_attribute_instancing; bool use_rgba_shadowmaps; + bool use_anisotropic_filter; + float anisotropic_level; bool use_half_float; diff --git a/drivers/gles2/shaders/copy.glsl b/drivers/gles2/shaders/copy.glsl index d8fb03f3a3a..ae7185a1d69 100644 --- a/drivers/gles2/shaders/copy.glsl +++ b/drivers/gles2/shaders/copy.glsl @@ -46,6 +46,15 @@ precision mediump int; #endif + +float sRGB_gamma_correct(float c){ + float a = 0.055; + if(c < 0.0031308) + return 12.92*c; + else + return (1.0+a)*pow(c, 1.0/2.4) - a; +} + #define LUM_RANGE 4.0 @@ -407,15 +416,26 @@ void main() { #ifdef USE_SRGB +#if 0 + //this was fast, but was commented out because it looked kind of shitty, might it be fixable? + { //i have my doubts about how fast this is + color.rgb = min(color.rgb,vec3(1.0)); //clamp just in case vec3 S1 = sqrt(color.rgb); vec3 S2 = sqrt(S1); vec3 S3 = sqrt(S2); color.rgb = 0.662002687 * S1 + 0.684122060 * S2 - 0.323583601 * S3 - 0.225411470 * color.rgb; } +#else + + color.r=sRGB_gamma_correct(color.r); + color.g=sRGB_gamma_correct(color.g); + color.b=sRGB_gamma_correct(color.b); + #endif +#endif #ifdef USE_HDR_COPY diff --git a/drivers/squish/image_compress_squish.cpp b/drivers/squish/image_compress_squish.cpp index 1d71f51db42..2c520bd1e9c 100644 --- a/drivers/squish/image_compress_squish.cpp +++ b/drivers/squish/image_compress_squish.cpp @@ -18,19 +18,20 @@ void image_compress_squish(Image *p_image) { if (p_image->get_format()>=Image::FORMAT_BC1) return; //do not compress, already compressed - - Image::AlphaMode alpha = p_image->detect_alpha(); - Image::Format target_format; int shift=0; int squish_comp=squish::kColourRangeFit; - switch(alpha) { + Image::Format target_format; - case Image::ALPHA_NONE: target_format = Image::FORMAT_BC1; shift=1; squish_comp|=squish::kDxt1; break; - case Image::ALPHA_BIT: target_format = Image::FORMAT_BC2; squish_comp|=squish::kDxt3; break; - case Image::ALPHA_BLEND: target_format = Image::FORMAT_BC3; squish_comp|=squish::kDxt5; break; + if (p_image->get_format()==Image::FORMAT_GRAYSCALE_ALPHA) { + //compressed normalmap + target_format = Image::FORMAT_BC3; squish_comp|=squish::kDxt5;; + } else if (p_image->detect_alpha()!=Image::ALPHA_NONE) { + + target_format = Image::FORMAT_BC2; squish_comp|=squish::kDxt3;; + } else { + target_format = Image::FORMAT_BC1; shift=1; squish_comp|=squish::kDxt1;; } - p_image->convert(Image::FORMAT_RGBA); //always expects rgba int mm_count = p_image->get_mipmaps(); diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index 78b5e23da07..7678cb980cc 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -250,7 +250,7 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap if (!E) { E = contact_monitor->body_map.insert(objid,BodyState()); - E->get().rc=0; +// E->get().rc=0; E->get().in_scene=node && node->is_inside_scene(); if (node) { node->connect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene,make_binds(objid)); @@ -260,8 +260,9 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } } + //E->get().rc++; } - E->get().rc++; + if (node) E->get().shapes.insert(ShapePair(p_body_shape,p_local_shape)); @@ -272,24 +273,26 @@ void RigidBody2D::_body_inout(int p_status, ObjectID p_instance, int p_body_shap } else { - E->get().rc--; + //E->get().rc--; if (node) E->get().shapes.erase(ShapePair(p_body_shape,p_local_shape)); - if (E->get().rc==0) { + bool in_scene = E->get().in_scene; + + if (E->get().shapes.empty()) { if (node) { node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene); node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene); - if (E->get().in_scene) + if (in_scene) emit_signal(SceneStringNames::get_singleton()->body_exit,obj); } contact_monitor->body_map.erase(E); } - if (node && E->get().in_scene) { + if (node && in_scene) { emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_local_shape); } @@ -381,6 +384,7 @@ void RigidBody2D::_direct_state_changed(Object *p_state) { //process remotions + for(int i=0;i shapes; }; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index 8b72308afbe..72ef653d145 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -311,10 +311,11 @@ void TileMap::_recompute_rect_cache() { r_total=r_total.merge(r); } + if (r_total==Rect2()) { rect_cache=Rect2(-10,-10,20,20); } else { - rect_cache=r_total; + rect_cache=r_total.grow(MAX(cell_size.x,cell_size.y)*quadrant_size); } item_rect_changed(); diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index a99964cc54b..831e1c95c2b 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -245,7 +245,7 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, if (!E) { E = contact_monitor->body_map.insert(objid,BodyState()); - E->get().rc=0; + //E->get().rc=0; E->get().in_scene=node && node->is_inside_scene(); if (node) { node->connect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene,make_binds(objid)); @@ -256,7 +256,7 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, } } - E->get().rc++; + //E->get().rc++; if (node) E->get().shapes.insert(ShapePair(p_body_shape,p_local_shape)); @@ -267,24 +267,26 @@ void RigidBody::_body_inout(int p_status, ObjectID p_instance, int p_body_shape, } else { - E->get().rc--; + //E->get().rc--; if (node) E->get().shapes.erase(ShapePair(p_body_shape,p_local_shape)); - if (E->get().rc==0) { + bool in_scene = E->get().in_scene; + + if (E->get().shapes.empty()) { if (node) { node->disconnect(SceneStringNames::get_singleton()->enter_scene,this,SceneStringNames::get_singleton()->_body_enter_scene); node->disconnect(SceneStringNames::get_singleton()->exit_scene,this,SceneStringNames::get_singleton()->_body_exit_scene); - if (E->get().in_scene) + if (in_scene) emit_signal(SceneStringNames::get_singleton()->body_exit,obj); } contact_monitor->body_map.erase(E); } - if (node && E->get().in_scene) { + if (node && in_scene) { emit_signal(SceneStringNames::get_singleton()->body_exit_shape,objid,obj,p_body_shape,p_local_shape); } diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index 442921302e7..951aaf4da3d 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -162,7 +162,7 @@ private: }; struct BodyState { - int rc; + //int rc; bool in_scene; VSet shapes; }; diff --git a/scene/resources/SCsub b/scene/resources/SCsub index 87bd33e00eb..eaa282ae1a2 100644 --- a/scene/resources/SCsub +++ b/scene/resources/SCsub @@ -1,6 +1,7 @@ Import('env') env.add_source_files(env.scene_sources,"*.cpp") +env.add_source_files(env.scene_sources,"*.c") Export('env') diff --git a/scene/resources/material.cpp b/scene/resources/material.cpp index 2314926b2b8..4320d4c0814 100644 --- a/scene/resources/material.cpp +++ b/scene/resources/material.cpp @@ -316,14 +316,14 @@ Transform FixedMaterial::get_uv_transform() const { void FixedMaterial::set_fixed_flag(FixedFlag p_flag, bool p_value) { - ERR_FAIL_INDEX(p_flag,4); + ERR_FAIL_INDEX(p_flag,5); fixed_flags[p_flag]=p_value; VisualServer::get_singleton()->fixed_material_set_flag(material,(VS::FixedMaterialFlags)p_flag,p_value); } bool FixedMaterial::get_fixed_flag(FixedFlag p_flag) const { - ERR_FAIL_INDEX_V(p_flag,4,false); + ERR_FAIL_INDEX_V(p_flag,5,false); return fixed_flags[p_flag]; } @@ -371,6 +371,7 @@ void FixedMaterial::_bind_methods() { ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_color_array" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_COLOR_ARRAY); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_point_size" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_POINT_SIZE); ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/discard_alpha" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_DISCARD_ALPHA); + ADD_PROPERTYI( PropertyInfo( Variant::BOOL, "fixed_flags/use_xy_normalmap" ), _SCS("set_fixed_flag"), _SCS("get_fixed_flag"), FLAG_USE_XY_NORMALMAP); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/diffuse" ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_DIFFUSE); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/specular", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_SPECULAR ); ADD_PROPERTYI( PropertyInfo( Variant::COLOR, "params/emission", PROPERTY_HINT_COLOR_NO_ALPHA ), _SCS("set_parameter"), _SCS("get_parameter"), PARAM_EMISSION ); @@ -431,6 +432,9 @@ FixedMaterial::FixedMaterial() : Material(VS::get_singleton()->fixed_material_cr fixed_flags[FLAG_USE_ALPHA]=false; fixed_flags[FLAG_USE_COLOR_ARRAY]=false; fixed_flags[FLAG_USE_POINT_SIZE]=false; + fixed_flags[FLAG_USE_XY_NORMALMAP]=false; + fixed_flags[FLAG_DISCARD_ALPHA]=false; + for(int i=0;i texture_param[PARAM_MAX]; TexCoordMode texture_texcoord[PARAM_MAX]; LightShader light_shader; - bool fixed_flags[3]; + bool fixed_flags[FLAG_MAX]; float point_size; diff --git a/scene/resources/texture.cpp b/scene/resources/texture.cpp index 5b31ba1f1ba..dae055890b7 100644 --- a/scene/resources/texture.cpp +++ b/scene/resources/texture.cpp @@ -79,6 +79,8 @@ void Texture::_bind_methods() { BIND_CONSTANT( FLAG_FILTER ); BIND_CONSTANT( FLAG_VIDEO_SURFACE ); BIND_CONSTANT( FLAGS_DEFAULT ); + BIND_CONSTANT( FLAG_ANISOTROPIC_FILTER ); + BIND_CONSTANT( FLAG_CONVERT_TO_LINEAR ); } @@ -179,7 +181,7 @@ void ImageTexture::_get_property_list( List *p_list) const { - p_list->push_back( PropertyInfo( Variant::INT, "flags", PROPERTY_HINT_FLAGS,"Mipmaps,Repeat,Filter") ); + p_list->push_back( PropertyInfo( Variant::INT, "flags", PROPERTY_HINT_FLAGS,"Mipmaps,Repeat,Filter,Anisotropic,sRGB") ); p_list->push_back( PropertyInfo( Variant::IMAGE, "image", img_hint,String::num(lossy_storage_quality)) ); p_list->push_back( PropertyInfo( Variant::VECTOR2, "size",PROPERTY_HINT_NONE, "")); p_list->push_back( PropertyInfo( Variant::INT, "storage", PROPERTY_HINT_ENUM,"Uncompressed,Compress Lossy,Compress Lossless")); diff --git a/scene/resources/texture.h b/scene/resources/texture.h index 86ff246498d..4bb2f6d9795 100644 --- a/scene/resources/texture.h +++ b/scene/resources/texture.h @@ -52,6 +52,8 @@ public: FLAG_MIPMAPS=VisualServer::TEXTURE_FLAG_MIPMAPS, FLAG_REPEAT=VisualServer::TEXTURE_FLAG_REPEAT, FLAG_FILTER=VisualServer::TEXTURE_FLAG_FILTER, + FLAG_ANISOTROPIC_FILTER=VisualServer::TEXTURE_FLAG_ANISOTROPIC_FILTER, + FLAG_CONVERT_TO_LINEAR=VisualServer::TEXTURE_FLAG_CONVERT_TO_LINEAR, FLAG_VIDEO_SURFACE=VisualServer::TEXTURE_FLAG_VIDEO_SURFACE, FLAGS_DEFAULT=FLAG_MIPMAPS|FLAG_REPEAT|FLAG_FILTER, }; diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index d112afa8e2f..bca6a9fa724 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -175,7 +175,7 @@ void BodyPairSW::validate_contacts() { bool BodyPairSW::setup(float p_step) { //cannot collide - if (A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) { + if (A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { collided=false; return false; } @@ -267,6 +267,14 @@ bool BodyPairSW::setup(float p_step) { B->add_contact(global_B,c.normal,depth,shape_B,global_A,shape_A,A->get_instance_id(),A->get_self(),crA); } + if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC)) { + c.active=false; + collided=false; + continue; + + } + + c.active=true; // Precompute normal mass, tangent mass, and bias. diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp index 0fd754ba254..73441882fb4 100644 --- a/servers/physics/body_sw.cpp +++ b/servers/physics/body_sw.cpp @@ -196,6 +196,7 @@ void BodySW::set_mode(PhysicsServer::BodyMode p_mode) { _inv_mass=0; _set_static(p_mode==PhysicsServer::BODY_MODE_STATIC); //set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC); + set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC && contacts.size()); linear_velocity=Vector3(); angular_velocity=Vector3(); } break; @@ -460,8 +461,8 @@ void BodySW::integrate_velocities(real_t p_step) { if (mode==PhysicsServer::BODY_MODE_KINEMATIC) { _set_transform(new_transform,false); - _set_inv_transform(new_transform.affine_inverse()); ; - if (linear_velocity==Vector3() && angular_velocity==Vector3()) + _set_inv_transform(new_transform.affine_inverse()); + if (contacts.size()==0 && linear_velocity==Vector3() && angular_velocity==Vector3()) set_active(false); //stopped moving, deactivate return; diff --git a/servers/physics/body_sw.h b/servers/physics/body_sw.h index 6317186d5f9..f152c4754a3 100644 --- a/servers/physics/body_sw.h +++ b/servers/physics/body_sw.h @@ -137,7 +137,7 @@ public: _FORCE_INLINE_ void add_area(AreaSW *p_area) { areas.insert(AreaCMP(p_area)); } _FORCE_INLINE_ void remove_area(AreaSW *p_area) { areas.erase(AreaCMP(p_area)); } - _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; } + _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; if (mode==PhysicsServer::BODY_MODE_KINEMATIC && p_size) set_active(true);} _FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); } _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); } diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index 98d05538a85..788292ad2a9 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -59,6 +59,9 @@ private: BroadPhaseSW::ID bpid; AABB aabb_cache; //for rayqueries ShapeSW *shape; + bool trigger; + + Shape() { trigger=false; } }; Vector shapes; @@ -125,6 +128,8 @@ public: _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_shape_as_trigger(int p_idx,bool p_enable) { shapes[p_idx].trigger=p_enable; } + _FORCE_INLINE_ bool is_shape_set_as_trigger(int p_idx) const { return shapes[p_idx].trigger; } _FORCE_INLINE_ void set_layer_mask(uint32_t p_mask) { layer_mask=p_mask; } _FORCE_INLINE_ uint32_t get_layer_mask() const { return layer_mask; } diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 31c4d8f1216..510a6ea93f9 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -540,6 +540,8 @@ void PhysicsServerSW::body_set_shape_as_trigger(RID p_body, int p_shape_idx,bool BodySW *body = body_owner.get(p_body); ERR_FAIL_COND(!body); + ERR_FAIL_INDEX(p_shape_idx,body->get_shape_count()); + body->set_shape_as_trigger(p_shape_idx,p_enable); } @@ -547,10 +549,9 @@ bool PhysicsServerSW::body_is_shape_set_as_trigger(RID p_body, int p_shape_idx) BodySW *body = body_owner.get(p_body); ERR_FAIL_COND_V(!body,false); + ERR_FAIL_INDEX_V(p_shape_idx,body->get_shape_count(),false); - // todo ? - - return false; + body->is_shape_set_as_trigger(p_shape_idx); } diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index f10cdadf4e3..e90faa3efb2 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -186,7 +186,7 @@ void Body2DSW::set_mode(Physics2DServer::BodyMode p_mode) { _set_inv_transform(get_transform().affine_inverse()); _inv_mass=0; _set_static(p_mode==Physics2DServer::BODY_MODE_STATIC); - //set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC); + set_active(p_mode==Physics2DServer::BODY_MODE_KINEMATIC && contacts.size()); linear_velocity=Vector2(); angular_velocity=0; } break; @@ -385,10 +385,10 @@ void Body2DSW::integrate_forces(real_t p_step) { motion = new_transform.elements[2] - get_transform().elements[2]; do_motion=true; - for(int i=0;icallback_udata}; + Object *obj = ObjectDB::get_instance(fi_callback->id); if (!obj) { diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index ffe47e0267d..cf4d5c92f2d 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -134,7 +134,8 @@ public: _FORCE_INLINE_ void add_area(Area2DSW *p_area) { areas.insert(AreaCMP(p_area)); } _FORCE_INLINE_ void remove_area(Area2DSW *p_area) { areas.erase(AreaCMP(p_area)); } - _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; } + _FORCE_INLINE_ void set_max_contacts_reported(int p_size) { contacts.resize(p_size); contact_count=0; if (mode==Physics2DServer::BODY_MODE_KINEMATIC && p_size) set_active(true);} + _FORCE_INLINE_ int get_max_contacts_reported() const { return contacts.size(); } _FORCE_INLINE_ bool can_report_contacts() const { return !contacts.empty(); } diff --git a/servers/physics_2d/body_pair_2d_sw.cpp b/servers/physics_2d/body_pair_2d_sw.cpp index ee169cde288..9abdd01791b 100644 --- a/servers/physics_2d/body_pair_2d_sw.cpp +++ b/servers/physics_2d/body_pair_2d_sw.cpp @@ -234,7 +234,7 @@ bool BodyPair2DSW::setup(float p_step) { //cannot collide - if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) { + if ((A->get_layer_mask()&B->get_layer_mask())==0 || A->has_exception(B->get_self()) || B->has_exception(A->get_self()) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { collided=false; return false; } @@ -343,9 +343,11 @@ bool BodyPair2DSW::setup(float p_step) { } } - if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B)) { + if (A->is_shape_set_as_trigger(shape_A) || B->is_shape_set_as_trigger(shape_B) || (A->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC && B->get_mode()<=Physics2DServer::BODY_MODE_KINEMATIC)) { c.active=false; collided=false; + continue; + } // Precompute normal mass, tangent mass, and bias. @@ -476,6 +478,7 @@ BodyPair2DSW::BodyPair2DSW(Body2DSW *p_A, int p_shape_A,Body2DSW *p_B, int p_sha BodyPair2DSW::~BodyPair2DSW() { + A->remove_constraint(this); B->remove_constraint(this); diff --git a/servers/physics_2d/collision_object_2d_sw.h b/servers/physics_2d/collision_object_2d_sw.h index cc7f8f50bd9..1d61a1df4a1 100644 --- a/servers/physics_2d/collision_object_2d_sw.h +++ b/servers/physics_2d/collision_object_2d_sw.h @@ -55,10 +55,8 @@ private: BroadPhase2DSW::ID bpid; Rect2 aabb_cache; //for rayqueries Shape2DSW *shape; - Vector2 kinematic_advance; - float kinematic_retreat; bool trigger; - Shape() { trigger=false; kinematic_retreat=0; } + Shape() { trigger=false; } }; Vector shapes; @@ -105,12 +103,6 @@ public: _FORCE_INLINE_ const Matrix32& get_shape_inv_transform(int p_index) const { return shapes[p_index].xform_inv; } _FORCE_INLINE_ const Rect2& get_shape_aabb(int p_index) const { return shapes[p_index].aabb_cache; } - _FORCE_INLINE_ void set_shape_kinematic_advance(int p_index,const Vector2& p_advance) { shapes[p_index].kinematic_advance=p_advance; } - _FORCE_INLINE_ Vector2 get_shape_kinematic_advance(int p_index) const { return shapes[p_index].kinematic_advance; } - - _FORCE_INLINE_ void set_shape_kinematic_retreat(int p_index,float p_retreat) { shapes[p_index].kinematic_retreat=p_retreat; } - _FORCE_INLINE_ float get_shape_kinematic_retreat(int p_index) const { return shapes[p_index].kinematic_retreat; } - _FORCE_INLINE_ Matrix32 get_transform() const { return transform; } _FORCE_INLINE_ Matrix32 get_inv_transform() const { return inv_transform; } _FORCE_INLINE_ Space2DSW* get_space() const { return space; } diff --git a/servers/visual/rasterizer.cpp b/servers/visual/rasterizer.cpp index e160b4dccce..95746b7675b 100644 --- a/servers/visual/rasterizer.cpp +++ b/servers/visual/rasterizer.cpp @@ -96,7 +96,12 @@ RID Rasterizer::_create_shader(const FixedMaterialShaderKey& p_key) { } else { uv_str=_TEXUVSTR(VS::FIXED_MATERIAL_PARAM_NORMAL); } - scode+="vec3 normal=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n"; + if (p_key.use_xy_normalmap) { + scode+="vec2 ywnormal=tex( fmp_normal_tex,"+uv_str+").wy * vec2(2.0,2.0) - vec2(1.0,1.0);\n"; + scode+="vec3 normal=vec3(ywnormal,sqrt(1 - (ywnormal.x * ywnormal.x) - (ywnormal.y * ywnormal.y) ));\n"; + } else { + scode+="vec3 normal=tex( fmp_normal_tex,"+uv_str+").xyz * vec3(2.0,2.0,1.0) - vec3(1.0,1.0,0.0);\n"; + } scode+="NORMAL = mix( NORMAL,mat3(TANGENT,BINORMAL,NORMAL) * normal, fmp_normal);\n"; code+=scode; } @@ -323,6 +328,7 @@ void Rasterizer::fixed_material_set_flag(RID p_material, VS::FixedMaterialFlags case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: fm.use_color_array=p_enabled; break; case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: fm.use_pointsize=p_enabled; break; case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: fm.discard_alpha=p_enabled; break; + case VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP: fm.use_xy_normalmap=p_enabled; break; } if (!fm.dirty_list.in_list()) @@ -341,6 +347,8 @@ bool Rasterizer::fixed_material_get_flag(RID p_material, VS::FixedMaterialFlags case VS::FIXED_MATERIAL_FLAG_USE_COLOR_ARRAY: return fm.use_color_array;; break; case VS::FIXED_MATERIAL_FLAG_USE_POINT_SIZE: return fm.use_pointsize;; break; case VS::FIXED_MATERIAL_FLAG_DISCARD_ALPHA: return fm.discard_alpha;; break; + case VS::FIXED_MATERIAL_FLAG_USE_XY_NORMALMAP: return fm.use_xy_normalmap;; break; + } @@ -610,6 +618,8 @@ Rasterizer::Rasterizer() { _fixed_material_uv_xform_name="fmp_uv_xform"; _fixed_material_point_size_name="fmp_point_size"; + ERR_FAIL_COND( sizeof(FixedMaterialShaderKey)!=4); + } RID Rasterizer::create_overdraw_debug_material() { diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index 5b07c633c34..dc970383b60 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -56,6 +56,7 @@ protected: bool use_color_array:1; bool use_pointsize:1; bool discard_alpha:1; + bool use_xy_normalmap:1; bool valid:1; }; @@ -83,6 +84,7 @@ protected: bool use_color_array; bool discard_alpha; bool use_pointsize; + bool use_xy_normalmap; float point_size; Transform uv_xform; VS::FixedMaterialLightShader light_shader; @@ -102,6 +104,7 @@ protected: k.use_alpha=use_alpha; k.use_color_array=use_color_array; k.use_pointsize=use_pointsize; + k.use_xy_normalmap=use_xy_normalmap; k.discard_alpha=discard_alpha; k.light_shader=light_shader; k.valid=true; @@ -123,6 +126,7 @@ protected: use_color_array=false; use_pointsize=false; discard_alpha=false; + use_xy_normalmap=false; point_size=1.0; light_shader=VS::FIXED_MATERIAL_LIGHT_SHADER_LAMBERT; for(int i=0;iLinear Of Diffuse Textures",false}, + {EditorSceneImportPlugin::SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY,"Actions","Convert Normal Maps to XY",true}, {EditorSceneImportPlugin::SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS,"Actions","Set Material Lightmap to UV2 if Tex2Array Exists",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_COLLISIONS,"Create","Create Collisions (-col},-colonly)",true}, {EditorSceneImportPlugin::SCENE_FLAG_CREATE_PORTALS,"Create","Create Portals (-portal)",true}, @@ -898,7 +899,7 @@ static String _fixstr(const String& p_what,const String& p_str) { -void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map, bool> &image_map) { +void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map, TextureRole> &image_map,int p_flags) { switch(p_var.get_type()) { @@ -910,7 +911,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Mapis_type("Texture") && !image_map.has(res)) { - image_map.insert(res,false); + image_map.insert(res,TEXTURE_ROLE_DEFAULT); } else { @@ -926,11 +927,22 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map tex =res->get(E->get().name); if (tex.is_valid()) { - image_map.insert(tex,true); + image_map.insert(tex,TEXTURE_ROLE_DIFFUSE); } + } else if (E->get().type==Variant::OBJECT && res->cast_to() && (E->get().name=="textures/normal")) { + + Ref tex =res->get(E->get().name); + if (tex.is_valid()) { + + image_map.insert(tex,TEXTURE_ROLE_NORMALMAP); + if (p_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) + res->cast_to()->set_fixed_flag(FixedMaterial::FLAG_USE_XY_NORMALMAP,true); + } + + } else { - _find_resources(res->get(E->get().name),image_map); + _find_resources(res->get(E->get().name),image_map,p_flags); } } } @@ -949,8 +961,8 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map::Element *E=keys.front();E;E=E->next()) { - _find_resources(E->get(),image_map); - _find_resources(d[E->get()],image_map); + _find_resources(E->get(),image_map,p_flags); + _find_resources(d[E->get()],image_map,p_flags); } @@ -961,7 +973,7 @@ void EditorSceneImportPlugin::_find_resources(const Variant& p_var, Map,Ref > &collision_map,uint32_t p_flags,Map,bool >& image_map) { +Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map,Ref > &collision_map,uint32_t p_flags,Map,TextureRole >& image_map) { // children first.. for(int i=0;iget_child_count();i++) { @@ -1002,7 +1014,7 @@ Node* EditorSceneImportPlugin::_fix_node(Node *p_node,Node *p_root,Map for(List::Element *E=pl.front();E;E=E->next()) { if (E->get().type==Variant::OBJECT || E->get().type==Variant::ARRAY || E->get().type==Variant::DICTIONARY) { - _find_resources(p_node->get(E->get().name),image_map); + _find_resources(p_node->get(E->get().name),image_map,p_flags); } } @@ -1925,7 +1937,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref imd = memnew(ResourceImportMetadata); - Map< Ref,bool > imagemap; + Map< Ref,TextureRole > imagemap; scene=_fix_node(scene,scene,collision_map,scene_flags,imagemap); @@ -1971,7 +1983,7 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c int image_flags = from->get_option("texture_flags"); float image_quality = from->get_option("texture_quality"); - for (Map< Ref,bool >::Element *E=imagemap.front();E;E=E->next()) { + for (Map< Ref,TextureRole >::Element *E=imagemap.front();E;E=E->next()) { //texture could be converted to something more useful for 3D, that could load individual mipmaps and stuff //but not yet.. @@ -2007,6 +2019,11 @@ Error EditorSceneImportPlugin::import2(Node *scene, const String& p_dest_path, c Ref imd = memnew( ResourceImportMetadata ); print_line("flags: "+itos(image_flags)); uint32_t flags = image_flags; + if (E->get()==TEXTURE_ROLE_DIFFUSE && scene_flags&SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_TO_LINEAR; + + if (E->get()==TEXTURE_ROLE_NORMALMAP && scene_flags&SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY) + flags|=EditorTextureImportPlugin::IMAGE_FLAG_CONVERT_NORMAL_TO_XY; imd->set_option("flags",flags); imd->set_option("format",image_format); diff --git a/tools/editor/io_plugins/editor_scene_import_plugin.h b/tools/editor/io_plugins/editor_scene_import_plugin.h index 6095ecf387d..72b4089d894 100644 --- a/tools/editor/io_plugins/editor_scene_import_plugin.h +++ b/tools/editor/io_plugins/editor_scene_import_plugin.h @@ -100,8 +100,14 @@ class EditorSceneImportPlugin : public EditorImportPlugin { Vector > importers; - void _find_resources(const Variant& p_var,Map,bool >& image_map); - Node* _fix_node(Node *p_node,Node *p_root,Map,Ref > &collision_map,uint32_t p_flags,Map,bool >& image_map); + enum TextureRole { + TEXTURE_ROLE_DEFAULT, + TEXTURE_ROLE_DIFFUSE, + TEXTURE_ROLE_NORMALMAP + }; + + void _find_resources(const Variant& p_var,Map,TextureRole >& image_map,int p_flags); + Node* _fix_node(Node *p_node,Node *p_root,Map,Ref > &collision_map,uint32_t p_flags,Map,TextureRole >& image_map); void _merge_existing_node(Node *p_node,Node *p_imported_scene,Set >& checked_resources,Set &checked_nodes); void _add_new_nodes(Node *p_node,Node *p_imported,Node *p_imported_scene,Set &checked_nodes); @@ -133,6 +139,7 @@ public: SCENE_FLAG_GENERATE_TANGENT_ARRAYS=1<<27, SCENE_FLAG_LINEARIZE_DIFFUSE_TEXTURES=1<<28, SCENE_FLAG_SET_LIGHTMAP_TO_UV2_IF_EXISTS=1<<29, + SCENE_FLAG_CONVERT_NORMALMAPS_TO_XY=1<<30, }; diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.cpp b/tools/editor/io_plugins/editor_texture_import_plugin.cpp index 760651bbfd9..86f7787a9c2 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.cpp +++ b/tools/editor/io_plugins/editor_texture_import_plugin.cpp @@ -46,6 +46,8 @@ static const char *flag_names[]={ "Filter (Magnifying)", "Premultiply Alpha", "Convert SRGB->Linear", + "Convert NormalMap to XY", + "Use Anisotropy", NULL }; @@ -59,6 +61,8 @@ static const char *flag_short_names[]={ "Filter", "PMAlpha", "ToLinear", + "ToRG", + "Anisoropic", NULL }; @@ -725,7 +729,7 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Refget_option("atlas"); int flags=from->get_option("flags"); - print_line("GET FLAGS: "+itos(flags)); + uint32_t tex_flags=0; if (flags&EditorTextureImportPlugin::IMAGE_FLAG_REPEAT) @@ -734,6 +738,10 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Ref1) { int orig_w=image.get_width(); @@ -992,12 +1004,16 @@ Error EditorTextureImportPlugin::import2(const String& p_path, const Refcreate_from_image(image,tex_flags); - if (shrink>1) { + if (shrink>1 || (format!=IMAGE_FORMAT_UNCOMPRESSED && (image.get_width()!=orig_w || image.get_height()!=orig_h))) { texture->set_size_override(Size2(orig_w,orig_h)); } diff --git a/tools/editor/io_plugins/editor_texture_import_plugin.h b/tools/editor/io_plugins/editor_texture_import_plugin.h index 9374c6eb0ba..d17b3c05c2f 100644 --- a/tools/editor/io_plugins/editor_texture_import_plugin.h +++ b/tools/editor/io_plugins/editor_texture_import_plugin.h @@ -93,7 +93,9 @@ public: IMAGE_FLAG_REPEAT=32, //usually disabled in 2D IMAGE_FLAG_FILTER=64, //almost always enabled IMAGE_FLAG_PREMULT_ALPHA=128,//almost always enabled - IMAGE_FLAG_CONVERT_TO_LINEAR=256 //convert image to linear + IMAGE_FLAG_CONVERT_TO_LINEAR=256, //convert image to linear + IMAGE_FLAG_CONVERT_NORMAL_TO_XY=512, //convert image to linear + IMAGE_FLAG_USE_ANISOTROPY=1024, //convert image to linear }; virtual String get_name() const;