Proper sliding character mechanics[ADVANCED, NOT CUT&&am

Post those lines of code you feel like sharing or find what you require for your project here; or simply use them as tutorials.
Post Reply
ChaiRuiPeng
Posts: 363
Joined: Thu Dec 16, 2010 8:50 pm
Location: Somewhere in the clouds.. drinking pink lemonade and sunshine..

Proper sliding character mechanics[ADVANCED, NOT CUT&&am

Post by ChaiRuiPeng »

okay so you can use this code to "vector" your vectors according to a hit surface normal.

it is up to you to:

get the hit surface normal.
determing which vectors you want to vector (e.g. force, linear velocity)


this transforms the vector

Code: Select all

//! Trasnforms a vector like velocity or force and transforms it along a surface
//! Needs the hit normal of the surface (or the total average normal for multiple surfaces)
//! And the vector to "vector" along the surface
/// n normal
/// v vector
btVector3 CPlayerCenter::vectorAlongSurface( const btVector3& v, const btVector3& n )
{

    /// Switch the normal, something weird is going on
    //! This might be bullet specific
    btVector3 nn(n);//.getZ(), n.getY(), n.getX());

    btScalar angle(ITetraVectorMath::getAngle(v, nn));

    printf("%f deg\n", angle);

    // Return a null vector because the opposing force is nearly driving straight against the surface
    // the rest of the algorithm will fail with near 180 degree values
    if(angle <= 180.0 && angle >= 179.0 )
    {

        return btVector3(0.0,0.0,0.0);
    }

    if( angle <= 90.0 )
    {
        // Return an unaltered direction, the force is going away from the surface
        btVector3 f(v);
        return f.normalize();
    }

    const btVector3 cross(ITetraVectorMath::crossProduct(v, nn));

    // Rotate by 90, giving a perp. vector to the surface
    btScalar h(90.0*core::DEGTORAD);

    btScalar inner(
        (v.getX() * nn.getX()) +
        (v.getY() * nn.getY()) +
        (v.getZ() * nn.getZ())
                   );

// rotating vector n around cross
    //btVector3 final = (cos(h))*v + ( (1 - cos(h)) * inner * nn ) + (sin(h)*(cross));

    btVector3 final = (cos(h))*nn + ( (1 - cos(h)) * inner * cross ) + (sin(h)*(cross));

    // Normalize it because it should only indicate the _new_ direction
    final.normalize();

    //printf("%f, %f, %f\n", final.getX(), final.getY(), final.getZ());

    return final;

}

here is the snippet for the cross product and angle between two vectors

Code: Select all


namespace tetra
{

class ITetraVectorMath
{

public:

    static btVector3 crossProduct( const btVector3& a, const btVector3& b )
    {

        btScalar x((a.getY()*b.getZ()) - (a.getZ()*b.getY()));
        btScalar y((a.getZ()*b.getX()) - (a.getX()*b.getZ()));
        btScalar z((a.getX()*b.getY()) - (a.getY()*b.getX()));

        btVector3 c(x, y, z);

        return c;

    }

    static btScalar getAngle( const btVector3& a, const btVector3& b )
    {

        btScalar dot( (a.getX()*b.getX()) + (a.getY()*b.getY()) + (a.getZ()*b.getZ()) );

        //printf("%f, %f\n", a.length(), b.length());

        return ( acos( dot/( a.length() * b.length() )))*irr::core::RADTODEG;

    }



};

}
again you might need to change a few variables to fit it into your whatever. but there it is. so do what you may.

EDIT:

after you vector your vectors you can take the cos() of the angle and use that to apply things like slope friction/difficulty, making a threshold for where some slope angles reduce your ability to climb in that direction.

EDITEDIT: :shock: the title got cut off... hehe it says "not cut&&paste simple"
ent1ty wrote: success is a matter of concentration and desire
Butler Lampson wrote: all problems in Computer Science can be solved by another level of indirection
at a cost measure in computer resources ;)
Post Reply