2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// SuperTuxKart - a fun racing game with go-kart
|
2015-03-29 20:31:42 -04:00
|
|
|
// Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>
|
|
|
|
// Copyright (C) 2006-2015 Joerg Henrichs, Steve Baker
|
2007-05-27 12:01:53 -04:00
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License
|
2008-06-12 20:53:52 -04:00
|
|
|
// as published by the Free Software Foundation; either version 3
|
2007-05-27 12:01:53 -04:00
|
|
|
// of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
|
2013-11-30 16:33:06 -05:00
|
|
|
#include <math.h>
|
2008-11-06 23:34:01 -05:00
|
|
|
#include "karts/moveable.hpp"
|
|
|
|
|
2009-02-10 00:30:59 -05:00
|
|
|
#include "graphics/irr_driver.hpp"
|
2009-06-02 08:37:29 -04:00
|
|
|
#include "graphics/material.hpp"
|
|
|
|
#include "graphics/material_manager.hpp"
|
2010-11-08 21:16:41 -05:00
|
|
|
#include "modes/world.hpp"
|
|
|
|
#include "tracks/track.hpp"
|
2007-05-27 12:01:53 -04:00
|
|
|
|
2012-03-19 16:21:11 -04:00
|
|
|
#include "ISceneNode.h"
|
|
|
|
|
2008-10-06 09:40:11 -04:00
|
|
|
Moveable::Moveable()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2007-12-08 08:04:56 -05:00
|
|
|
m_body = 0;
|
|
|
|
m_motion_state = 0;
|
2009-03-16 01:27:28 -04:00
|
|
|
m_mesh = NULL;
|
|
|
|
m_node = NULL;
|
2010-06-27 20:39:45 -04:00
|
|
|
m_heading = 0;
|
2007-05-27 12:01:53 -04:00
|
|
|
} // Moveable
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
Moveable::~Moveable()
|
|
|
|
{
|
2007-11-08 17:40:15 -05:00
|
|
|
// The body is being removed from the world in kart/projectile
|
2007-12-08 08:04:56 -05:00
|
|
|
if(m_body) delete m_body;
|
2007-09-30 10:17:28 -04:00
|
|
|
if(m_motion_state) delete m_motion_state;
|
2009-03-26 19:31:00 -04:00
|
|
|
if(m_node) irr_driver->removeNode(m_node);
|
2011-04-27 07:47:33 -04:00
|
|
|
if(m_mesh) irr_driver->removeMeshFromCache(m_mesh);
|
2007-05-27 12:01:53 -04:00
|
|
|
} // ~Moveable
|
|
|
|
|
2009-04-05 08:53:17 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-03-04 07:35:58 -05:00
|
|
|
/** Sets the mesh for this model.
|
2009-04-05 08:53:17 -04:00
|
|
|
* \param n The scene node.
|
|
|
|
*/
|
|
|
|
void Moveable::setNode(scene::ISceneNode *n)
|
|
|
|
{
|
2010-04-11 18:48:01 -04:00
|
|
|
m_node = n;
|
2009-04-05 08:53:17 -04:00
|
|
|
} // setNode
|
|
|
|
|
2009-01-22 07:02:40 -05:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-03-02 00:14:56 -05:00
|
|
|
/** Updates the graphics model. Mainly set the graphical position to be the
|
|
|
|
* same as the physics position, but uses offsets to position and rotation
|
2013-05-29 18:04:35 -04:00
|
|
|
* for special gfx effects (e.g. skidding will turn the karts more).
|
2010-03-04 07:35:58 -05:00
|
|
|
* \param offset_xyz Offset to be added to the position.
|
|
|
|
* \param rotation Additional rotation.
|
2010-03-02 00:14:56 -05:00
|
|
|
*/
|
2013-05-29 18:04:35 -04:00
|
|
|
void Moveable::updateGraphics(float dt, const Vec3& offset_xyz,
|
2010-03-04 07:35:58 -05:00
|
|
|
const btQuaternion& rotation)
|
2009-01-22 07:02:40 -05:00
|
|
|
{
|
2010-03-04 07:35:58 -05:00
|
|
|
Vec3 xyz=getXYZ()+offset_xyz;
|
2010-07-07 19:53:27 -04:00
|
|
|
m_node->setPosition(xyz.toIrrVector());
|
2010-03-04 07:35:58 -05:00
|
|
|
btQuaternion r_all = getRotation()*rotation;
|
2012-12-16 19:33:47 -05:00
|
|
|
if(btFuzzyZero(r_all.getX()) && btFuzzyZero(r_all.getY()-0.70710677f) &&
|
|
|
|
btFuzzyZero(r_all.getZ()) && btFuzzyZero(r_all.getW()-0.70710677f) )
|
|
|
|
r_all.setX(0.000001f);
|
2010-03-04 07:35:58 -05:00
|
|
|
Vec3 hpr;
|
|
|
|
hpr.setHPR(r_all);
|
|
|
|
m_node->setRotation(hpr.toIrrHPR());
|
2009-01-22 07:02:40 -05:00
|
|
|
} // updateGraphics
|
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2012-03-25 12:41:21 -04:00
|
|
|
/** The reset position must be set before calling reset
|
|
|
|
*/
|
2008-11-06 20:05:52 -05:00
|
|
|
void Moveable::reset()
|
2007-05-27 12:01:53 -04:00
|
|
|
{
|
2008-06-20 05:34:35 -04:00
|
|
|
if(m_body)
|
|
|
|
{
|
|
|
|
m_body->setLinearVelocity(btVector3(0.0, 0.0, 0.0));
|
|
|
|
m_body->setAngularVelocity(btVector3(0, 0, 0));
|
|
|
|
m_body->setCenterOfMassTransform(m_transform);
|
|
|
|
}
|
2010-03-04 07:35:58 -05:00
|
|
|
m_node->setVisible(true); // In case that the objects was eliminated
|
2010-02-17 06:59:51 -05:00
|
|
|
|
2010-03-23 06:39:39 -04:00
|
|
|
Vec3 up = getTrans().getBasis().getColumn(1);
|
|
|
|
m_pitch = atan2(up.getZ(), fabsf(up.getY()));
|
|
|
|
m_roll = atan2(up.getX(), up.getY());
|
2010-05-06 21:48:24 -04:00
|
|
|
m_velocityLC = Vec3(0, 0, 0);
|
2011-09-14 02:59:16 -04:00
|
|
|
Vec3 forw_vec = m_transform.getBasis().getColumn(0);
|
|
|
|
m_heading = -atan2f(forw_vec.getZ(), forw_vec.getX());
|
2010-03-23 06:39:39 -04:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
} // reset
|
|
|
|
|
2010-10-25 19:07:35 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void Moveable::flyUp()
|
|
|
|
{
|
2010-11-08 21:16:41 -05:00
|
|
|
m_body->setGravity(btVector3(0.0, 8.0, 0.0));
|
2010-10-25 19:07:35 -04:00
|
|
|
m_body->applyCentralImpulse(btVector3(0.0, 100.0, 0.0));
|
2014-03-04 00:56:03 -05:00
|
|
|
} // flyUp
|
2010-10-25 19:07:35 -04:00
|
|
|
|
2014-03-04 00:56:03 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2010-10-25 19:07:35 -04:00
|
|
|
void Moveable::flyDown()
|
|
|
|
{
|
|
|
|
m_body->applyCentralImpulse(btVector3(0.0, -100.0, 0.0));
|
2014-03-04 00:56:03 -05:00
|
|
|
} // flyDown
|
2010-10-25 19:07:35 -04:00
|
|
|
|
2014-03-04 00:56:03 -05:00
|
|
|
// ----------------------------------------------------------------------------
|
2010-11-08 21:16:41 -05:00
|
|
|
void Moveable::stopFlying()
|
|
|
|
{
|
|
|
|
m_body->setGravity(btVector3(0.0, -World::getWorld()->getTrack()->getGravity(), 0.0));
|
2014-03-04 00:56:03 -05:00
|
|
|
} // stopFlying
|
2010-11-08 21:16:41 -05:00
|
|
|
|
2007-09-30 10:17:28 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2010-04-20 19:50:38 -04:00
|
|
|
/** Updates the current position and rotation from the corresponding physics
|
|
|
|
* body, and then calls updateGraphics to position the model correctly.
|
|
|
|
* \param float dt Time step size.
|
|
|
|
*/
|
2009-01-22 07:02:40 -05:00
|
|
|
void Moveable::update(float dt)
|
|
|
|
{
|
2011-07-19 20:39:32 -04:00
|
|
|
if(m_body->getInvMass()!=0)
|
|
|
|
m_motion_state->getWorldTransform(m_transform);
|
2010-03-05 19:44:17 -05:00
|
|
|
m_velocityLC = getVelocity()*m_transform.getBasis();
|
2010-02-25 08:20:22 -05:00
|
|
|
Vec3 forw_vec = m_transform.getBasis().getColumn(0);
|
2010-03-05 19:44:17 -05:00
|
|
|
m_heading = -atan2f(forw_vec.getZ(), forw_vec.getX());
|
|
|
|
|
|
|
|
// The pitch in hpr is in between -pi and pi. But for the camera it
|
|
|
|
// must be restricted to -pi/2 and pi/2 - so recompute it by restricting
|
|
|
|
// y to positive values, i.e. no pitch of more than pi/2.
|
|
|
|
Vec3 up = getTrans().getBasis().getColumn(1);
|
|
|
|
m_pitch = atan2(up.getZ(), fabsf(up.getY()));
|
2010-03-19 06:37:51 -04:00
|
|
|
m_roll = atan2(up.getX(), up.getY());
|
2010-03-05 19:44:17 -05:00
|
|
|
|
2011-05-01 20:21:53 -04:00
|
|
|
updateGraphics(dt, Vec3(0,0,0), btQuaternion(0, 0, 0, 1));
|
2009-01-22 07:02:40 -05:00
|
|
|
} // update
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2010-04-20 19:50:38 -04:00
|
|
|
/** Creates the bullet rigid body for this moveable.
|
|
|
|
* \param mass Mass of this object.
|
|
|
|
* \param trans Transform (=position and orientation) for this object).
|
|
|
|
* \param shape Bullet collision shape for this object.
|
|
|
|
*/
|
2009-01-22 07:02:40 -05:00
|
|
|
void Moveable::createBody(float mass, btTransform& trans,
|
2011-12-12 05:40:09 -05:00
|
|
|
btCollisionShape *shape,
|
2013-05-29 18:04:35 -04:00
|
|
|
float restitution)
|
2011-12-12 05:40:09 -05:00
|
|
|
{
|
2007-11-03 09:13:26 -04:00
|
|
|
btVector3 inertia;
|
|
|
|
shape->calculateLocalInertia(mass, inertia);
|
2008-11-27 21:42:16 -05:00
|
|
|
m_transform = trans;
|
2008-11-06 20:05:52 -05:00
|
|
|
m_motion_state = new KartMotionState(trans);
|
2007-09-30 10:17:28 -04:00
|
|
|
|
2013-05-29 18:04:35 -04:00
|
|
|
btRigidBody::btRigidBodyConstructionInfo info(mass, m_motion_state,
|
2011-07-19 20:39:32 -04:00
|
|
|
shape, inertia);
|
2011-12-12 05:40:09 -05:00
|
|
|
info.m_restitution = restitution;
|
2008-01-31 07:40:22 -05:00
|
|
|
|
2007-09-30 10:17:28 -04:00
|
|
|
// Then create a rigid body
|
|
|
|
// ------------------------
|
2008-01-31 07:40:22 -05:00
|
|
|
m_body = new btRigidBody(info);
|
2011-07-19 20:39:32 -04:00
|
|
|
if(mass==0)
|
|
|
|
{
|
|
|
|
// Create a kinematic object
|
2013-05-29 18:04:35 -04:00
|
|
|
m_body->setCollisionFlags(m_body->getCollisionFlags() |
|
2011-07-19 20:39:32 -04:00
|
|
|
btCollisionObject::CF_KINEMATIC_OBJECT );
|
|
|
|
m_body->setActivationState(DISABLE_DEACTIVATION);
|
|
|
|
}
|
|
|
|
|
2008-02-05 06:56:21 -05:00
|
|
|
// The value of user_pointer must be set from the actual class, otherwise this
|
2013-05-29 18:04:35 -04:00
|
|
|
// is only a pointer to moveable, not to (say) kart, and virtual
|
2008-02-05 06:56:21 -05:00
|
|
|
// functions are not called correctly. So only init the pointer to zero.
|
|
|
|
m_user_pointer.zero();
|
2008-01-30 00:30:10 -05:00
|
|
|
m_body->setUserPointer(&m_user_pointer);
|
2007-09-30 10:17:28 -04:00
|
|
|
} // createBody
|
2007-12-08 08:04:56 -05:00
|
|
|
|
2007-05-27 12:01:53 -04:00
|
|
|
//-----------------------------------------------------------------------------
|
2008-11-06 20:05:52 -05:00
|
|
|
/** Places this moveable at a certain location and stores this transform in
|
|
|
|
* this Moveable, so that it can be accessed easily.
|
|
|
|
* \param t New transform for this moveable.
|
|
|
|
*/
|
|
|
|
void Moveable::setTrans(const btTransform &t)
|
|
|
|
{
|
|
|
|
m_transform=t;
|
2012-03-06 21:41:41 -05:00
|
|
|
if(m_motion_state)
|
|
|
|
m_motion_state->setWorldTransform(t);
|
2008-11-06 20:05:52 -05:00
|
|
|
} // setTrans
|