00001 #include "TransformNode.h"
00002 #include "RelationalNode.h"
00003 #include "Property.h"
00004
00005 namespace RenderTools {
00006
00007 TransformNode::TransformNode( void ):
00008 m_warp( false ){
00009 }
00010
00011 void TransformNode::createProperties( void ) {
00012 createProperty( this, "currentTransform", & m_local );
00013 createProperty( this, "previousTransform", & m_previousLocal );
00014 createProperty( this, "warping", BooleanStruct( & m_warp ) );
00015 createProperty( this, "warpVector", & m_warpVector );
00016 }
00017
00018 const string TransformNode::getTypeName( bool ofComponent ) const {
00019 return( "TransformNode" );
00020 }
00021
00022 void TransformNode::transform( const Mat4 & global ){
00023 onTransform( global );
00024 }
00025
00026 void TransformNode::onTransform( const Mat4 & global ){
00027 m_previousGlobal = m_global;
00028 m_global = global * m_local;
00029
00030 m_naabb.reset();
00031 for( int i = 0; i < 8; i++ ){
00032 m_naabb.adjust( ( m_global * Vec4( m_aabb.getCorner( i ), 0.0 ) ).xyz() );
00033 }
00034 }
00035
00036 const Mat4 TransformNode::getGlobal( const RelationalNodePtr root ) const {
00037
00038 if( ! root ){
00039 return( m_local );
00040 }
00041
00042 RelationalNodeList path;
00043 if( ! root->getChild( getSharedPtr< RelationalNode >(), path ) ){
00044
00045 Error::error( Error::NODE_NOT_FOUND, __FILE__, __LINE__ );
00046 }
00047
00048
00049 Mat4 global;
00050 for( int i = (int)path.size() - 1; i >= 0; i-- ){
00051 global *= ( ( path[ i ] ) )->getLocal();
00052 }
00053 return( global );
00054 }
00055
00057 const Mat4 & TransformNode::getGlobal() const{
00058 return( m_global );
00059 }
00060
00062 Mat4 & TransformNode::getGlobal( void ){
00063 return( m_global );
00064 }
00065
00066
00068 const Mat4 & TransformNode::getLocal() const{
00069 return( m_local );
00070 }
00071
00073 Mat4 & TransformNode::getLocal( void ){
00074 return( m_local );
00075 }
00076
00078 void TransformNode::setLocal( const Mat4 & matrix ){
00079 m_local = matrix;
00080 }
00081
00083 const Mat4 & TransformNode::getPreviousLocal( void ) const{
00084 return( m_previousLocal );
00085 }
00086
00088 Mat4 & TransformNode::getPreviousGlobal( void ){
00089 return( m_previousGlobal );
00090 }
00091
00093 const Mat4 & TransformNode::getPreviousGlobal( void ) const{
00094 return( m_previousGlobal );
00095 }
00096
00098 Mat4 & TransformNode::getPreviousLocal( void ){
00099 return( m_previousLocal );
00100 }
00101
00103 void TransformNode::setPreviousLocal( const Mat4 & matrix ){
00104 m_previousLocal = matrix;
00105 }
00106
00108 void TransformNode::setMovement( const Vec3 & v, const Quat & q, bool relative, bool push ){
00109
00110 Mat4 previous = m_local;
00111
00112 if( relative ){
00113
00114 m_local.getCol(3).xyz() += v;
00115
00116 Quat q1 = Quat::fromMat3( m_local.rotation() );
00117
00118 q1 = q1 + q;
00119 m_local = Mat4::fromQuaternion( q1 );
00120 }
00121 else{
00122
00123 m_local = Mat4::fromQuaternion( q );
00124 m_local.setCol( 3, Vec4( v[0], v[1], v[2], 1.0 ) );
00125 }
00126
00127
00128 if( push && ( ! m_local.equals( previous, 0.05f ) ) ){
00129 m_previousLocal = previous;
00130 }
00131 }
00132
00133 void TransformNode::setMovement( const Mat4 & matrix, bool relative, bool push ){
00134
00135 Mat4 previous = m_local;
00136
00137 if( relative ){
00138 m_local *= matrix;
00139 }
00140 else{
00141 m_local = matrix;
00142 }
00143
00144
00145 if( push && ( ! m_local.equals( previous, 0.05f ) ) ){
00146 m_previousLocal = previous;
00147 }
00148 }
00149
00151 Vec3 TransformNode::getMovement( const Vec3 & global, bool fromPrevious ) const{
00152 Mat4 inv;
00153 Vec3 local;
00154 Vec3 previous;
00155
00156 if( ! fromPrevious ){
00157 inv = m_local.inverse();
00158 previous = ( m_previousLocal * inv * Vec4( global, 0.0 ) ).xyz();
00159 return( global - previous );
00160 }
00161 else{
00162 inv = m_previousLocal.inverse();
00163 local = ( m_local * inv * Vec4( global, 0.0 ) ).xyz();
00164 return( local - global );
00165 }
00166 }
00167
00168 Vec3 TransformNode::warpVector( const Vec3 & local ) const{
00169 if( ! m_warp ){
00170 return( local );
00171 }
00172 Vec3 r = local;
00173 Vec3 warp = m_warpVector;
00174 while( r[0] > warp[0] )r[0] -= 2.0 * warp[0];
00175 while( r[0] < -warp[0] )r[0] += 2.0 * warp[0];
00176 while( r[1] > warp[1] )r[1] -= 2.0 * warp[1];
00177 while( r[1] < -warp[1] )r[1] += 2.0 * warp[1];
00178 while( r[2] > warp[2] )r[2] -= 2.0 * warp[2];
00179 while( r[2] < -warp[2] )r[2] += 2.0 * warp[2];
00180 return( r );
00181 }
00182
00183 bool TransformNode::needsWarping( const Vec3 & local ) const{
00184 if( ! m_warp ){
00185 return( false );
00186 }
00187 Vec3 warp = m_warpVector;
00188 return( local[0] > warp[0] ||\
00189 local[1] > warp[1] ||\
00190 local[2] > warp[2] ||\
00191 local[0] < -warp[0] ||\
00192 local[1] < -warp[1] ||\
00193 local[2] < -warp[2] );
00194 }
00195
00196 void TransformNode::warp( const Vec3 & warped ){
00197
00198 m_local[12] += warped[0];
00199 m_local[13] += warped[1];
00200 m_local[14] += warped[2];
00201
00202
00203 m_previousLocal[12] += warped[0];
00204 m_previousLocal[13] += warped[1];
00205 m_previousLocal[14] += warped[2];
00206 }
00207
00208 void TransformNode::warp( void ){
00209 if( m_warp ){
00210
00211
00212
00213 Mat4 global = get( Matrix::MODELVIEW ) * m_local;
00214 Vec3 warped = warpVector( global.getCol(3).xyz() ) - global.getCol(3).xyz();
00215
00216
00217 if( warped[0] != 0.0 || warped[1] != 0.0 || warped[2] != 0.0 ){
00218 warp( warped );
00219 }
00220 }
00221 }
00222
00223 void TransformNode::setWarping( bool state, const Vec3 & warp ){
00224 m_warp = state;
00225 m_warpVector = warp;
00226 }
00227
00228 const NAABB & TransformNode::getNAABB( void ) const {
00229 return( m_naabb );
00230 }
00231
00232 const AABB & TransformNode::getAABB( void ) const {
00233 return( m_aabb );
00234 }
00235
00236 void TransformNode::setNAABB( const NAABB & box, bool send ){
00237 m_naabb = box;
00238 sendPropertyEvent( PropertyEvent( PropertyEvent::CHANGED, findProperty( & m_naabb ) ) );
00239 }
00240
00241 void TransformNode::setAABB( const AABB & box, bool send ){
00242 m_aabb = box;
00243 sendPropertyEvent( PropertyEvent( PropertyEvent::CHANGED, findProperty( & m_aabb ) ) );
00244 }
00245
00246
00247 };
00248