// // Functions of general utility for use with "algebra3.h". // // John Nagle // nagle@animats.com // This code may be freely used by others. // #ifndef ALGEBRA3AUXH #define ALGEBRA3AUXH #include "algebra3.h" // // Vector utilities // // // MultiplyElementwise -- element by element multiplication // inline vec2 MultiplyElementwise(const vec2& v1, const vec2& v2) { return(vec2(v1[0]*v2[0],v1[1]*v2[1])); } inline vec3 MultiplyElementwise(const vec3& v1, const vec3& v2) { return(vec3(v1[0]*v2[0],v1[1]*v2[1],v1[2]*v2[2])); } inline vec4 MultiplyElementwise(const vec4& v1, const vec4& v2) { return(vec4(v1[0]*v2[0],v1[1]*v2[1],v1[2]*v2[2],v1[3]*v2[3])); } // // Matrix utilities // mat3 ExtractRotation(const mat4& pose); vec3 ExtractTranslation(const mat4& pose); vec3 ExtractScaling(const mat4& pose); mat4 rotation3D(const mat3& m); // // rotation3D -- convert 3x3 rotation matrix to 4x4 // inline mat4 rotation3D(const mat3& m) { return(mat4(vec4(m[0][0],m[0][1],m[0][2],0.0), vec4(m[1][0],m[1][1],m[1][2],0.0), vec4(m[2][0],m[2][1],m[2][2],0.0), vec4(0.0,0.0,0.0,1.0))); } // // Matrix utilities for affine matrices. // // The input matrix must be affine, but need not be orthogonal. // In other words, it may contain scaling, rotation, and translation, // but not perspective projection. // // ExtractTranslation -- extract translation vector // inline vec3 ExtractTranslation(const mat4& pose) { // Ref. Foley and Van Dam, 2nd ed, p. 217. return(vec3(pose[0][3],pose[1][3],pose[2][3])); } // // ExtractScaling // inline vec3 ExtractScaling(const mat4& mat) { // Per Valerie Demers, Softimage. // Transposed for mat4 matrices return(vec3( sqrt( mat[ 0 ][ 0 ] * mat[ 0 ][ 0 ] + mat[ 1 ][ 0 ] * mat[ 1 ][ 0 ] + mat[ 2 ][ 0 ] * mat[ 2 ][ 0 ] ), sqrt( mat[ 0 ][ 1 ] * mat[ 0 ][ 1 ] + mat[ 1 ][ 1 ] * mat[ 1 ][ 1 ] + mat[ 2 ][ 1 ] * mat[ 2 ][ 1 ] ), sqrt( mat[ 0 ][ 2 ] * mat[ 0 ][ 2 ] + mat[ 1 ][ 2 ] * mat[ 1 ][ 2 ] + mat[ 2 ][ 2 ] * mat[ 2 ][ 2 ] ))); } // // // ExtractRotation -- extract rotation matrix from transformation matrix // inline mat3 ExtractRotation(const mat4& pose) { vec3 scale(ExtractScaling(pose)); // get scaling // Compute inverse of scaling vec3 invscale(1.0/scale[0],1.0/scale[1],1.0/scale[2]); // Apply inverse of scaling as a transformation, to get unit scaling. mat4 unscaled(pose*scaling3D(invscale));// unscale pose // Return pure rotation matrix return(mat3( // drop last column and row vec3(unscaled[0],VW), vec3(unscaled[1],VW), vec3(unscaled[2],VW))); } // // PointToPlane -- signed distance from a point to a plane // // Outside the plane yields positive values // inline double PointToPlane(const vec3& point, const vec4& plane) { vec3 planeNormal(plane[0],plane[1],plane[2]); assert(fabs(planeNormal.length2() - 1.0) < 0.00001); // check normalized double dist = point * planeNormal + plane[3]; return(dist); } // // fmin, fmax -- min, max for various types // // Avoids conflicts with Windows macros. // inline double fmin(double x, double y) { return(x < y ? x : y); } inline double fmax(double x, double y) { return(x > y ? x : y); } inline vec2 fmin(const vec2& v1, const vec2& v2) { return(vec3(fmin(v1[0],v2[0]),fmin(v1[1],v2[1]))); } inline vec2 fmax(const vec2& v1, const vec2& v2) { return(vec3(fmax(v1[0],v2[0]),fmax(v1[1],v2[1]))); } inline vec3 fmin(const vec3& v1, const vec3& v2) { return(vec3(fmin(v1[0],v2[0]),fmin(v1[1],v2[1]),fmin(v1[2],v2[2]))); } inline vec3 fmax(const vec3& v1, const vec3& v2) { return(vec3(fmax(v1[0],v2[0]),fmax(v1[1],v2[1]),fmax(v1[2],v2[2]))); } inline vec4 fmin(const vec4& v1, const vec4& v2) { return(vec4(fmin(v1[0],v2[0]),fmin(v1[1],v2[1]),fmin(v1[2],v2[2]),fmin(v1[3],v2[3]))); } inline vec4 fmax(const vec4& v1, const vec4& v2) { return(vec4(fmax(v1[0],v2[0]),fmax(v1[1],v2[1]),fmax(v1[2],v2[2]),fmax(v1[3],v2[3]))); } #endif // ALGEBRA3AUXH