//------------------------------------------------------------------------------- // @ IvQuat::Set() //------------------------------------------------------------------------------- // Set quaternion based on axis-angle //------------------------------------------------------------------------------- void IvQuat::Set( const IvVector3& axis, float angle ) { // if axis of rotation is zero vector, just set to identity quat float length = axis.LengthSquared(); if ( ::IsZero( length ) ) { Identity(); return; } // take half-angle angle *= 0.5f; float sintheta, costheta; IvSinCos(angle, sintheta, costheta); float scaleFactor = sintheta/IvSqrt( length ); w = costheta; x = scaleFactor * axis.x; y = scaleFactor * axis.y; z = scaleFactor * axis.z; } // End of IvQuat::Set()
//------------------------------------------------------------------------------- // @ ::Distance() //------------------------------------------------------------------------------- // Point distance //------------------------------------------------------------------------------- float Distance( const IvVector3& p0, const IvVector3& p1 ) { float x = p0.x - p1.x; float y = p0.y - p1.y; float z = p0.z - p1.z; return IvSqrt( x*x + y*y + z*z ); } // End of IvVector3::Length()
//------------------------------------------------------------------------------- // Utility function to convert to pre-multiplied alpha //------------------------------------------------------------------------------- static void CopyAndPremulAlpha(void* outData, void* inData, unsigned int width, unsigned int height) { unsigned char* inComponent = (unsigned char*)inData; unsigned char* outComponent = (unsigned char*)outData; for (unsigned int j = 0; j < height; ++j) { for (unsigned int i = 0; i < width; ++i) { // sRGB input float r = *inComponent++/255.f; float g = *inComponent++/255.f; float b = *inComponent++/255.f; unsigned char a = *inComponent++; float aFloat = (float)a/255.f; // convert to approximately linear r *= r; g *= g; b *= b; // premultiply alpha r *= aFloat; g *= aFloat; b *= aFloat; // convert back to approximately sRGB gamma r = IvSqrt(r); g = IvSqrt(g); b = IvSqrt(b); *outComponent++ = (unsigned char) (r*255.f); *outComponent++ = (unsigned char) (g*255.f); *outComponent++ = (unsigned char) (b*255.f); *outComponent++ = a; } } }
//------------------------------------------------------------------------------- // @ 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()
//------------------------------------------------------------------------------- // @ IvVector3::Length() //------------------------------------------------------------------------------- // Vector length //------------------------------------------------------------------------------- float IvVector3::Length() const { return IvSqrt( x*x + y*y + z*z ); } // End of IvVector3::Length()
//------------------------------------------------------------------------------- // @ IvQuat::Magnitude() //------------------------------------------------------------------------------- // Quaternion magnitude (square root of norm) //------------------------------------------------------------------------------- float IvQuat::Magnitude() const { return IvSqrt( w*w + x*x + y*y + z*z ); } // End of IvQuat::Magnitude()
//Vector length float CVector3::Length() const { return IvSqrt(LengthSquared()); }