From b4832697c25e36cbf7cd421aaa68b6032f7dad59 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Wed, 13 Nov 2013 22:24:53 +0000 Subject: [PATCH] Added push back to soccer ball, which can be used to push the ball away from the edge of the soccer field (so prevents the ball from getting stuck there). git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14423 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/physics/physical_object.cpp | 21 +++++++++++++++++++-- src/physics/physical_object.hpp | 15 +++++++++++---- src/physics/physics.cpp | 20 ++++++++++++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-) diff --git a/src/physics/physical_object.cpp b/src/physics/physical_object.cpp index 0d75b9a82..c9d2590d5 100644 --- a/src/physics/physical_object.cpp +++ b/src/physics/physical_object.cpp @@ -529,10 +529,27 @@ void PhysicalObject::handleExplosion(const Vec3& pos, bool direct_hit) } // handleExplosion // ---------------------------------------------------------------------------- -bool PhysicalObject::isSoccerBall() +/** Returns true if this object is a soccer ball. + */ +bool PhysicalObject::isSoccerBall() const { return m_object->isSoccerBall(); -} +} // is SoccerBall + +// ---------------------------------------------------------------------------- +/** Called when a physical object hits the track. Atm only used to push a + * soccer ball away from the edge of the field. + * \param m Material which was hit. + * \param normal Normal of the track at the hit point. + */ +void PhysicalObject::hit(const Material *m, const Vec3 &normal) +{ + if(isSoccerBall() && m->getCollisionReaction() == Material::PUSH_BACK) + { + m_body->applyCentralImpulse(normal * 1000.0f); + } +} // hit + // ---------------------------------------------------------------------------- /* EOF */ diff --git a/src/physics/physical_object.hpp b/src/physics/physical_object.hpp index 6f2deb4a0..32d00a65f 100644 --- a/src/physics/physical_object.hpp +++ b/src/physics/physical_object.hpp @@ -28,8 +28,9 @@ #include "utils/leak_check.hpp" -class XMLNode; +class Material; class TrackObject; +class XMLNode; /** * \ingroup physics @@ -139,8 +140,9 @@ public: virtual void handleExplosion(const Vec3& pos, bool directHit); void update (float dt); void init (); - bool isSoccerBall(); - + void move (const Vec3& xyz, const core::vector3df& hpr); + void hit (const Material *m, const Vec3 &normal); + bool isSoccerBall () const; // ------------------------------------------------------------------------ /** Returns the rigid body of this physical object. */ btRigidBody *getBody () { return m_body; } @@ -148,10 +150,15 @@ public: /** Returns true if this object should trigger a rescue in a kart that * hits it. */ bool isCrashReset() const { return m_crash_reset; } + // ------------------------------------------------------------------------ + /** Returns true if this object should cause an explosion if a kart hits + * it. */ bool isExplodeKartObject () const { return m_explode_kart; } + // ------------------------------------------------------------------------ + /** Returns true if this object should cause a kart that touches it to + * be flattened. */ bool isFlattenKartObject () const { return m_flatten_kart; } - void move(const Vec3& xyz, const core::vector3df& hpr); LEAK_CHECK() }; // PhysicalObject diff --git a/src/physics/physics.cpp b/src/physics/physics.cpp index 0b955f97a..b17d1fc27 100644 --- a/src/physics/physics.cpp +++ b/src/physics/physics.cpp @@ -486,6 +486,16 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, .m_normalWorldOnB; kart->crashed(m, normal); } + else if(upB->is(UserPointer::UP_PHYSICAL_OBJECT)) + { + int n = contact_manifold->getContactPoint(0).m_index1; + const Material *m + = n>=0 ? upA->getPointerTriangleMesh()->getMaterial(n) + : NULL; + const btVector3 &normal = contact_manifold->getContactPoint(0) + .m_normalWorldOnB; + upB->getPointerPhysicalObject()->hit(m, normal); + } } // 2) object a is a kart // ===================== @@ -553,6 +563,16 @@ btScalar Physics::solveGroup(btCollisionObject** bodies, int numBodies, m_all_collisions.push_back( upA, contact_manifold->getContactPoint(0).m_localPointA, upB, contact_manifold->getContactPoint(0).m_localPointB); + else if(upB->is(UserPointer::UP_TRACK)) + { + int n = contact_manifold->getContactPoint(0).m_index1; + const Material *m + = n>=0 ? upB->getPointerTriangleMesh()->getMaterial(n) + : NULL; + const btVector3 &normal = contact_manifold->getContactPoint(0) + .m_normalWorldOnB; + upA->getPointerPhysicalObject()->hit(m, normal); + } } else if (upA->is(UserPointer::UP_ANIMATION)) {