Exemplo n.º 1
0
//-------------------------------------------------------------------------------
// @ ::BarycentricCoordinates()
//-------------------------------------------------------------------------------
// Returns barycentric coordinates for point inside triangle (3D version)
// Assumes triangle is not degenerate
//-------------------------------------------------------------------------------
void BarycentricCoordinates( float &r, float &s, float& t,
                             const IvVector3& point, const IvVector3& P0,
                             const IvVector3& P1, const IvVector3& P2 )
{
    // get difference vectors
    IvVector3 u = P1 - P0;
    IvVector3 v = P2 - P0;
    IvVector3 w = point - P0;

    // compute cross product to get area of parallelograms
    IvVector3 a = u.Cross(w);
    IvVector3 b = v.Cross(w);
    IvVector3 c = u.Cross(v);

    // compute barycentric coordinates as ratios of areas
    float denom = 1.0f/c.Length();
    s = b.Length()*denom;
    t = a.Length()*denom;
    r = 1.0f - s - t;
}
Exemplo n.º 2
0
//-------------------------------------------------------------------------------
// @ ::TriangleIntersect()
//-------------------------------------------------------------------------------
// Returns true if ray intersects triangle
//-------------------------------------------------------------------------------
bool
TriangleIntersect( float& t, const IvVector3& P0, const IvVector3& P1,
                   const IvVector3& P2, const IvRay3& ray )
{
    // test ray direction against triangle
    IvVector3 e1 = P1 - P0;
    IvVector3 e2 = P2 - P0;
    IvVector3 p = ray.GetDirection().Cross(e2);
    float a = e1.Dot(p);

    // if result zero, no intersection or infinite intersections
    // (ray parallel to triangle plane)
    if ( IvIsZero(a) )
        return false;

    // compute denominator
    float f = 1.0f/a;

    // compute barycentric coordinates
    IvVector3 s = ray.GetOrigin() - P0;
    float u = f*s.Dot(p);

    // ray falls outside triangle
    if (u < 0.0f || u > 1.0f)
        return false;

    IvVector3 q = s.Cross(e1);
    float v = f*ray.GetDirection().Dot(q);

    // ray falls outside triangle
    if (v < 0.0f || u+v > 1.0f)
        return false;

    // compute line parameter
    t = f*e2.Dot(q);

    return (t >= 0.0f);
}
Exemplo n.º 3
0
//-------------------------------------------------------------------------------
// @ IvQuat::Set()
//-------------------------------------------------------------------------------
// Set quaternion based on start and end vectors
//-------------------------------------------------------------------------------
void
IvQuat::Set( const IvVector3& from, const IvVector3& to )
{
    // Ensure that our vectors are unit
    ASSERT( from.IsUnit() && to.IsUnit() );

    // get axis of rotation
    IvVector3 axis = from.Cross( to );
    // get cos of angle between vectors
    float costheta = from.Dot( to );

    // if vectors are 180 degrees apart
    if ( costheta <= -1.0f )
    {
        // find orthogonal vector
        IvVector3 orthoVector;
        orthoVector.Normalize();

        w = 0.0f;
        x = orthoVector.x;
        y = orthoVector.y;
        z = orthoVector.z;

        return;
    }

    // use trig identities to get the values we want
    float factor = IvSqrt( 2.0f*(1.0f + costheta) );
    float scaleFactor = 1.0f/factor;

    // set values
    w = 0.5f*factor;
    x = scaleFactor*axis.x;
    y = scaleFactor*axis.y;
    z = scaleFactor*axis.z;

}   // End of IvQuat::Set()
Exemplo n.º 4
0
//-------------------------------------------------------------------------------
// @ Player::Update()
//-------------------------------------------------------------------------------
// Main update loop
//-------------------------------------------------------------------------------
void
Player::Update( float dt )
{
    // update based on input
    if (IvGame::mGame->mEventHandler->IsKeyPressed(' '))
    {
        if (mRun)
        {
            mTime = 0.0f;
            mRun = false;
        }
        else
        {
            mRun = true;
        }
    }

    if (IvGame::mGame->mEventHandler->IsKeyPressed('m'))
    {
        mMode = (mMode + 1)%4;
    }

    if (mRun)
    {
        mTime += dt;
        // stop just before end so we don't end up with zero vector
        // when we look ahead
        if ( mTime > 11.5f )
            mTime = 11.5f;
    }

    // now we set up the camera
    // get eye position
    IvVector3 eye = mCurve.Evaluate( mTime );
    IvVector3 viewDir;
    IvVector3 viewSide;
    IvVector3 viewUp;

    // set parameters depending on what mode we're in

    // Frenet frame
    if ( mMode == 3 )
    {   
        IvVector3 T = mCurve.Velocity( mTime );
        IvVector3 a = mCurve.Acceleration( mTime );
        IvVector3 B = T.Cross( a );
        B.Normalize();
        T.Normalize();
        IvVector3 N = B.Cross( T );
    
        viewDir = T;
        viewSide = -N;     // have to negate to get from RH frame to LH frame
        viewUp = B;        
    }
    else
    {
        IvVector3 lookAt;
        
        // look same direction all the time
        if ( mMode == 2 ) 
        {
            viewDir = IvVector3::xAxis;
        }
        // look along tangent
        else if ( mMode == 1 )
        {
            viewDir = mCurve.Velocity( mTime );
        }
        // look ahead .5 in parameter
        else if ( mMode == 0 )
        {
            viewDir = mCurve.Evaluate( mTime+0.5f ) - eye;
        }

        // compute view vectors
        viewDir.Normalize();
        viewUp = IvVector3::zAxis - IvVector3::zAxis.Dot(viewDir)*viewDir;
        viewUp.Normalize();
        viewSide = viewDir.Cross(viewUp);
    }

    // now set up matrices
    // build transposed rotation matrix
    IvMatrix33 rotate;
    if ( IvRenderer::mRenderer->GetAPI() == kOpenGL )
    {
        rotate.SetRows( viewSide, viewUp, -viewDir );
    }
    else
    {
        rotate.SetRows( viewSide, viewUp, viewDir );
    }
    // transform translation
    IvVector3 eyeInv = -(rotate*eye);
    // build 4x4 matrix
    IvMatrix44 matrix(rotate);
    matrix(0,3) = eyeInv.x;
    matrix(1,3) = eyeInv.y;
    matrix(2,3) = eyeInv.z;

    ::IvSetViewMatrix( matrix );

}   // End of Player::Update()