diff options
Diffstat (limited to 'scene')
-rw-r--r-- | scene/2d/node_2d.cpp | 28 | ||||
-rw-r--r-- | scene/2d/node_2d.h | 4 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.cpp | 28 | ||||
-rw-r--r-- | scene/2d/physics_body_2d.h | 6 | ||||
-rw-r--r-- | scene/2d/ray_cast_2d.cpp | 17 | ||||
-rw-r--r-- | scene/2d/ray_cast_2d.h | 4 | ||||
-rw-r--r-- | scene/2d/tile_map.cpp | 21 | ||||
-rw-r--r-- | scene/2d/tile_map.h | 4 | ||||
-rw-r--r-- | scene/3d/baked_light.cpp | 7 | ||||
-rw-r--r-- | scene/3d/baked_light.h | 15 | ||||
-rw-r--r-- | scene/3d/physics_body.cpp | 16 | ||||
-rw-r--r-- | scene/3d/physics_body.h | 15 | ||||
-rw-r--r-- | scene/3d/visual_instance.h | 1 | ||||
-rw-r--r-- | scene/animation/animation_player.cpp | 2 | ||||
-rw-r--r-- | scene/gui/rich_text_label.cpp | 4 | ||||
-rw-r--r-- | scene/main/viewport.cpp | 17 | ||||
-rw-r--r-- | scene/main/viewport.h | 4 | ||||
-rw-r--r-- | scene/register_scene_types.cpp | 3 | ||||
-rw-r--r-- | scene/resources/environment.cpp | 3 | ||||
-rw-r--r-- | scene/resources/environment.h | 1 | ||||
-rw-r--r-- | scene/resources/mesh.cpp | 33 | ||||
-rw-r--r-- | scene/resources/surface_tool.cpp | 441 | ||||
-rw-r--r-- | scene/resources/surface_tool.h | 12 |
23 files changed, 523 insertions, 163 deletions
diff --git a/scene/2d/node_2d.cpp b/scene/2d/node_2d.cpp index a2bee43e58..85adfbbbde 100644 --- a/scene/2d/node_2d.cpp +++ b/scene/2d/node_2d.cpp @@ -224,6 +224,30 @@ Rect2 Node2D::get_item_rect() const { return Rect2(Point2(-32,-32),Size2(64,64)); } +void Node2D::rotate(float p_degrees) { + + set_rot( get_rot() + p_degrees); +} + +void Node2D::move_x(float p_delta,bool p_scaled){ + + Matrix32 t = get_transform(); + Vector2 m = t[0]; + if (!p_scaled) + m.normalize(); + set_pos(t[2]+m*p_delta); +} + +void Node2D::move_y(float p_delta,bool p_scaled){ + + Matrix32 t = get_transform(); + Vector2 m = t[1]; + if (!p_scaled) + m.normalize(); + set_pos(t[2]+m*p_delta); +} + + Point2 Node2D::get_global_pos() const { return get_global_transform().get_origin(); @@ -268,6 +292,10 @@ void Node2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("get_rot"),&Node2D::get_rot); ObjectTypeDB::bind_method(_MD("get_scale"),&Node2D::get_scale); + ObjectTypeDB::bind_method(_MD("rotate","degrees"),&Node2D::rotate); + ObjectTypeDB::bind_method(_MD("move_local_x","delta","scaled"),&Node2D::move_x,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("move_local_y","delta","scaled"),&Node2D::move_y,DEFVAL(false)); + ObjectTypeDB::bind_method(_MD("get_global_pos"),&Node2D::get_global_pos); ObjectTypeDB::bind_method(_MD("set_transform","xform"),&Node2D::set_transform); diff --git a/scene/2d/node_2d.h b/scene/2d/node_2d.h index 8da441dc63..8e1f22c235 100644 --- a/scene/2d/node_2d.h +++ b/scene/2d/node_2d.h @@ -70,6 +70,10 @@ public: void set_rot(float p_angle); void set_scale(const Size2& p_scale); + void rotate(float p_degrees); + void move_x(float p_delta,bool p_scaled=false); + void move_y(float p_delta,bool p_scaled=false); + Point2 get_pos() const; float get_rot() const; Size2 get_scale() const; diff --git a/scene/2d/physics_body_2d.cpp b/scene/2d/physics_body_2d.cpp index a1e7195b0a..ecd147afde 100644 --- a/scene/2d/physics_body_2d.cpp +++ b/scene/2d/physics_body_2d.cpp @@ -43,9 +43,27 @@ void PhysicsBody2D::_notification(int p_what) { */ } -PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { +void PhysicsBody2D::_bind_methods() { + + ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&PhysicsBody2D::set_layer_mask); + ObjectTypeDB::bind_method(_MD("get_layer_mask"),&PhysicsBody2D::get_layer_mask); + ADD_PROPERTY(PropertyInfo(Variant::INT,"layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); +} + +void PhysicsBody2D::set_layer_mask(uint32_t p_mask) { + + mask=p_mask; + Physics2DServer::get_singleton()->body_set_layer_mask(get_rid(),p_mask); +} + +uint32_t PhysicsBody2D::get_layer_mask() const { + return mask; +} + +PhysicsBody2D::PhysicsBody2D(Physics2DServer::BodyMode p_mode) : CollisionObject2D( Physics2DServer::get_singleton()->body_create(p_mode), false) { + mask=1; } @@ -789,7 +807,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { for(int i=0;i<get_shape_count();i++) { - if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,0,mask)) + if (dss->collide_shape(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i),Vector2(),margin,sr,max_shapes,res_shapes,exclude,get_layer_mask(),mask)) collided=true; } @@ -834,7 +852,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { float lsafe,lunsafe; - bool valid = dss->cast_motion(get_shape(i)->get_rid(), get_global_transform() * get_shape_transform(i), p_motion, 0,lsafe,lunsafe,exclude,0,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)); if (!valid) { safe=0; @@ -865,7 +883,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) { Matrix32 ugt = get_global_transform(); ugt.elements[2]+=p_motion*unsafe; Physics2DDirectSpaceState::ShapeRestInfo rest_info; - bool c2 = dss->rest_info(get_shape(best_shape)->get_rid(), ugt*get_shape_transform(best_shape), Vector2(), margin,&rest_info,exclude,0,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) { //should not happen, but floating point precision is so weird.. colliding=false; @@ -927,7 +945,7 @@ bool KinematicBody2D::can_move_to(const Vector2& p_position, bool p_discrete) { for(int i=0;i<get_shape_count();i++) { - bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,0,mask); + bool col = dss->intersect_shape(get_shape(i)->get_rid(), xform * get_shape_transform(i),motion,0,NULL,0,exclude,get_layer_mask(),mask); if (col) return false; } diff --git a/scene/2d/physics_body_2d.h b/scene/2d/physics_body_2d.h index e7b65b1ef3..1319d2e4f0 100644 --- a/scene/2d/physics_body_2d.h +++ b/scene/2d/physics_body_2d.h @@ -38,12 +38,18 @@ class PhysicsBody2D : public CollisionObject2D { OBJ_TYPE(PhysicsBody2D,CollisionObject2D); + uint32_t mask; protected: void _notification(int p_what); PhysicsBody2D(Physics2DServer::BodyMode p_mode); + + static void _bind_methods(); public: + void set_layer_mask(uint32_t p_mask); + uint32_t get_layer_mask() const; + PhysicsBody2D(); }; diff --git a/scene/2d/ray_cast_2d.cpp b/scene/2d/ray_cast_2d.cpp index 540c825485..8479338521 100644 --- a/scene/2d/ray_cast_2d.cpp +++ b/scene/2d/ray_cast_2d.cpp @@ -43,6 +43,16 @@ Vector2 RayCast2D::get_cast_to() const{ return cast_to; } +void RayCast2D::set_layer_mask(uint32_t p_mask) { + + layer_mask=p_mask; +} + +uint32_t RayCast2D::get_layer_mask() const { + + return layer_mask; +} + bool RayCast2D::is_colliding() const{ return collided; @@ -152,7 +162,7 @@ void RayCast2D::_notification(int p_what) { Physics2DDirectSpaceState::RayResult rr; - if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude)) { + if (dss->intersect_ray(gt.get_origin(),gt.xform(to),rr,exclude,layer_mask)) { collided=true; against=rr.collider_id; @@ -228,8 +238,12 @@ void RayCast2D::_bind_methods() { ObjectTypeDB::bind_method(_MD("clear_exceptions"),&RayCast2D::clear_exceptions); + ObjectTypeDB::bind_method(_MD("set_layer_mask","mask"),&RayCast2D::set_layer_mask); + ObjectTypeDB::bind_method(_MD("get_layer_mask"),&RayCast2D::get_layer_mask); + ADD_PROPERTY(PropertyInfo(Variant::BOOL,"enabled"),_SCS("set_enabled"),_SCS("is_enabled")); ADD_PROPERTY(PropertyInfo(Variant::VECTOR2,"cast_to"),_SCS("set_cast_to"),_SCS("get_cast_to")); + ADD_PROPERTY(PropertyInfo(Variant::INT,"layer_mask",PROPERTY_HINT_ALL_FLAGS),_SCS("set_layer_mask"),_SCS("get_layer_mask")); } RayCast2D::RayCast2D() { @@ -238,5 +252,6 @@ RayCast2D::RayCast2D() { against=0; collided=false; against_shape=0; + layer_mask=1; cast_to=Vector2(0,50); } diff --git a/scene/2d/ray_cast_2d.h b/scene/2d/ray_cast_2d.h index 32b95fbefe..b27fc4bf3d 100644 --- a/scene/2d/ray_cast_2d.h +++ b/scene/2d/ray_cast_2d.h @@ -43,6 +43,7 @@ class RayCast2D : public Node2D { Vector2 collision_point; Vector2 collision_normal; Set<RID> exclude; + uint32_t layer_mask; Vector2 cast_to; @@ -58,6 +59,9 @@ public: void set_cast_to(const Vector2& p_point); Vector2 get_cast_to() const; + void set_layer_mask(uint32_t p_mask); + uint32_t get_layer_mask() const; + bool is_colliding() const; Object *get_collider() const; int get_collider_shape() const; diff --git a/scene/2d/tile_map.cpp b/scene/2d/tile_map.cpp index c8711f10ac..6fe8b8c4c2 100644 --- a/scene/2d/tile_map.cpp +++ b/scene/2d/tile_map.cpp @@ -315,6 +315,7 @@ Map<TileMap::PosKey,TileMap::Quadrant>::Element *TileMap::_create_quadrant(const VisualServer::get_singleton()->canvas_item_set_parent( q.canvas_item, get_canvas_item() ); VisualServer::get_singleton()->canvas_item_set_transform( q.canvas_item, xform ); q.static_body=Physics2DServer::get_singleton()->body_create(Physics2DServer::BODY_MODE_STATIC); + Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); if (is_inside_scene()) { xform = get_global_transform() * xform; RID space = get_world_2d()->get_space(); @@ -545,6 +546,22 @@ Rect2 TileMap::get_item_rect() const { return rect_cache; } +void TileMap::set_collision_layer_mask(uint32_t p_layer) { + + collision_layer=p_layer; + for (Map<PosKey,Quadrant>::Element *E=quadrant_map.front();E;E=E->next()) { + + Quadrant &q=E->get(); + Physics2DServer::get_singleton()->body_set_layer_mask(q.static_body,collision_layer); + } +} + +uint32_t TileMap::get_collision_layer_mask() const { + + return collision_layer; +} + + void TileMap::_bind_methods() { @@ -564,6 +581,8 @@ void TileMap::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_center_y","enable"),&TileMap::set_center_y); ObjectTypeDB::bind_method(_MD("get_center_y"),&TileMap::get_center_y); + ObjectTypeDB::bind_method(_MD("set_collision_layer_mask","mask"),&TileMap::set_collision_layer_mask); + ObjectTypeDB::bind_method(_MD("get_collision_layer_mask"),&TileMap::get_collision_layer_mask); ObjectTypeDB::bind_method(_MD("set_cell","x","y","tile","flip_x","flip_y"),&TileMap::set_cell,DEFVAL(false),DEFVAL(false)); ObjectTypeDB::bind_method(_MD("get_cell","x","y"),&TileMap::get_cell); @@ -583,6 +602,7 @@ void TileMap::_bind_methods() { 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::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,"collision_layers",PROPERTY_HINT_ALL_FLAGS),_SCS("set_collision_layer_mask"),_SCS("get_collision_layer_mask")); ADD_SIGNAL(MethodInfo("settings_changed")); @@ -599,6 +619,7 @@ TileMap::TileMap() { cell_size=64; center_x=false; center_y=false; + collision_layer=1; fp_adjust=0.01; fp_adjust=0.01; diff --git a/scene/2d/tile_map.h b/scene/2d/tile_map.h index a2414382c6..9265a7b55e 100644 --- a/scene/2d/tile_map.h +++ b/scene/2d/tile_map.h @@ -98,6 +98,7 @@ class TileMap : public Node2D { Rect2 rect_cache; bool rect_cache_dirty; float fp_adjust; + uint32_t collision_layer; Map<PosKey,Quadrant>::Element *_create_quadrant(const PosKey& p_qk); @@ -145,6 +146,9 @@ public: Rect2 get_item_rect() const; + void set_collision_layer_mask(uint32_t p_layer); + uint32_t get_collision_layer_mask() const; + void clear(); TileMap(); diff --git a/scene/3d/baked_light.cpp b/scene/3d/baked_light.cpp new file mode 100644 index 0000000000..55832b7c18 --- /dev/null +++ b/scene/3d/baked_light.cpp @@ -0,0 +1,7 @@ +#include "baked_light.h" +#include "mesh_instance.h" + +BakedLight::BakedLight() { + + +} diff --git a/scene/3d/baked_light.h b/scene/3d/baked_light.h new file mode 100644 index 0000000000..a6f997afe9 --- /dev/null +++ b/scene/3d/baked_light.h @@ -0,0 +1,15 @@ +#ifndef BAKED_LIGHT_H +#define BAKED_LIGHT_H + +#include "scene/3d/spatial.h" +class BakedLightBaker; + + +class BakedLight : public Spatial { + OBJ_TYPE(BakedLight,Spatial); + +public: + BakedLight(); +}; + +#endif // BAKED_LIGHT_H diff --git a/scene/3d/physics_body.cpp b/scene/3d/physics_body.cpp index 0733a9196e..2a1a5972a9 100644 --- a/scene/3d/physics_body.cpp +++ b/scene/3d/physics_body.cpp @@ -632,6 +632,16 @@ bool RigidBody::is_contact_monitor_enabled() const { return contact_monitor!=NULL; } +void RigidBody::set_axis_lock(AxisLock p_lock) { + + axis_lock=p_lock; + PhysicsServer::get_singleton()->body_set_axis_lock(get_rid(),PhysicsServer::BodyAxisLock(axis_lock)); +} + +RigidBody::AxisLock RigidBody::get_axis_lock() const { + + return axis_lock; +} void RigidBody::_bind_methods() { @@ -682,6 +692,9 @@ void RigidBody::_bind_methods() { ObjectTypeDB::bind_method(_MD("_body_enter_scene"),&RigidBody::_body_enter_scene); ObjectTypeDB::bind_method(_MD("_body_exit_scene"),&RigidBody::_body_exit_scene); + ObjectTypeDB::bind_method(_MD("set_axis_lock","axis_lock"),&RigidBody::set_axis_lock); + ObjectTypeDB::bind_method(_MD("get_axis_lock"),&RigidBody::get_axis_lock); + BIND_VMETHOD(MethodInfo("_integrate_forces",PropertyInfo(Variant::OBJECT,"state:PhysicsDirectBodyState"))); ADD_PROPERTY( PropertyInfo(Variant::INT,"mode",PROPERTY_HINT_ENUM,"Rigid,Static,Character,Kinematic"),_SCS("set_mode"),_SCS("get_mode")); @@ -695,6 +708,7 @@ void RigidBody::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"contact_monitor"),_SCS("set_contact_monitor"),_SCS("is_contact_monitor_enabled")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"active"),_SCS("set_active"),_SCS("is_active")); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"can_sleep"),_SCS("set_can_sleep"),_SCS("is_able_to_sleep")); + ADD_PROPERTY( PropertyInfo(Variant::INT,"axis_lock",PROPERTY_HINT_ENUM,"Disabled,Lock X,Lock Y,Lock Z"),_SCS("set_axis_lock"),_SCS("get_axis_lock")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/linear"),_SCS("set_linear_velocity"),_SCS("get_linear_velocity")); ADD_PROPERTY( PropertyInfo(Variant::VECTOR3,"velocity/angular"),_SCS("set_angular_velocity"),_SCS("get_angular_velocity")); @@ -727,6 +741,8 @@ RigidBody::RigidBody() : PhysicsBody(PhysicsServer::BODY_MODE_RIGID) { contact_monitor=NULL; can_sleep=true; + axis_lock = AXIS_LOCK_DISABLED; + PhysicsServer::get_singleton()->body_set_force_integration_callback(get_rid(),this,"_direct_state_changed"); } diff --git a/scene/3d/physics_body.h b/scene/3d/physics_body.h index a5faa9857b..6695ee719a 100644 --- a/scene/3d/physics_body.h +++ b/scene/3d/physics_body.h @@ -94,6 +94,14 @@ public: MODE_CHARACTER, MODE_KINEMATIC, }; + + enum AxisLock { + AXIS_LOCK_DISABLED, + AXIS_LOCK_X, + AXIS_LOCK_Y, + AXIS_LOCK_Z, + }; + private: bool can_sleep; @@ -109,6 +117,8 @@ private: bool active; bool ccd; + AxisLock axis_lock; + int max_contacts_reported; @@ -208,6 +218,10 @@ public: void set_use_continuous_collision_detection(bool p_enable); bool is_using_continuous_collision_detection() const; + void set_axis_lock(AxisLock p_lock); + AxisLock get_axis_lock() const; + + void apply_impulse(const Vector3& p_pos, const Vector3& p_impulse); RigidBody(); @@ -216,4 +230,5 @@ public: }; VARIANT_ENUM_CAST(RigidBody::Mode); +VARIANT_ENUM_CAST(RigidBody::AxisLock); #endif // PHYSICS_BODY__H diff --git a/scene/3d/visual_instance.h b/scene/3d/visual_instance.h index 4e652912c6..afb9ed70f8 100644 --- a/scene/3d/visual_instance.h +++ b/scene/3d/visual_instance.h @@ -91,6 +91,7 @@ public: FLAG_BILLBOARD_FIX_Y=VS::INSTANCE_FLAG_BILLBOARD_FIX_Y, FLAG_DEPH_SCALE=VS::INSTANCE_FLAG_DEPH_SCALE, FLAG_VISIBLE_IN_ALL_ROOMS=VS::INSTANCE_FLAG_VISIBLE_IN_ALL_ROOMS, + FLAG_USE_BAKED_LIGHT_VOLUME=VS::INSTANCE_FLAG_USE_BAKED_LIGHT_VOLUME, FLAG_MAX=VS::INSTANCE_FLAG_MAX, }; diff --git a/scene/animation/animation_player.cpp b/scene/animation/animation_player.cpp index c659447c23..15d3dccb71 100644 --- a/scene/animation/animation_player.cpp +++ b/scene/animation/animation_player.cpp @@ -907,8 +907,8 @@ void AnimationPlayer::play(const StringName& p_name, float p_custom_blend, float } } - c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0; c.current.from=&animation_set[name]; + c.current.pos=p_from_end ? c.current.from->animation->get_length() : 0; c.current.speed_scale=p_custom_scale; c.assigned=p_name; diff --git a/scene/gui/rich_text_label.cpp b/scene/gui/rich_text_label.cpp index 5ac278a38e..241d66fce4 100644 --- a/scene/gui/rich_text_label.cpp +++ b/scene/gui/rich_text_label.cpp @@ -1512,6 +1512,10 @@ void RichTextLabel::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_selection_enabled","enabled"),&RichTextLabel::set_selection_enabled); ObjectTypeDB::bind_method(_MD("is_selection_enabled"),&RichTextLabel::is_selection_enabled); + ObjectTypeDB::bind_method(_MD("parse_bbcode", "bbcode"),&RichTextLabel::parse_bbcode); + ObjectTypeDB::bind_method(_MD("append_bbcode", "bbcode"),&RichTextLabel::append_bbcode); + + ADD_SIGNAL( MethodInfo("meta_clicked",PropertyInfo(Variant::NIL,"meta"))); BIND_CONSTANT( ALIGN_LEFT ); diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp index 0bbc2dc695..91769bbb82 100644 --- a/scene/main/viewport.cpp +++ b/scene/main/viewport.cpp @@ -728,6 +728,7 @@ void Viewport::set_as_render_target(bool p_enable){ render_target_texture_rid=RID(); } + render_target_texture->set_flags(render_target_texture->flags); render_target_texture->emit_changed(); } @@ -773,6 +774,18 @@ bool Viewport::get_render_target_vflip() const{ } +void Viewport::set_render_target_filter(bool p_enable) { + + render_target_texture->set_flags(p_enable?int(Texture::FLAG_FILTER):int(0)); + +} + +bool Viewport::get_render_target_filter() const{ + + return (render_target_texture->get_flags()&Texture::FLAG_FILTER)!=0; +} + + Matrix32 Viewport::_get_input_pre_xform() const { Matrix32 pre_xf; @@ -990,6 +1003,9 @@ void Viewport::_bind_methods() { ObjectTypeDB::bind_method(_MD("set_render_target_vflip","enable"), &Viewport::set_render_target_vflip); ObjectTypeDB::bind_method(_MD("get_render_target_vflip"), &Viewport::get_render_target_vflip); + ObjectTypeDB::bind_method(_MD("set_render_target_filter","enable"), &Viewport::set_render_target_filter); + ObjectTypeDB::bind_method(_MD("get_render_target_filter"), &Viewport::get_render_target_filter); + ObjectTypeDB::bind_method(_MD("set_render_target_update_mode","mode"), &Viewport::set_render_target_update_mode); ObjectTypeDB::bind_method(_MD("get_render_target_update_mode"), &Viewport::get_render_target_update_mode); @@ -1020,6 +1036,7 @@ void Viewport::_bind_methods() { ADD_PROPERTY( PropertyInfo(Variant::BOOL,"transparent_bg"), _SCS("set_transparent_background"), _SCS("has_transparent_background") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/enabled"), _SCS("set_as_render_target"), _SCS("is_set_as_render_target") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/v_flip"), _SCS("set_render_target_vflip"), _SCS("get_render_target_vflip") ); + ADD_PROPERTY( PropertyInfo(Variant::BOOL,"render_target/filter"), _SCS("set_render_target_filter"), _SCS("get_render_target_filter") ); ADD_PROPERTY( PropertyInfo(Variant::INT,"render_target/update_mode",PROPERTY_HINT_ENUM,"Disabled,Once,When Visible,Always"), _SCS("set_render_target_update_mode"), _SCS("get_render_target_update_mode") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_2d"), _SCS("set_as_audio_listener_2d"), _SCS("is_audio_listener_2d") ); ADD_PROPERTY( PropertyInfo(Variant::BOOL,"audio_listener/enable_3d"), _SCS("set_as_audio_listener"), _SCS("is_audio_listener") ); diff --git a/scene/main/viewport.h b/scene/main/viewport.h index cc7f93cfa3..d54b489843 100644 --- a/scene/main/viewport.h +++ b/scene/main/viewport.h @@ -113,6 +113,7 @@ friend class RenderTargetTexture; bool transparent_bg; bool render_target_vflip; + bool render_target_filter; void _update_rect(); @@ -210,6 +211,9 @@ public: void set_render_target_vflip(bool p_enable); bool get_render_target_vflip() const; + void set_render_target_filter(bool p_enable); + bool get_render_target_filter() const; + void set_render_target_update_mode(RenderTargetUpdateMode p_mode); RenderTargetUpdateMode get_render_target_update_mode() const; Ref<RenderTargetTexture> get_render_target_texture() const; diff --git a/scene/register_scene_types.cpp b/scene/register_scene_types.cpp index 8fd39b0d74..b30ad2d71f 100644 --- a/scene/register_scene_types.cpp +++ b/scene/register_scene_types.cpp @@ -187,6 +187,7 @@ #include "scene/3d/area.h" #include "scene/3d/physics_joint.h" #include "scene/3d/multimesh_instance.h" +#include "scene/3d/baked_light.h" #include "scene/3d/ray_cast.h" #include "scene/3d/spatial_sample_player.h" #include "scene/3d/spatial_stream_player.h" @@ -401,7 +402,7 @@ void register_scene_types() { ObjectTypeDB::register_type<PathFollow>(); ObjectTypeDB::register_type<VisibilityNotifier>(); ObjectTypeDB::register_type<VisibilityEnabler>(); - + ObjectTypeDB::register_type<BakedLight>(); ObjectTypeDB::register_type<WorldEnvironment>(); //scenariofx diff --git a/scene/resources/environment.cpp b/scene/resources/environment.cpp index 3e12c7a5b5..0c55d22dbe 100644 --- a/scene/resources/environment.cpp +++ b/scene/resources/environment.cpp @@ -101,6 +101,8 @@ void Environment::_bind_methods() { ObjectTypeDB::bind_method(_MD("fx_set_param","param","value"),&Environment::fx_set_param); ObjectTypeDB::bind_method(_MD("fx_get_param","param"),&Environment::fx_get_param); + ADD_PROPERTYI( PropertyInfo(Variant::BOOL,"fxaa/enabled"),_SCS("set_enable_fx"),_SCS("is_fx_enabled"), FX_FXAA); + ADD_PROPERTY( PropertyInfo(Variant::INT,"background/mode",PROPERTY_HINT_ENUM,"Keep,Default Color,Color,Texture,Cubemap,Texture RGBE,Cubemap RGBE"),_SCS("set_background"),_SCS("get_background")); ADD_PROPERTYI( PropertyInfo(Variant::COLOR,"background/color"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_COLOR); ADD_PROPERTYI( PropertyInfo(Variant::OBJECT,"background/texture",PROPERTY_HINT_RESOURCE_TYPE,"Texture"),_SCS("set_background_param"),_SCS("get_background_param"), BG_PARAM_TEXTURE); @@ -181,6 +183,7 @@ void Environment::_bind_methods() { BIND_CONSTANT( BG_PARAM_MAX ); + BIND_CONSTANT( FX_FXAA ); BIND_CONSTANT( FX_GLOW ); BIND_CONSTANT( FX_DOF_BLUR ); BIND_CONSTANT( FX_HDR ); diff --git a/scene/resources/environment.h b/scene/resources/environment.h index c94c81b694..b90a043634 100644 --- a/scene/resources/environment.h +++ b/scene/resources/environment.h @@ -60,6 +60,7 @@ public: }; enum Fx { + FX_FXAA=VS::ENV_FX_FXAA, FX_GLOW=VS::ENV_FX_GLOW, FX_DOF_BLUR=VS::ENV_FX_DOF_BLUR, FX_HDR=VS::ENV_FX_HDR, diff --git a/scene/resources/mesh.cpp b/scene/resources/mesh.cpp index 6d0a1cf76b..c6e492fcb3 100644 --- a/scene/resources/mesh.cpp +++ b/scene/resources/mesh.cpp @@ -92,10 +92,17 @@ bool Mesh::_set(const StringName& p_name, const Variant& p_value) { return true; } - if (sname.begins_with("materials/")) { - - int idx=sname.get_slice("/",1).to_int()-1; - surface_set_material(idx,p_value); + if (sname.begins_with("surface_")) { + + int sl=sname.find("/"); + if (sl==-1) + return false; + int idx=sname.substr(8,sl-8).to_int()-1; + String what = sname.get_slice("/",1); + if (what=="material") + surface_set_material(idx,p_value); + else if (what=="name") + surface_set_name(idx,p_value); return true; } @@ -166,10 +173,17 @@ bool Mesh::_get(const StringName& p_name,Variant &r_ret) const { r_ret = get_morph_target_mode(); return true; - } else if (sname.begins_with("materials/")) { - - int idx=sname.get_slice("/",1).to_int()-1; - r_ret=surface_get_material(idx); + } else if (sname.begins_with("surface_")) { + + int sl=sname.find("/"); + if (sl==-1) + return false; + int idx=sname.substr(8,sl-8).to_int()-1; + String what = sname.get_slice("/",1); + if (what=="material") + r_ret=surface_get_material(idx); + else if (what=="name") + r_ret=surface_get_name(idx); return true; } else if (sname=="custom_aabb/custom_aabb") { @@ -210,7 +224,8 @@ void Mesh::_get_property_list( List<PropertyInfo> *p_list) const { for (int i=0;i<surfaces.size();i++) { p_list->push_back( PropertyInfo( Variant::DICTIONARY,"surfaces/"+itos(i), PROPERTY_HINT_NONE,"",PROPERTY_USAGE_NOEDITOR ) ); - p_list->push_back( PropertyInfo( Variant::OBJECT,"materials/"+itos(i+1), PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) ); + p_list->push_back( PropertyInfo( Variant::STRING,"surface_"+itos(i+1)+"/name", PROPERTY_HINT_NONE,"",PROPERTY_USAGE_EDITOR ) ); + p_list->push_back( PropertyInfo( Variant::OBJECT,"surface_"+itos(i+1)+"/material", PROPERTY_HINT_RESOURCE_TYPE,"Material",PROPERTY_USAGE_EDITOR ) ); } p_list->push_back( PropertyInfo( Variant::_AABB,"custom_aabb/custom_aabb" ) ); diff --git a/scene/resources/surface_tool.cpp b/scene/resources/surface_tool.cpp index d0c159e9f0..2856101674 100644 --- a/scene/resources/surface_tool.cpp +++ b/scene/resources/surface_tool.cpp @@ -32,57 +32,56 @@ #define EQ_VERTEX_DIST 0.00001 +bool SurfaceTool::Vertex::operator==(const Vertex& p_b) const { -bool SurfaceTool::compare(const Vertex& p_a,const Vertex& p_b) const { - if (p_a.vertex.distance_to(p_b.vertex)>EQ_VERTEX_DIST) + if (vertex!=p_b.vertex) return false; - if (format&Mesh::ARRAY_FORMAT_TEX_UV) { + if (uv!=p_b.uv) + return false; - if (p_a.uv.distance_to(p_b.uv)>EQ_VERTEX_DIST) - return false; - } + if (uv2!=p_b.uv2) + return false; - if (format&Mesh::ARRAY_FORMAT_TEX_UV2) { + if (normal!=p_b.normal) + return false; - if (p_a.uv2.distance_to(p_b.uv2)>EQ_VERTEX_DIST) - return false; - } + if (binormal!=p_b.binormal) + return false; - if (format&Mesh::ARRAY_FORMAT_NORMAL) { - if (p_a.normal.distance_to(p_b.normal)>EQ_VERTEX_DIST) - return false; - } + if (color!=p_b.color) + return false; - if (format&Mesh::ARRAY_FORMAT_TANGENT) { - if (p_a.binormal.distance_to(p_b.binormal)>EQ_VERTEX_DIST) - return false; - if (p_a.tangent.distance_to(p_b.tangent)>EQ_VERTEX_DIST) + if (bones.size()!=p_b.bones.size()) + return false; + + for(int i=0;i<bones.size();i++) { + if (bones[i]!=p_b.bones[i]) return false; } - if (format&Mesh::ARRAY_FORMAT_COLOR) { - if (p_a.color!=p_b.color) + for(int i=0;i<weights.size();i++) { + if (weights[i]!=p_b.weights[i]) return false; } - if (format&Mesh::ARRAY_FORMAT_BONES) { - for(int i=0;i<4;i++) { - if (Math::abs(p_a.bones[i]-p_b.bones[i])>CMP_EPSILON) - return false; - } - } + return true; +} - if (format&Mesh::ARRAY_FORMAT_WEIGHTS) { - for(int i=0;i<4;i++) { - if (Math::abs(p_a.weights[i]-p_b.weights[i])>CMP_EPSILON) - return false; - } - } +uint32_t SurfaceTool::VertexHasher::hash(const Vertex &p_vtx) { - return true; + uint32_t h = hash_djb2_buffer((const uint8_t*)&p_vtx.vertex,sizeof(real_t)*3); + h = hash_djb2_buffer((const uint8_t*)&p_vtx.normal,sizeof(real_t)*3,h); + h = hash_djb2_buffer((const uint8_t*)&p_vtx.binormal,sizeof(real_t)*3,h); + h = hash_djb2_buffer((const uint8_t*)&p_vtx.tangent,sizeof(real_t)*3,h); + h = hash_djb2_buffer((const uint8_t*)&p_vtx.uv,sizeof(real_t)*2,h); + h = hash_djb2_buffer((const uint8_t*)&p_vtx.uv2,sizeof(real_t)*2,h); + h = hash_djb2_buffer((const uint8_t*)&p_vtx.color,sizeof(real_t)*4,h); + h = hash_djb2_buffer((const uint8_t*)p_vtx.bones.ptr(),p_vtx.bones.size()*sizeof(int),h); + h = hash_djb2_buffer((const uint8_t*)p_vtx.weights.ptr(),p_vtx.weights.size()*sizeof(float),h); + return h; } void SurfaceTool::begin(Mesh::PrimitiveType p_primitive) { @@ -186,6 +185,17 @@ void SurfaceTool::add_weights( const Vector<float>& p_weights) { } +void SurfaceTool::add_smooth_group(bool p_smooth) { + + ERR_FAIL_COND(!begun); + if (index_array.size()) { + smooth_groups[index_array.size()]=p_smooth; + } else { + + smooth_groups[vertex_array.size()]=p_smooth; + } +} + void SurfaceTool::add_index( int p_index) { @@ -377,79 +387,53 @@ Ref<Mesh> SurfaceTool::commit(const Ref<Mesh>& p_existing) { void SurfaceTool::index() { -#if 0 - printf("indexing..\n"); - ERR_FAIL_COND( format & Surface::ARRAY_FORMAT_INDEX ); // already indexed - - index_array.clear(); - DVector< Vertex > indexed_vertex_array; + if (index_array.size()) + return; //already indexed - int vertex_array_len = vertex_array.size(); - vertex_array.read_lock(); - const Vertex*vertex_array_ptr = vertex_array.read(); - for (int i=0;i<vertex_array_len;i++) { + HashMap<Vertex,int,VertexHasher> indices; + List<Vertex> new_vertices; - int index_pos=-1; + for(List< Vertex >::Element *E=vertex_array.front();E;E=E->next()) { - int indexed_vertex_array_len=indexed_vertex_array.size(); - - if (indexed_vertex_array_len) { - - indexed_vertex_array.read_lock(); - const Vertex* indexed_vertex_array_ptr=indexed_vertex_array.read(); - - for (int j=0;j<indexed_vertex_array_len;j++) { - - if (vertex_array_ptr[i].same_as(indexed_vertex_array_ptr[j])) { - - index_pos=j; - break; - } - } - - indexed_vertex_array.read_unlock(); - } - - if (index_pos==-1) { - - index_pos=indexed_vertex_array.size(); - indexed_vertex_array.push_back(vertex_array_ptr[i]); + int *idxptr=indices.getptr(E->get()); + int idx; + if (!idxptr) { + idx=indices.size(); + new_vertices.push_back(E->get()); + indices[E->get()]=idx; } else { - - indexed_vertex_array.write_lock(); - indexed_vertex_array.write()[index_pos].normal+=vertex_array_ptr[i].normal; - indexed_vertex_array.write()[index_pos].binormal+=vertex_array_ptr[i].binormal; - indexed_vertex_array.write()[index_pos].tangent+=vertex_array_ptr[i].tangent; - indexed_vertex_array.write_unlock(); + idx=*idxptr; } - index_array.push_back(index_pos); - } - - int idxvertsize=indexed_vertex_array.size(); - indexed_vertex_array.write_lock(); - Vertex* idxvert=indexed_vertex_array.write(); - for (int i=0;i<idxvertsize;i++) { + index_array.push_back(idx); - idxvert[i].normal.normalize(); - idxvert[i].tangent.normalize(); - idxvert[i].binormal.normalize(); } - indexed_vertex_array.write_unlock(); - vertex_array.read_unlock(); - - format|=Surface::ARRAY_FORMAT_INDEX; - vertex_array=indexed_vertex_array; + vertex_array.clear(); + vertex_array=new_vertices; - printf("indexing.. end\n"); -#endif + format|=Mesh::ARRAY_FORMAT_INDEX; } void SurfaceTool::deindex() { + if (index_array.size()==0) + return; //nothing to deindex + Vector< Vertex > varr; + varr.resize(vertex_array.size()); + int idx=0; + for (List< Vertex >::Element *E=vertex_array.front();E;E=E->next()) { + varr[idx++]=E->get(); + } + vertex_array.clear(); + for (List<int>::Element *E=index_array.front();E;E=E->next()) { + + ERR_FAIL_INDEX(E->get(),varr.size()); + vertex_array.push_back(varr[E->get()]); + } + format&=~Mesh::ARRAY_FORMAT_INDEX; } @@ -631,80 +615,250 @@ void SurfaceTool::append_from(const Ref<Mesh>& p_existing, int p_surface,const T void SurfaceTool::generate_tangents() { ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_TEX_UV)); + ERR_FAIL_COND(!(format&Mesh::ARRAY_FORMAT_NORMAL)); -#if 0 - int len=vertex_array.size(); - vertex_array.write_lock(); - Vertex *vertexptr=vertex_array.write(); - - for (int i=0;i<len/3;i++) { + if (index_array.size()) { + Vector<List<Vertex>::Element*> vtx; + vtx.resize(vertex_array.size()); + int idx=0; + for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) { + vtx[idx++]=E; + E->get().binormal=Vector3(); + E->get().tangent=Vector3(); + } - Vector3 v1 = vertexptr[i*3+0].vertex; - Vector3 v2 = vertexptr[i*3+1].vertex; - Vector3 v3 = vertexptr[i*3+2].vertex; + for (List<int>::Element *E=index_array.front();E;) { + + int i[3]; + i[0]=E->get(); + E=E->next(); + ERR_FAIL_COND(!E); + i[1]=E->get(); + E=E->next(); + ERR_FAIL_COND(!E); + i[2]=E->get(); + E=E->next(); + ERR_FAIL_COND(!E); + + + Vector3 v1 = vtx[ i[0] ]->get().vertex; + Vector3 v2 = vtx[ i[1] ]->get().vertex; + Vector3 v3 = vtx[ i[2] ]->get().vertex; + + Vector2 w1 = vtx[ i[0] ]->get().uv; + Vector2 w2 = vtx[ i[1] ]->get().uv; + Vector2 w3 = vtx[ i[2] ]->get().uv; + + + float x1 = v2.x - v1.x; + float x2 = v3.x - v1.x; + float y1 = v2.y - v1.y; + float y2 = v3.y - v1.y; + float z1 = v2.z - v1.z; + float z2 = v3.z - v1.z; + + float s1 = w2.x - w1.x; + float s2 = w3.x - w1.x; + float t1 = w2.y - w1.y; + float t2 = w3.y - w1.y; + + float r = (s1 * t2 - s2 * t1); + + Vector3 binormal,tangent; + + if (r==0) { + binormal=Vector3(0,0,0); + tangent=Vector3(0,0,0); + } else { + tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); + binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); + } - Vector3 w1 = vertexptr[i*3+0].uv[0]; - Vector3 w2 = vertexptr[i*3+1].uv[0]; - Vector3 w3 = vertexptr[i*3+2].uv[0]; + tangent.normalize(); + binormal.normalize(); + Vector3 normal=Plane( v1, v2, v3 ).normal; + Vector3 tangentp = tangent - normal * normal.dot( tangent ); + Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal)); - float x1 = v2.x - v1.x; - float x2 = v3.x - v1.x; - float y1 = v2.y - v1.y; - float y2 = v3.y - v1.y; - float z1 = v2.z - v1.z; - float z2 = v3.z - v1.z; + tangentp.normalize(); + binormalp.normalize(); - float s1 = w2.x - w1.x; - float s2 = w3.x - w1.x; - float t1 = w2.y - w1.y; - float t2 = w3.y - w1.y; - float r = (s1 * t2 - s2 * t1); + for (int j=0;j<3;j++) { + vtx[ i[j] ]->get().binormal+=binormalp; + vtx[ i[j] ]->get().tangent+=tangentp; - Vector3 binormal,tangent; + } + } - if (r==0) { - binormal=Vector3(0,0,0); - tangent=Vector3(0,0,0); - } else { - tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, - (t2 * z1 - t1 * z2) * r); - binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, - (s1 * z2 - s2 * z1) * r); + for (List<Vertex>::Element *E=vertex_array.front();E;E=E->next()) { + E->get().binormal.normalize(); + E->get().tangent.normalize(); } - tangent.normalize(); - binormal.normalize(); - Vector3 normal=Plane( v1, v2, v3 ).normal; - Vector3 tangentp = tangent - normal * normal.dot( tangent ); - Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal)); + } else { + - tangentp.normalize(); - binormalp.normalize(); + for (List<Vertex>::Element *E=vertex_array.front();E;) { + List< Vertex >::Element *v[3]; + v[0]=E; + v[1]=v[0]->next(); + ERR_FAIL_COND(!v[1]); + v[2]=v[1]->next(); + ERR_FAIL_COND(!v[2]); + E=v[2]->next(); - for (int j=0;j<3;j++) { - vertexptr[i*3+j].normal=normal; - vertexptr[i*3+j].binormal=binormalp; - vertexptr[i*3+j].tangent=tangentp; + Vector3 v1 = v[0]->get().vertex; + Vector3 v2 = v[1]->get().vertex; + Vector3 v3 = v[2]->get().vertex; + + Vector2 w1 = v[0]->get().uv; + Vector2 w2 = v[1]->get().uv; + Vector2 w3 = v[2]->get().uv; + + + float x1 = v2.x - v1.x; + float x2 = v3.x - v1.x; + float y1 = v2.y - v1.y; + float y2 = v3.y - v1.y; + float z1 = v2.z - v1.z; + float z2 = v3.z - v1.z; + + float s1 = w2.x - w1.x; + float s2 = w3.x - w1.x; + float t1 = w2.y - w1.y; + float t2 = w3.y - w1.y; + + float r = (s1 * t2 - s2 * t1); + + Vector3 binormal,tangent; + + if (r==0) { + binormal=Vector3(0,0,0); + tangent=Vector3(0,0,0); + } else { + tangent = Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, + (t2 * z1 - t1 * z2) * r); + binormal = Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, + (s1 * z2 - s2 * z1) * r); + } + + tangent.normalize(); + binormal.normalize(); + Vector3 normal=Plane( v1, v2, v3 ).normal; + + Vector3 tangentp = tangent - normal * normal.dot( tangent ); + Vector3 binormalp = binormal - normal * (normal.dot(binormal)) - tangent * (tangent.dot(binormal)); + + tangentp.normalize(); + binormalp.normalize(); + + + for (int j=0;j<3;j++) { + v[j]->get().binormal=binormalp; + v[j]->get().tangent=tangentp; + + } } } - format|=Surface::ARRAY_FORMAT_TANGENT; - printf("adding tangents to the format\n"); + format|=Mesh::ARRAY_FORMAT_TANGENT; - vertex_array.write_unlock(); -#endif } -void SurfaceTool::generate_flat_normals() { +void SurfaceTool::generate_normals() { -} -void SurfaceTool::generate_smooth_normals() { + ERR_FAIL_COND(primitive!=Mesh::PRIMITIVE_TRIANGLES); + + bool was_indexed=index_array.size(); + + deindex(); + + HashMap<Vertex,Vector3,VertexHasher> vertex_hash; + + int count=0; + bool smooth=false; + if (smooth_groups.has(0)) + smooth=smooth_groups[0]; + + print_line("SMOOTH BEGIN? "+itos(smooth)); + + List< Vertex >::Element *B=vertex_array.front(); + for(List< Vertex >::Element *E=B;E;) { + + List< Vertex >::Element *v[3]; + v[0]=E; + v[1]=v[0]->next(); + ERR_FAIL_COND(!v[1]); + v[2]=v[1]->next(); + ERR_FAIL_COND(!v[2]); + E=v[2]->next(); + + Vector3 normal = Plane(v[0]->get().vertex,v[1]->get().vertex,v[2]->get().vertex).normal; + + if (smooth) { + + for(int i=0;i<3;i++) { + + Vector3 *lv=vertex_hash.getptr(v[i]->get()); + if (!lv) { + vertex_hash.set(v[i]->get(),normal); + } else { + (*lv)+=normal; + } + } + } else { + + for(int i=0;i<3;i++) { + + v[i]->get().normal=normal; + + } + } + count+=3; + + if (smooth_groups.has(count) || !E) { + + if (vertex_hash.size()) { + + while (B!=E) { + + + Vector3* lv=vertex_hash.getptr(B->get()); + if (lv) { + B->get().normal=lv->normalized(); + } + + B=B->next(); + } + + } else { + B=E; + } + + vertex_hash.clear(); + if (E) { + smooth=smooth_groups[count]; + print_line("SMOOTH AT "+itos(count)+": "+itos(smooth)); + + } + } + + } + + format|=Mesh::ARRAY_FORMAT_NORMAL; + + if (was_indexed) { + index(); + smooth_groups.clear(); + } } @@ -722,6 +876,7 @@ void SurfaceTool::clear() { last_weights.clear(); index_array.clear(); vertex_array.clear(); + smooth_groups.clear(); } @@ -736,12 +891,12 @@ void SurfaceTool::_bind_methods() { ObjectTypeDB::bind_method(_MD("add_uv2","uv2"),&SurfaceTool::add_uv2); ObjectTypeDB::bind_method(_MD("add_bones","bones"),&SurfaceTool::add_bones); ObjectTypeDB::bind_method(_MD("add_weights","weights"),&SurfaceTool::add_weights); + ObjectTypeDB::bind_method(_MD("add_smooth_group","smooth"),&SurfaceTool::add_smooth_group); ObjectTypeDB::bind_method(_MD("set_material","material:Material"),&SurfaceTool::set_material); ObjectTypeDB::bind_method(_MD("index"),&SurfaceTool::index); ObjectTypeDB::bind_method(_MD("deindex"),&SurfaceTool::deindex); - ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals); - ObjectTypeDB::bind_method(_MD("generate_smooth_normals"),&SurfaceTool::generate_smooth_normals); - ObjectTypeDB::bind_method(_MD("generate_tangents"),&SurfaceTool::generate_tangents); + ///ObjectTypeDB::bind_method(_MD("generate_flat_normals"),&SurfaceTool::generate_flat_normals); + ObjectTypeDB::bind_method(_MD("generate_normals"),&SurfaceTool::generate_normals); ObjectTypeDB::bind_method(_MD("commit:Mesh","existing:Mesh"),&SurfaceTool::commit,DEFVAL( RefPtr() )); ObjectTypeDB::bind_method(_MD("clear"),&SurfaceTool::clear); diff --git a/scene/resources/surface_tool.h b/scene/resources/surface_tool.h index 8f0fcaa01a..fe82d3a4ce 100644 --- a/scene/resources/surface_tool.h +++ b/scene/resources/surface_tool.h @@ -49,12 +49,17 @@ public: Vector<int> bones; Vector<float> weights; + bool operator==(const Vertex& p_vertex) const; + Vertex() { } }; private: - bool compare(const Vertex& p_a,const Vertex& p_b) const; + + struct VertexHasher { + static _FORCE_INLINE_ uint32_t hash(const Vertex &p_vtx); + }; bool begun; bool first; @@ -64,6 +69,7 @@ private: //arrays List< Vertex > vertex_array; List< int > index_array; + Map<int,bool> smooth_groups; //memory Color last_color; @@ -92,13 +98,13 @@ public: void add_uv2( const Vector2& p_uv); void add_bones( const Vector<int>& p_indices); void add_weights( const Vector<float>& p_weights); + void add_smooth_group(bool p_smooth); void add_index( int p_index); void index(); void deindex(); - void generate_flat_normals(); - void generate_smooth_normals(); + void generate_normals(); void generate_tangents(); void add_to_format(int p_flags) { format|=p_flags; } |