/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "physic_bullet/bullet_constraint.h" #include "physic_bullet/bullet_item.h" #include "scene3d/mitem.h" using namespace GS; using namespace GS::S3D; void BulletConstraint::setLimitHinge(float low, float high, float _softness, float _biasFactor, float _relaxationFactor) { if (!constraint) return; switch (type) { case PhysicConstraintDesc::TypeHinge: ((btHingeConstraint*)constraint)->setLimit(low, high, _softness, _biasFactor, _relaxationFactor); break; } } //------------------------------------------------------------------------------ void BulletConstraint::SetPivotA(const Matrix4 &pivot) { if (!constraint) return; switch (type) { case PhysicConstraintDesc::TypePoint: { Vector4 p = pivot.GetRow(3); if (item_a.IsValid()) p -= ((BulletPhysicItem *)item_a.c_ptr())->GetCenter(); btVector3 bt_pivot(p.x, p.y, p.z); ((btPoint2PointConstraint *)constraint)->setPivotA(bt_pivot); } break; default: break; } } void BulletConstraint::SetPivotB(const Matrix4 &pivot) { if (constraint) switch (type) { case PhysicConstraintDesc::TypePoint: { Vector4 p = pivot.GetRow(3); if (item_b.IsValid()) p -= ((BulletPhysicItem *)item_b.c_ptr())->GetCenter(); btVector3 bt_pivot(p.x, p.y, p.z); ((btPoint2PointConstraint *)constraint)->setPivotB(bt_pivot); } break; default: break; } } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void BulletConstraint::Enable(bool b) { if (constraint) constraint->setEnabled(b); } bool BulletConstraint::SetupConstraint(const PhysicConstraintDesc &desc) { DeleteConstraint(); // Get constraint items. item_a = desc.item_a.IsValid() ? desc.item_a->physic_item.c_ptr() : NULL; item_b = desc.item_b.IsValid() ? desc.item_b->physic_item.c_ptr() : NULL; BulletPhysicItem *bullet_item_a = (BulletPhysicItem *)item_a.c_ptr(), *bullet_item_b = (BulletPhysicItem *)item_b.c_ptr(); btRigidBody *rigid_body_a = bullet_item_a ? bullet_item_a->rigid_body.c_ptr() : NULL, *rigid_body_b = bullet_item_b ? bullet_item_b->rigid_body.c_ptr() : NULL; if (!rigid_body_a && !rigid_body_b) return false; // Create constraint. type = desc.type; switch (type) { case PhysicConstraintDesc::TypePoint: { Vector4 np_a = desc.pivot_a.GetRow(3), np_b = desc.pivot_b.GetRow(3); if (bullet_item_a) np_a -= bullet_item_a->GetCenter(); if (bullet_item_b) np_b -= bullet_item_b->GetCenter(); btVector3 btp_a(np_a.x, np_a.y, np_a.z), btp_b(np_b.x, np_b.y, np_b.z); if (rigid_body_a && rigid_body_b) constraint = new btPoint2PointConstraint(*rigid_body_a, *rigid_body_b, btp_a, btp_b); if (rigid_body_a && !rigid_body_b) constraint = new btPoint2PointConstraint(*rigid_body_a, btp_a); // constraint->setParam(BT_CONSTRAINT_ERP, 0.8); // constraint->setParam(BT_CONSTRAINT_CFM, 0); } break; case PhysicConstraintDesc::TypeHinge: { Vector4 np_a = desc.pivot_a.GetRow(3), np_b = desc.pivot_b.GetRow(3); if (bullet_item_a) np_a -= bullet_item_a->GetCenter(); if (bullet_item_b) np_b -= bullet_item_b->GetCenter(); btVector3 btp_a(np_a.x, np_a.y, np_a.z), btp_b(np_b.x, np_b.y, np_b.z); if (rigid_body_a && rigid_body_b) constraint = new btHingeConstraint(*rigid_body_a, *rigid_body_b, btp_a, btp_b, btVector3(0,0,1), btVector3(0,0,1)); if (rigid_body_a && !rigid_body_b) constraint = new btHingeConstraint(*rigid_body_a, btp_a, btVector3(0,1,0)); // ((btHingeConstraint*)constraint)->setLimit(0, 0); // constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0); // constraint->setParam(BT_CONSTRAINT_CFM, 0); // constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.8); // constraint->setParam(BT_CONSTRAINT_ERP, 0.8); } break; default: break; } if (constraint) world->addConstraint(constraint); return true; } void BulletConstraint::DeleteConstraint() { if (constraint) { world->removeConstraint(constraint); _safe_delete(constraint); } item_a = NULL; item_b = NULL; type = PhysicConstraintDesc::TypeNone; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ BulletConstraint::BulletConstraint(btDiscreteDynamicsWorld *_world) { type = PhysicConstraintDesc::TypeNone; world = _world; constraint = NULL; } BulletConstraint::~BulletConstraint() { DeleteConstraint(); } //------------------------------------------------------------------------------