123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561 |
- /****************************************************************************
- Copyright (c) 2015-2017 Chukong Technologies Inc.
-
- http://www.cocos2d-x.org
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- ****************************************************************************/
- #include "physics3d/CCPhysics3D.h"
- #include "base/ccUTF8.h"
- #if CC_USE_3D_PHYSICS
- #if (CC_ENABLE_BULLET_INTEGRATION)
- #include "bullet/btBulletCollisionCommon.h"
- #include "bullet/btBulletDynamicsCommon.h"
- NS_CC_BEGIN
- Physics3DRigidBody::Physics3DRigidBody()
- : _btRigidBody(nullptr)
- , _physics3DShape(nullptr)
- {
-
- }
- Physics3DRigidBody::~Physics3DRigidBody()
- {
- if (_physicsWorld)
- {
- for(auto constraint : _constraintList)
- {
- _physicsWorld->removePhysics3DConstraint(constraint);
- }
- _constraintList.clear();
- }
- auto ms = _btRigidBody->getMotionState();
- CC_SAFE_DELETE(ms);
- CC_SAFE_DELETE(_btRigidBody);
- CC_SAFE_RELEASE(_physics3DShape);
- }
- Physics3DRigidBody* Physics3DRigidBody::create(Physics3DRigidBodyDes* info)
- {
- auto ret = new (std::nothrow) Physics3DRigidBody();
- if (ret->init(info))
- {
- ret->autorelease();
- return ret;
- }
-
- CC_SAFE_DELETE(ret);
- return ret;
- }
- bool Physics3DRigidBody::init(Physics3DRigidBodyDes* info)
- {
- if (info->shape == nullptr)
- return false;
-
- btScalar mass = info->mass;
- auto shape = info->shape->getbtShape();
- auto localInertia = convertVec3TobtVector3(info->localInertia);
- if (mass != 0.f)
- {
- shape->calculateLocalInertia(mass,localInertia);
- }
-
- auto transform = convertMat4TobtTransform(info->originalTransform);
- btDefaultMotionState* myMotionState = new btDefaultMotionState(transform);
- btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia);
- _btRigidBody = new btRigidBody(rbInfo);
- _type = Physics3DObject::PhysicsObjType::RIGID_BODY;
- _physics3DShape = info->shape;
- _physics3DShape->retain();
- if (info->disableSleep)
- _btRigidBody->setActivationState(DISABLE_DEACTIVATION);
- return true;
- }
- void Physics3DRigidBody::setActive(bool active)
- {
- if (_btRigidBody)
- {
- _btRigidBody->setActivationState(active ? ACTIVE_TAG : WANTS_DEACTIVATION);
- }
- }
- void Physics3DRigidBody::applyForce( const cocos2d::Vec3& force, const cocos2d::Vec3& rel_pos )
- {
- _btRigidBody->applyForce(convertVec3TobtVector3(force), convertVec3TobtVector3(rel_pos));
- }
- void Physics3DRigidBody::setLinearVelocity( const cocos2d::Vec3& lin_vel )
- {
- _btRigidBody->setLinearVelocity(convertVec3TobtVector3(lin_vel));
- }
- void Physics3DRigidBody::applyCentralForce( const cocos2d::Vec3& force )
- {
- _btRigidBody->applyCentralForce(convertVec3TobtVector3(force));
- }
- void Physics3DRigidBody::applyCentralImpulse( const cocos2d::Vec3& impulse )
- {
- _btRigidBody->applyCentralImpulse(convertVec3TobtVector3(impulse));
- }
- void Physics3DRigidBody::applyTorque( const cocos2d::Vec3& torque )
- {
- _btRigidBody->applyTorque(convertVec3TobtVector3(torque));
- }
- void Physics3DRigidBody::applyTorqueImpulse( const cocos2d::Vec3& torque )
- {
- _btRigidBody->applyTorqueImpulse(convertVec3TobtVector3(torque));
- }
- void Physics3DRigidBody::applyImpulse( const cocos2d::Vec3& impulse, const cocos2d::Vec3& rel_pos )
- {
- _btRigidBody->applyImpulse(convertVec3TobtVector3(impulse), convertVec3TobtVector3(rel_pos));
- }
- void Physics3DRigidBody::applyDamping( float timeStep )
- {
- _btRigidBody->applyDamping(timeStep);
- }
- cocos2d::Vec3 Physics3DRigidBody::getLinearVelocity() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getLinearVelocity());
- }
- void Physics3DRigidBody::setLinearFactor( const cocos2d::Vec3& linearFactor )
- {
- _btRigidBody->setLinearFactor(convertVec3TobtVector3(linearFactor));
- }
- cocos2d::Vec3 Physics3DRigidBody::getLinearFactor() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getLinearFactor());
- }
- void Physics3DRigidBody::setAngularFactor( const cocos2d::Vec3& angFac )
- {
- _btRigidBody->setAngularFactor(convertVec3TobtVector3(angFac));
- }
- void Physics3DRigidBody::setAngularFactor( float angFac )
- {
- _btRigidBody->setAngularFactor(angFac);
- }
- cocos2d::Vec3 Physics3DRigidBody::getAngularFactor() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getAngularFactor());
- }
- void Physics3DRigidBody::setAngularVelocity( const cocos2d::Vec3& ang_vel )
- {
- _btRigidBody->setAngularVelocity(convertVec3TobtVector3(ang_vel));
- }
- cocos2d::Vec3 Physics3DRigidBody::getAngularVelocity() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getAngularVelocity());
- }
- void Physics3DRigidBody::setCenterOfMassTransform( const cocos2d::Mat4& xform )
- {
- _btRigidBody->setCenterOfMassTransform(convertMat4TobtTransform(xform));
- }
- cocos2d::Mat4 Physics3DRigidBody::getCenterOfMassTransform() const
- {
- return convertbtTransformToMat4(_btRigidBody->getCenterOfMassTransform());
- }
- void Physics3DRigidBody::setDamping( float lin_damping, float ang_damping )
- {
- _btRigidBody->setDamping(lin_damping, ang_damping);
- }
- float Physics3DRigidBody::getLinearDamping() const
- {
- return _btRigidBody->getLinearDamping();
- }
- float Physics3DRigidBody::getAngularDamping() const
- {
- return _btRigidBody->getAngularDamping();
- }
- void Physics3DRigidBody::setGravity( const cocos2d::Vec3& acceleration )
- {
- _btRigidBody->setGravity(convertVec3TobtVector3(acceleration));
- }
- cocos2d::Vec3 Physics3DRigidBody::getGravity() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getGravity());
- }
- void Physics3DRigidBody::setInvInertiaDiagLocal( const cocos2d::Vec3& diagInvInertia )
- {
- _btRigidBody->setInvInertiaDiagLocal(convertVec3TobtVector3(diagInvInertia));
- }
- cocos2d::Vec3 Physics3DRigidBody::getInvInertiaDiagLocal() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getInvInertiaDiagLocal());
- }
- void Physics3DRigidBody::setMassProps( float mass, const cocos2d::Vec3& inertia )
- {
- _btRigidBody->setMassProps(mass, convertVec3TobtVector3(inertia));
- }
- float Physics3DRigidBody::getInvMass() const
- {
- return _btRigidBody->getInvMass();
- }
- cocos2d::Vec3 Physics3DRigidBody::getTotalForce() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getTotalForce());
- }
- cocos2d::Vec3 Physics3DRigidBody::getTotalTorque() const
- {
- return convertbtVector3ToVec3(_btRigidBody->getTotalTorque());
- }
- void Physics3DRigidBody::setRestitution( float rest )
- {
- _btRigidBody->setRestitution(rest);
- }
- float Physics3DRigidBody::getRestitution() const
- {
- return _btRigidBody->getRestitution();
- }
- void Physics3DRigidBody::setFriction( float frict )
- {
- _btRigidBody->setFriction(frict);
- }
- float Physics3DRigidBody::getFriction() const
- {
- return _btRigidBody->getFriction();
- }
- void Physics3DRigidBody::setRollingFriction( float frict )
- {
- _btRigidBody->setRollingFriction(frict);
- }
- float Physics3DRigidBody::getRollingFriction() const
- {
- return _btRigidBody->getRollingFriction();
- }
- void Physics3DRigidBody::setHitFraction( float hitFraction )
- {
- _btRigidBody->setHitFraction(hitFraction);
- }
- float Physics3DRigidBody::getHitFraction() const
- {
- return _btRigidBody->getHitFraction();
- }
- void Physics3DRigidBody::setCcdMotionThreshold( float ccdMotionThreshold )
- {
- _btRigidBody->setCcdMotionThreshold(ccdMotionThreshold);
- }
- float Physics3DRigidBody::getCcdMotionThreshold() const
- {
- return _btRigidBody->getCcdMotionThreshold();
- }
- void Physics3DRigidBody::setCcdSweptSphereRadius( float radius )
- {
- _btRigidBody->setCcdSweptSphereRadius(radius);
- }
- float Physics3DRigidBody::getCcdSweptSphereRadius() const
- {
- return _btRigidBody->getCcdSweptSphereRadius();
- }
- void Physics3DRigidBody::addConstraint( Physics3DConstraint *constraint )
- {
- auto iter = std::find(_constraintList.begin(), _constraintList.end(), constraint);
- if (iter == _constraintList.end()){
- _constraintList.push_back(constraint);
- constraint->retain();
- }
- }
- void Physics3DRigidBody::removeConstraint( Physics3DConstraint *constraint )
- {
- auto iter = std::find(_constraintList.begin(), _constraintList.end(), constraint);
- if (iter != _constraintList.end()){
- constraint->release();
- _constraintList.erase(iter);
- }
- }
- void Physics3DRigidBody::removeConstraint( unsigned int idx )
- {
- CCASSERT(idx < _constraintList.size(), "idx < _constraintList.size()");
- removeConstraint(_constraintList[idx]);
- }
- Physics3DConstraint* Physics3DRigidBody::getConstraint( unsigned int idx ) const
- {
- CCASSERT(idx < _constraintList.size(), "idx < _constraintList.size()");
- return _constraintList[idx];
- }
- unsigned int Physics3DRigidBody::getConstraintCount() const
- {
- return (unsigned int)_constraintList.size();
- }
- cocos2d::Mat4 Physics3DRigidBody::getWorldTransform() const
- {
- const auto& transform = _btRigidBody->getWorldTransform();
- return convertbtTransformToMat4(transform);
- }
- void Physics3DRigidBody::setKinematic(bool kinematic)
- {
- if (kinematic)
- {
- _btRigidBody->setCollisionFlags(_btRigidBody->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
- _btRigidBody->setActivationState(DISABLE_DEACTIVATION);
- }
- else
- {
- _btRigidBody->setCollisionFlags(_btRigidBody->getCollisionFlags() & ~btCollisionObject::CF_KINEMATIC_OBJECT);
- _btRigidBody->setActivationState(ACTIVE_TAG);
- }
- }
- bool Physics3DRigidBody::isKinematic() const
- {
- if (_btRigidBody)
- return _btRigidBody->isKinematicObject();
- return false;
- }
- class btCollider : public btGhostObject
- {
- public:
- btCollider(Physics3DCollider *collider)
- : _collider(collider)
- {};
- ~btCollider(){};
- ///this method is mainly for expert/internal use only.
- virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy = nullptr) override
- {
- btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
- btAssert(otherObject);
- ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure
- int index = m_overlappingObjects.findLinearSearch(otherObject);
- if (index == m_overlappingObjects.size())
- {
- //not found
- m_overlappingObjects.push_back(otherObject);
- if (_collider->onTriggerEnter != nullptr && _collider->isTrigger())
- _collider->onTriggerEnter(getPhysicsObject(otherObject));
- }
- }
- ///this method is mainly for expert/internal use only.
- virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btDispatcher* /*dispatcher*/, btBroadphaseProxy* thisProxy = nullptr) override
- {
- btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject;
- btAssert(otherObject);
- int index = m_overlappingObjects.findLinearSearch(otherObject);
- if (index < m_overlappingObjects.size())
- {
- m_overlappingObjects[index] = m_overlappingObjects[m_overlappingObjects.size() - 1];
- m_overlappingObjects.pop_back();
- if (_collider->onTriggerExit != nullptr && _collider->isTrigger())
- _collider->onTriggerExit(getPhysicsObject(otherObject));
- }
- }
- Physics3DObject* getPhysicsObject(const btCollisionObject* btObj)
- {
- for (auto it : _collider->getPhysicsWorld()->getPhysicsObjects())
- {
- if (it->getObjType() == Physics3DObject::PhysicsObjType::RIGID_BODY)
- {
- if (static_cast<Physics3DRigidBody*>(it)->getRigidBody() == btObj)
- return it;
- }
- else if (it->getObjType() == Physics3DObject::PhysicsObjType::COLLIDER)
- {
- if (static_cast<Physics3DCollider*>(it)->getGhostObject() == btObj)
- return it;
- }
- }
- return nullptr;
- }
- private:
- Physics3DCollider *_collider;
- };
- Physics3DCollider::Physics3DCollider()
- : _btGhostObject(nullptr)
- , _physics3DShape(nullptr)
- {
- }
- Physics3DCollider::~Physics3DCollider()
- {
- CC_SAFE_DELETE(_btGhostObject);
- CC_SAFE_RELEASE(_physics3DShape);
- }
- Physics3DCollider* Physics3DCollider::create(Physics3DColliderDes *info)
- {
- auto ret = new (std::nothrow) Physics3DCollider();
- if (ret->init(info))
- {
- ret->autorelease();
- return ret;
- }
- CC_SAFE_DELETE(ret);
- return ret;
- }
- float Physics3DCollider::getCcdSweptSphereRadius() const
- {
- return _btGhostObject->getCcdSweptSphereRadius();
- }
- void Physics3DCollider::setCcdSweptSphereRadius(float radius)
- {
- _btGhostObject->setCcdSweptSphereRadius(radius);
- }
- float Physics3DCollider::getCcdMotionThreshold() const
- {
- return _btGhostObject->getCcdMotionThreshold();
- }
- void Physics3DCollider::setCcdMotionThreshold(float ccdMotionThreshold)
- {
- _btGhostObject->setCcdMotionThreshold(ccdMotionThreshold);
- }
- float Physics3DCollider::getHitFraction() const
- {
- return _btGhostObject->getHitFraction();
- }
- void Physics3DCollider::setHitFraction(float hitFraction)
- {
- _btGhostObject->setHitFraction(hitFraction);
- }
- float Physics3DCollider::getRollingFriction() const
- {
- return _btGhostObject->getRollingFriction();
- }
- void Physics3DCollider::setRollingFriction(float frict)
- {
- _btGhostObject->setRollingFriction(frict);
- }
- float Physics3DCollider::getFriction() const
- {
- return _btGhostObject->getFriction();
- }
- void Physics3DCollider::setFriction(float frict)
- {
- _btGhostObject->setFriction(frict);
- }
- float Physics3DCollider::getRestitution() const
- {
- return _btGhostObject->getRestitution();
- }
- void Physics3DCollider::setRestitution(float rest)
- {
- _btGhostObject->setRestitution(rest);
- }
- bool Physics3DCollider::isTrigger() const
- {
- return (_btGhostObject->getCollisionFlags() & btCollisionObject::CF_NO_CONTACT_RESPONSE) != 0;
- }
- void Physics3DCollider::setTrigger(bool isTrigger)
- {
- _btGhostObject->setCollisionFlags(isTrigger == true ?
- _btGhostObject->getCollisionFlags() | btCollisionObject::CF_NO_CONTACT_RESPONSE :
- _btGhostObject->getCollisionFlags() & ~btCollisionObject::CF_NO_CONTACT_RESPONSE);
- }
- bool Physics3DCollider::init(Physics3DColliderDes *info)
- {
- _physics3DShape = info->shape;
- _physics3DShape->retain();
- _btGhostObject = new btCollider(this);
- _btGhostObject->setCollisionShape(_physics3DShape->getbtShape());
-
- setTrigger(info->isTrigger);
- setFriction(info->friction);
- setRollingFriction(info->rollingFriction);
- setRestitution(info->restitution);
- setHitFraction(info->hitFraction);
- setCcdSweptSphereRadius(info->ccdSweptSphereRadius);
- setCcdMotionThreshold(info->ccdMotionThreshold);
-
- _type = Physics3DObject::PhysicsObjType::COLLIDER;
- return true;
- }
- cocos2d::Mat4 Physics3DCollider::getWorldTransform() const
- {
- return convertbtTransformToMat4(_btGhostObject->getWorldTransform());
- }
- NS_CC_END
- #endif // CC_ENABLE_BULLET_INTEGRATION
- #endif // CC_USE_3D_PHYSICS
|