Visualization Library

A lightweight C++ OpenGL middleware for 2D/3D graphics
[Home] [Tutorials] [All Classes] [Grouped Classes]

X:/dropbox/visualizationlibrary/src/vlCore/Transform.hpp

Go to the documentation of this file.
00001 /**************************************************************************************/
00002 /*                                                                                    */
00003 /*  Visualization Library                                                             */
00004 /*  http://www.visualizationlibrary.org                                               */
00005 /*                                                                                    */
00006 /*  Copyright (c) 2005-2010, Michele Bosi                                             */
00007 /*  All rights reserved.                                                              */
00008 /*                                                                                    */
00009 /*  Redistribution and use in source and binary forms, with or without modification,  */
00010 /*  are permitted provided that the following conditions are met:                     */
00011 /*                                                                                    */
00012 /*  - Redistributions of source code must retain the above copyright notice, this     */
00013 /*  list of conditions and the following disclaimer.                                  */
00014 /*                                                                                    */
00015 /*  - Redistributions in binary form must reproduce the above copyright notice, this  */
00016 /*  list of conditions and the following disclaimer in the documentation and/or       */
00017 /*  other materials provided with the distribution.                                   */
00018 /*                                                                                    */
00019 /*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND   */
00020 /*  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED     */
00021 /*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE            */
00022 /*  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR  */
00023 /*  ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    */
00024 /*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;      */
00025 /*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON    */
00026 /*  ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT           */
00027 /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS     */
00028 /*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                      */
00029 /*                                                                                    */
00030 /**************************************************************************************/
00031 
00032 #ifndef Transform_INCLUDE_ONCE
00033 #define Transform_INCLUDE_ONCE
00034 
00035 #include <vlCore/vlnamespace.hpp>
00036 #include <vlCore/Object.hpp>
00037 #include <vlCore/Matrix4.hpp>
00038 #include <vector>
00039 #include <set>
00040 #include <algorithm>
00041 
00042 namespace vl
00043 {
00044   class Camera;
00045 
00046   //------------------------------------------------------------------------------
00047   // Transform
00048   //------------------------------------------------------------------------------
00072   class VLCORE_EXPORT Transform: public Object
00073   {
00074     VL_INSTRUMENT_CLASS(vl::Transform, Object)
00075 
00076   public:
00078     Transform(): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false), mParent(NULL)
00079     {
00080       VL_DEBUG_SET_OBJECT_NAME()
00081 
00082       #if VL_TRANSFORM_USER_DATA 
00083         mTransformUserData = NULL;
00084       #endif
00085     }
00086 
00088     Transform(const mat4& matrix): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false), mParent(NULL)
00089     { 
00090       VL_DEBUG_SET_OBJECT_NAME()
00091 
00092       #if VL_TRANSFORM_USER_DATA 
00093         mTransformUserData = NULL;
00094       #endif
00095 
00096       setLocalMatrix(matrix);
00097       setWorldMatrix(matrix);
00098     }
00099 
00101     ~Transform();
00102 
00104     const Transform* parent() const { return mParent; }
00105     
00107     Transform* parent() { return mParent; }
00108 
00111     void translate(real x, real y, real z);
00112     
00115     void translate(const vec3& t);
00116     
00119     void scale(real x, real y, real z);
00120     
00123     void rotate(real degrees, real x, real y, real z);
00124     
00127     void rotate(const vec3& from, const vec3& to);
00128 
00131     void preMultiply(const mat4& m);
00132 
00135     void postMultiply(const mat4& m);
00136 
00139     void setLocalMatrix(const mat4& m)
00140     { 
00141       mLocalMatrix = m;
00142     }
00143 
00145     const mat4& localMatrix() const
00146     { 
00147       return mLocalMatrix;
00148     }
00149 
00153     void setWorldMatrix(const mat4& matrix) 
00154     { 
00155       mWorldMatrix = matrix; 
00156       ++mWorldMatrixUpdateTick;
00157     }
00158 
00160     const mat4& worldMatrix() const 
00161     { 
00162       return mWorldMatrix;
00163     }
00164 
00168     void setLocalAndWorldMatrix(const mat4& matrix)
00169     { 
00170       mLocalMatrix = matrix;
00171       setWorldMatrix(matrix);
00172     }
00173 
00176     long long worldMatrixUpdateTick() const { return mWorldMatrixUpdateTick; }
00177 
00180     void setAssumeIdentityWorldMatrix(bool assume_I) { mAssumeIdentityWorldMatrix = assume_I; }
00181 
00184     bool assumeIdentityWorldMatrix() { return mAssumeIdentityWorldMatrix; }
00185 
00187     virtual void computeWorldMatrix(Camera* /*camera*/ = NULL)
00188     {
00189       if( assumeIdentityWorldMatrix() )
00190       {
00191         setWorldMatrix(mat4()); 
00192       }
00193       else
00194       /* top Transforms are usually assumeIdentityWorldMatrix() == true for performance reasons */
00195       if( parent() && !parent()->assumeIdentityWorldMatrix() )
00196       {
00197         setWorldMatrix( parent()->worldMatrix() * localMatrix() );
00198       }
00199       else
00200         setWorldMatrix( localMatrix() );
00201     }
00202 
00204     void computeWorldMatrixRecursive(Camera* camera = NULL)
00205     {
00206       computeWorldMatrix(camera);
00207       for(size_t i=0; i<mChildren.size(); ++i)
00208         mChildren[i]->computeWorldMatrixRecursive(camera);
00209     }
00210 
00212     mat4 getComputedWorldMatrix()
00213     {
00214       mat4 world = localMatrix();
00215       Transform* par = parent();
00216       while(par)
00217       {
00218         world = par->localMatrix() * world;
00219         par = par->parent();
00220       }
00221       return world;
00222     }
00223 
00224     // --- --- children management --- ---
00225 
00227     const ref<Transform>* children() const { if (mChildren.empty()) return NULL; else return &mChildren[0]; }
00228 
00230     ref<Transform>* children() { if (mChildren.empty()) return NULL; else return &mChildren[0]; }
00231 
00233     size_t childrenCount() const { return mChildren.size(); }
00234 
00236     void addChild(Transform* child)
00237     {
00238       VL_CHECK(child != NULL)
00239       VL_CHECK(child->mParent == NULL)
00240 
00241       mChildren.push_back(child);
00242       child->mParent = this;
00243     }
00244     
00246     void addChildren(Transform*const* children, size_t count)
00247     {
00248       VL_CHECK(children != NULL)
00249 
00250       if (count)
00251       {
00252         size_t insert_point = mChildren.size();
00253         mChildren.resize(mChildren.size() + count);
00254         vl::ref<Transform>* ptr = &mChildren[insert_point];
00255         for(size_t i=0; i<count; ++i, ++ptr)
00256         {
00257           VL_CHECK(children[i]->mParent == NULL);
00258           children[i]->mParent = this;
00259           (*ptr) = children[i];
00260         }
00261       }
00262     }
00263 
00264     void addChildren(const ref<Transform>* children, size_t count)
00265     {
00266       VL_CHECK(children != NULL)
00267 
00268       if (count)
00269       {
00270         size_t insert_point = mChildren.size();
00271         mChildren.resize(mChildren.size() + count);
00272         vl::ref<Transform>* ptr = &mChildren[insert_point];
00273         for(size_t i=0; i<count; ++i)
00274         {
00275           VL_CHECK(children[i]->mParent == NULL);
00276           ptr[i] = children[i];
00277           ptr[i]->mParent = this;
00278         }
00279       }
00280     }
00281 
00282     void addChildren(const std::vector< ref<Transform> >& children)
00283     {
00284       if (children.size())
00285         addChildren( &children[0], children.size() );
00286     }
00287 
00289     void addChildren(const std::vector< Transform* >& children)
00290     {
00291       if (children.size())
00292         addChildren( &children[0], children.size() );
00293     }
00294 
00296     void setChild(int index, Transform* child)
00297     {
00298       VL_CHECK(child)
00299       VL_CHECK( index < (int)mChildren.size() )
00300       mChildren[index]->mParent = NULL;
00301       mChildren[index] = child;
00302       mChildren[index]->mParent = this;
00303     }
00304 
00306     const Transform* lastChild() const { return mChildren.back().get(); }
00307 
00309     Transform* lastChild() { return mChildren.back().get(); }
00310 
00312     void eraseChild(const Transform* child)
00313     {
00314       VL_CHECK(child != NULL)
00315       std::vector< ref<Transform> >::iterator it;
00316       it = std::find(mChildren.begin(), mChildren.end(), child);
00317       VL_CHECK(it != mChildren.end())
00318       if (it != mChildren.end())
00319       {
00320         (*it)->mParent = NULL;
00321         mChildren.erase(it);
00322       }
00323     }
00324 
00326     void eraseChildren(int index, int count)
00327     {
00328       VL_CHECK( index + count <= (int)mChildren.size() );
00329 
00330       for(int j=index; j<index+count; ++j)
00331         mChildren[j]->mParent = NULL;
00332 
00333       for(int i=index+count, j=index; i<(int)mChildren.size(); ++i, ++j)
00334         mChildren[j] = mChildren[i];
00335 
00336       mChildren.resize( mChildren.size() - count );
00337     }    
00338 
00340     void eraseAllChildren()
00341     {
00342       for(int i=0; i<(int)mChildren.size(); ++i)
00343         mChildren[i]->mParent = NULL;
00344       mChildren.clear();
00345     }
00346 
00348     void eraseAllChildrenRecursive()
00349     {
00350       for(int i=0; i<(int)mChildren.size(); ++i)
00351       {
00352         mChildren[i]->eraseAllChildrenRecursive();
00353         mChildren[i]->mParent = NULL;
00354       }
00355       mChildren.clear();
00356     }
00357 
00359     void flattenHierarchy()
00360     {
00361       for(int i=0; i<(int)mChildren.size(); ++i)
00362       {
00363         mChildren[i]->setLocalAndWorldMatrix( mChildren[i]->worldMatrix() );
00364         mChildren[i]->eraseAllChildrenRecursive();
00365         mChildren[i]->mParent = NULL;
00366       }
00367       mChildren.clear();
00368     }
00369 
00371     void removeFromParent()
00372     {
00373       if (parent())
00374       {
00375         mParent->eraseChild(this);
00376         setLocalMatrix( worldMatrix() );
00377       }
00378     }
00379 
00381     void shrink()
00382     {
00383       std::vector< ref<Transform> > tmp (mChildren);
00384       mChildren.swap(tmp);
00385     }
00386 
00388     void shrinkRecursive()
00389     {
00390       shrink();
00391       for(size_t i=0; i<mChildren.size(); ++i)
00392         mChildren[i]->shrinkRecursive();
00393     }
00394 
00399     void reserveChildren(size_t count) { mChildren.reserve(count); }
00400 
00402     bool hasDuplicatedChildren() const
00403     {
00404       std::set<const Transform*> tr_set;
00405       for(size_t i=0; i<mChildren.size(); ++i)
00406         tr_set.insert( mChildren[i].get() );
00407       return tr_set.size() != mChildren.size();
00408     }
00409 
00410 #if VL_TRANSFORM_USER_DATA 
00411   public:
00412     void setTransformUserData(void* data) { mTransformUserData = data; }
00413     const void* transformUserData() const { return mTransformUserData; }
00414     void* transformUserData() { return mTransformUserData; }
00415 
00416   private:
00417     void* mTransformUserData;
00418 #endif
00419 
00420   protected:
00421     mat4 mLocalMatrix;
00422     mat4 mWorldMatrix;
00423     long long mWorldMatrixUpdateTick;
00424     bool mAssumeIdentityWorldMatrix;
00425     std::vector< ref<Transform> > mChildren;
00426     Transform* mParent;
00427   };
00428 
00429 }
00430 
00431 #endif

Visualization Library 2011.09.1160 Reference Documentation
Copyright 2005-2011 Michele Bosi. All rights reserved.
Updated on Thu May 2 2013 13:40:32.
Permission is granted to use this page to write and publish articles regarding Visualization Library.