diff options
Diffstat (limited to 'servers')
31 files changed, 463 insertions, 36 deletions
diff --git a/servers/physics/area_pair_sw.cpp b/servers/physics/area_pair_sw.cpp index c6bf6114a0..24f3b75ca5 100644 --- a/servers/physics/area_pair_sw.cpp +++ b/servers/physics/area_pair_sw.cpp @@ -32,6 +32,11 @@ bool AreaPairSW::setup(float p_step) { + if (!area->test_collision_mask(body)) { + colliding = false; + return false; + } + bool result = CollisionSolverSW::solve_static(body->get_shape(body_shape),body->get_transform() * body->get_shape_transform(body_shape),area->get_shape(area_shape),area->get_transform() * area->get_shape_transform(area_shape),NULL,this); if (result!=colliding) { @@ -100,6 +105,11 @@ AreaPairSW::~AreaPairSW() { bool Area2PairSW::setup(float p_step) { + if (!area_a->test_collision_mask(area_b)) { + colliding = false; + return false; + } + // bool result = area_a->test_collision_mask(area_b) && CollisionSolverSW::solve(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),Vector2(),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),Vector2(),NULL,this); bool result = CollisionSolverSW::solve_static(area_a->get_shape(shape_a),area_a->get_transform() * area_a->get_shape_transform(shape_a),area_b->get_shape(shape_b),area_b->get_transform() * area_b->get_shape_transform(shape_b),NULL,this); diff --git a/servers/physics/body_pair_sw.cpp b/servers/physics/body_pair_sw.cpp index a971cdaad8..40e906c36c 100644 --- a/servers/physics/body_pair_sw.cpp +++ b/servers/physics/body_pair_sw.cpp @@ -221,7 +221,7 @@ bool BodyPairSW::_test_ccd(float p_step,BodySW *p_A, int p_shape_A,const Transfo bool BodyPairSW::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()<=PhysicsServer::BODY_MODE_KINEMATIC && B->get_mode()<=PhysicsServer::BODY_MODE_KINEMATIC && A->get_max_contacts_reported()==0 && B->get_max_contacts_reported()==0)) { + if (!A->test_collision_mask(B) || 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; } diff --git a/servers/physics/collision_object_sw.cpp b/servers/physics/collision_object_sw.cpp index 55c8c1b955..f2864ee95e 100644 --- a/servers/physics/collision_object_sw.cpp +++ b/servers/physics/collision_object_sw.cpp @@ -217,5 +217,6 @@ CollisionObjectSW::CollisionObjectSW(Type p_type) { space=NULL; instance_id=0; layer_mask=1; + collision_mask=1; ray_pickable=true; } diff --git a/servers/physics/collision_object_sw.h b/servers/physics/collision_object_sw.h index 592c84e667..bc71c2709b 100644 --- a/servers/physics/collision_object_sw.h +++ b/servers/physics/collision_object_sw.h @@ -53,6 +53,7 @@ private: RID self; ObjectID instance_id; uint32_t layer_mask; + uint32_t collision_mask; struct Shape { @@ -136,6 +137,13 @@ public: _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; } + _FORCE_INLINE_ void set_collision_mask(uint32_t p_mask) { collision_mask=p_mask; } + _FORCE_INLINE_ uint32_t get_collision_mask() const { return collision_mask; } + + _FORCE_INLINE_ bool test_collision_mask(CollisionObjectSW* p_other) const { + return layer_mask&p_other->collision_mask || p_other->layer_mask&collision_mask; + } + void remove_shape(ShapeSW *p_shape); void remove_shape(int p_index); diff --git a/servers/physics/joints/hinge_joint_sw.cpp b/servers/physics/joints/hinge_joint_sw.cpp index feaf00290d..37b73f64c7 100644 --- a/servers/physics/joints/hinge_joint_sw.cpp +++ b/servers/physics/joints/hinge_joint_sw.cpp @@ -420,7 +420,6 @@ float HingeJointSW::get_param(PhysicsServer::HingeJointParam p_param) const{ void HingeJointSW::set_flag(PhysicsServer::HingeJointFlag p_flag, bool p_value){ - print_line(p_flag+": "+itos(p_value)); switch (p_flag) { case PhysicsServer::HINGE_JOINT_FLAG_USE_LIMIT: m_useLimit=p_value; break; case PhysicsServer::HINGE_JOINT_FLAG_ENABLE_MOTOR: m_enableAngularMotor=p_value; break; diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp index 5eb14d80dc..6c098a6df2 100644 --- a/servers/physics/physics_server_sw.cpp +++ b/servers/physics/physics_server_sw.cpp @@ -34,7 +34,8 @@ #include "joints/slider_joint_sw.h" #include "joints/cone_twist_joint_sw.h" #include "joints/generic_6dof_joint_sw.h" - +#include "script_language.h" +#include "os/os.h" RID PhysicsServerSW::shape_create(ShapeType p_shape) { @@ -418,6 +419,22 @@ Transform PhysicsServerSW::area_get_transform(RID p_area) const { return area->get_transform(); }; +void PhysicsServerSW::area_set_layer_mask(RID p_area,uint32_t p_mask) { + + AreaSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_layer_mask(p_mask); +} + +void PhysicsServerSW::area_set_collision_mask(RID p_area,uint32_t p_mask) { + + AreaSW *area = area_owner.get(p_area); + ERR_FAIL_COND(!area); + + area->set_collision_mask(p_mask); +} + void PhysicsServerSW::area_set_monitorable(RID p_area,bool p_monitorable) { AreaSW *area = area_owner.get(p_area); @@ -657,6 +674,25 @@ uint32_t PhysicsServerSW::body_get_layer_mask(RID p_body, uint32_t p_mask) const } +void PhysicsServerSW::body_set_collision_mask(RID p_body, uint32_t p_mask) { + + BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + + body->set_collision_mask(p_mask); + body->wakeup(); + +} + +uint32_t PhysicsServerSW::body_get_collision_mask(RID p_body, uint32_t p_mask) const{ + + const BodySW *body = body_owner.get(p_body); + ERR_FAIL_COND_V(!body,0); + + return body->get_collision_mask(); + +} + void PhysicsServerSW::body_attach_object_instance_ID(RID p_body,uint32_t p_ID) { @@ -1474,12 +1510,51 @@ void PhysicsServerSW::flush_queries() { return; doing_sync=true; + + uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); + for( Set<const SpaceSW*>::Element *E=active_spaces.front();E;E=E->next()) { SpaceSW *space=(SpaceSW *)E->get(); space->call_queries(); } + + if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) { + + uint64_t total_time[SpaceSW::ELAPSED_TIME_MAX]; + static const char* time_name[SpaceSW::ELAPSED_TIME_MAX]={ + "integrate_forces", + "generate_islands", + "setup_constraints", + "solve_constraints", + "integrate_velocities" + }; + + for(int i=0;i<SpaceSW::ELAPSED_TIME_MAX;i++) { + total_time[i]=0; + } + + for( Set<const SpaceSW*>::Element *E=active_spaces.front();E;E=E->next()) { + + for(int i=0;i<SpaceSW::ELAPSED_TIME_MAX;i++) { + total_time[i]+=E->get()->get_elapsed_time(SpaceSW::ElapsedTime(i)); + } + + } + + Array values; + values.resize(SpaceSW::ELAPSED_TIME_MAX*2); + for(int i=0;i<SpaceSW::ELAPSED_TIME_MAX;i++) { + values[i*2+0]=time_name[i]; + values[i*2+1]=USEC_TO_SEC(total_time[i]); + } + values.push_back("flush_queries"); + values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()-time_beg)); + + ScriptDebugger::get_singleton()->add_profiling_frame_data("physics",values); + + } }; diff --git a/servers/physics/physics_server_sw.h b/servers/physics/physics_server_sw.h index 2aadac2216..59eeeb42a7 100644 --- a/servers/physics/physics_server_sw.h +++ b/servers/physics/physics_server_sw.h @@ -131,6 +131,9 @@ public: virtual void area_set_ray_pickable(RID p_area,bool p_enable); virtual bool area_is_ray_pickable(RID p_area) const; + virtual void area_set_collision_mask(RID p_area,uint32_t p_mask); + virtual void area_set_layer_mask(RID p_area,uint32_t p_mask); + virtual void area_set_monitorable(RID p_area,bool p_monitorable); virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method); @@ -171,6 +174,9 @@ public: virtual void body_set_layer_mask(RID p_body, uint32_t p_mask); virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const; + virtual void body_set_collision_mask(RID p_body, uint32_t p_mask); + virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const; + virtual void body_set_user_flags(RID p_body, uint32_t p_flags); virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const; diff --git a/servers/physics/space_sw.cpp b/servers/physics/space_sw.cpp index 4cf7729b09..1e6f42aa02 100644 --- a/servers/physics/space_sw.cpp +++ b/servers/physics/space_sw.cpp @@ -736,6 +736,10 @@ SpaceSW::SpaceSW() { direct_access = memnew( PhysicsDirectSpaceStateSW ); direct_access->space=this; + + for(int i=0;i<ELAPSED_TIME_MAX;i++) + elapsed_time[i]=0; + } SpaceSW::~SpaceSW() { diff --git a/servers/physics/space_sw.h b/servers/physics/space_sw.h index 6300c206d8..3fdef7e62b 100644 --- a/servers/physics/space_sw.h +++ b/servers/physics/space_sw.h @@ -59,6 +59,20 @@ public: class SpaceSW { +public: + + enum ElapsedTime { + ELAPSED_TIME_INTEGRATE_FORCES, + ELAPSED_TIME_GENERATE_ISLANDS, + ELAPSED_TIME_SETUP_CONSTRAINTS, + ELAPSED_TIME_SOLVE_CONSTRAINTS, + ELAPSED_TIME_INTEGRATE_VELOCITIES, + ELAPSED_TIME_MAX + + }; +private: + + uint64_t elapsed_time[ELAPSED_TIME_MAX]; PhysicsDirectSpaceStateSW *direct_access; RID self; @@ -178,6 +192,8 @@ public: void set_static_global_body(RID p_body) { static_global_body=p_body; } RID get_static_global_body() { return static_global_body; } + void set_elapsed_time(ElapsedTime p_time,uint64_t p_msec) { elapsed_time[p_time]=p_msec; } + uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; } SpaceSW(); ~SpaceSW(); diff --git a/servers/physics/step_sw.cpp b/servers/physics/step_sw.cpp index f10dadf81a..5b7ebce817 100644 --- a/servers/physics/step_sw.cpp +++ b/servers/physics/step_sw.cpp @@ -29,6 +29,8 @@ #include "step_sw.h" #include "joints_sw.h" +#include "os/os.h" + void StepSW::_populate_island(BodySW* p_body,BodySW** p_island,ConstraintSW **p_constraint_island) { p_body->set_island_step(_step); @@ -152,6 +154,10 @@ void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) { const SelfList<BodySW>::List * body_list = &p_space->get_active_body_list(); /* INTEGRATE FORCES */ + + uint64_t profile_begtime = OS::get_singleton()->get_ticks_usec(); + uint64_t profile_endtime=0; + int active_count=0; const SelfList<BodySW>*b = body_list->first(); @@ -165,6 +171,12 @@ void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) { p_space->set_active_objects(active_count); + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(SpaceSW::ELAPSED_TIME_INTEGRATE_FORCES,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* GENERATE CONSTRAINT ISLANDS */ BodySW *island_list=NULL; @@ -214,6 +226,13 @@ void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) { p_space->area_remove_from_moved_list((SelfList<AreaSW>*)aml.first()); //faster to remove here } + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(SpaceSW::ELAPSED_TIME_GENERATE_ISLANDS,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + + // print_line("island count: "+itos(island_count)+" active count: "+itos(active_count)); /* SETUP CONSTRAINT ISLANDS */ @@ -226,6 +245,12 @@ void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) { } } + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(SpaceSW::ELAPSED_TIME_SETUP_CONSTRAINTS,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* SOLVE CONSTRAINT ISLANDS */ { @@ -237,6 +262,13 @@ void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) { } } + + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(SpaceSW::ELAPSED_TIME_SOLVE_CONSTRAINTS,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* INTEGRATE VELOCITIES */ b = body_list->first(); @@ -257,6 +289,12 @@ void StepSW::step(SpaceSW* p_space,float p_delta,int p_iterations) { } } + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(SpaceSW::ELAPSED_TIME_INTEGRATE_VELOCITIES,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + p_space->update(); p_space->unlock(); _step++; diff --git a/servers/physics_2d/body_2d_sw.cpp b/servers/physics_2d/body_2d_sw.cpp index ab1c7ef66f..12ac0bd1ca 100644 --- a/servers/physics_2d/body_2d_sw.cpp +++ b/servers/physics_2d/body_2d_sw.cpp @@ -33,7 +33,7 @@ void Body2DSW::_update_inertia() { - if (get_space() && !inertia_update_list.in_list()) + if (!user_inertia && get_space() && !inertia_update_list.in_list()) get_space()->body_add_to_inertia_update_list(&inertia_update_list); } @@ -48,6 +48,8 @@ void Body2DSW::update_inertias() { case Physics2DServer::BODY_MODE_RIGID: { + if(user_inertia) break; + //update tensor for allshapes, not the best way but should be somehow OK. (inspired from bullet) float total_area=0; @@ -157,6 +159,15 @@ void Body2DSW::set_param(Physics2DServer::BodyParameter p_param, float p_value) _update_inertia(); } break; + case Physics2DServer::BODY_PARAM_INERTIA: { + if(p_value<=0) { + user_inertia = false; + _update_inertia(); + } else { + user_inertia = true; + _inv_inertia = 1.0 / p_value; + } + } break; case Physics2DServer::BODY_PARAM_GRAVITY_SCALE: { gravity_scale=p_value; } break; @@ -186,6 +197,9 @@ float Body2DSW::get_param(Physics2DServer::BodyParameter p_param) const { case Physics2DServer::BODY_PARAM_MASS: { return mass; } break; + case Physics2DServer::BODY_PARAM_INERTIA: { + return _inv_inertia==0 ? 0 : 1.0 / _inv_inertia; + } break; case Physics2DServer::BODY_PARAM_GRAVITY_SCALE: { return gravity_scale; } break; @@ -665,6 +679,7 @@ Body2DSW::Body2DSW() : CollisionObject2DSW(TYPE_BODY), active_list(this), inerti angular_velocity=0; biased_angular_velocity=0; mass=1; + user_inertia=false; _inv_inertia=0; _inv_mass=1; bounce=0; diff --git a/servers/physics_2d/body_2d_sw.h b/servers/physics_2d/body_2d_sw.h index b7f3ab01db..ed98017629 100644 --- a/servers/physics_2d/body_2d_sw.h +++ b/servers/physics_2d/body_2d_sw.h @@ -57,6 +57,7 @@ class Body2DSW : public CollisionObject2DSW { real_t _inv_mass; real_t _inv_inertia; + bool user_inertia; Vector2 gravity; real_t area_linear_damp; @@ -204,10 +205,10 @@ public: _FORCE_INLINE_ real_t get_biased_angular_velocity() const { return biased_angular_velocity; } - _FORCE_INLINE_ void apply_impulse(const Vector2& p_pos, const Vector2& p_j) { + _FORCE_INLINE_ void apply_impulse(const Vector2& p_offset, const Vector2& p_impulse) { - linear_velocity += p_j * _inv_mass; - angular_velocity += _inv_inertia * p_pos.cross(p_j); + linear_velocity += p_impulse * _inv_mass; + angular_velocity += _inv_inertia * p_offset.cross(p_impulse); } _FORCE_INLINE_ void apply_bias_impulse(const Vector2& p_pos, const Vector2& p_j) { @@ -243,6 +244,11 @@ public: void set_applied_torque(real_t p_torque) { applied_torque=p_torque; } real_t get_applied_torque() const { return applied_torque; } + _FORCE_INLINE_ void add_force(const Vector2& p_force, const Vector2& p_offset) { + + applied_force += p_force; + applied_torque += p_offset.cross(p_force); + } _FORCE_INLINE_ void set_continuous_collision_detection_mode(Physics2DServer::CCDMode p_mode) { continuous_cd_mode=p_mode; } _FORCE_INLINE_ Physics2DServer::CCDMode get_continuous_collision_detection_mode() const { return continuous_cd_mode; } diff --git a/servers/physics_2d/physics_2d_server_sw.cpp b/servers/physics_2d/physics_2d_server_sw.cpp index c571331498..54cd929c2f 100644 --- a/servers/physics_2d/physics_2d_server_sw.cpp +++ b/servers/physics_2d/physics_2d_server_sw.cpp @@ -31,6 +31,9 @@ #include "broad_phase_2d_hash_grid.h" #include "collision_solver_2d_sw.h" #include "globals.h" +#include "script_language.h" +#include "os/os.h" + RID Physics2DServerSW::shape_create(ShapeType p_shape) { Shape2DSW *shape=NULL; @@ -860,6 +863,15 @@ void Physics2DServerSW::body_apply_impulse(RID p_body, const Vector2& p_pos, con body->wakeup(); }; +void Physics2DServerSW::body_add_force(RID p_body, const Vector2& p_offset, const Vector2& p_force) { + + Body2DSW *body = body_owner.get(p_body); + ERR_FAIL_COND(!body); + + body->add_force(p_force,p_offset); + body->wakeup(); +}; + void Physics2DServerSW::body_set_axis_velocity(RID p_body, const Vector2& p_axis_velocity) { Body2DSW *body = body_owner.get(p_body); @@ -1267,6 +1279,8 @@ void Physics2DServerSW::step(float p_step) { active_objects+=E->get()->get_active_objects(); collision_pairs+=E->get()->get_collision_pairs(); } + + }; void Physics2DServerSW::sync() { @@ -1279,6 +1293,7 @@ void Physics2DServerSW::flush_queries() { if (!active) return; + uint64_t time_beg = OS::get_singleton()->get_ticks_usec(); for( Set<const Space2DSW*>::Element *E=active_spaces.front();E;E=E->next()) { @@ -1286,7 +1301,44 @@ void Physics2DServerSW::flush_queries() { space->call_queries(); } -}; + + if (ScriptDebugger::get_singleton() && ScriptDebugger::get_singleton()->is_profiling()) { + + uint64_t total_time[Space2DSW::ELAPSED_TIME_MAX]; + static const char* time_name[Space2DSW::ELAPSED_TIME_MAX]={ + "integrate_forces", + "generate_islands", + "setup_constraints", + "solve_constraints", + "integrate_velocities" + }; + + for(int i=0;i<Space2DSW::ELAPSED_TIME_MAX;i++) { + total_time[i]=0; + } + + for( Set<const Space2DSW*>::Element *E=active_spaces.front();E;E=E->next()) { + + for(int i=0;i<Space2DSW::ELAPSED_TIME_MAX;i++) { + total_time[i]+=E->get()->get_elapsed_time(Space2DSW::ElapsedTime(i)); + } + + } + + Array values; + values.resize(Space2DSW::ELAPSED_TIME_MAX*2); + for(int i=0;i<Space2DSW::ELAPSED_TIME_MAX;i++) { + values[i*2+0]=time_name[i]; + values[i*2+1]=USEC_TO_SEC(total_time[i]); + } + values.push_back("flush_queries"); + values.push_back(USEC_TO_SEC(OS::get_singleton()->get_ticks_usec()-time_beg)); + + ScriptDebugger::get_singleton()->add_profiling_frame_data("physics_2d",values); + + } + +} void Physics2DServerSW::end_sync() { doing_sync=false; diff --git a/servers/physics_2d/physics_2d_server_sw.h b/servers/physics_2d/physics_2d_server_sw.h index cd4dfc1a8b..d557688b91 100644 --- a/servers/physics_2d/physics_2d_server_sw.h +++ b/servers/physics_2d/physics_2d_server_sw.h @@ -55,6 +55,7 @@ friend class Physics2DDirectBodyStateSW; bool using_threads; + Step2DSW *stepper; Set<const Space2DSW*> active_spaces; @@ -205,6 +206,8 @@ public: virtual void body_set_applied_torque(RID p_body, float p_torque); virtual float body_get_applied_torque(RID p_body) const; + virtual void body_add_force(RID p_body, const Vector2& p_offset, const Vector2& p_force); + virtual void body_apply_impulse(RID p_body, const Vector2& p_pos, const Vector2& p_impulse); virtual void body_set_axis_velocity(RID p_body, const Vector2& p_axis_velocity); diff --git a/servers/physics_2d/physics_2d_server_wrap_mt.h b/servers/physics_2d/physics_2d_server_wrap_mt.h index 60f8a4c879..891c45addf 100644 --- a/servers/physics_2d/physics_2d_server_wrap_mt.h +++ b/servers/physics_2d/physics_2d_server_wrap_mt.h @@ -205,6 +205,7 @@ public: FUNC2(body_set_applied_torque,RID,float); FUNC1RC(float,body_get_applied_torque,RID); + FUNC3(body_add_force,RID,const Vector2&,const Vector2&); FUNC3(body_apply_impulse,RID,const Vector2&,const Vector2&); FUNC2(body_set_axis_velocity,RID,const Vector2&); diff --git a/servers/physics_2d/space_2d_sw.cpp b/servers/physics_2d/space_2d_sw.cpp index 027e218bfc..ddef5fc86b 100644 --- a/servers/physics_2d/space_2d_sw.cpp +++ b/servers/physics_2d/space_2d_sw.cpp @@ -198,7 +198,7 @@ int Physics2DDirectSpaceStateSW::intersect_shape(const RID& p_shape, const Matri Rect2 aabb = p_xform.xform(shape->get_aabb()); aabb=aabb.grow(p_margin); - int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,Space2DSW::INTERSECTION_QUERY_MAX,space->intersection_query_subindex_results); + int amount = space->broadphase->cull_aabb(aabb,space->intersection_query_results,p_result_max,space->intersection_query_subindex_results); bool collided=false; int cc=0; @@ -1325,7 +1325,8 @@ Space2DSW::Space2DSW() { direct_access->space=this; - + for(int i=0;i<ELAPSED_TIME_MAX;i++) + elapsed_time[i]=0; } diff --git a/servers/physics_2d/space_2d_sw.h b/servers/physics_2d/space_2d_sw.h index 5f35f224b2..f8e1f32838 100644 --- a/servers/physics_2d/space_2d_sw.h +++ b/servers/physics_2d/space_2d_sw.h @@ -60,6 +60,20 @@ public: class Space2DSW { +public: + + enum ElapsedTime { + ELAPSED_TIME_INTEGRATE_FORCES, + ELAPSED_TIME_GENERATE_ISLANDS, + ELAPSED_TIME_SETUP_CONSTRAINTS, + ELAPSED_TIME_SOLVE_CONSTRAINTS, + ELAPSED_TIME_INTEGRATE_VELOCITIES, + ELAPSED_TIME_MAX + + }; +private: + + uint64_t elapsed_time[ELAPSED_TIME_MAX]; Physics2DDirectSpaceStateSW *direct_access; RID self; @@ -182,6 +196,9 @@ public: Physics2DDirectSpaceStateSW *get_direct_state(); + void set_elapsed_time(ElapsedTime p_time,uint64_t p_msec) { elapsed_time[p_time]=p_msec; } + uint64_t get_elapsed_time(ElapsedTime p_time) const { return elapsed_time[p_time]; } + Space2DSW(); ~Space2DSW(); }; diff --git a/servers/physics_2d/step_2d_sw.cpp b/servers/physics_2d/step_2d_sw.cpp index 4f9d06ee96..4f86168c1e 100644 --- a/servers/physics_2d/step_2d_sw.cpp +++ b/servers/physics_2d/step_2d_sw.cpp @@ -27,7 +27,7 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "step_2d_sw.h" - +#include "os/os.h" void Step2DSW::_populate_island(Body2DSW* p_body,Body2DSW** p_island,Constraint2DSW **p_constraint_island) { @@ -142,6 +142,11 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { const SelfList<Body2DSW>::List * body_list = &p_space->get_active_body_list(); /* INTEGRATE FORCES */ + + uint64_t profile_begtime = OS::get_singleton()->get_ticks_usec(); + uint64_t profile_endtime=0; + + int active_count=0; const SelfList<Body2DSW>*b = body_list->first(); @@ -154,6 +159,13 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { p_space->set_active_objects(active_count); + + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_INTEGRATE_FORCES,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* GENERATE CONSTRAINT ISLANDS */ Body2DSW *island_list=NULL; @@ -190,7 +202,6 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { const SelfList<Area2DSW>::List &aml = p_space->get_moved_area_list(); - while(aml.first()) { for(const Set<Constraint2DSW*>::Element *E=aml.first()->self()->get_constraints().front();E;E=E->next()) { @@ -206,6 +217,13 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { } // print_line("island count: "+itos(island_count)+" active count: "+itos(active_count)); + + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_GENERATE_ISLANDS,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* SETUP CONSTRAINT ISLANDS */ { @@ -248,6 +266,12 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { } } + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_SETUP_CONSTRAINTS,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* SOLVE CONSTRAINT ISLANDS */ { @@ -259,6 +283,12 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { } } + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_SOLVE_CONSTRAINTS,profile_endtime-profile_begtime); + profile_begtime=profile_endtime; + } + /* INTEGRATE VELOCITIES */ b = body_list->first(); @@ -280,6 +310,12 @@ void Step2DSW::step(Space2DSW* p_space,float p_delta,int p_iterations) { } } + { //profile + profile_endtime=OS::get_singleton()->get_ticks_usec(); + p_space->set_elapsed_time(Space2DSW::ELAPSED_TIME_INTEGRATE_VELOCITIES,profile_endtime-profile_begtime); + //profile_begtime=profile_endtime; + } + p_space->update(); p_space->unlock(); _step++; diff --git a/servers/physics_2d_server.cpp b/servers/physics_2d_server.cpp index 2d267a5749..411b99ebc8 100644 --- a/servers/physics_2d_server.cpp +++ b/servers/physics_2d_server.cpp @@ -597,6 +597,7 @@ void Physics2DServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("body_get_state","body","state"),&Physics2DServer::body_get_state); ObjectTypeDB::bind_method(_MD("body_apply_impulse","body","pos","impulse"),&Physics2DServer::body_apply_impulse); + ObjectTypeDB::bind_method(_MD("body_add_force","body","offset","force"),&Physics2DServer::body_add_force); ObjectTypeDB::bind_method(_MD("body_set_axis_velocity","body","axis_velocity"),&Physics2DServer::body_set_axis_velocity); ObjectTypeDB::bind_method(_MD("body_add_collision_exception","body","excepted_body"),&Physics2DServer::body_add_collision_exception); @@ -629,7 +630,7 @@ void Physics2DServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("groove_joint_create","groove1_a","groove2_a","anchor_b","body_a","body_b"),&Physics2DServer::groove_joint_create,DEFVAL(RID()),DEFVAL(RID())); ObjectTypeDB::bind_method(_MD("damped_spring_joint_create","anchor_a","anchor_b","body_a","body_b"),&Physics2DServer::damped_spring_joint_create,DEFVAL(RID())); - ObjectTypeDB::bind_method(_MD("damped_string_joint_set_param","joint","param","value"),&Physics2DServer::damped_string_joint_set_param,DEFVAL(RID())); + ObjectTypeDB::bind_method(_MD("damped_string_joint_set_param","joint","param","value"),&Physics2DServer::damped_string_joint_set_param); ObjectTypeDB::bind_method(_MD("damped_string_joint_get_param","joint","param"),&Physics2DServer::damped_string_joint_get_param); ObjectTypeDB::bind_method(_MD("joint_get_type","joint"),&Physics2DServer::joint_get_type); @@ -677,6 +678,7 @@ void Physics2DServer::_bind_methods() { BIND_CONSTANT( BODY_PARAM_BOUNCE ); BIND_CONSTANT( BODY_PARAM_FRICTION ); BIND_CONSTANT( BODY_PARAM_MASS ); + BIND_CONSTANT( BODY_PARAM_INERTIA ); BIND_CONSTANT( BODY_PARAM_GRAVITY_SCALE ); BIND_CONSTANT( BODY_PARAM_LINEAR_DAMP); BIND_CONSTANT( BODY_PARAM_ANGULAR_DAMP); diff --git a/servers/physics_2d_server.h b/servers/physics_2d_server.h index 25875f16d3..53c5a9ecc0 100644 --- a/servers/physics_2d_server.h +++ b/servers/physics_2d_server.h @@ -421,6 +421,7 @@ public: BODY_PARAM_BOUNCE, BODY_PARAM_FRICTION, BODY_PARAM_MASS, ///< unused for static, always infinite + BODY_PARAM_INERTIA, // read-only: computed from mass & shapes BODY_PARAM_GRAVITY_SCALE, BODY_PARAM_LINEAR_DAMP, BODY_PARAM_ANGULAR_DAMP, @@ -450,7 +451,9 @@ public: virtual void body_set_applied_torque(RID p_body, float p_torque)=0; virtual float body_get_applied_torque(RID p_body) const=0; - virtual void body_apply_impulse(RID p_body, const Vector2& p_pos, const Vector2& p_impulse)=0; + virtual void body_add_force(RID p_body, const Vector2& p_offset, const Vector2& p_force)=0; + + virtual void body_apply_impulse(RID p_body, const Vector2& p_offset, const Vector2& p_impulse)=0; virtual void body_set_axis_velocity(RID p_body, const Vector2& p_axis_velocity)=0; //fix @@ -559,7 +562,9 @@ public: INFO_ACTIVE_OBJECTS, INFO_COLLISION_PAIRS, - INFO_ISLAND_COUNT + INFO_ISLAND_COUNT, + INFO_STEP_TIME, + INFO_BROAD_PHASE_TIME }; virtual int get_process_info(ProcessInfo p_info)=0; diff --git a/servers/physics_server.cpp b/servers/physics_server.cpp index 89fcffe7ed..685477ed79 100644 --- a/servers/physics_server.cpp +++ b/servers/physics_server.cpp @@ -457,6 +457,8 @@ void PhysicsServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("area_remove_shape","area","shape_idx"),&PhysicsServer::area_remove_shape); ObjectTypeDB::bind_method(_MD("area_clear_shapes","area"),&PhysicsServer::area_clear_shapes); + ObjectTypeDB::bind_method(_MD("area_set_layer_mask","area","mask"),&PhysicsServer::area_set_layer_mask); + ObjectTypeDB::bind_method(_MD("area_set_collision_mask","area","mask"),&PhysicsServer::area_set_collision_mask); ObjectTypeDB::bind_method(_MD("area_set_param","area","param","value"),&PhysicsServer::area_set_param); ObjectTypeDB::bind_method(_MD("area_set_transform","area","transform"),&PhysicsServer::area_set_transform); @@ -480,6 +482,12 @@ void PhysicsServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("body_set_mode","body","mode"),&PhysicsServer::body_set_mode); ObjectTypeDB::bind_method(_MD("body_get_mode","body"),&PhysicsServer::body_get_mode); + ObjectTypeDB::bind_method(_MD("body_set_layer_mask","body","mask"),&PhysicsServer::body_set_layer_mask); + ObjectTypeDB::bind_method(_MD("body_get_layer_mask","body"),&PhysicsServer::body_get_layer_mask); + + ObjectTypeDB::bind_method(_MD("body_set_collision_mask","body","mask"),&PhysicsServer::body_set_collision_mask); + ObjectTypeDB::bind_method(_MD("body_get_collision_mask","body"),&PhysicsServer::body_get_collision_mask); + ObjectTypeDB::bind_method(_MD("body_add_shape","body","shape","transform"),&PhysicsServer::body_add_shape,DEFVAL(Transform())); ObjectTypeDB::bind_method(_MD("body_set_shape","body","shape_idx","shape"),&PhysicsServer::body_set_shape); ObjectTypeDB::bind_method(_MD("body_set_shape_transform","body","shape_idx","transform"),&PhysicsServer::body_set_shape_transform); diff --git a/servers/physics_server.h b/servers/physics_server.h index 9b00825d92..5221b38ccb 100644 --- a/servers/physics_server.h +++ b/servers/physics_server.h @@ -346,6 +346,9 @@ public: virtual Variant area_get_param(RID p_parea,AreaParameter p_param) const=0; virtual Transform area_get_transform(RID p_area) const=0; + virtual void area_set_collision_mask(RID p_area,uint32_t p_mask)=0; + virtual void area_set_layer_mask(RID p_area,uint32_t p_mask)=0; + virtual void area_set_monitorable(RID p_area,bool p_monitorable)=0; virtual void area_set_monitor_callback(RID p_area,Object *p_receiver,const StringName& p_method)=0; @@ -397,6 +400,9 @@ public: virtual void body_set_layer_mask(RID p_body, uint32_t p_mask)=0; virtual uint32_t body_get_layer_mask(RID p_body, uint32_t p_mask) const=0; + virtual void body_set_collision_mask(RID p_body, uint32_t p_mask)=0; + virtual uint32_t body_get_collision_mask(RID p_body, uint32_t p_mask) const=0; + virtual void body_set_user_flags(RID p_body, uint32_t p_flags)=0; virtual uint32_t body_get_user_flags(RID p_body, uint32_t p_flags) const=0; diff --git a/servers/server_wrap_mt_common.h b/servers/server_wrap_mt_common.h index cbb75129d0..149e9ec4f9 100644 --- a/servers/server_wrap_mt_common.h +++ b/servers/server_wrap_mt_common.h @@ -698,3 +698,64 @@ }\ } +#define FUNC8R(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ + if (Thread::get_caller_ID()!=server_thread) {\ + m_r ret;\ + command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8, &ret);\ + SYNC_DEBUG\ + return ret;\ + } else {\ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + +#define FUNC8RC(m_r,m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual m_r m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ + if (Thread::get_caller_ID()!=server_thread) {\ + m_r ret;\ + command_queue.push_and_ret( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8, &ret);\ + SYNC_DEBUG\ + return ret;\ + } else {\ + return server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + + +#define FUNC8S(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + +#define FUNC8SC(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push_and_sync( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + + +#define FUNC8(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } + +#define FUNC8C(m_type,m_arg1, m_arg2, m_arg3, m_arg4, m_arg5, m_arg6, m_arg7, m_arg8)\ + virtual void m_type(m_arg1 p1, m_arg2 p2, m_arg3 p3, m_arg4 p4, m_arg5 p5, m_arg6 p6, m_arg7 p7, m_arg8 p8) const { \ + if (Thread::get_caller_ID()!=server_thread) {\ + command_queue.push( server_name, &ServerName::m_type,p1, p2, p3, p4, p5, p6, p7, p8);\ + } else {\ + server_name->m_type(p1, p2, p3, p4, p5, p6, p7, p8);\ + }\ + } diff --git a/servers/visual/rasterizer.h b/servers/visual/rasterizer.h index e2de20785a..50ec6792cc 100644 --- a/servers/visual/rasterizer.h +++ b/servers/visual/rasterizer.h @@ -196,6 +196,8 @@ public: virtual String texture_get_path(RID p_texture) const=0; virtual void texture_debug_usage(List<VS::TextureInfo> *r_info)=0; + virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0; + /* SHADER API */ virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL)=0; @@ -540,6 +542,7 @@ public: RID skeleton; RID material_override; RID sampled_light; + Vector<RID> materials; Vector<RID> light_instances; Vector<float> morph_values; BakedLightData *baked_light; @@ -699,6 +702,7 @@ public: struct CommandStyle : public Command { Rect2 rect; + Rect2 source; RID texture; float margin[4]; bool draw_center; @@ -941,12 +945,12 @@ public: virtual void canvas_disable_blending()=0; virtual void canvas_set_opacity(float p_opacity)=0; virtual void canvas_set_blend_mode(VS::MaterialBlendMode p_mode)=0; - virtual void canvas_begin_rect(const Matrix32& p_transform)=0;; + virtual void canvas_begin_rect(const Matrix32& p_transform)=0; virtual void canvas_set_clip(bool p_clip, const Rect2& p_rect)=0; virtual void canvas_end_rect()=0; virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width)=0; virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate)=0; - virtual void canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; + virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width)=0; virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor)=0; virtual void canvas_set_transform(const Matrix32& p_transform)=0; diff --git a/servers/visual/rasterizer_dummy.cpp b/servers/visual/rasterizer_dummy.cpp index 3b12b503dd..0e71d224d5 100644 --- a/servers/visual/rasterizer_dummy.cpp +++ b/servers/visual/rasterizer_dummy.cpp @@ -1627,7 +1627,7 @@ void RasterizerDummy::canvas_draw_rect(const Rect2& p_rect, int p_flags, const R } -void RasterizerDummy::canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) { +void RasterizerDummy::canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margin, bool p_draw_center,const Color& p_modulate) { } @@ -1959,4 +1959,3 @@ RasterizerDummy::RasterizerDummy() { RasterizerDummy::~RasterizerDummy() { }; - diff --git a/servers/visual/rasterizer_dummy.h b/servers/visual/rasterizer_dummy.h index efa843839a..ac320e55f9 100644 --- a/servers/visual/rasterizer_dummy.h +++ b/servers/visual/rasterizer_dummy.h @@ -415,6 +415,8 @@ public: virtual String texture_get_path(RID p_texture) const { return String(); } virtual void texture_debug_usage(List<VS::TextureInfo> *r_info) {} + virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable) {} + /* SHADER API */ virtual RID shader_create(VS::ShaderMode p_mode=VS::SHADER_MATERIAL); @@ -706,7 +708,7 @@ public: virtual void canvas_end_rect(); virtual void canvas_draw_line(const Point2& p_from, const Point2& p_to,const Color& p_color,float p_width); virtual void canvas_draw_rect(const Rect2& p_rect, int p_flags, const Rect2& p_source,RID p_texture,const Color& p_modulate); - virtual void canvas_draw_style_box(const Rect2& p_rect, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_draw_style_box(const Rect2& p_rect, const Rect2& p_src_region, RID p_texture,const float *p_margins, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_draw_primitive(const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width); virtual void canvas_draw_polygon(int p_vertex_count, const int* p_indices, const Vector2* p_vertices, const Vector2* p_uvs, const Color* p_colors,const RID& p_texture,bool p_singlecolor); virtual void canvas_set_transform(const Matrix32& p_transform); diff --git a/servers/visual/visual_server_raster.cpp b/servers/visual/visual_server_raster.cpp index 1db7971d3b..532247d94c 100644 --- a/servers/visual/visual_server_raster.cpp +++ b/servers/visual/visual_server_raster.cpp @@ -127,6 +127,11 @@ void VisualServerRaster::texture_debug_usage(List<TextureInfo> *r_info){ rasterizer->texture_debug_usage(r_info); } +void VisualServerRaster::texture_set_shrink_all_x2_on_set_data(bool p_enable) { + + rasterizer->texture_set_shrink_all_x2_on_set_data(p_enable); +} + /* SHADER API */ RID VisualServerRaster::shader_create(ShaderMode p_mode) { @@ -393,7 +398,7 @@ void VisualServerRaster::mesh_add_custom_surface(RID p_mesh,const Variant& p_dat void VisualServerRaster::mesh_add_surface(RID p_mesh,PrimitiveType p_primitive,const Array& p_arrays,const Array& p_blend_shapes,bool p_alpha_sort) { VS_CHANGED; - _dependency_queue_update(p_mesh,true); + _dependency_queue_update(p_mesh,true,true); rasterizer->mesh_add_surface(p_mesh,p_primitive,p_arrays,p_blend_shapes,p_alpha_sort); } @@ -447,6 +452,7 @@ VisualServer::PrimitiveType VisualServerRaster::mesh_surface_get_primitive_type( void VisualServerRaster::mesh_remove_surface(RID p_mesh,int p_surface){ rasterizer->mesh_remove_surface(p_mesh,p_surface); + _dependency_queue_update(p_mesh,true,true); } int VisualServerRaster::mesh_get_surface_count(RID p_mesh) const{ @@ -475,6 +481,8 @@ void VisualServerRaster::mesh_clear(RID p_mesh) { while(rasterizer->mesh_get_surface_count(p_mesh)) { rasterizer->mesh_remove_surface(p_mesh,0); } + + _dependency_queue_update(p_mesh,true,true); } @@ -2033,7 +2041,7 @@ Variant VisualServerRaster::environment_fx_get_param(RID p_env,EnvironmentFxPara /* SCENARIO API */ -void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb) { +void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb,bool p_update_materials) { Map< RID, Set<RID> >::Element * E = instance_dependency_map.find( p_rid ); @@ -2046,17 +2054,19 @@ void VisualServerRaster::_dependency_queue_update(RID p_rid,bool p_update_aabb) while(I) { Instance *ins = instance_owner.get( I->get() ); - _instance_queue_update( ins , p_update_aabb ); + _instance_queue_update( ins , p_update_aabb, p_update_materials ); I = I->next(); } } -void VisualServerRaster::_instance_queue_update(Instance *p_instance,bool p_update_aabb) { +void VisualServerRaster::_instance_queue_update(Instance *p_instance,bool p_update_aabb,bool p_update_materials) { if (p_update_aabb) p_instance->update_aabb=true; + if (p_update_materials) + p_instance->update_materials=true; if (p_instance->update) return; @@ -2268,6 +2278,7 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) { } instance->data.morph_values.clear(); + instance->data.materials.clear(); } @@ -2281,6 +2292,7 @@ void VisualServerRaster::instance_set_base(RID p_instance, RID p_base) { if (rasterizer->is_mesh(p_base)) { instance->base_type=INSTANCE_MESH; instance->data.morph_values.resize( rasterizer->mesh_get_morph_target_count(p_base)); + instance->data.materials.resize( rasterizer->mesh_get_surface_count(p_base)); } else if (rasterizer->is_multimesh(p_base)) { instance->base_type=INSTANCE_MULTIMESH; } else if (rasterizer->is_immediate(p_base)) { @@ -2505,6 +2517,16 @@ float VisualServerRaster::instance_get_morph_target_weight(RID p_instance,int p_ return instance->data.morph_values[p_shape]; } +void VisualServerRaster::instance_set_surface_material(RID p_instance,int p_surface, RID p_material) { + + VS_CHANGED; + Instance *instance = instance_owner.get( p_instance ); + ERR_FAIL_COND( !instance); + ERR_FAIL_INDEX( p_surface, instance->data.materials.size() ); + instance->data.materials[p_surface]=p_material; +} + + void VisualServerRaster::instance_set_transform(RID p_instance, const Transform& p_transform) { VS_CHANGED; Instance *instance = instance_owner.get( p_instance ); @@ -3041,6 +3063,7 @@ void VisualServerRaster::_update_instance(Instance *p_instance) { } + if (p_instance->aabb.has_no_surface()) return; @@ -3296,10 +3319,17 @@ void VisualServerRaster::_update_instances() { if (instance->update_aabb) _update_instance_aabb(instance); + if (instance->update_materials) { + if (instance->base_type==INSTANCE_MESH) { + instance->data.materials.resize(rasterizer->mesh_get_surface_count(instance->base_rid)); + } + } + _update_instance(instance); instance->update=false; instance->update_aabb=false; + instance->update_materials=false; instance->update_next=0; } } @@ -3656,8 +3686,11 @@ void VisualServerRaster::canvas_item_add_texture_rect(RID p_item, const Rect2& p rect->modulate=p_modulate; rect->rect=p_rect; rect->flags=0; - if (p_tile) + if (p_tile) { rect->flags|=Rasterizer::CANVAS_RECT_TILE; + rect->flags|=Rasterizer::CANVAS_RECT_REGION; + rect->source=Rect2(0,0,p_rect.size.width,p_rect.size.height); + } if (p_rect.size.x<0) { @@ -3712,7 +3745,7 @@ void VisualServerRaster::canvas_item_add_texture_rect_region(RID p_item, const R } -void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { +void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture, const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center,const Color& p_modulate) { VS_CHANGED; CanvasItem *canvas_item = canvas_item_owner.get( p_item ); @@ -3722,6 +3755,7 @@ void VisualServerRaster::canvas_item_add_style_box(RID p_item, const Rect2& p_re ERR_FAIL_COND(!style); style->texture=p_texture; style->rect=p_rect; + style->source=p_source; style->draw_center=p_draw_center; style->color=p_modulate; style->margin[MARGIN_LEFT]=p_topleft.x; diff --git a/servers/visual/visual_server_raster.h b/servers/visual/visual_server_raster.h index 2b72b0b900..dcaac6e8d2 100644 --- a/servers/visual/visual_server_raster.h +++ b/servers/visual/visual_server_raster.h @@ -160,6 +160,7 @@ class VisualServerRaster : public VisualServer { Scenario *scenario; bool update; bool update_aabb; + bool update_materials; Instance *update_next; InstanceType base_type; @@ -317,6 +318,8 @@ class VisualServerRaster : public VisualServer { draw_range_end=0; extra_margin=0; visible_in_all_rooms=false; + update_aabb=false; + update_materials=false; baked_light=NULL; baked_light_info=NULL; @@ -583,8 +586,8 @@ class VisualServerRaster : public VisualServer { void _portal_disconnect(Instance *p_portal,bool p_cleanup=false); void _portal_attempt_connect(Instance *p_portal); - void _dependency_queue_update(RID p_rid,bool p_update_aabb=false); - _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false); + void _dependency_queue_update(RID p_rid, bool p_update_aabb=false, bool p_update_materials=false); + _FORCE_INLINE_ void _instance_queue_update(Instance *p_instance,bool p_update_aabb=false,bool p_update_materials=false); void _update_instances(); void _update_instance_aabb(Instance *p_instance); void _update_instance(Instance *p_instance); @@ -673,6 +676,8 @@ public: virtual void texture_debug_usage(List<TextureInfo> *r_info); + virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable); + /* SHADER API */ @@ -1081,6 +1086,9 @@ public: virtual void instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight); virtual float instance_get_morph_target_weight(RID p_instance,int p_shape) const; + virtual void instance_set_surface_material(RID p_instance,int p_surface, RID p_material); + + virtual void instance_set_transform(RID p_instance, const Transform& p_transform); virtual Transform instance_get_transform(RID p_instance) const; @@ -1163,7 +1171,7 @@ public: virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color); virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false); - virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); + virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1)); virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0); virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID()); virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID(), int p_count=-1); diff --git a/servers/visual/visual_server_wrap_mt.h b/servers/visual/visual_server_wrap_mt.h index b6018f1c25..a97b232c03 100644 --- a/servers/visual/visual_server_wrap_mt.h +++ b/servers/visual/visual_server_wrap_mt.h @@ -101,6 +101,8 @@ public: FUNC2(texture_set_path,RID,const String&); FUNC1RC(String,texture_get_path,RID); + FUNC1(texture_set_shrink_all_x2_on_set_data,bool); + virtual void texture_debug_usage(List<TextureInfo> *r_info) { //pass directly, should lock the server anyway visual_server->texture_debug_usage(r_info); @@ -523,6 +525,8 @@ public: FUNC3(instance_set_morph_target_weight,RID,int, float); FUNC2RC(float,instance_get_morph_target_weight,RID,int); + FUNC3(instance_set_surface_material,RID,int, RID); + FUNC2(instance_set_transform,RID, const Transform&); FUNC1RC(Transform,instance_get_transform,RID); @@ -603,7 +607,7 @@ public: FUNC4(canvas_item_add_circle,RID, const Point2& , float ,const Color& ); FUNC6(canvas_item_add_texture_rect,RID, const Rect2& , RID ,bool ,const Color&,bool ); FUNC6(canvas_item_add_texture_rect_region,RID, const Rect2& , RID ,const Rect2& ,const Color&,bool ); - FUNC7(canvas_item_add_style_box,RID, const Rect2& , RID ,const Vector2& ,const Vector2&, bool ,const Color& ); + FUNC8(canvas_item_add_style_box,RID, const Rect2& , const Rect2&, RID ,const Vector2& ,const Vector2&, bool ,const Color& ); FUNC6(canvas_item_add_primitive,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ,float ); FUNC5(canvas_item_add_polygon,RID, const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID ); FUNC7(canvas_item_add_triangle_array,RID, const Vector<int>& , const Vector<Point2>& , const Vector<Color>& ,const Vector<Point2>& , RID , int ); diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index 17d5b16b9f..570a5a6ee4 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -355,8 +355,12 @@ void VisualServer::_bind_methods() { ObjectTypeDB::bind_method(_MD("texture_get_flags"),&VisualServer::texture_get_flags ); ObjectTypeDB::bind_method(_MD("texture_get_width"),&VisualServer::texture_get_width ); ObjectTypeDB::bind_method(_MD("texture_get_height"),&VisualServer::texture_get_height ); + + ObjectTypeDB::bind_method(_MD("texture_set_shrink_all_x2_on_set_data","shrink"),&VisualServer::texture_set_shrink_all_x2_on_set_data ); + #ifndef _3D_DISABLED + ObjectTypeDB::bind_method(_MD("shader_create","mode"),&VisualServer::shader_create,DEFVAL(SHADER_MATERIAL)); ObjectTypeDB::bind_method(_MD("shader_set_mode","shader","mode"),&VisualServer::shader_set_mode); @@ -701,10 +705,10 @@ void VisualServer::_bind_methods() { } -void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate) { +void VisualServer::_canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate) { ERR_FAIL_COND(p_margins.size()!=4); - canvas_item_add_style_box(p_item, p_rect, p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate); + canvas_item_add_style_box(p_item,p_rect,p_source,p_texture,Vector2(p_margins[0],p_margins[1]),Vector2(p_margins[2],p_margins[3]),true,p_modulate); } void VisualServer::_camera_set_orthogonal(RID p_camera,float p_size,float p_z_near,float p_z_far) { @@ -818,5 +822,3 @@ VisualServer::~VisualServer() { singleton=NULL; } - - diff --git a/servers/visual_server.h b/servers/visual_server.h index c70a72ef2a..f330a6faee 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -52,7 +52,7 @@ class VisualServer : public Object { void _camera_set_orthogonal(RID p_camera,float p_size,float p_z_near,float p_z_far); void _viewport_set_rect(RID p_viewport,const Rect2& p_rect); Rect2 _viewport_get_rect(RID p_viewport) const; - void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1)); + void _canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector<float>& p_margins, const Color& p_modulate=Color(1,1,1)); protected: RID _make_test_cube(); void _free_internal_rids(); @@ -138,6 +138,8 @@ public: virtual void texture_set_path(RID p_texture,const String& p_path)=0; virtual String texture_get_path(RID p_texture) const=0; + virtual void texture_set_shrink_all_x2_on_set_data(bool p_enable)=0; + struct TextureInfo { RID texture; Size2 size; @@ -917,6 +919,8 @@ public: virtual void instance_set_morph_target_weight(RID p_instance,int p_shape, float p_weight)=0; virtual float instance_get_morph_target_weight(RID p_instance,int p_shape) const=0; + virtual void instance_set_surface_material(RID p_instance,int p_surface, RID p_material)=0; + virtual void instance_attach_skeleton(RID p_instance,RID p_skeleton)=0; virtual RID instance_get_skeleton(RID p_instance) const=0; @@ -1021,7 +1025,7 @@ public: virtual void canvas_item_add_circle(RID p_item, const Point2& p_pos, float p_radius,const Color& p_color)=0; virtual void canvas_item_add_texture_rect(RID p_item, const Rect2& p_rect, RID p_texture,bool p_tile=false,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; virtual void canvas_item_add_texture_rect_region(RID p_item, const Rect2& p_rect, RID p_texture,const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1),bool p_transpose=false)=0; - virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; + virtual void canvas_item_add_style_box(RID p_item, const Rect2& p_rect, const Rect2& p_source, RID p_texture,const Vector2& p_topleft, const Vector2& p_bottomright, bool p_draw_center=true,const Color& p_modulate=Color(1,1,1))=0; virtual void canvas_item_add_primitive(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs, RID p_texture,float p_width=1.0)=0; virtual void canvas_item_add_polygon(RID p_item, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID())=0; virtual void canvas_item_add_triangle_array(RID p_item, const Vector<int>& p_indices, const Vector<Point2>& p_points, const Vector<Color>& p_colors,const Vector<Point2>& p_uvs=Vector<Point2>(), RID p_texture=RID(), int p_count=-1)=0; |