SDS.cc

Go to the documentation of this file.
00001 #include <esg/spacesorting/SDS.h>
00002 
00003 using namespace esg;
00004 
00005 void SDS::_duplicate_attributes(const SDS& s)
00006 {
00007     _delayBuild = s._delayBuild;
00008 }
00009 
00010 Matrix4* SDS::multiTrans(const Matrix4* U,
00011                          const Matrix4* R,
00012                          Vector3&       scale)
00013 {
00014     /*
00015      * Change two transformations to one.
00016      * To compute distance of objects transformed by Ux+t and Rx+s it is
00017      * sufficient to compute distance of the first object (non-transformed)
00018      * and the second object transformed by the rot*x+tra matrix, where
00019      *
00020      *       rot   = U^{-1} * R
00021      *       tra   = scaleU^{-1} * U^{-1} * (s-t)
00022      *       scale = scaleU^{-1} * rot * scaleR 
00023      *
00024      * Where
00025      *    U^{-1}      = U^T
00026      *    scaleU^{-1} = (1/scaleU.x, 1/scaleU.y, 1/scaleU.z)
00027      */
00028 
00029     /*
00030      * I'm not sure about correctness of this code  - untested !!!
00031      */
00032 
00033     if (!U && !R) { scale.set(1.0, 1.0, 1.0); return NULL; }
00034 
00035     Vector3  s,t,tra;
00036     Matrix4* pRet = new Matrix4;
00037     Matrix3  rotU, rotR;
00038     Matrix4  auxMat;
00039 
00040     if (!U) { // U = identity
00041         scale.set(1.0, 1.0, 1.0);
00042         pRet->set(*R);
00043         return pRet;
00044     }
00045 
00046     if (!R) { // R = identity
00047         U->get(rotU, t, scale);
00048         scale.x = 1.0 / scale.x;
00049         scale.y = 1.0 / scale.y;
00050         scale.z = 1.0 / scale.z;
00051         rotU.transpose();
00052         t.negate();
00053         rotU.transform(t);
00054         t.x *= scale.x;
00055         t.y *= scale.y;
00056         t.z *= scale.z;
00057 
00058         pRet->setIdentity();
00059         pRet->setElement(0, 0, scale.x);
00060         pRet->setElement(1, 1, scale.y);
00061         pRet->setElement(2, 2, scale.z);
00062 
00063         auxMat.set(rotU);
00064         pRet->mul(auxMat);        // first rotate and then scale
00065         pRet->setTranslation(t);  // finilly translate
00066     
00067         //pRet->set(rotU, t, scale);
00068         return pRet;
00069     }
00070 
00071     Vector3 scR;
00072     U->get(rotU, t, scale);
00073     R->get(rotR, s, scR);
00074 
00075     scale.x = 1.0 / scale.x;
00076     scale.y = 1.0 / scale.y;
00077     scale.z = 1.0 / scale.z;
00078     
00079     rotU.transpose();
00080 
00081     // get translation
00082     s.sub(t);
00083     rotU.transform(s);
00084     s.x *= scale.x;
00085     s.y *= scale.y;
00086     s.z *= scale.z;
00087 
00088     // initialize to set transformation matrices from left to right
00089     pRet->setIdentity();
00090 
00091     // S1^-1
00092     pRet->setElement(0, 0, scale.x);
00093     pRet->setElement(1, 1, scale.y);
00094     pRet->setElement(2, 2, scale.z);
00095 
00096     // S1^-1 * (R1^T * R2)
00097     rotU.mul(rotR);
00098     auxMat.set(rotU);
00099     pRet->mul(auxMat);        // first rotate and then scale
00100 
00101     // S1^-1 * (R1^T * R2) * S2
00102     auxMat.setIdentity();
00103     auxMat.setElement(0, 0, scR.x);
00104     auxMat.setElement(1, 1, scR.y);
00105     auxMat.setElement(2, 2, scR.z);
00106     pRet->mul(auxMat);
00107 
00108     // finally set translation
00109     pRet->setTranslation(s); 
00110     
00111     //pRet->set(rotU, s, Vector3(scR.x*scale.x, scR.y*scale.y, scR.z*scale.z));
00112 
00113     return pRet;
00114 }
00115 
00116 Matrix4* SDS::multiTrans(const Matrix4* U,
00117                          const Matrix4* R,
00118                          double&        scale)
00119 {
00120     /*
00121      * Change two transformations to one.
00122      * To compute distance of objects transformed by Ux+t and Rx+s it is
00123      * sufficient to compute distance of the first object (non-transformed)
00124      * and the second object transformed by the rot*x+tra matrix, where
00125      *
00126      *       rot   = U^{-1} * R
00127      *       tra   = U^{-1} * (s-t)
00128      *       scale = scaleU * scaleR 
00129      *
00130      * Where
00131      *    U^{-1} = U^T
00132      */
00133 
00134     scale = 1.0;
00135     
00136     if (!U && !R) return NULL;
00137 
00138     Vector3  s,t,tra;
00139     Matrix4* pRet = new Matrix4;
00140     Matrix3  rotU, rotR;
00141 
00142     if (!U) { // U = identity
00143         pRet->set(*R);
00144         return pRet;
00145     }
00146 
00147     if (!R) { // R = identity
00148         scale = 1.0 / U->get(rotU, t);
00149         rotU.transpose();
00150         t.negate();
00151         t.scale(scale);
00152         rotU.transform(t);
00153         pRet->set(rotU, t, scale);
00154         return pRet;
00155     }
00156 
00157     scale    = 1.0 / U->get(rotU, t);
00158     float sR = R->get(rotR, s);
00159 
00160     rotU.transpose();
00161     s.sub(t);
00162     s.scale(scale);
00163     rotU.transform(s);
00164     rotU.mul(rotR);
00165     pRet->set(rotU, s, sR * scale);
00166     
00167     return pRet;
00168 }

Generated on Wed Jun 28 12:24:32 2006 for esg by  doxygen 1.4.6