diff options
author | Juan Linietsky <reduzio@gmail.com> | 2014-05-14 01:22:15 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2014-05-14 01:22:15 -0300 |
commit | b324ff7ea584676fcc3292808d7e7ea609982f8e (patch) | |
tree | b80e9aa0b8f2926a398e25ef904f6229cb3e28dd /scene | |
parent | 45a509282e912d85c46b40974a2deb926be5be42 (diff) | |
download | redot-engine-b324ff7ea584676fcc3292808d7e7ea609982f8e.tar.gz |
A bit of everything:
-IMA-ADPCM support for samples, this means that sound effects can be compressed and use 4 timess less RAM.
-New 3D import workflow based on Wavefront OBJ. Import single objects as mesh resources instead of full scenes. Many people prefers to work this way. Just like the rest of the imported resources, these are updated in realtime if modified externally.
-Mesh resources now support naming surfaces. This helps reimporting to identify which user-created materials must be kept.
-Several fixes and improvements to SurfaceTool.
-Anti Aliasing added to WorldEnvironment effects (using FXAA)
-2D Physics bodies (RigidBody, KinematicBody, etc), Raycasts, Tilemap, etc support collision layers. This makes easy to group which objects collide against which.
-2D Trigger shapes can now also trigger collision reporting in other 2D bodies (it used to be in Area2D before)
-Viewport render target textures can now be filtered.
-Few fixes in GDscript make it easier to work with static functions and class members.
-Several and many bugfixes.
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; } |