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 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* = NULL)
00188 {
00189 if( assumeIdentityWorldMatrix() )
00190 {
00191 setWorldMatrix(mat4());
00192 }
00193 else
00194
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
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