summaryrefslogtreecommitdiff
path: root/servers/physics/physics_server_sw.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'servers/physics/physics_server_sw.cpp')
-rw-r--r--servers/physics/physics_server_sw.cpp435
1 files changed, 427 insertions, 8 deletions
diff --git a/servers/physics/physics_server_sw.cpp b/servers/physics/physics_server_sw.cpp
index aff60b5881..043d2149fe 100644
--- a/servers/physics/physics_server_sw.cpp
+++ b/servers/physics/physics_server_sw.cpp
@@ -29,6 +29,12 @@
#include "physics_server_sw.h"
#include "broad_phase_basic.h"
#include "broad_phase_octree.h"
+#include "joints/pin_joint_sw.h"
+#include "joints/hinge_joint_sw.h"
+#include "joints/slider_joint_sw.h"
+#include "joints/cone_twist_joint_sw.h"
+#include "joints/generic_6dof_joint_sw.h"
+
RID PhysicsServerSW::shape_create(ShapeType p_shape) {
@@ -137,6 +143,10 @@ RID PhysicsServerSW::space_create() {
space->set_default_area(area);
area->set_space(space);
area->set_priority(-1);
+ RID sgb = body_create();
+ body_set_space(sgb,id);
+ body_set_mode(sgb,BODY_MODE_STATIC);
+ space->set_static_global_body(sgb);
return id;
};
@@ -394,6 +404,25 @@ void PhysicsServerSW::area_set_monitor_callback(RID p_area,Object *p_receiver,co
}
+void PhysicsServerSW::area_set_ray_pickable(RID p_area,bool p_enable) {
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND(!area);
+
+ area->set_ray_pickable(p_enable);
+
+}
+
+bool PhysicsServerSW::area_is_ray_pickable(RID p_area) const{
+
+ AreaSW *area = area_owner.get(p_area);
+ ERR_FAIL_COND_V(!area,false);
+
+ return area->is_ray_pickable();
+
+}
+
+
/* BODY API */
@@ -568,6 +597,25 @@ bool PhysicsServerSW::body_is_continuous_collision_detection_enabled(RID p_body)
return body->is_continuous_collision_detection_enabled();
}
+void PhysicsServerSW::body_set_layer_mask(RID p_body, uint32_t p_mask) {
+
+ BodySW *body = body_owner.get(p_body);
+ ERR_FAIL_COND(!body);
+
+ body->set_layer_mask(p_mask);
+
+}
+
+uint32_t PhysicsServerSW::body_get_layer_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_layer_mask();
+
+}
+
+
void PhysicsServerSW::body_attach_object_instance_ID(RID p_body,uint32_t p_ID) {
BodySW *body = body_owner.get(p_body);
@@ -618,13 +666,6 @@ float PhysicsServerSW::body_get_param(RID p_body, BodyParameter p_param) const {
};
-void PhysicsServerSW::body_static_simulate_motion(RID p_body,const Transform& p_new_transform) {
-
- BodySW *body = body_owner.get(p_body);
- ERR_FAIL_COND(!body);
- body->simulate_motion(p_new_transform,last_step);
-
-};
void PhysicsServerSW::body_set_state(RID p_body, BodyState p_state, const Variant& p_variant) {
@@ -798,6 +839,308 @@ void PhysicsServerSW::body_set_force_integration_callback(RID p_body,Object *p_r
/* JOINT API */
+RID PhysicsServerSW::joint_create_pin(RID p_body_A,const Vector3& p_local_A,RID p_body_B,const Vector3& p_local_B) {
+
+ BodySW *body_A = body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A,RID());
+
+ if (!p_body_B.is_valid()) {
+ ERR_FAIL_COND_V(!body_A->get_space(),RID());
+ p_body_B=body_A->get_space()->get_static_global_body();
+ }
+
+ BodySW *body_B = body_owner.get(p_body_B);
+ ERR_FAIL_COND_V(!body_B,RID());
+
+ ERR_FAIL_COND_V(body_A==body_B,RID());
+
+ JointSW *joint = memnew( PinJointSW(body_A,p_local_A,body_B,p_local_B) );
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+}
+
+void PhysicsServerSW::pin_joint_set_param(RID p_joint,PinJointParam p_param, float p_value){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_PIN);
+ PinJointSW *pin_joint = static_cast<PinJointSW*>(joint);
+ pin_joint->set_param(p_param,p_value);
+
+}
+float PhysicsServerSW::pin_joint_get_param(RID p_joint,PinJointParam p_param) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,0);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_PIN,0);
+ PinJointSW *pin_joint = static_cast<PinJointSW*>(joint);
+ return pin_joint->get_param(p_param);
+
+}
+
+void PhysicsServerSW::pin_joint_set_local_A(RID p_joint, const Vector3& p_A){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_PIN);
+ PinJointSW *pin_joint = static_cast<PinJointSW*>(joint);
+ pin_joint->set_pos_A(p_A);
+
+}
+Vector3 PhysicsServerSW::pin_joint_get_local_A(RID p_joint) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,Vector3());
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_PIN,Vector3());
+ PinJointSW *pin_joint = static_cast<PinJointSW*>(joint);
+ return pin_joint->get_pos_A();
+
+}
+
+void PhysicsServerSW::pin_joint_set_local_B(RID p_joint, const Vector3& p_B){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_PIN);
+ PinJointSW *pin_joint = static_cast<PinJointSW*>(joint);
+ pin_joint->set_pos_B(p_B);
+
+}
+Vector3 PhysicsServerSW::pin_joint_get_local_B(RID p_joint) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,Vector3());
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_PIN,Vector3());
+ PinJointSW *pin_joint = static_cast<PinJointSW*>(joint);
+ return pin_joint->get_pos_B();
+
+}
+
+
+RID PhysicsServerSW::joint_create_hinge(RID p_body_A,const Transform& p_frame_A,RID p_body_B,const Transform& p_frame_B) {
+
+ BodySW *body_A = body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A,RID());
+
+ if (!p_body_B.is_valid()) {
+ ERR_FAIL_COND_V(!body_A->get_space(),RID());
+ p_body_B=body_A->get_space()->get_static_global_body();
+ }
+
+ BodySW *body_B = body_owner.get(p_body_B);
+ ERR_FAIL_COND_V(!body_B,RID());
+
+ ERR_FAIL_COND_V(body_A==body_B,RID());
+
+ JointSW *joint = memnew( HingeJointSW(body_A,body_B,p_frame_A,p_frame_B) );
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+
+}
+
+
+RID PhysicsServerSW::joint_create_hinge_simple(RID p_body_A,const Vector3& p_pivot_A,const Vector3& p_axis_A,RID p_body_B,const Vector3& p_pivot_B,const Vector3& p_axis_B) {
+
+ BodySW *body_A = body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A,RID());
+
+ if (!p_body_B.is_valid()) {
+ ERR_FAIL_COND_V(!body_A->get_space(),RID());
+ p_body_B=body_A->get_space()->get_static_global_body();
+ }
+
+ BodySW *body_B = body_owner.get(p_body_B);
+ ERR_FAIL_COND_V(!body_B,RID());
+
+ ERR_FAIL_COND_V(body_A==body_B,RID());
+
+ JointSW *joint = memnew( HingeJointSW(body_A,body_B,p_pivot_A,p_pivot_B,p_axis_A,p_axis_B) );
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+
+}
+
+void PhysicsServerSW::hinge_joint_set_param(RID p_joint,HingeJointParam p_param, float p_value){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_HINGE);
+ HingeJointSW *hinge_joint = static_cast<HingeJointSW*>(joint);
+ hinge_joint->set_param(p_param,p_value);
+
+}
+float PhysicsServerSW::hinge_joint_get_param(RID p_joint,HingeJointParam p_param) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,0);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_HINGE,0);
+ HingeJointSW *hinge_joint = static_cast<HingeJointSW*>(joint);
+ return hinge_joint->get_param(p_param);
+
+}
+
+void PhysicsServerSW::hinge_joint_set_flag(RID p_joint,HingeJointFlag p_flag, bool p_value){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_HINGE);
+ HingeJointSW *hinge_joint = static_cast<HingeJointSW*>(joint);
+ hinge_joint->set_flag(p_flag,p_value);
+
+}
+bool PhysicsServerSW::hinge_joint_get_flag(RID p_joint,HingeJointFlag p_flag) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,false);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_HINGE,false);
+ HingeJointSW *hinge_joint = static_cast<HingeJointSW*>(joint);
+ return hinge_joint->get_flag(p_flag);
+}
+
+PhysicsServerSW::JointType PhysicsServerSW::joint_get_type(RID p_joint) const {
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,JOINT_PIN);
+ return joint->get_type();
+}
+
+RID PhysicsServerSW::joint_create_slider(RID p_body_A,const Transform& p_local_frame_A,RID p_body_B,const Transform& p_local_frame_B) {
+
+ BodySW *body_A = body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A,RID());
+
+ if (!p_body_B.is_valid()) {
+ ERR_FAIL_COND_V(!body_A->get_space(),RID());
+ p_body_B=body_A->get_space()->get_static_global_body();
+ }
+
+ BodySW *body_B = body_owner.get(p_body_B);
+ ERR_FAIL_COND_V(!body_B,RID());
+
+ ERR_FAIL_COND_V(body_A==body_B,RID());
+
+ JointSW *joint = memnew( SliderJointSW(body_A,body_B,p_local_frame_A,p_local_frame_B) );
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+}
+
+void PhysicsServerSW::slider_joint_set_param(RID p_joint,SliderJointParam p_param, float p_value){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_SLIDER);
+ SliderJointSW *slider_joint = static_cast<SliderJointSW*>(joint);
+ slider_joint->set_param(p_param,p_value);
+}
+float PhysicsServerSW::slider_joint_get_param(RID p_joint,SliderJointParam p_param) const{
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,0);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_CONE_TWIST,0);
+ SliderJointSW *slider_joint = static_cast<SliderJointSW*>(joint);
+ return slider_joint->get_param(p_param);
+}
+
+
+RID PhysicsServerSW::joint_create_cone_twist(RID p_body_A,const Transform& p_local_frame_A,RID p_body_B,const Transform& p_local_frame_B) {
+
+ BodySW *body_A = body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A,RID());
+
+ if (!p_body_B.is_valid()) {
+ ERR_FAIL_COND_V(!body_A->get_space(),RID());
+ p_body_B=body_A->get_space()->get_static_global_body();
+ }
+
+ BodySW *body_B = body_owner.get(p_body_B);
+ ERR_FAIL_COND_V(!body_B,RID());
+
+ ERR_FAIL_COND_V(body_A==body_B,RID());
+
+ JointSW *joint = memnew( ConeTwistJointSW(body_A,body_B,p_local_frame_A,p_local_frame_B) );
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+}
+
+void PhysicsServerSW::cone_twist_joint_set_param(RID p_joint,ConeTwistJointParam p_param, float p_value) {
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_CONE_TWIST);
+ ConeTwistJointSW *cone_twist_joint = static_cast<ConeTwistJointSW*>(joint);
+ cone_twist_joint->set_param(p_param,p_value);
+}
+float PhysicsServerSW::cone_twist_joint_get_param(RID p_joint,ConeTwistJointParam p_param) const {
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,0);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_CONE_TWIST,0);
+ ConeTwistJointSW *cone_twist_joint = static_cast<ConeTwistJointSW*>(joint);
+ return cone_twist_joint->get_param(p_param);
+}
+
+
+RID PhysicsServerSW::joint_create_generic_6dof(RID p_body_A,const Transform& p_local_frame_A,RID p_body_B,const Transform& p_local_frame_B) {
+
+ BodySW *body_A = body_owner.get(p_body_A);
+ ERR_FAIL_COND_V(!body_A,RID());
+
+ if (!p_body_B.is_valid()) {
+ ERR_FAIL_COND_V(!body_A->get_space(),RID());
+ p_body_B=body_A->get_space()->get_static_global_body();
+ }
+
+ BodySW *body_B = body_owner.get(p_body_B);
+ ERR_FAIL_COND_V(!body_B,RID());
+
+ ERR_FAIL_COND_V(body_A==body_B,RID());
+
+ JointSW *joint = memnew( Generic6DOFJointSW(body_A,body_B,p_local_frame_A,p_local_frame_B,true) );
+ RID rid = joint_owner.make_rid(joint);
+ joint->set_self(rid);
+ return rid;
+}
+
+void PhysicsServerSW::generic_6dof_joint_set_param(RID p_joint,Vector3::Axis p_axis,G6DOFJointAxisParam p_param, float p_value){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_6DOF);
+ Generic6DOFJointSW *generic_6dof_joint = static_cast<Generic6DOFJointSW*>(joint);
+ generic_6dof_joint->set_param(p_axis,p_param,p_value);
+}
+float PhysicsServerSW::generic_6dof_joint_get_param(RID p_joint,Vector3::Axis p_axis,G6DOFJointAxisParam p_param){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,0);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_6DOF,0);
+ Generic6DOFJointSW *generic_6dof_joint = static_cast<Generic6DOFJointSW*>(joint);
+ return generic_6dof_joint->get_param(p_axis,p_param);
+}
+
+void PhysicsServerSW::generic_6dof_joint_set_flag(RID p_joint,Vector3::Axis p_axis,G6DOFJointAxisFlag p_flag, bool p_enable){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND(!joint);
+ ERR_FAIL_COND(joint->get_type()!=JOINT_6DOF);
+ Generic6DOFJointSW *generic_6dof_joint = static_cast<Generic6DOFJointSW*>(joint);
+ generic_6dof_joint->set_flag(p_axis,p_flag,p_enable);
+}
+bool PhysicsServerSW::generic_6dof_joint_get_flag(RID p_joint,Vector3::Axis p_axis,G6DOFJointAxisFlag p_flag){
+
+ JointSW *joint = joint_owner.get(p_joint);
+ ERR_FAIL_COND_V(!joint,false);
+ ERR_FAIL_COND_V(joint->get_type()!=JOINT_6DOF,false);
+ Generic6DOFJointSW *generic_6dof_joint = static_cast<Generic6DOFJointSW*>(joint);
+ return generic_6dof_joint->get_flag(p_axis,p_flag);
+}
+
+
#if 0
void PhysicsServerSW::joint_set_param(RID p_joint, JointParam p_param, real_t p_value) {
@@ -976,12 +1319,18 @@ void PhysicsServerSW::free(RID p_rid) {
active_spaces.erase(space);
free(space->get_default_area()->get_self());
+ free(space->get_static_global_body());
+
space_owner.free(p_rid);
memdelete(space);
} else if (joint_owner.owns(p_rid)) {
JointSW *joint = joint_owner.get(p_rid);
+ for(int i=0;i<joint->get_body_count();i++) {
+
+ joint->get_body_ptr()[i]->remove_constraint(joint);
+ }
joint_owner.free(p_rid);
memdelete(joint);
@@ -1021,11 +1370,18 @@ void PhysicsServerSW::step(float p_step) {
last_step=p_step;
PhysicsDirectBodyStateSW::singleton->step=p_step;
+ island_count=0;
+ active_objects=0;
+ collision_pairs=0;
for( Set<const SpaceSW*>::Element *E=active_spaces.front();E;E=E->next()) {
stepper->step((SpaceSW*)E->get(),p_step,iterations);
+ island_count+=E->get()->get_island_count();
+ active_objects+=E->get()->get_active_objects();
+ collision_pairs+=E->get()->get_collision_pairs();
}
-};
+
+}
void PhysicsServerSW::sync() {
@@ -1054,9 +1410,72 @@ void PhysicsServerSW::finish() {
};
+int PhysicsServerSW::get_process_info(ProcessInfo p_info) {
+
+ switch(p_info) {
+
+ case INFO_ACTIVE_OBJECTS: {
+
+ return active_objects;
+ } break;
+ case INFO_COLLISION_PAIRS: {
+ return collision_pairs;
+ } break;
+ case INFO_ISLAND_COUNT: {
+
+ return island_count;
+ } break;
+
+ }
+
+ return 0;
+}
+
+
+void PhysicsServerSW::_shape_col_cbk(const Vector3& p_point_A,const Vector3& p_point_B,void *p_userdata) {
+
+
+ CollCbkData *cbk=(CollCbkData *)p_userdata;
+
+ if (cbk->max==0)
+ return;
+
+ if (cbk->amount == cbk->max) {
+ //find least deep
+ float min_depth=1e20;
+ int min_depth_idx=0;
+ for(int i=0;i<cbk->amount;i++) {
+
+ float d = cbk->ptr[i*2+0].distance_squared_to(cbk->ptr[i*2+1]);
+ if (d<min_depth) {
+ min_depth=d;
+ min_depth_idx=i;
+ }
+
+ }
+
+ float d = p_point_A.distance_squared_to(p_point_B);
+ if (d<min_depth)
+ return;
+ cbk->ptr[min_depth_idx*2+0]=p_point_A;
+ cbk->ptr[min_depth_idx*2+1]=p_point_B;
+
+
+ } else {
+
+ cbk->ptr[cbk->amount*2+0]=p_point_A;
+ cbk->ptr[cbk->amount*2+1]=p_point_B;
+ cbk->amount++;
+ }
+}
+
+
PhysicsServerSW::PhysicsServerSW() {
BroadPhaseSW::create_func=BroadPhaseOctree::_create;
+ island_count=0;
+ active_objects=0;
+ collision_pairs=0;
active=true;