Back to index

supertuxkart  0.5+dfsg1
Public Types | Public Member Functions | Protected Attributes
MovingPhysics Class Reference

#include <moving_physics.hpp>

Inheritance diagram for MovingPhysics:
Inheritance graph
[legend]
Collaboration diagram for MovingPhysics:
Collaboration graph
[legend]

List of all members.

Public Types

enum  bodyTypes { MP_NONE, MP_CONE, MP_BOX, MP_SPHERE }

Public Member Functions

 MovingPhysics (const std::string data)
 ~MovingPhysics ()
void update (float dt)
void init ()
 Additional initialisation after loading of the model is finished.
virtual void reset ()
const char * getTypeName ()
virtual void handleExplosion (const btVector3 &pos, bool directHit)

Protected Attributes

bodyTypes m_body_type
btCollisionShapem_shape
btRigidBodym_body
btDefaultMotionStatem_motion_state
float m_half_height
float m_mass
UserPointer m_user_pointer
btTransform m_init_pos

Detailed Description

Definition at line 28 of file moving_physics.hpp.


Member Enumeration Documentation

Enumerator:
MP_NONE 
MP_CONE 
MP_BOX 
MP_SPHERE 

Definition at line 31 of file moving_physics.hpp.


Constructor & Destructor Documentation

MovingPhysics::MovingPhysics ( const std::string  data)

Definition at line 30 of file moving_physics.cpp.

             : ssgTransform(), Callback()
{
    m_shape        = NULL;
    m_body         = NULL;
    m_motion_state = NULL;
    m_mass         = 1;
    setUserData(new ssgBase());   // prevent tree optimisations to remove this node

    std::vector<std::string> parameters = StringUtils::split(data, ' ');
    if(parameters.size()<2)
    {
        fprintf(stderr, "Invalid physics specification: '%s'\n",data.c_str());
    }
    parameters.erase(parameters.begin());
    std::string &shape=parameters[0];
    m_body_type = MP_NONE;
    if(shape=="cone"   ) m_body_type = MP_CONE;
    else if(shape=="box"    ) m_body_type = MP_BOX;
    else if(shape=="sphere" ) m_body_type = MP_SPHERE;
    parameters.erase(parameters.begin());

    // Scan for additional parameters, which are in the form of keyword=value
    // (without any spaces). Currently only mass=... is supported.
    while(parameters.size()>0)
    {
        // Split the parameter string by '=' to get the keyword and value
        std::vector<std::string> p=StringUtils::split(parameters[0],'=');
        if(p.size()!=2) 
        {
            fprintf(stderr, "Invalid physics parameter string: '%s'\n",data.c_str());
            break;
        } 
        if(p[0]=="mass") 
        {
            StringUtils::from_string<float>(p[1], m_mass);
        }
        else
        {
            fprintf(stderr, "Invalid physics parameter string: '%s'\n",
                    data.c_str());
            break;
        }

        parameters.erase(parameters.begin());
    }
}   // MovingPhysics

Here is the call graph for this function:

Definition at line 79 of file moving_physics.cpp.

{
    world->getPhysics()->removeBody(m_body);
    delete m_body;
    delete m_motion_state;
    delete m_shape;
    scene->remove(this);
}  // ~MovingPhysics

Here is the call graph for this function:


Member Function Documentation

const char* MovingPhysics::getTypeName ( ) [inline]

Definition at line 48 of file moving_physics.hpp.

{return "moving physics";}
void MovingPhysics::handleExplosion ( const btVector3 pos,
bool  directHit 
) [virtual]

Reimplemented from Callback.

Definition at line 225 of file moving_physics.cpp.

                                                                         {
    if(direct_hit) {
        btVector3 impulse(0.0f, 0.0f, stk_config->m_explosion_impulse_objects);
        m_body->applyCentralImpulse(impulse);
    }
    else  // only affected by a distant explosion
    {
        btTransform t;
        m_motion_state->getWorldTransform(t);
        btVector3 diff=t.getOrigin()-pos;

        float len2=diff.length2();

        // The correct formhale would be to first normalise diff,
        // then apply the impulse (which decreases 1/r^2 depending
        // on the distance r), so:
        // diff/len(diff) * impulseSize/len(diff)^2
        // = diff*impulseSize/len(diff)^3
        // We use diff*impulseSize/len(diff)^2 here, this makes the impulse
        // somewhat larger, which is actually more fun :)
        btVector3 impulse=diff*stk_config->m_explosion_impulse_objects/len2;
        m_body->applyCentralImpulse(impulse);
    }
    m_body->activate();

}   // handleExplosion

Here is the call graph for this function:

void MovingPhysics::init ( ) [virtual]

Additional initialisation after loading of the model is finished.

Implements Callback.

Definition at line 99 of file moving_physics.cpp.

{

    // 1. Remove the object from the graph and attach it to the root
    // -------------------------------------------------------------
    if(getNumParents()>1) 
    {
        fprintf(stderr, "WARNING: physical object with more than one parent!!\n");
        return;
    }
    ssgBranch *parent = getParent(0);

    scene->add(this);
    parent->removeKid(this);

    // 2. Determine the original position of the object
    // ------------------------------------------------

    ssgEntity *p=parent;
    sgMat4    pos;
    sgMakeIdentMat4(pos);
    while(p->getNumParents())
    {
        if(p->getNumParents()!=1)
        {
            // FIXME: Not sure if this is needed: if one object has more than
            //        one parent (--> this object appears more than once in the
            //        scene), we have to follow all possible ways up to the
            //        root, and for each way add one instance to the root.
            //        For now this is unsupported, and we abort here.
            fprintf(stderr, "MovingPhysics: init: %d parents found, ignored.\n",
                    p->getNumParents());
            return;
        }   // if numparents!=1
        if(p->isAKindOf(ssgTypeTransform()))
        {
            ssgBaseTransform *trans=(ssgBaseTransform*)p;
            sgMat4 change_position;
            trans->getTransform(change_position);
            sgPostMultMat4(pos, change_position);
        }
        if(p->getNumKids()==0)
        {
            ssgBranch *new_parent=p->getParent(0);
            new_parent->removeKid(p);
            p = new_parent;
        }
        else
        {
            p=p->getParent(0);
        }
    }   // while

    // 3. Determine size of the object
    // -------------------------------
    float x_min, x_max, y_min, y_max, z_min, z_max, radius;
    MinMax(this, &x_min, &x_max, &y_min, &y_max, &z_min, &z_max);
    m_half_height = 0.5f*(z_max-z_min);
    switch (m_body_type)
    {
    case MP_CONE:   radius = 0.5f*std::max(x_max-x_min, y_max-y_min);
                    m_shape = new btConeShapeZ(radius, z_max-z_min);
                    setName("cone");
                    break;
    case MP_BOX:    m_shape = new btBoxShape(btVector3(0.5f*(x_max-x_min),
                                                       0.5f*(y_max-y_min),
                                                       0.5f*(z_max-z_min) ) );
                    setName("box");
                    break;
    case MP_SPHERE: radius = std::max(x_max-x_min, y_max-y_min);
                    radius = 0.5f*std::max(radius, z_max-z_min);
                    m_shape = new btSphereShape(radius);
                    setName("sphere");
                    break;
    case MP_NONE:   fprintf(stderr, "WARNING: Uninitialised moving shape\n");
        break;
    }

    // 4. Create the rigid object
    // --------------------------
    
    m_init_pos.setIdentity();
    m_init_pos.setOrigin(btVector3(pos[3][0],pos[3][1],pos[3][2]+m_half_height));
    m_motion_state = new btDefaultMotionState(m_init_pos);
    btVector3 inertia;
    m_shape->calculateLocalInertia(m_mass, inertia);
    btRigidBody::btRigidBodyConstructionInfo info(m_mass, m_motion_state, m_shape, inertia);
    
    // Make sure that the cones stop rolling by defining angular friction != 0.
    info.m_angularDamping = 0.5f;
    m_body = new btRigidBody(info);
    m_user_pointer.set(this);
    m_body->setUserPointer(&m_user_pointer);
    world->getPhysics()->addBody(m_body);
}   // init

Here is the call graph for this function:

void MovingPhysics::reset ( ) [virtual]

Reimplemented from Callback.

Definition at line 217 of file moving_physics.cpp.

Here is the call graph for this function:

void MovingPhysics::update ( float  dt) [virtual]

Implements Callback.

Definition at line 196 of file moving_physics.cpp.

{
    btTransform t;
    m_motion_state->getWorldTransform(t);
    float m[4][4];
    t.getOpenGLMatrix((float*)&m);
    
    // Transfer the new position and hpr to curr_pos
    sgCoord curr_pos;
    sgSetCoord(&curr_pos, m);
    if(curr_pos.xyz[2]<-100)
    {
        m_body->setCenterOfMassTransform(m_init_pos);
        curr_pos.xyz[0]=m_init_pos.getOrigin().getX();
        curr_pos.xyz[1]=m_init_pos.getOrigin().getY();
        curr_pos.xyz[2]=m_init_pos.getOrigin().getZ();
    }
    setTransform(&curr_pos);

}   // update

Here is the call graph for this function:


Member Data Documentation

Definition at line 36 of file moving_physics.hpp.

Definition at line 34 of file moving_physics.hpp.

float MovingPhysics::m_half_height [protected]

Definition at line 38 of file moving_physics.hpp.

Definition at line 41 of file moving_physics.hpp.

float MovingPhysics::m_mass [protected]

Definition at line 39 of file moving_physics.hpp.

Definition at line 37 of file moving_physics.hpp.

Definition at line 35 of file moving_physics.hpp.

Definition at line 40 of file moving_physics.hpp.


The documentation for this class was generated from the following files: