void BulletPhysicsServer::area_clear_shapes(RID p_area) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); for (int i = area->get_shape_count(); 0 < i; --i) area->remove_shape(0); }
ObjectID BulletPhysicsServer::area_get_object_instance_id(RID p_area) const { if (space_owner.owns(p_area)) { return 0; } AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, ObjectID()); return area->get_instance_id(); }
void BulletPhysicsServer::area_attach_object_instance_id(RID p_area, ObjectID p_ID) { if (space_owner.owns(p_area)) { return; } AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_instance_id(p_ID); }
void BulletPhysicsServer::area_set_shape(RID p_area, int p_shape_idx, RID p_shape) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); ShapeBullet *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); area->set_shape(p_shape_idx, shape); }
void BulletPhysicsServer::area_add_shape(RID p_area, RID p_shape, const Transform &p_transform) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); ShapeBullet *shape = shape_owner.get(p_shape); ERR_FAIL_COND(!shape); area->add_shape(shape, p_transform); }
void BulletPhysicsServer::area_set_space(RID p_area, RID p_space) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); SpaceBullet *space = NULL; if (p_space.is_valid()) { space = space_owner.get(p_space); ERR_FAIL_COND(!space); } area->set_space(space); }
Variant BulletPhysicsServer::area_get_param(RID p_area, AreaParameter p_param) const { if (space_owner.owns(p_area)) { SpaceBullet *space = space_owner.get(p_area); return space->get_param(p_param); } else { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, Variant()); return area->get_param(p_param); } }
void BulletPhysicsServer::area_set_param(RID p_area, AreaParameter p_param, const Variant &p_value) { if (space_owner.owns(p_area)) { SpaceBullet *space = space_owner.get(p_area); if (space) { space->set_param(p_param, p_value); } } else { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_param(p_param, p_value); } }
RID BulletPhysicsServer::area_create() { AreaBullet *area = bulletnew(AreaBullet); area->set_collision_layer(1); area->set_collision_mask(1); CreateThenReturnRID(area_owner, area) }
bool BulletPhysicsServer::area_is_ray_pickable(RID p_area) const { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, false); return area->is_ray_pickable(); }
void BulletPhysicsServer::area_set_area_monitor_callback(RID p_area, Object *p_receiver, const StringName &p_method) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_event_callback(CollisionObjectBullet::TYPE_AREA, p_receiver ? p_receiver->get_instance_id() : 0, p_method); }
Transform BulletPhysicsServer::area_get_transform(RID p_area) const { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, Transform()); return area->get_transform(); }
int BulletPhysicsServer::area_get_shape_count(RID p_area) const { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, 0); return area->get_shape_count(); }
PhysicsServer::AreaSpaceOverrideMode BulletPhysicsServer::area_get_space_override_mode(RID p_area) const { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED); return area->get_spOv_mode(); }
void BulletPhysicsServer::area_set_space_override_mode(RID p_area, AreaSpaceOverrideMode p_mode) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area) area->set_spOv_mode(p_mode); }
RID BulletPhysicsServer::area_get_space(RID p_area) const { AreaBullet *area = area_owner.get(p_area); return area->get_space()->get_self(); }
void BulletPhysicsServer::area_set_transform(RID p_area, const Transform &p_transform) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_transform(p_transform); }
RID BulletPhysicsServer::area_get_shape(RID p_area, int p_shape_idx) const { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND_V(!area, RID()); return area->get_shape(p_shape_idx)->get_self(); }
void BulletPhysicsServer::area_set_collision_layer(RID p_area, uint32_t p_layer) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_collision_layer(p_layer); }
void BulletPhysicsServer::area_remove_shape(RID p_area, int p_shape_idx) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); return area->remove_shape(p_shape_idx); }
void BulletPhysicsServer::area_set_ray_pickable(RID p_area, bool p_enable) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_ray_pickable(p_enable); }
void BulletPhysicsServer::area_set_shape_disabled(RID p_area, int p_shape_idx, bool p_disabled) { AreaBullet *area = area_owner.get(p_area); ERR_FAIL_COND(!area); area->set_shape_disabled(p_shape_idx, p_disabled); }
void RigidBodyBullet::reload_space_override_modificator() { // Make sure that kinematic bodies have their total gravity calculated if (!is_active() && PhysicsServer::BODY_MODE_KINEMATIC != mode) return; Vector3 newGravity(space->get_gravity_direction() * space->get_gravity_magnitude()); real_t newLinearDamp(linearDamp); real_t newAngularDamp(angularDamp); AreaBullet *currentArea; // Variable used to calculate new gravity for gravity point areas, it is pointed by currentGravity pointer Vector3 support_gravity(0, 0, 0); int countCombined(0); for (int i = areaWhereIamCount - 1; 0 <= i; --i) { currentArea = areasWhereIam[i]; if (PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED == currentArea->get_spOv_mode()) { continue; } /// Here is calculated the gravity if (currentArea->is_spOv_gravityPoint()) { /// It calculates the direction of new gravity support_gravity = currentArea->get_transform().xform(currentArea->get_spOv_gravityVec()) - get_transform().get_origin(); real_t distanceMag = support_gravity.length(); // Normalized in this way to avoid the double call of function "length()" if (distanceMag == 0) { support_gravity.x = 0; support_gravity.y = 0; support_gravity.z = 0; } else { support_gravity.x /= distanceMag; support_gravity.y /= distanceMag; support_gravity.z /= distanceMag; } /// Here is calculated the final gravity if (currentArea->get_spOv_gravityPointDistanceScale() > 0) { // Scaled gravity by distance support_gravity *= currentArea->get_spOv_gravityMag() / Math::pow(distanceMag * currentArea->get_spOv_gravityPointDistanceScale() + 1, 2); } else { // Unscaled gravity support_gravity *= currentArea->get_spOv_gravityMag(); } } else { support_gravity = currentArea->get_spOv_gravityVec() * currentArea->get_spOv_gravityMag(); } switch (currentArea->get_spOv_mode()) { ///case PhysicsServer::AREA_SPACE_OVERRIDE_DISABLED: /// This area does not affect gravity/damp. These are generally areas /// that exist only to detect collisions, and objects entering or exiting them. /// break; case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE: /// This area adds its gravity/damp values to whatever has been /// calculated so far. This way, many overlapping areas can combine /// their physics to make interesting newGravity += support_gravity; newLinearDamp += currentArea->get_spOv_linearDamp(); newAngularDamp += currentArea->get_spOv_angularDamp(); ++countCombined; break; case PhysicsServer::AREA_SPACE_OVERRIDE_COMBINE_REPLACE: /// This area adds its gravity/damp values to whatever has been calculated /// so far. Then stops taking into account the rest of the areas, even the /// default one. newGravity += support_gravity; newLinearDamp += currentArea->get_spOv_linearDamp(); newAngularDamp += currentArea->get_spOv_angularDamp(); ++countCombined; goto endAreasCycle; case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE: /// This area replaces any gravity/damp, even the default one, and /// stops taking into account the rest of the areas. newGravity = support_gravity; newLinearDamp = currentArea->get_spOv_linearDamp(); newAngularDamp = currentArea->get_spOv_angularDamp(); countCombined = 1; goto endAreasCycle; case PhysicsServer::AREA_SPACE_OVERRIDE_REPLACE_COMBINE: /// This area replaces any gravity/damp calculated so far, but keeps /// calculating the rest of the areas, down to the default one. newGravity = support_gravity; newLinearDamp = currentArea->get_spOv_linearDamp(); newAngularDamp = currentArea->get_spOv_angularDamp(); countCombined = 1; break; } } endAreasCycle: if (1 < countCombined) { newGravity /= countCombined; newLinearDamp /= countCombined; newAngularDamp /= countCombined; } btVector3 newBtGravity; G_TO_B(newGravity * gravity_scale, newBtGravity); btBody->setGravity(newBtGravity); btBody->setDamping(newLinearDamp, newAngularDamp); }
void BulletPhysicsServer::free(RID p_rid) { if (shape_owner.owns(p_rid)) { ShapeBullet *shape = shape_owner.get(p_rid); // Notify the shape is configured for (Map<ShapeOwnerBullet *, int>::Element *element = shape->get_owners().front(); element; element = element->next()) { static_cast<ShapeOwnerBullet *>(element->key())->remove_shape(shape); } shape_owner.free(p_rid); bulletdelete(shape); } else if (rigid_body_owner.owns(p_rid)) { RigidBodyBullet *body = rigid_body_owner.get(p_rid); body->set_space(NULL); body->remove_all_shapes(true); rigid_body_owner.free(p_rid); bulletdelete(body); } else if (soft_body_owner.owns(p_rid)) { SoftBodyBullet *body = soft_body_owner.get(p_rid); body->set_space(NULL); soft_body_owner.free(p_rid); bulletdelete(body); } else if (area_owner.owns(p_rid)) { AreaBullet *area = area_owner.get(p_rid); area->set_space(NULL); area->remove_all_shapes(true); area_owner.free(p_rid); bulletdelete(area); } else if (joint_owner.owns(p_rid)) { JointBullet *joint = joint_owner.get(p_rid); joint->destroy_internal_constraint(); joint_owner.free(p_rid); bulletdelete(joint); } else if (space_owner.owns(p_rid)) { SpaceBullet *space = space_owner.get(p_rid); space->remove_all_collision_objects(); space_set_active(p_rid, false); space_owner.free(p_rid); bulletdelete(space); } else { ERR_EXPLAIN("Invalid ID"); ERR_FAIL(); } }