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;
}
};
}
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: the title got cut off... hehe it says "not cut&&paste simple"