summaryrefslogtreecommitdiff
path: root/servers/physics/body_sw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics/body_sw.cpp')
-rw-r--r--servers/physics/body_sw.cpp107
1 files changed, 72 insertions, 35 deletions
diff --git a/servers/physics/body_sw.cpp b/servers/physics/body_sw.cpp
index 52edc0faa7..0fd754ba25 100644
--- a/servers/physics/body_sw.cpp
+++ b/servers/physics/body_sw.cpp
@@ -195,7 +195,7 @@ void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
_set_inv_transform(get_transform().affine_inverse());
_inv_mass=0;
_set_static(p_mode==PhysicsServer::BODY_MODE_STATIC);
- set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC);
+ //set_active(p_mode==PhysicsServer::BODY_MODE_KINEMATIC);
linear_velocity=Vector3();
angular_velocity=Vector3();
} break;
@@ -203,14 +203,12 @@ void BodySW::set_mode(PhysicsServer::BodyMode p_mode) {
_inv_mass=mass>0?(1.0/mass):0;
_set_static(false);
- simulated_motion=false; //jic
} break;
case PhysicsServer::BODY_MODE_CHARACTER: {
_inv_mass=mass>0?(1.0/mass):0;
_set_static(false);
- simulated_motion=false; //jic
} break;
}
@@ -235,13 +233,19 @@ void BodySW::set_state(PhysicsServer::BodyState p_state, const Variant& p_varian
case PhysicsServer::BODY_STATE_TRANSFORM: {
- if (mode==PhysicsServer::BODY_MODE_STATIC || mode==PhysicsServer::BODY_MODE_KINEMATIC) {
+ if (mode==PhysicsServer::BODY_MODE_KINEMATIC) {
+ new_transform=p_variant;
+ //wakeup_neighbours();
+ set_active(true);
+
+ } else if (mode==PhysicsServer::BODY_MODE_STATIC) {
_set_transform(p_variant);
_set_inv_transform(get_transform().affine_inverse());
wakeup_neighbours();
} else {
Transform t = p_variant;
t.orthonormalize();
+ new_transform=get_transform(); //used as old to compute motion
_set_transform(t);
_set_inv_transform(get_transform().inverse());
@@ -353,7 +357,7 @@ void BodySW::_compute_area_gravity(const AreaSW *p_area) {
void BodySW::integrate_forces(real_t p_step) {
- if (mode==PhysicsServer::BODY_MODE_STATIC || mode==PhysicsServer::BODY_MODE_KINEMATIC)
+ if (mode==PhysicsServer::BODY_MODE_STATIC)
return;
AreaSW *current_area = get_space()->get_default_area();
@@ -374,28 +378,56 @@ void BodySW::integrate_forces(real_t p_step) {
_compute_area_gravity(current_area);
density=current_area->get_density();
- if (!omit_force_integration) {
- //overriden by direct state query
+ Vector3 motion;
+ bool do_motion=false;
- Vector3 force=gravity*mass;
- force+=applied_force;
- Vector3 torque=applied_torque;
+ if (mode==PhysicsServer::BODY_MODE_KINEMATIC) {
- real_t damp = 1.0 - p_step * density;
+ //compute motion, angular and etc. velocities from prev transform
+ linear_velocity = (new_transform.origin - get_transform().origin)/p_step;
- if (damp<0) // reached zero in the given time
- damp=0;
+ //compute a FAKE angular velocity, not so easy
+ Matrix3 rot=new_transform.basis.orthonormalized().transposed() * get_transform().basis.orthonormalized();
+ Vector3 axis;
+ float angle;
+
+ rot.get_axis_and_angle(axis,angle);
+ axis.normalize();
+ angular_velocity=axis.normalized() * (angle/p_step);
+
+ motion = new_transform.origin - get_transform().origin;
+ do_motion=true;
+
+ } else {
+ if (!omit_force_integration) {
+ //overriden by direct state query
- real_t angular_damp = 1.0 - p_step * density * get_space()->get_body_angular_velocity_damp_ratio();
+ Vector3 force=gravity*mass;
+ force+=applied_force;
+ Vector3 torque=applied_torque;
- if (angular_damp<0) // reached zero in the given time
- angular_damp=0;
+ real_t damp = 1.0 - p_step * density;
- linear_velocity*=damp;
- angular_velocity*=angular_damp;
+ if (damp<0) // reached zero in the given time
+ damp=0;
+
+ real_t angular_damp = 1.0 - p_step * density * get_space()->get_body_angular_velocity_damp_ratio();
+
+ if (angular_damp<0) // reached zero in the given time
+ angular_damp=0;
+
+ linear_velocity*=damp;
+ angular_velocity*=angular_damp;
+
+ linear_velocity+=_inv_mass * force * p_step;
+ angular_velocity+=_inv_inertia_tensor.xform(torque)*p_step;
+ }
+
+ if (continuous_cd) {
+ motion=linear_velocity*p_step;
+ do_motion=true;
+ }
- linear_velocity+=_inv_mass * force * p_step;
- angular_velocity+=_inv_inertia_tensor.xform(torque)*p_step;
}
applied_force=Vector3();
@@ -406,8 +438,11 @@ void BodySW::integrate_forces(real_t p_step) {
biased_angular_velocity=Vector3();
biased_linear_velocity=Vector3();
- if (continuous_cd) //shapes temporarily extend for raycast
- _update_shapes_with_motion(linear_velocity*p_step);
+
+ if (do_motion) {//shapes temporarily extend for raycast
+ _update_shapes_with_motion(motion);
+ }
+
current_area=NULL; // clear the area, so it is set in the next frame
contact_count=0;
@@ -419,9 +454,16 @@ void BodySW::integrate_velocities(real_t p_step) {
if (mode==PhysicsServer::BODY_MODE_STATIC)
return;
+ if (fi_callback)
+ get_space()->body_add_to_state_query_list(&direct_state_query_list);
+
if (mode==PhysicsServer::BODY_MODE_KINEMATIC) {
- if (fi_callback)
- get_space()->body_add_to_state_query_list(&direct_state_query_list);
+
+ _set_transform(new_transform,false);
+ _set_inv_transform(new_transform.affine_inverse()); ;
+ if (linear_velocity==Vector3() && angular_velocity==Vector3())
+ set_active(false); //stopped moving, deactivate
+
return;
}
@@ -475,14 +517,13 @@ void BodySW::integrate_velocities(real_t p_step) {
_update_inertia_tensor();
- if (fi_callback) {
-
- get_space()->body_add_to_state_query_list(&direct_state_query_list);
- }
+ //if (fi_callback) {
+ // get_space()->body_add_to_state_query_list(&direct_state_query_list);
+ //
}
-
+/*
void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) {
Transform inv_xform = p_xform.affine_inverse();
@@ -514,6 +555,7 @@ void BodySW::simulate_motion(const Transform& p_xform,real_t p_step) {
}
+*/
void BodySW::wakeup_neighbours() {
@@ -562,12 +604,7 @@ void BodySW::call_queries() {
}
- if (simulated_motion) {
- // linear_velocity=Vector3();
- // angular_velocity=0;
- simulated_motion=false;
- }
}
@@ -634,7 +671,7 @@ BodySW::BodySW() : CollisionObjectSW(TYPE_BODY), active_list(this), inertia_upda
_set_static(false);
density=0;
contact_count=0;
- simulated_motion=false;
+
still_time=0;
continuous_cd=false;
can_sleep=false;