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_ORIENTED3DRENDERERINTERFACE
00024 #define H_SPK_ORIENTED3DRENDERERINTERFACE
00025
00026 #include "Core/SPK_Vector3D.h"
00027 #include "Core/SPK_Group.h"
00028
00029
00030 #define PACK_ORIENTATION(lock,look,up) ((lock << 0x10)|(look << 0x8)|(up))
00031
00032 namespace SPK
00033 {
00042 enum LookOrientation
00043 {
00044 LOOK_CAMERA_PLANE,
00045 LOOK_CAMERA_POINT,
00046 LOOK_AXIS,
00047 LOOK_POINT,
00048 };
00049
00058 enum UpOrientation
00059 {
00060 UP_CAMERA,
00061 UP_DIRECTION,
00062 UP_AXIS,
00063 UP_POINT,
00064 };
00065
00073 enum LockedAxis
00074 {
00075 LOCK_LOOK,
00076 LOCK_UP,
00077 };
00078
00083 enum OrientationPreset
00084 {
00085 CAMERA_PLANE_ALIGNED = PACK_ORIENTATION(LOCK_LOOK,LOOK_CAMERA_PLANE,UP_CAMERA),
00086 CAMERA_POINT_ALIGNED = PACK_ORIENTATION(LOCK_LOOK,LOOK_CAMERA_POINT,UP_CAMERA),
00087 DIRECTION_ALIGNED = PACK_ORIENTATION(LOCK_UP,LOOK_CAMERA_PLANE,UP_DIRECTION),
00088 AROUND_AXIS = PACK_ORIENTATION(LOCK_UP,LOOK_CAMERA_POINT,LOOK_AXIS),
00089 TOWARDS_POINT = PACK_ORIENTATION(LOCK_LOOK,LOOK_POINT,UP_CAMERA),
00090 FIXED_ORIENTATION = PACK_ORIENTATION(LOCK_LOOK,LOOK_AXIS,UP_AXIS),
00091 };
00092
00093
00098 class SPK_PREFIX Oriented3DRendererInterface
00099 {
00100 public :
00101
00103
00105
00116 Vector3D lookVector;
00117
00128 Vector3D upVector;
00129
00131
00133
00135 Oriented3DRendererInterface();
00136
00138
00140
00142 virtual ~Oriented3DRendererInterface() {}
00143
00145
00147
00159 void setOrientation(LookOrientation lookOrientation,UpOrientation upOrientation,LockedAxis lockedAxis);
00160
00170 void setOrientation(OrientationPreset orientation);
00171
00173
00175
00180 LookOrientation getLookOrientation() const;
00181
00186 UpOrientation getUpOrientation() const;
00187
00192 LockedAxis getLockedAxis() const;
00193
00194 protected :
00195
00196
00197 LookOrientation lookOrientation;
00198 UpOrientation upOrientation;
00199 LockedAxis lockedAxis;
00200
00201 bool precomputeOrientation3D(const Group& group,const Vector3D& look,const Vector3D& up,const Vector3D& pos);
00202 void computeGlobalOrientation3D();
00203 void computeSingleOrientation3D(const Particle& particle);
00204
00205 void scaleQuadVectors(const Particle& particle,float scaleX,float scaleY) const;
00206 void rotateAndScaleQuadVectors(const Particle& particle,float scaleX,float scaleY) const;
00207
00208 const Vector3D& quadUp() const;
00209 const Vector3D& quadSide() const;
00210
00211 private :
00212
00213
00214 mutable Vector3D mVLook;
00215 mutable Vector3D mVUp;
00216 mutable Vector3D mVPos;
00217
00218
00219 mutable Vector3D globalLook;
00220 mutable Vector3D globalUp;
00221
00222
00223 mutable Vector3D up;
00224 mutable Vector3D side;
00225 mutable Vector3D look;
00226
00227
00228 mutable int quadRotated;
00229
00230
00231 mutable Vector3D sideQuad;
00232 mutable Vector3D upQuad;
00233 };
00234
00235
00236 inline LookOrientation Oriented3DRendererInterface::getLookOrientation() const
00237 {
00238 return lookOrientation;
00239 }
00240
00241 inline UpOrientation Oriented3DRendererInterface::getUpOrientation() const
00242 {
00243 return upOrientation;
00244 }
00245
00246 inline LockedAxis Oriented3DRendererInterface::getLockedAxis() const
00247 {
00248 return lockedAxis;
00249 }
00250
00251 inline const Vector3D& Oriented3DRendererInterface::quadUp() const
00252 {
00253 return upQuad;
00254 }
00255
00256 inline const Vector3D& Oriented3DRendererInterface::quadSide() const
00257 {
00258 return sideQuad;
00259 }
00260
00261 inline bool Oriented3DRendererInterface::precomputeOrientation3D(const Group& group,const Vector3D& modelViewLook,const Vector3D& modelViewUp,const Vector3D& modelViewPos)
00262 {
00263 mVLook = modelViewLook;
00264 mVUp = modelViewUp;
00265 mVPos = modelViewPos;
00266
00267 bool globalOrientation = true;
00268
00269 if (lookOrientation == LOOK_CAMERA_PLANE)
00270 globalLook = -mVLook;
00271 else if (lookOrientation == LOOK_AXIS)
00272 globalLook = lookVector;
00273 else
00274 globalOrientation = false;
00275
00276 if (upOrientation == UP_CAMERA)
00277 globalUp = mVUp;
00278 else if (upOrientation == UP_AXIS)
00279 globalUp = upVector;
00280 else globalOrientation = false;
00281
00282 quadRotated = group.getModel()->isEnabled(PARAM_ANGLE);
00283
00284 return globalOrientation;
00285 }
00286
00287 inline void Oriented3DRendererInterface::computeGlobalOrientation3D()
00288 {
00289 look = globalLook;
00290 up = globalUp;
00291
00292 crossProduct(up,look,side);
00293 if (lockedAxis == LOCK_LOOK)
00294 crossProduct(look,side,up);
00295 else if (quadRotated)
00296 {
00297 crossProduct(side,up,look);
00298 look.normalize();
00299 }
00300
00301 up.normalize();
00302 up *= 0.5f;
00303
00304 side.normalize();
00305 side *= 0.5f;
00306 }
00307
00308 inline void Oriented3DRendererInterface::computeSingleOrientation3D(const Particle& particle)
00309 {
00310 if (lookOrientation == LOOK_CAMERA_POINT)
00311 {
00312 look = mVPos;
00313 look -= particle.position();
00314 }
00315 else if (lookOrientation == LOOK_POINT)
00316 {
00317 look = lookVector;
00318 look -= particle.position();
00319 }
00320 else
00321 look = globalLook;
00322
00323 if (upOrientation == UP_DIRECTION)
00324 up = particle.velocity();
00325 else if (upOrientation == UP_POINT)
00326 {
00327 up = upVector;
00328 up -= particle.position();
00329 }
00330 else
00331 up = globalUp;
00332
00333 crossProduct(up,look,side);
00334 if (lockedAxis == LOCK_LOOK)
00335 crossProduct(look,side,up);
00336 else if (quadRotated)
00337 {
00338 crossProduct(side,up,look);
00339 look.normalize();
00340 }
00341
00342 side.normalize();
00343 side *= 0.5f;
00344
00345 up.normalize();
00346 up *= 0.5f;
00347 }
00348
00349 inline void Oriented3DRendererInterface::scaleQuadVectors(const Particle& particle,float scaleX,float scaleY) const
00350 {
00351 float size = particle.getParamCurrentValue(PARAM_SIZE);
00352
00353 sideQuad = side;
00354 sideQuad *= size * scaleX;
00355
00356 upQuad = up;
00357 upQuad *= size * scaleY;
00358 }
00359
00360 inline void Oriented3DRendererInterface::rotateAndScaleQuadVectors(const Particle& particle,float scaleX,float scaleY) const
00361 {
00362 float size = particle.getParamCurrentValue(PARAM_SIZE);
00363
00364 float angleTexture = particle.getParamCurrentValue(PARAM_ANGLE);
00365 float cosA = std::cos(angleTexture);
00366 float sinA = std::sin(angleTexture);
00367
00368 upQuad.x = (look.x * look.x + (1.0f - look.x * look.x) * cosA) * up.x
00369 + (look.x * look.y * (1.0f - cosA) - look.z * sinA) * up.y
00370 + (look.x * look.z * (1.0f - cosA) + look.y * sinA) * up.z;
00371
00372 upQuad.y = (look.x * look.y * (1.0f - cosA) + look.z * sinA) * up.x
00373 + (look.y * look.y + (1.0f - look.y * look.y) * cosA) * up.y
00374 + (look.y * look.z * (1.0f - cosA) - look.x * sinA) * up.z;
00375
00376 upQuad.z = (look.x * look.z * (1.0f - cosA) - look.y * sinA) * up.x
00377 + (look.y * look.z * (1.0f - cosA) + look.x * sinA) * up.y
00378 + (look.z * look.z + (1.0f - look.z * look.z) * cosA) * up.z;
00379
00380 crossProduct(upQuad,look,sideQuad);
00381
00382 sideQuad *= size * scaleX;
00383 upQuad *= size * scaleY;
00384 }
00385 }
00386
00387 #endif