improved kinematic motion, improved demos for kinematic motion
This commit is contained in:
parent
04fb3402c5
commit
e7aa37fe75
Binary file not shown.
After Width: | Height: | Size: 6.0 KiB |
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 534 B |
|
@ -21,6 +21,8 @@ const STOP_FORCE = 1300
|
||||||
const JUMP_SPEED = 200
|
const JUMP_SPEED = 200
|
||||||
const JUMP_MAX_AIRBORNE_TIME=0.2
|
const JUMP_MAX_AIRBORNE_TIME=0.2
|
||||||
|
|
||||||
|
const SLIDE_STOP_VELOCITY=1.0 #one pixel per second
|
||||||
|
const SLIDE_STOP_MIN_TRAVEL=1.0 #one pixel
|
||||||
var velocity = Vector2()
|
var velocity = Vector2()
|
||||||
var on_air_time=100
|
var on_air_time=100
|
||||||
var jumping=false
|
var jumping=false
|
||||||
|
@ -86,14 +88,27 @@ func _fixed_process(delta):
|
||||||
#char is on floor
|
#char is on floor
|
||||||
on_air_time=0
|
on_air_time=0
|
||||||
floor_velocity=get_collider_velocity()
|
floor_velocity=get_collider_velocity()
|
||||||
#velocity.y=0
|
|
||||||
|
|
||||||
#But we were moving and our motion was interrupted,
|
|
||||||
#so try to complete the motion by "sliding"
|
if (on_air_time==0 and force.x==0 and get_travel().length() < SLIDE_STOP_MIN_TRAVEL and abs(velocity.x) < SLIDE_STOP_VELOCITY and get_collider_velocity()==Vector2()):
|
||||||
|
#Since this formula will always slide the character around,
|
||||||
|
#a special case must be considered to to stop it from moving
|
||||||
|
#if standing on an inclined floor. Conditions are:
|
||||||
|
# 1) Standin on floor (on_air_time==0)
|
||||||
|
# 2) Did not move more than one pixel (get_travel().length() < SLIDE_STOP_MIN_TRAVEL)
|
||||||
|
# 3) Not moving horizontally (abs(velocity.x) < SLIDE_STOP_VELOCITY)
|
||||||
|
# 4) Collider is not moving
|
||||||
|
|
||||||
|
revert_motion()
|
||||||
|
velocity.y=0.0
|
||||||
|
|
||||||
|
else:
|
||||||
|
#For every other case of motion,our motion was interrupted.
|
||||||
|
#Try to complete the motion by "sliding"
|
||||||
#by the normal
|
#by the normal
|
||||||
|
|
||||||
motion = n.slide(motion)
|
motion = n.slide(motion)
|
||||||
velocity = n.slide(velocity)
|
velocity = n.slide(velocity)
|
||||||
|
|
||||||
#then move again
|
#then move again
|
||||||
move(motion)
|
move(motion)
|
||||||
|
|
||||||
|
|
|
@ -925,6 +925,19 @@ Variant KinematicBody2D::_get_collider() const {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KinematicBody2D::revert_motion() {
|
||||||
|
|
||||||
|
Matrix32 gt = get_global_transform();
|
||||||
|
gt.elements[2]-=travel;
|
||||||
|
travel=Vector2();
|
||||||
|
set_global_transform(gt);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 KinematicBody2D::get_travel() const {
|
||||||
|
|
||||||
|
return travel;
|
||||||
|
}
|
||||||
|
|
||||||
Vector2 KinematicBody2D::move(const Vector2& p_motion) {
|
Vector2 KinematicBody2D::move(const Vector2& p_motion) {
|
||||||
|
|
||||||
|
@ -942,6 +955,7 @@ Vector2 KinematicBody2D::move(const Vector2& p_motion) {
|
||||||
Matrix32 gt = get_global_transform();
|
Matrix32 gt = get_global_transform();
|
||||||
gt.elements[2]+=result.motion;
|
gt.elements[2]+=result.motion;
|
||||||
set_global_transform(gt);
|
set_global_transform(gt);
|
||||||
|
travel=result.motion;
|
||||||
return result.remainder;
|
return result.remainder;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
@ -1173,6 +1187,8 @@ void KinematicBody2D::_bind_methods() {
|
||||||
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to);
|
ObjectTypeDB::bind_method(_MD("move_to","position"),&KinematicBody2D::move_to);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move);
|
ObjectTypeDB::bind_method(_MD("test_move","rel_vec"),&KinematicBody2D::test_move);
|
||||||
|
ObjectTypeDB::bind_method(_MD("get_travel"),&KinematicBody2D::get_travel);
|
||||||
|
ObjectTypeDB::bind_method(_MD("revert_motion"),&KinematicBody2D::revert_motion);
|
||||||
|
|
||||||
ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding);
|
ObjectTypeDB::bind_method(_MD("is_colliding"),&KinematicBody2D::is_colliding);
|
||||||
|
|
||||||
|
|
|
@ -280,6 +280,7 @@ class KinematicBody2D : public PhysicsBody2D {
|
||||||
ObjectID collider;
|
ObjectID collider;
|
||||||
int collider_shape;
|
int collider_shape;
|
||||||
Variant collider_metadata;
|
Variant collider_metadata;
|
||||||
|
Vector2 travel;
|
||||||
|
|
||||||
Variant _get_collider() const;
|
Variant _get_collider() const;
|
||||||
|
|
||||||
|
@ -294,6 +295,10 @@ public:
|
||||||
|
|
||||||
bool test_move(const Vector2& p_motion);
|
bool test_move(const Vector2& p_motion);
|
||||||
bool is_colliding() const;
|
bool is_colliding() const;
|
||||||
|
|
||||||
|
Vector2 get_travel() const;
|
||||||
|
void revert_motion();
|
||||||
|
|
||||||
Vector2 get_collision_pos() const;
|
Vector2 get_collision_pos() const;
|
||||||
Vector2 get_collision_normal() const;
|
Vector2 get_collision_normal() const;
|
||||||
Vector2 get_collider_velocity() const;
|
Vector2 get_collider_velocity() const;
|
||||||
|
|
|
@ -105,6 +105,9 @@ bool Theme::_get(const StringName& p_name,Variant &r_ret) const {
|
||||||
|
|
||||||
void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
|
|
||||||
|
List<PropertyInfo> list;
|
||||||
|
|
||||||
const StringName *key=NULL;
|
const StringName *key=NULL;
|
||||||
|
|
||||||
while((key=icon_map.next(key))) {
|
while((key=icon_map.next(key))) {
|
||||||
|
@ -113,7 +116,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
while((key2=icon_map[*key].next(key2))) {
|
while((key2=icon_map[*key].next(key2))) {
|
||||||
|
|
||||||
p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) );
|
list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/icons/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Texture" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +128,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
while((key2=style_map[*key].next(key2))) {
|
while((key2=style_map[*key].next(key2))) {
|
||||||
|
|
||||||
p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) );
|
list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/styles/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +141,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
while((key2=font_map[*key].next(key2))) {
|
while((key2=font_map[*key].next(key2))) {
|
||||||
|
|
||||||
p_list->push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) );
|
list.push_back( PropertyInfo( Variant::OBJECT, String()+*key+"/fonts/"+*key2, PROPERTY_HINT_RESOURCE_TYPE, "Font" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,7 +153,7 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
while((key2=color_map[*key].next(key2))) {
|
while((key2=color_map[*key].next(key2))) {
|
||||||
|
|
||||||
p_list->push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) );
|
list.push_back( PropertyInfo( Variant::COLOR, String()+*key+"/colors/"+*key2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,10 +165,15 @@ void Theme::_get_property_list( List<PropertyInfo> *p_list) const {
|
||||||
|
|
||||||
while((key2=constant_map[*key].next(key2))) {
|
while((key2=constant_map[*key].next(key2))) {
|
||||||
|
|
||||||
p_list->push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) );
|
list.push_back( PropertyInfo( Variant::INT, String()+*key+"/constants/"+*key2 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
list.sort();
|
||||||
|
for(List<PropertyInfo>::Element *E=list.front();E;E=E->next()) {
|
||||||
|
p_list->push_back(E->get());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ref<Theme> Theme::get_default() {
|
Ref<Theme> Theme::get_default() {
|
||||||
|
|
|
@ -555,38 +555,10 @@ Physics2DDirectSpaceStateSW::Physics2DDirectSpaceStateSW() {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Space2DSW::_cull_aabb_for_body(Body2DSW *p_body,const Rect2& p_aabb) {
|
||||||
bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p_margin,Physics2DServer::MotionResult *r_result) {
|
|
||||||
|
|
||||||
//give me back regular physics engine logic
|
|
||||||
//this is madness
|
|
||||||
//and most people using this function will think
|
|
||||||
//what it does is simpler than using physics
|
|
||||||
//this took about a week to get right..
|
|
||||||
//but is it right? who knows at this point..
|
|
||||||
|
|
||||||
Rect2 body_aabb;
|
|
||||||
|
|
||||||
for(int i=0;i<p_body->get_shape_count();i++) {
|
|
||||||
|
|
||||||
if (i==0)
|
|
||||||
body_aabb=p_body->get_shape_aabb(i);
|
|
||||||
else
|
|
||||||
body_aabb=body_aabb.merge(p_body->get_shape_aabb(i));
|
|
||||||
}
|
|
||||||
|
|
||||||
body_aabb=body_aabb.grow(p_margin);
|
|
||||||
|
|
||||||
{
|
|
||||||
//add motion
|
|
||||||
|
|
||||||
Rect2 motion_aabb=body_aabb;
|
|
||||||
motion_aabb.pos+=p_motion;
|
|
||||||
body_aabb=body_aabb.merge(motion_aabb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int amount = broadphase->cull_aabb(body_aabb,intersection_query_results,INTERSECTION_QUERY_MAX,intersection_query_subindex_results);
|
int amount = broadphase->cull_aabb(p_aabb,intersection_query_results,INTERSECTION_QUERY_MAX,intersection_query_subindex_results);
|
||||||
|
|
||||||
for(int i=0;i<amount;i++) {
|
for(int i=0;i<amount;i++) {
|
||||||
|
|
||||||
|
@ -617,6 +589,31 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p_margin,Physics2DServer::MotionResult *r_result) {
|
||||||
|
|
||||||
|
//give me back regular physics engine logic
|
||||||
|
//this is madness
|
||||||
|
//and most people using this function will think
|
||||||
|
//what it does is simpler than using physics
|
||||||
|
//this took about a week to get right..
|
||||||
|
//but is it right? who knows at this point..
|
||||||
|
|
||||||
|
Rect2 body_aabb;
|
||||||
|
|
||||||
|
for(int i=0;i<p_body->get_shape_count();i++) {
|
||||||
|
|
||||||
|
if (i==0)
|
||||||
|
body_aabb=p_body->get_shape_aabb(i);
|
||||||
|
else
|
||||||
|
body_aabb=body_aabb.merge(p_body->get_shape_aabb(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
body_aabb=body_aabb.grow(p_margin);
|
||||||
|
|
||||||
|
|
||||||
Matrix32 body_transform = p_body->get_transform();
|
Matrix32 body_transform = p_body->get_transform();
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -642,6 +639,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
|
||||||
|
|
||||||
bool collided=false;
|
bool collided=false;
|
||||||
|
|
||||||
|
int amount = _cull_aabb_for_body(p_body,body_aabb);
|
||||||
|
|
||||||
for(int j=0;j<p_body->get_shape_count();j++) {
|
for(int j=0;j<p_body->get_shape_count();j++) {
|
||||||
if (p_body->is_shape_set_as_trigger(j))
|
if (p_body->is_shape_set_as_trigger(j))
|
||||||
|
@ -694,6 +692,7 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
|
||||||
}
|
}
|
||||||
|
|
||||||
body_transform.elements[2]+=recover_motion;
|
body_transform.elements[2]+=recover_motion;
|
||||||
|
body_aabb.pos+=recover_motion;
|
||||||
|
|
||||||
recover_attempts--;
|
recover_attempts--;
|
||||||
|
|
||||||
|
@ -709,7 +708,11 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
|
||||||
{
|
{
|
||||||
// STEP 2 ATTEMPT MOTION
|
// STEP 2 ATTEMPT MOTION
|
||||||
|
|
||||||
|
Rect2 motion_aabb=body_aabb;
|
||||||
|
motion_aabb.pos+=p_motion;
|
||||||
|
motion_aabb=motion_aabb.merge(body_aabb);
|
||||||
|
|
||||||
|
int amount = _cull_aabb_for_body(p_body,motion_aabb);
|
||||||
|
|
||||||
for(int j=0;j<p_body->get_shape_count();j++) {
|
for(int j=0;j<p_body->get_shape_count();j++) {
|
||||||
|
|
||||||
|
@ -847,6 +850,10 @@ bool Space2DSW::test_body_motion(Body2DSW *p_body,const Vector2&p_motion,float p
|
||||||
Matrix32 body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
|
Matrix32 body_shape_xform = ugt * p_body->get_shape_transform(best_shape);
|
||||||
Shape2DSW *body_shape = p_body->get_shape(best_shape);
|
Shape2DSW *body_shape = p_body->get_shape(best_shape);
|
||||||
|
|
||||||
|
body_aabb.pos+=p_motion*unsafe;
|
||||||
|
|
||||||
|
int amount = _cull_aabb_for_body(p_body,body_aabb);
|
||||||
|
|
||||||
|
|
||||||
for(int i=0;i<amount;i++) {
|
for(int i=0;i<amount;i++) {
|
||||||
|
|
||||||
|
|
|
@ -101,6 +101,8 @@ class Space2DSW {
|
||||||
int active_objects;
|
int active_objects;
|
||||||
int collision_pairs;
|
int collision_pairs;
|
||||||
|
|
||||||
|
int _cull_aabb_for_body(Body2DSW *p_body,const Rect2& p_aabb);
|
||||||
|
|
||||||
friend class Physics2DDirectSpaceStateSW;
|
friend class Physics2DDirectSpaceStateSW;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue