Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
godot
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
community
godot
Commits
c4650540
Commit
c4650540
authored
Feb 10, 2020
by
Marcel Admiraal
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Normalise p_up_direction vector in move_and_slide() and
move_and_slide_with_snap() and fix tolerance in move_and_slide_with_snap() max floor angle.
parent
4b5b60de
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
22 additions
and
18 deletions
+22
-18
physics_body_2d.cpp
scene/2d/physics_body_2d.cpp
+11
-9
physics_body_3d.cpp
scene/3d/physics_body_3d.cpp
+11
-9
No files found.
scene/2d/physics_body_2d.cpp
View file @
c4650540
...
...
@@ -997,6 +997,7 @@ bool KinematicBody2D::move_and_collide(const Vector2 &p_motion, bool p_infinite_
Vector2
KinematicBody2D
::
move_and_slide
(
const
Vector2
&
p_linear_velocity
,
const
Vector2
&
p_up_direction
,
bool
p_stop_on_slope
,
int
p_max_slides
,
float
p_floor_max_angle
,
bool
p_infinite_inertia
)
{
Vector2
body_velocity
=
p_linear_velocity
;
Vector2
body_velocity_normal
=
body_velocity
.
normalized
();
Vector2
up_direction
=
p_up_direction
.
normalized
();
Vector2
current_floor_velocity
=
floor_velocity
;
if
(
on_floor
&&
on_floor_body
.
is_valid
())
{
...
...
@@ -1043,11 +1044,11 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
colliders
.
push_back
(
collision
);
motion
=
collision
.
remainder
;
if
(
p_
up_direction
==
Vector2
())
{
if
(
up_direction
==
Vector2
())
{
//all is a wall
on_wall
=
true
;
}
else
{
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
p_
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//floor
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//floor
on_floor
=
true
;
floor_normal
=
collision
.
normal
;
...
...
@@ -1055,14 +1056,14 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
floor_velocity
=
collision
.
collider_vel
;
if
(
p_stop_on_slope
)
{
if
((
body_velocity_normal
+
p_
up_direction
).
length
()
<
0.01
&&
collision
.
travel
.
length
()
<
1
)
{
if
((
body_velocity_normal
+
up_direction
).
length
()
<
0.01
&&
collision
.
travel
.
length
()
<
1
)
{
Transform2D
gt
=
get_global_transform
();
gt
.
elements
[
2
]
-=
collision
.
travel
.
slide
(
p_
up_direction
);
gt
.
elements
[
2
]
-=
collision
.
travel
.
slide
(
up_direction
);
set_global_transform
(
gt
);
return
Vector2
();
}
}
}
else
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
-
p_
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//ceiling
}
else
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
-
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//ceiling
on_ceiling
=
true
;
}
else
{
on_wall
=
true
;
...
...
@@ -1085,9 +1086,10 @@ Vector2 KinematicBody2D::move_and_slide(const Vector2 &p_linear_velocity, const
}
Vector2
KinematicBody2D
::
move_and_slide_with_snap
(
const
Vector2
&
p_linear_velocity
,
const
Vector2
&
p_snap
,
const
Vector2
&
p_up_direction
,
bool
p_stop_on_slope
,
int
p_max_slides
,
float
p_floor_max_angle
,
bool
p_infinite_inertia
)
{
Vector2
up_direction
=
p_up_direction
.
normalized
();
bool
was_on_floor
=
on_floor
;
Vector2
ret
=
move_and_slide
(
p_linear_velocity
,
p_
up_direction
,
p_stop_on_slope
,
p_max_slides
,
p_floor_max_angle
,
p_infinite_inertia
);
Vector2
ret
=
move_and_slide
(
p_linear_velocity
,
up_direction
,
p_stop_on_slope
,
p_max_slides
,
p_floor_max_angle
,
p_infinite_inertia
);
if
(
!
was_on_floor
||
p_snap
==
Vector2
())
{
return
ret
;
}
...
...
@@ -1097,8 +1099,8 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
if
(
move_and_collide
(
p_snap
,
p_infinite_inertia
,
col
,
false
,
true
))
{
bool
apply
=
true
;
if
(
p_
up_direction
!=
Vector2
())
{
if
(
Math
::
acos
(
p_up_direction
.
normalized
().
dot
(
col
.
normal
))
<
p_floor_max_angle
)
{
if
(
up_direction
!=
Vector2
())
{
if
(
Math
::
acos
(
col
.
normal
.
dot
(
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
on_floor
=
true
;
floor_normal
=
col
.
normal
;
on_floor_body
=
col
.
collider_rid
;
...
...
@@ -1106,7 +1108,7 @@ Vector2 KinematicBody2D::move_and_slide_with_snap(const Vector2 &p_linear_veloci
if
(
p_stop_on_slope
)
{
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
col
.
travel
=
p_up_direction
*
p_
up_direction
.
dot
(
col
.
travel
);
col
.
travel
=
up_direction
*
up_direction
.
dot
(
col
.
travel
);
}
}
else
{
...
...
scene/3d/physics_body_3d.cpp
View file @
c4650540
...
...
@@ -945,6 +945,7 @@ bool KinematicBody3D::move_and_collide(const Vector3 &p_motion, bool p_infinite_
Vector3
KinematicBody3D
::
move_and_slide
(
const
Vector3
&
p_linear_velocity
,
const
Vector3
&
p_up_direction
,
bool
p_stop_on_slope
,
int
p_max_slides
,
float
p_floor_max_angle
,
bool
p_infinite_inertia
)
{
Vector3
body_velocity
=
p_linear_velocity
;
Vector3
body_velocity_normal
=
body_velocity
.
normalized
();
Vector3
up_direction
=
p_up_direction
.
normalized
();
for
(
int
i
=
0
;
i
<
3
;
i
++
)
{
if
(
locked_axis
&
(
1
<<
i
))
{
...
...
@@ -988,11 +989,11 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
colliders
.
push_back
(
collision
);
motion
=
collision
.
remainder
;
if
(
p_
up_direction
==
Vector3
())
{
if
(
up_direction
==
Vector3
())
{
//all is a wall
on_wall
=
true
;
}
else
{
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
p_
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//floor
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//floor
on_floor
=
true
;
floor_normal
=
collision
.
normal
;
...
...
@@ -1000,14 +1001,14 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
floor_velocity
=
collision
.
collider_vel
;
if
(
p_stop_on_slope
)
{
if
((
body_velocity_normal
+
p_
up_direction
).
length
()
<
0.01
&&
collision
.
travel
.
length
()
<
1
)
{
if
((
body_velocity_normal
+
up_direction
).
length
()
<
0.01
&&
collision
.
travel
.
length
()
<
1
)
{
Transform
gt
=
get_global_transform
();
gt
.
origin
-=
collision
.
travel
.
slide
(
p_
up_direction
);
gt
.
origin
-=
collision
.
travel
.
slide
(
up_direction
);
set_global_transform
(
gt
);
return
Vector3
();
}
}
}
else
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
-
p_
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//ceiling
}
else
if
(
Math
::
acos
(
collision
.
normal
.
dot
(
-
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
//ceiling
on_ceiling
=
true
;
}
else
{
on_wall
=
true
;
...
...
@@ -1036,9 +1037,10 @@ Vector3 KinematicBody3D::move_and_slide(const Vector3 &p_linear_velocity, const
}
Vector3
KinematicBody3D
::
move_and_slide_with_snap
(
const
Vector3
&
p_linear_velocity
,
const
Vector3
&
p_snap
,
const
Vector3
&
p_up_direction
,
bool
p_stop_on_slope
,
int
p_max_slides
,
float
p_floor_max_angle
,
bool
p_infinite_inertia
)
{
Vector3
up_direction
=
p_up_direction
.
normalized
();
bool
was_on_floor
=
on_floor
;
Vector3
ret
=
move_and_slide
(
p_linear_velocity
,
p_
up_direction
,
p_stop_on_slope
,
p_max_slides
,
p_floor_max_angle
,
p_infinite_inertia
);
Vector3
ret
=
move_and_slide
(
p_linear_velocity
,
up_direction
,
p_stop_on_slope
,
p_max_slides
,
p_floor_max_angle
,
p_infinite_inertia
);
if
(
!
was_on_floor
||
p_snap
==
Vector3
())
{
return
ret
;
}
...
...
@@ -1048,8 +1050,8 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
if
(
move_and_collide
(
p_snap
,
p_infinite_inertia
,
col
,
false
,
true
))
{
bool
apply
=
true
;
if
(
p_
up_direction
!=
Vector3
())
{
if
(
Math
::
acos
(
p_up_direction
.
normalized
().
dot
(
col
.
normal
))
<
p_floor_max_angle
)
{
if
(
up_direction
!=
Vector3
())
{
if
(
Math
::
acos
(
col
.
normal
.
dot
(
up_direction
))
<=
p_floor_max_angle
+
FLOOR_ANGLE_THRESHOLD
)
{
on_floor
=
true
;
floor_normal
=
col
.
normal
;
on_floor_body
=
col
.
collider_rid
;
...
...
@@ -1057,7 +1059,7 @@ Vector3 KinematicBody3D::move_and_slide_with_snap(const Vector3 &p_linear_veloci
if
(
p_stop_on_slope
)
{
// move and collide may stray the object a bit because of pre un-stucking,
// so only ensure that motion happens on floor direction in this case.
col
.
travel
=
col
.
travel
.
project
(
p_
up_direction
);
col
.
travel
=
col
.
travel
.
project
(
up_direction
);
}
}
else
{
apply
=
false
;
//snapped with floor direction, but did not snap to a floor, do not snap.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment