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
00049
00050
00051
00052
00053
00054
00056 class VLCORE_EXPORT ITransform: public Object
00057 {
00058 public:
00059 ITransform(): mWorldMatrixUpdateTick(0), mAssumeIdentityWorldMatrix(false)
00060 {
00061 #if VL_TRANSFORM_USER_DATA
00062 mTransformUserData = NULL;
00063 #endif
00064 }
00065
00066 virtual size_t childrenCount() const = 0;
00067
00068 virtual ITransform* getChildren(size_t i) = 0;
00069
00070 virtual const ITransform* getChildren(size_t i) const = 0;
00071
00072 virtual ITransform* parent() = 0;
00073
00074 virtual const ITransform* parent() const = 0;
00075
00078 void setLocalMatrix(const mat4& m)
00079 {
00080 mLocalMatrix = m;
00081 }
00082
00084 const mat4& localMatrix() const
00085 {
00086 return mLocalMatrix;
00087 }
00088
00090 virtual void computeWorldMatrix(Camera* = NULL)
00091 {
00092 if( assumeIdentityWorldMatrix() )
00093 {
00094 setWorldMatrix(mat4());
00095 }
00096 else
00097
00098 if( parent() && !parent()->assumeIdentityWorldMatrix() )
00099 {
00100 setWorldMatrix( parent()->worldMatrix() * localMatrix() );
00101 }
00102 else
00103 setWorldMatrix( localMatrix() );
00104 }
00105
00107 void computeWorldMatrixRecursive(Camera* camera = NULL)
00108 {
00109 computeWorldMatrix(camera);
00110 for(size_t i=0; i<childrenCount(); ++i)
00111 getChildren(i)->computeWorldMatrixRecursive(camera);
00112 }
00113
00115 mat4 getComputedWorldMatrix()
00116 {
00117 mat4 world = localMatrix();
00118 ref<ITransform> par = parent();
00119 while(par)
00120 {
00121 world = par->localMatrix() * world;
00122 par = par->parent();
00123 }
00124 return world;
00125 }
00126
00128 const mat4& worldMatrix() const
00129 {
00130 return mWorldMatrix;
00131 }
00132
00136 void setWorldMatrix(const mat4& matrix)
00137 {
00138 mWorldMatrix = matrix;
00139 ++mWorldMatrixUpdateTick;
00140 }
00141
00144 long long worldMatrixUpdateTick() const { return mWorldMatrixUpdateTick; }
00145
00148 void setAssumeIdentityWorldMatrix(bool assume_I) { mAssumeIdentityWorldMatrix = assume_I; }
00149
00152 bool assumeIdentityWorldMatrix() { return mAssumeIdentityWorldMatrix; }
00153
00155 bool hasDuplicatedChildren() const
00156 {
00157 std::set<const ITransform*> tr_set;
00158 for(size_t i=0; i<childrenCount(); ++i)
00159 tr_set.insert(getChildren(i));
00160 return tr_set.size() != childrenCount();
00161 }
00162
00163 #if VL_TRANSFORM_USER_DATA
00164 public:
00165 void setTransformUserData(void* data) { mTransformUserData = data; }
00166 const void* transformUserData() const { return mTransformUserData; }
00167 void* transformUserData() { return mTransformUserData; }
00168
00169 private:
00170 void* mTransformUserData;
00171 #endif
00172
00173 protected:
00174 mat4 mLocalMatrix;
00175 mat4 mWorldMatrix;
00176 long long mWorldMatrixUpdateTick;
00177 bool mAssumeIdentityWorldMatrix;
00178 };
00179
00180
00181
00182
00184 template<class Ttype>
00185 class TransformHierarchy: public ITransform
00186 {
00187 public:
00188 TransformHierarchy(): mParent(NULL) {}
00189
00190
00191
00192 virtual size_t childrenCount() const { return mChildren.size(); }
00193
00194 virtual ITransform* getChildren(size_t i) { return mChildren[i].get(); }
00195
00196 virtual const ITransform* getChildren(size_t i) const { return mChildren[i].get(); }
00197
00198 virtual const ITransform* parent() const { return mParent; }
00199
00200 virtual ITransform* parent() { return mParent; }
00201
00202
00203
00205 const std::vector< ref<Ttype> >& children() const { return mChildren; }
00206
00208 void addChild(Ttype* child)
00209 {
00210 VL_CHECK(child != NULL)
00211 VL_CHECK(child->mParent == NULL)
00212
00213 mChildren.push_back(child);
00214 child->mParent = this;
00215 }
00216
00218 void addChildren(Ttype*const* children, size_t count)
00219 {
00220 VL_CHECK(children != NULL)
00221
00222 if (count)
00223 {
00224 size_t insert_point = mChildren.size();
00225 mChildren.resize(mChildren.size() + count);
00226 vl::ref<Ttype>* ptr = &mChildren[insert_point];
00227 for(size_t i=0; i<count; ++i, ++ptr)
00228 {
00229 VL_CHECK(children[i]->mParent == NULL);
00230 children[i]->mParent = this;
00231 (*ptr) = children[i];
00232 }
00233 }
00234 }
00235
00236 void addChildren(const ref<Ttype>* children, size_t count)
00237 {
00238 VL_CHECK(children != NULL)
00239
00240 if (count)
00241 {
00242 size_t insert_point = mChildren.size();
00243 mChildren.resize(mChildren.size() + count);
00244 vl::ref<Ttype>* ptr = &mChildren[insert_point];
00245 for(size_t i=0; i<count; ++i)
00246 {
00247 VL_CHECK(children[i]->mParent == NULL);
00248 children[i]->mParent = this;
00249 ptr[i] = children[i];
00250 }
00251 }
00252 }
00253
00254 void addChildren(const std::vector< ref<Ttype> >& children)
00255 {
00256 if (children.size())
00257 addChildren( &children[0], children.size() );
00258 }
00259
00261 void addChildren(const std::vector< Ttype* >& children)
00262 {
00263 if (children.size())
00264 addChildren( &children[0], children.size() );
00265 }
00266
00268 void setChild(int index, Ttype* child)
00269 {
00270 VL_CHECK(child)
00271 VL_CHECK( index < (int)mChildren.size() )
00272 mChildren[index]->mParent = NULL;
00273 mChildren[index] = child;
00274 mChildren[index]->mParent = this;
00275 }
00276
00278 Ttype* lastChild()
00279 {
00280 return mChildren.back().get();
00281 }
00282
00284 void eraseChild(Ttype* child)
00285 {
00286 VL_CHECK(child != NULL)
00287 typename std::vector< ref<Ttype> >::iterator it;
00288 it = std::find(mChildren.begin(), mChildren.end(), child);
00289 VL_CHECK(it != mChildren.end())
00290 if (it != mChildren.end())
00291 {
00292 (*it)->mParent = NULL;
00293 mChildren.erase(it);
00294 }
00295 }
00296
00298 void eraseChildren(int index, int count)
00299 {
00300 VL_CHECK( index + count <= (int)mChildren.size() );
00301
00302 for(int j=index; j<index+count; ++j)
00303 mChildren[j]->mParent = NULL;
00304
00305 for(int i=index+count, j=index; i<(int)mChildren.size(); ++i, ++j)
00306 mChildren[j] = mChildren[i];
00307
00308 mChildren.resize( mChildren.size() - count );
00309 }
00310
00312 void eraseAllChildren()
00313 {
00314 for(int i=0; i<(int)mChildren.size(); ++i)
00315 mChildren[i]->mParent = NULL;
00316 mChildren.clear();
00317 }
00318
00320 void eraseAllChildrenRecursive()
00321 {
00322 for(int i=0; i<(int)mChildren.size(); ++i)
00323 {
00324 mChildren[i]->eraseAllChildrenRecursive();
00325 mChildren[i]->mParent = NULL;
00326 }
00327 mChildren.clear();
00328 }
00329
00331 void shrink()
00332 {
00333 std::vector< ref<Ttype> > tmp (mChildren);
00334 mChildren.swap(tmp);
00335 }
00336
00338 void shrinkRecursive()
00339 {
00340 shrink();
00341 for(size_t i=0; i<mChildren.size(); ++i)
00342 mChildren[i]->shrinkRecursive();
00343 }
00344
00349 void reserveChildren(size_t count) { mChildren.reserve(count); }
00350
00351 protected:
00352 std::vector< ref<Ttype> > mChildren;
00353 TransformHierarchy* mParent;
00354 };
00355
00356
00357
00358
00383 class VLCORE_EXPORT Transform: public TransformHierarchy<Transform>
00384 {
00385 public:
00386 virtual const char* className() { return "vl::Transform"; }
00387
00389 Transform()
00390 {
00391 VL_DEBUG_SET_OBJECT_NAME()
00392 }
00393
00395 Transform(const mat4& matrix)
00396 {
00397 VL_DEBUG_SET_OBJECT_NAME()
00398 setLocalMatrix(matrix);
00399 setWorldMatrix(matrix);
00400 }
00401
00405 void setLocalAndWorldMatrix(const mat4& matrix)
00406 {
00407 mLocalMatrix = matrix;
00408 setWorldMatrix(matrix);
00409 }
00410
00413 void translate(Real x, Real y, Real z);
00414
00417 void translate(const vec3& t);
00418
00421 void scale(Real x, Real y, Real z);
00422
00425 void rotate(Real degrees, Real x, Real y, Real z);
00426
00429 void rotate(const vec3& from, const vec3& to);
00430 };
00431 }
00432
00433 #endif