Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
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
00048
00072 class VLCORE_EXPORT Transform: public Object
00073 {
00074 public:
00076 Transform(): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false), mParent(NULL)
00077 {
00078 VL_DEBUG_SET_OBJECT_NAME()
00079
00080 #if VL_TRANSFORM_USER_DATA
00081 mTransformUserData = NULL;
00082 #endif
00083 }
00084
00086 Transform(const mat4& matrix): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false), mParent(NULL)
00087 {
00088 VL_DEBUG_SET_OBJECT_NAME()
00089
00090 #if VL_TRANSFORM_USER_DATA
00091 mTransformUserData = NULL;
00092 #endif
00093
00094 setLocalMatrix(matrix);
00095 setWorldMatrix(matrix);
00096 }
00097
00099 ~Transform();
00100
00102 const Transform* parent() const { return mParent; }
00103
00105 Transform* parent() { return mParent; }
00106
00109 void translate(Real x, Real y, Real z);
00110
00113 void translate(const vec3& t);
00114
00117 void scale(Real x, Real y, Real z);
00118
00121 void rotate(Real degrees, Real x, Real y, Real z);
00122
00125 void rotate(const vec3& from, const vec3& to);
00126
00129 void preMultiply(const mat4& m);
00130
00133 void postMultiply(const mat4& m);
00134
00137 void setLocalMatrix(const mat4& m)
00138 {
00139 mLocalMatrix = m;
00140 }
00141
00143 const mat4& localMatrix() const
00144 {
00145 return mLocalMatrix;
00146 }
00147
00151 void setWorldMatrix(const mat4& matrix)
00152 {
00153 mWorldMatrix = matrix;
00154 ++mWorldMatrixUpdateTick;
00155 }
00156
00158 const mat4& worldMatrix() const
00159 {
00160 return mWorldMatrix;
00161 }
00162
00166 void setLocalAndWorldMatrix(const mat4& matrix)
00167 {
00168 mLocalMatrix = matrix;
00169 setWorldMatrix(matrix);
00170 }
00171
00174 long long worldMatrixUpdateTick() const { return mWorldMatrixUpdateTick; }
00175
00178 void setAssumeIdentityWorldMatrix(bool assume_I) { mAssumeIdentityWorldMatrix = assume_I; }
00179
00182 bool assumeIdentityWorldMatrix() { return mAssumeIdentityWorldMatrix; }
00183
00185 virtual void computeWorldMatrix(Camera* = NULL)
00186 {
00187 if( assumeIdentityWorldMatrix() )
00188 {
00189 setWorldMatrix(mat4());
00190 }
00191 else
00192
00193 if( parent() && !parent()->assumeIdentityWorldMatrix() )
00194 {
00195 setWorldMatrix( parent()->worldMatrix() * localMatrix() );
00196 }
00197 else
00198 setWorldMatrix( localMatrix() );
00199 }
00200
00202 void computeWorldMatrixRecursive(Camera* camera = NULL)
00203 {
00204 computeWorldMatrix(camera);
00205 for(size_t i=0; i<mChildren.size(); ++i)
00206 mChildren[i]->computeWorldMatrixRecursive(camera);
00207 }
00208
00210 mat4 getComputedWorldMatrix()
00211 {
00212 mat4 world = localMatrix();
00213 Transform* par = parent();
00214 while(par)
00215 {
00216 world = par->localMatrix() * world;
00217 par = par->parent();
00218 }
00219 return world;
00220 }
00221
00222
00223
00225 const ref<Transform>* children() const { if (mChildren.empty()) return NULL; else return &mChildren[0]; }
00226
00228 ref<Transform>* children() { if (mChildren.empty()) return NULL; else return &mChildren[0]; }
00229
00231 size_t childrenCount() const { return mChildren.size(); }
00232
00234 void addChild(Transform* child)
00235 {
00236 VL_CHECK(child != NULL)
00237 VL_CHECK(child->mParent == NULL)
00238
00239 mChildren.push_back(child);
00240 child->mParent = this;
00241 }
00242
00244 void addChildren(Transform*const* children, size_t count)
00245 {
00246 VL_CHECK(children != NULL)
00247
00248 if (count)
00249 {
00250 size_t insert_point = mChildren.size();
00251 mChildren.resize(mChildren.size() + count);
00252 vl::ref<Transform>* ptr = &mChildren[insert_point];
00253 for(size_t i=0; i<count; ++i, ++ptr)
00254 {
00255 VL_CHECK(children[i]->mParent == NULL);
00256 children[i]->mParent = this;
00257 (*ptr) = children[i];
00258 }
00259 }
00260 }
00261
00262 void addChildren(const ref<Transform>* children, size_t count)
00263 {
00264 VL_CHECK(children != NULL)
00265
00266 if (count)
00267 {
00268 size_t insert_point = mChildren.size();
00269 mChildren.resize(mChildren.size() + count);
00270 vl::ref<Transform>* ptr = &mChildren[insert_point];
00271 for(size_t i=0; i<count; ++i)
00272 {
00273 VL_CHECK(children[i]->mParent == NULL);
00274 ptr[i] = children[i];
00275 ptr[i]->mParent = this;
00276 }
00277 }
00278 }
00279
00280 void addChildren(const std::vector< ref<Transform> >& children)
00281 {
00282 if (children.size())
00283 addChildren( &children[0], children.size() );
00284 }
00285
00287 void addChildren(const std::vector< Transform* >& children)
00288 {
00289 if (children.size())
00290 addChildren( &children[0], children.size() );
00291 }
00292
00294 void setChild(int index, Transform* child)
00295 {
00296 VL_CHECK(child)
00297 VL_CHECK( index < (int)mChildren.size() )
00298 mChildren[index]->mParent = NULL;
00299 mChildren[index] = child;
00300 mChildren[index]->mParent = this;
00301 }
00302
00304 const Transform* lastChild() const { return mChildren.back().get(); }
00305
00307 Transform* lastChild() { return mChildren.back().get(); }
00308
00310 void eraseChild(const Transform* child)
00311 {
00312 VL_CHECK(child != NULL)
00313 std::vector< ref<Transform> >::iterator it;
00314 it = std::find(mChildren.begin(), mChildren.end(), child);
00315 VL_CHECK(it != mChildren.end())
00316 if (it != mChildren.end())
00317 {
00318 (*it)->mParent = NULL;
00319 mChildren.erase(it);
00320 }
00321 }
00322
00324 void eraseChildren(int index, int count)
00325 {
00326 VL_CHECK( index + count <= (int)mChildren.size() );
00327
00328 for(int j=index; j<index+count; ++j)
00329 mChildren[j]->mParent = NULL;
00330
00331 for(int i=index+count, j=index; i<(int)mChildren.size(); ++i, ++j)
00332 mChildren[j] = mChildren[i];
00333
00334 mChildren.resize( mChildren.size() - count );
00335 }
00336
00338 void eraseAllChildren()
00339 {
00340 for(int i=0; i<(int)mChildren.size(); ++i)
00341 mChildren[i]->mParent = NULL;
00342 mChildren.clear();
00343 }
00344
00346 void eraseAllChildrenRecursive()
00347 {
00348 for(int i=0; i<(int)mChildren.size(); ++i)
00349 {
00350 mChildren[i]->eraseAllChildrenRecursive();
00351 mChildren[i]->mParent = NULL;
00352 }
00353 mChildren.clear();
00354 }
00355
00357 void flattenHierarchy()
00358 {
00359 for(int i=0; i<(int)mChildren.size(); ++i)
00360 {
00361 mChildren[i]->setLocalAndWorldMatrix( mChildren[i]->worldMatrix() );
00362 mChildren[i]->eraseAllChildrenRecursive();
00363 mChildren[i]->mParent = NULL;
00364 }
00365 mChildren.clear();
00366 }
00367
00369 void removeFromParent()
00370 {
00371 if (parent())
00372 {
00373 mParent->eraseChild(this);
00374 setLocalMatrix( worldMatrix() );
00375 }
00376 }
00377
00379 void shrink()
00380 {
00381 std::vector< ref<Transform> > tmp (mChildren);
00382 mChildren.swap(tmp);
00383 }
00384
00386 void shrinkRecursive()
00387 {
00388 shrink();
00389 for(size_t i=0; i<mChildren.size(); ++i)
00390 mChildren[i]->shrinkRecursive();
00391 }
00392
00397 void reserveChildren(size_t count) { mChildren.reserve(count); }
00398
00400 bool hasDuplicatedChildren() const
00401 {
00402 std::set<const Transform*> tr_set;
00403 for(size_t i=0; i<mChildren.size(); ++i)
00404 tr_set.insert( mChildren[i].get() );
00405 return tr_set.size() != mChildren.size();
00406 }
00407
00408 #if VL_TRANSFORM_USER_DATA
00409 public:
00410 void setTransformUserData(void* data) { mTransformUserData = data; }
00411 const void* transformUserData() const { return mTransformUserData; }
00412 void* transformUserData() { return mTransformUserData; }
00413
00414 private:
00415 void* mTransformUserData;
00416 #endif
00417
00418 protected:
00419 mat4 mLocalMatrix;
00420 mat4 mWorldMatrix;
00421 long long mWorldMatrixUpdateTick;
00422 bool mAssumeIdentityWorldMatrix;
00423 std::vector< ref<Transform> > mChildren;
00424 Transform* mParent;
00425 };
00426
00427 }
00428
00429 #endif