00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00021
00022
00023 #ifndef H_SPK_TRANSFORMABLE
00024 #define H_SPK_TRANSFORMABLE
00025
00026 #include "Core/SPK_Vector3D.h"
00027
00028
00029 namespace SPK
00030 {
00031 class Zone;
00032
00033
00056 class SPK_PREFIX Transformable
00057 {
00058 public :
00059
00061
00063
00065 static const size_t TRANSFORM_LENGTH = 16;
00066
00068 static const float IDENTITY[TRANSFORM_LENGTH];
00069
00071
00073
00075 Transformable();
00076
00077 Transformable(const Transformable& transformable);
00078
00080
00082
00084 virtual ~Transformable() {}
00085
00087
00089
00103 void setTransform(const float* transform);
00104
00117 void setTransformNC(const float* transform);
00118
00130 void setTransformPosition(const Vector3D& pos);
00131
00144 void setTransformOrientationRH(Vector3D look,Vector3D up);
00145
00158 void setTransformOrientationLH(Vector3D look,Vector3D up);
00159
00173 void setTransformOrientation(Vector3D axis,float angle);
00174
00187 void setTransformOrientationX(float angle);
00188
00201 void setTransformOrientationY(float angle);
00202
00215 void setTransformOrientationZ(float angle);
00216
00218
00220
00225 const float* getLocalTransform() const;
00226
00231 const float* getWorldTransform() const;
00232
00237 bool isLocalIdentity() const;
00238
00244 Vector3D getLocalTransformPos() const;
00245
00251 Vector3D getLocalTransformSide() const;
00252
00258 Vector3D getLocalTransformUp() const;
00259
00265 Vector3D getLocalTransformLookRH() const;
00266
00272 Vector3D getLocalTransformLookLH() const;
00273
00279 Vector3D getWorldTransformPos() const;
00280
00286 Vector3D getWorldTransformSide() const;
00287
00293 Vector3D getWorldTransformUp() const;
00294
00300 Vector3D getWorldTransformLookRH() const;
00301
00307 Vector3D getWorldTransformLookLH() const;
00308
00310
00312
00326 void lookAtRH(const Vector3D& target,Vector3D up,const Vector3D& pos);
00327
00341 void lookAtLH(const Vector3D& target,Vector3D up,const Vector3D& pos);
00342
00353 void updateTransform(const Transformable* parent = NULL);
00354
00356 void resetTransform();
00357
00358 protected :
00359
00365 void transformPos(Vector3D& tPos,const Vector3D& pos);
00366
00372 void transformDir(Vector3D& tDir,const Vector3D& dir);
00373
00378 bool isUpdateNotified() const;
00379
00385 void notifyForUpdate();
00386
00391 const Transformable* getParentTransform() const;
00392
00399 virtual void innerUpdateTransform() {}
00400
00409 virtual void propagateUpdateTransform() {}
00410
00411 private :
00412
00413 float local[TRANSFORM_LENGTH];
00414 float world[TRANSFORM_LENGTH];
00415
00416 unsigned long int currentUpdate;
00417 unsigned long int lastUpdate;
00418 unsigned long int lastParentUpdate;
00419 bool localIdentity;
00420
00421 const Transformable* parent;
00422
00423 static void multiply(
00424 float* dest,
00425 const float* src0,
00426 const float* src1);
00427
00428 static void multiply(
00429 Vector3D& dest,
00430 const Vector3D& v,
00431 const float* m);
00432
00433 static void rotate(
00434 Vector3D& dest,
00435 const Vector3D& v,
00436 const float* m);
00437 };
00438
00439
00440 inline void Transformable::setTransform(const float* transform)
00441 {
00442 std::memcpy(local,transform,sizeof(float) * TRANSFORM_LENGTH);
00443 localIdentity = false;
00444 notifyForUpdate();
00445 }
00446
00447 inline const float* Transformable::getLocalTransform() const
00448 {
00449 return local;
00450 }
00451
00452 inline const float* Transformable::getWorldTransform() const
00453 {
00454 return world;
00455 }
00456
00457 inline bool Transformable::isLocalIdentity() const
00458 {
00459 return localIdentity;
00460 }
00461
00462 inline Vector3D Transformable::getLocalTransformPos() const
00463 {
00464 return Vector3D(local[12],local[13],local[14]);
00465 }
00466
00467 inline Vector3D Transformable::getLocalTransformSide() const
00468 {
00469 return Vector3D(local[0],local[1],local[2]);
00470 }
00471
00472 inline Vector3D Transformable::getLocalTransformUp() const
00473 {
00474 return Vector3D(local[4],local[5],local[6]);
00475 }
00476
00477 inline Vector3D Transformable::getLocalTransformLookRH() const
00478 {
00479 return Vector3D(-local[8],-local[9],-local[10]);
00480 }
00481
00482 inline Vector3D Transformable::getLocalTransformLookLH() const
00483 {
00484 return Vector3D(local[8],local[9],local[10]);
00485 }
00486
00487 inline Vector3D Transformable::getWorldTransformPos() const
00488 {
00489 return Vector3D(world[12],world[13],world[14]);
00490 }
00491
00492 inline Vector3D Transformable::getWorldTransformSide() const
00493 {
00494 return Vector3D(world[0],world[1],world[2]);
00495 }
00496
00497 inline Vector3D Transformable::getWorldTransformUp() const
00498 {
00499 return Vector3D(world[4],world[5],world[6]);
00500 }
00501
00502 inline Vector3D Transformable::getWorldTransformLookRH() const
00503 {
00504 return Vector3D(-world[8],-world[9],-world[10]);
00505 }
00506
00507 inline Vector3D Transformable::getWorldTransformLookLH() const
00508 {
00509 return Vector3D(world[8],world[9],world[10]);
00510 }
00511
00512 inline void Transformable::lookAtRH(const Vector3D& target,Vector3D up,const Vector3D& pos)
00513 {
00514 setTransformOrientationRH(target - pos,up);
00515 setTransformPosition(pos);
00516 }
00517
00518 inline void Transformable::lookAtLH(const Vector3D& target,Vector3D up,const Vector3D& pos)
00519 {
00520 setTransformOrientationLH(target - pos,up);
00521 setTransformPosition(pos);
00522 }
00523
00524 inline void Transformable::resetTransform()
00525 {
00526 setTransform(IDENTITY);
00527 localIdentity = true;
00528 }
00529
00530 inline bool Transformable::isUpdateNotified() const
00531 {
00532 return lastUpdate != currentUpdate;
00533 }
00534
00535 inline void Transformable::notifyForUpdate()
00536 {
00537 ++currentUpdate;
00538 }
00539
00540 inline const Transformable* Transformable::getParentTransform() const
00541 {
00542 return parent;
00543 }
00544
00545 inline void Transformable::multiply(
00546 float* dest,
00547 const float* src0,
00548 const float* src1)
00549 {
00550
00551
00552 for (size_t i = 0; i < 4; ++i)
00553 {
00554 for (size_t j = 0; j < 4; ++j)
00555 {
00556 dest[(i << 2) + j] = 0.0f;
00557 for (size_t k = 0; k < 4; ++k)
00558 dest[(i << 2) + j] += src0[(k << 2) + j] * src1[(i << 2) + k];
00559
00560 }
00561
00562 }
00563 }
00564
00565 inline void Transformable::multiply(
00566 Vector3D& dest,
00567 const Vector3D& v,
00568 const float* m)
00569 {
00570
00571
00572 dest.x = v.x * m[0] + v.y * m[4] + v.z * m[8] + m[12];
00573 dest.y = v.x * m[1] + v.y * m[5] + v.z * m[9] + m[13];
00574 dest.z = v.x * m[2] + v.y * m[6] + v.z * m[10] + m[14];
00575 }
00576
00577 inline void Transformable::rotate(
00578 Vector3D& dest,
00579 const Vector3D& v,
00580 const float* m)
00581 {
00582
00583
00584 dest.x = v.x * m[0] + v.y * m[4] + v.z * m[8];
00585 dest.y = v.x * m[1] + v.y * m[5] + v.z * m[9];
00586 dest.z = v.x * m[2] + v.y * m[6] + v.z * m[10];
00587 }
00588 }
00589
00590 #endif