00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <util/coordTrans.h>
00021 #include <assert.h>
00022 #include <iostream>
00023 using namespace std;
00024 using namespace gutz;
00025
00026 using namespace glift;
00027
00028 CoordTrans::CoordTrans()
00029 {
00030 init(vec3f(1.0f), vec3f(0.0f), false, false);
00031 }
00032
00033 CoordTrans::CoordTrans( const vec2f& bias, bool relBias )
00034 {
00035 init(vec3f(1.0f), vec3f(bias.s, bias.t, 0.0f), false, relBias);
00036 }
00037
00038 CoordTrans::CoordTrans( const vec3f& bias, bool relBias)
00039 {
00040 init(vec3f(1.0f), bias, false, relBias);
00041 }
00042
00043 CoordTrans::CoordTrans( const vec3f& scale, const vec3f& bias, bool relScale, bool relBias )
00044 {
00045 init(scale, bias, relScale, relBias);
00046 }
00047
00048 CoordTrans::CoordTrans( const mat4f& mat, bool relScale, bool relBias )
00049 {
00050 m_mat = mat;
00051 m_relScale = relScale;
00052 m_relBias = relBias;
00053 }
00054
00055 void CoordTrans::init( const vec3f& scale, const vec3f& bias, bool relScale, bool relBias )
00056 {
00057 mat3f scaleMat;
00058 scaleMat[0] = scale.x;
00059 scaleMat[4] = scale.y;
00060 scaleMat[8] = scale.z;
00061
00062 m_mat = mat4f( scaleMat, bias );
00063 m_relScale = relScale;
00064 m_relBias = relBias;
00065 }
00066
00067 vec2f CoordTrans::apply( const vec2f& coord, const vec2f& divisor )
00068 {
00069 mat4f mat = applyDivisor( arrayo1f(2, divisor.v()) );
00070 vec4f coordVec(coord, 0.0f, 1.0f);
00071 coordVec = mat * coordVec;
00072 return vec2f(coordVec);
00073 }
00074
00075 vec3f CoordTrans::apply( const vec3f& coord, const vec3f& divisor )
00076 {
00077 mat4f mat = applyDivisor( arrayo1f(3, divisor.v() ) );
00078 vec4f coordVec(coord, 1.0f);
00079 coordVec = mat * coordVec;
00080 return vec3f(coordVec);
00081 }
00082
00083 gutz::arrayo1f CoordTrans::apply( const arrayw1f& coord, const arrayw1f& divisor )
00084 {
00085 if( (coord.size() != 2) && (coord.size() != 3) && (coord.size() != 4) ) {
00086 err() << "CoordTrans::transform(...) Error:\n"
00087 << "\tcoord.size() == " << coord.size() << ". 'coord' must be array of size 2, 3, or 4.\n";
00088 exit(1);
00089 }
00090
00091 if( (divisor.size() != 2) && (divisor.size() != 3) ) {
00092 err() << "CoordTrans::transform(...) Error:\n"
00093 << "\tdivisor.size() == " << divisor.size() << ". 'divisor' must be array of size 2 or 3.\n";
00094 exit(1);
00095 }
00096
00097
00098 vec4f coordVec;
00099 coordVec[0] = coord[0];
00100 coordVec[1] = coord[1];
00101 coordVec[2] = coord.size() > 2 ? coord[2] : 0.0f;
00102 coordVec[3] = coord.size() > 3 ? coord[3] : 1.0f;
00103
00104 mat4f mat = applyDivisor( divisor );
00105 coordVec = mat * coordVec;
00106
00107 switch( coord.size() ) {
00108 case 2: return arrayo1f(2, coordVec.v() ); break;
00109 case 3: return arrayo1f(3, coordVec.v() ); break;
00110 case 4: return arrayo1f(4, coordVec.v() ); break;
00111 default: return arrayo1f(4, coordVec.v() ); break;
00112 }
00113 }
00114
00115 mat4f CoordTrans::applyDivisor( const arrayw1f& divisor )
00116 {
00117 assert( divisor.size() == 2 || divisor.size() == 3 );
00118
00119 mat4f mat = m_mat;
00120
00121 if( m_relScale ) {
00122 mat[0] /= divisor[0];
00123 mat[1] /= divisor[1];
00124 mat[2] /= divisor.size()==3 ? divisor[2] : 1.0f;
00125 }
00126 if( m_relBias ) {
00127 mat[12] /= divisor[0];
00128 mat[13] /= divisor[1];
00129 mat[14] /= divisor.size()==3 ? divisor[2] : 1.0f;
00130 }
00131
00132 return mat;
00133 }
00134
00135