Advertisement
Guest User

Untitled

a guest
Nov 11th, 2010
132
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.60 KB | None | 0 0
  1. //h
  2. #pragma once
  3.  
  4. #include "CDrawable.h"
  5.  
  6. class CameraAnimator : public ISceneNodeAnimator, CDrawable
  7. {
  8. public:
  9.    using CDrawable::CDrawable;
  10.  
  11.    CameraAnimator(ICameraSceneNode* cam);
  12.    ~CameraAnimator(void);
  13.  
  14.    virtual void animateNode(ISceneNode* node, u32 timeMs);
  15.    virtual ISceneNodeAnimator* createClone(ISceneNode* node, ISceneManager* newManager = 0);
  16.    virtual bool OnEvent(const SEvent& event);
  17.    virtual bool isEventReceiverEnabled() const { return true; }
  18.    virtual ESCENE_NODE_ANIMATOR_TYPE getType() const { return ESNAT_UNKNOWN; }
  19.    virtual bool hasFinished() const { return false; }
  20.  
  21.    static void ApplyForceAndTorqueCallback(const NewtonBody* body, dFloat timestep, int threadIndex);
  22.    static void SetTransformCallback(const NewtonBody* body, const dFloat* matrix, int threadIndex);
  23.  
  24.    void OnDraw();
  25.  
  26. protected:
  27.    core::map<EKEY_ACTION, bool> _pressed;
  28.    core::map<EKEY_CODE, EKEY_ACTION> _actions;
  29.  
  30.    u32 LastAnimationTime;
  31.    ICursorControl* _cursor;
  32.    ICameraSceneNode* _cam;
  33.    vector2df _cursorPos, _centerCursor;
  34.  
  35.    f32 _rotateSpeed, _mouseYDirection, _maxVerticalAngle, _moveSpeed, _jumpSpeed;
  36.  
  37.    NewtonBody* _body;
  38.    NewtonCollision* _collision;
  39. };
  40.  
  41.  
  42. //cpp
  43. #include "StdAfx.h"
  44. #include "CameraAnimator.h"
  45.  
  46.  
  47. CameraAnimator::CameraAnimator(ICameraSceneNode* cam) : LastAnimationTime(0), _maxVerticalAngle(88.0f),
  48.     _moveSpeed(0.01f), _rotateSpeed(50.0f), _jumpSpeed(1.0f),
  49.     _mouseYDirection(1.0f), _cam(cam)
  50. {
  51.     _cursor = device->getCursorControl();
  52.     _cursor->setVisible(false);
  53.  
  54.     _actions[KEY_KEY_W] = EKA_MOVE_FORWARD;
  55.     _actions[KEY_KEY_A] = EKA_STRAFE_LEFT;
  56.     _actions[KEY_KEY_S] = EKA_MOVE_BACKWARD;
  57.     _actions[KEY_KEY_D] = EKA_STRAFE_RIGHT;
  58.  
  59.     _pressed[EKA_MOVE_FORWARD] = false;
  60.     _pressed[EKA_MOVE_BACKWARD] = false;
  61.     _pressed[EKA_STRAFE_RIGHT] = false;
  62.     _pressed[EKA_STRAFE_LEFT] = false;
  63.  
  64.     _cursor->setPosition(0.5f, 0.5f);
  65.     _cursorPos = _centerCursor = _cursor->getRelativePosition();
  66.  
  67.     f32 bodyOffset[16] = {
  68.         1.0f, 0.0f, 0.0f, 0.0f,
  69.         0.0f, 1.0f, 0.0f, 0.0f,
  70.         0.0f, 0.0f, 1.0f, 0.0f,
  71.         0.0f, 0.0f, 0.0f, 1.0f
  72.     };
  73.  
  74.     _collision = NewtonCreateCapsule(world->phys, 1.0f, 2.0f, 0, bodyOffset);
  75.     _body = NewtonCreateBody(world->phys, _collision);
  76.     NewtonBodySetUserData(_body, this->_cam);
  77.  
  78.     vector3df rot = cam->getRotation();
  79.     vector3df pos = cam->getPosition() * IRRTONEWTON;
  80.  
  81.     matrix4 mx;
  82.     mx.setTranslation(pos);
  83.  
  84.     NewtonBodySetMatrix(_body, mx.pointer());
  85.     NewtonBodySetMassMatrix(_body, 1.0f, 1.0f, 1.0f, 1.0f);
  86.     NewtonBodySetForceAndTorqueCallback(_body, CameraAnimator::ApplyForceAndTorqueCallback);
  87.     NewtonBodySetTransformCallback(_body, CameraAnimator::SetTransformCallback);
  88. }
  89.  
  90.  
  91. CameraAnimator::~CameraAnimator(void)
  92. {
  93.     NewtonReleaseCollision(world->phys, _collision);
  94.     NewtonDestroyBody(world->phys, _body);
  95.     _cursor->drop();
  96. }
  97.  
  98. void CameraAnimator::animateNode( ISceneNode* node, u32 timeMs )
  99. {
  100.     if (!node || node->getType() != ESNT_CAMERA)
  101.         return;
  102.  
  103.     ICameraSceneNode* camera = static_cast<ICameraSceneNode*>(node);
  104.  
  105.     if (!LastAnimationTime && LastAnimationTime != timeMs)
  106.     {
  107.         camera->updateAbsolutePosition();
  108.         LastAnimationTime = timeMs;
  109.     }
  110.  
  111.     // If the camera isn't the active camera, and receiving input, then don't process it.
  112.     if(!camera->isInputReceiverEnabled())
  113.         return;
  114.  
  115.     try
  116.     {
  117.         if(camera->getSceneManager()->getActiveCamera() != camera)
  118.             return;
  119.     }
  120.     catch (SeException* e)
  121.     {
  122.         return;
  123.     }
  124.  
  125.     // get time
  126.     f32 timeDiff = (f32) ( timeMs - LastAnimationTime );
  127.     LastAnimationTime = timeMs;
  128.  
  129.     // update position
  130.     core::vector3df pos = camera->getPosition();
  131.  
  132.     // Update rotation
  133.     core::vector3df target = (camera->getTarget() - camera->getAbsolutePosition());
  134.     core::vector3df relativeRotation = target.getHorizontalAngle();
  135.  
  136.     if (_cursor)
  137.     {
  138.         _cursorPos = _cursor->getRelativePosition();
  139.         if (_cursorPos != _centerCursor)
  140.         {
  141.             relativeRotation.Y -= (0.5f - _cursorPos.X) * _rotateSpeed;
  142.             relativeRotation.X -= (0.5f - _cursorPos.Y) * _rotateSpeed * _mouseYDirection;
  143.  
  144.             // X < MaxVerticalAngle or X > 360-MaxVerticalAngle
  145.  
  146.             if (relativeRotation.X > _maxVerticalAngle * 2 && relativeRotation.X < 360.0f-_maxVerticalAngle)
  147.             {
  148.                 relativeRotation.X = 360.0f-_maxVerticalAngle;
  149.             }
  150.             else if (relativeRotation.X > _maxVerticalAngle && relativeRotation.X < 360.0f-_maxVerticalAngle)
  151.             {
  152.                 relativeRotation.X = _maxVerticalAngle;
  153.             }
  154.  
  155.             // Do the fix as normal, special case below
  156.             // reset cursor position to the centre of the window.
  157.             _cursor->setPosition(0.5f, 0.5f);
  158.             _centerCursor = _cursor->getRelativePosition();
  159.  
  160.             // needed to avoid problems when the event receiver is disabled
  161.             _cursorPos = _centerCursor;
  162.         }
  163.  
  164.         // Special case, mouse is whipped outside of window before it can update.
  165.         core::vector2d<u32> mousepos(u32(_cursor->getPosition().X), u32(_cursor->getPosition().Y));
  166.         core::rect<u32> screenRect(0, 0, driver->getScreenSize().Width, driver->getScreenSize().Height);
  167.  
  168.         // Only if we are moving outside quickly.
  169.         if(!screenRect.isPointInside(mousepos))
  170.         {
  171.             // Force a reset.
  172.             _cursor->setPosition(0.5f, 0.5f);
  173.             _centerCursor = _cursor->getRelativePosition();
  174.             _cursorPos = _centerCursor;
  175.         }
  176.     }
  177.  
  178.     // set target
  179.  
  180.     target.set(0,0, core::max_(1.f, pos.getLength()));
  181.     core::vector3df movedir = target;
  182.  
  183.     core::matrix4 mat;
  184.     mat.setRotationDegrees(core::vector3df(relativeRotation.X, relativeRotation.Y, 0));
  185.     mat.transformVect(target);
  186.  
  187. //  if (NoVerticalMovement)
  188. //  {
  189. //      mat.setRotationDegrees(core::vector3df(0, relativeRotation.Y, 0));
  190. //      mat.transformVect(movedir);
  191. //  }
  192. //  else
  193. //  {
  194.         movedir = target;
  195. //  }
  196.  
  197.     movedir.normalize();
  198.  
  199.     if (_pressed[EKA_MOVE_FORWARD])
  200.         pos += movedir * timeDiff * _moveSpeed;
  201.  
  202.     if (_pressed[EKA_MOVE_BACKWARD])
  203.         pos -= movedir * timeDiff * _moveSpeed;
  204.  
  205.     // strafing
  206.  
  207.     core::vector3df strafevect = target;
  208.     strafevect = strafevect.crossProduct(camera->getUpVector());
  209.  
  210. //  if (NoVerticalMovement)
  211. //      strafevect.Y = 0.0f;
  212.  
  213.     strafevect.normalize();
  214.  
  215.     if (_pressed[EKA_STRAFE_LEFT])
  216.         pos += strafevect * timeDiff * _moveSpeed;
  217.  
  218.     if (_pressed[EKA_STRAFE_RIGHT])
  219.         pos -= strafevect * timeDiff * _moveSpeed;
  220.  
  221.     // For jumping, we find the collision response animator attached to our camera
  222.     // and if it's not falling, we tell it to jump.
  223. //  if (CursorKeys[EKA_JUMP_UP])
  224. //  {
  225. //      const ISceneNodeAnimatorList& animators = camera->getAnimators();
  226. //      ISceneNodeAnimatorList::ConstIterator it = animators.begin();
  227. //      while(it != animators.end())
  228. //      {
  229. //          if(ESNAT_COLLISION_RESPONSE == (*it)->getType())
  230. //          {
  231. //              ISceneNodeAnimatorCollisionResponse * collisionResponse =
  232. //                  static_cast<ISceneNodeAnimatorCollisionResponse *>(*it);
  233. //
  234. //              if(!collisionResponse->isFalling())
  235. //                  collisionResponse->jump(JumpSpeed);
  236. //          }
  237. //
  238. //          it++;
  239. //      }
  240. //  }
  241.  
  242.     // write translation
  243.     camera->setPosition(pos);
  244.  
  245.     // write right target
  246.     target += pos;
  247.     camera->setTarget(target);
  248.  
  249. }
  250.  
  251. ISceneNodeAnimator* CameraAnimator::createClone( ISceneNode* node, ISceneManager* newManager /*= 0*/ )
  252. {
  253.     ISceneNodeAnimator* clone = new CameraAnimator(_cam);
  254.     return clone;
  255. }
  256.  
  257. bool CameraAnimator::OnEvent( const SEvent& event )
  258. {
  259.     switch(event.EventType)
  260.     {
  261.     case EET_MOUSE_INPUT_EVENT:
  262.         break;
  263.     case EET_KEY_INPUT_EVENT:
  264.        
  265.         map<EKEY_CODE, EKEY_ACTION>::Node* action = _actions.find(event.KeyInput.Key);
  266.         if(action)
  267.             _pressed[action->getValue()] = event.KeyInput.PressedDown;
  268.         break;
  269.     }
  270.  
  271.     return true;
  272. }
  273.  
  274. void CameraAnimator::ApplyForceAndTorqueCallback( const NewtonBody* body, dFloat timestep, int threadIndex )
  275. {
  276.     dFloat Ixx, Iyy, Izz;
  277.     dFloat mass;
  278.  
  279.     NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz);
  280.  
  281.     dVector gravityForce(0.0f, mass * -0.5f, 0.0f, 1.0f);
  282.     NewtonBodySetForce(body, &gravityForce[0]);
  283. }
  284.  
  285. void CameraAnimator::SetTransformCallback( const NewtonBody* body, const dFloat* matrix, int threadIndex )
  286. {
  287.     ISceneNode* node = (ISceneNode*) NewtonBodyGetUserData(body);
  288.  
  289.     if (node)
  290.     {
  291.         matrix4 transform;
  292.         transform.setM(matrix);
  293.  
  294.         node->setPosition(transform.getTranslation() * NEWTONTOIRR);
  295.         node->setRotation(transform.getRotationDegrees());
  296.     }
  297. }
  298.  
  299. void _cdecl NewtonDebugCollision(void* body, int vertexCount, const float* faceVertec, int faceId)
  300. {
  301.     s32 i = vertexCount - 1;
  302.  
  303.     core::vector3df p0 (faceVertec[i * 3 + 0] * NEWTONTOIRR, faceVertec[i * 3 + 1] * NEWTONTOIRR, faceVertec[i * 3 + 2] * NEWTONTOIRR);
  304.  
  305.     SColor color(255, 55, 255, 0);
  306.  
  307.     for (i = 0; i < vertexCount; i++)
  308.     {
  309.         core::vector3df p1 (faceVertec[i * 3 + 0] * NEWTONTOIRR, faceVertec[i * 3 + 1] * NEWTONTOIRR, faceVertec[i * 3 + 2] * NEWTONTOIRR);
  310.         driver->draw3DLine (p0, p1, color);
  311.         p0 = p1;
  312.     }
  313. }
  314.  
  315. void CameraAnimator::OnDraw()
  316. {
  317.     // phys debug
  318.     matrix4 matx;
  319.     NewtonBodyGetMatrix(_body, &matx[0]);
  320.     NewtonCollisionForEachPolygonDo(_collision, &matx[0], NewtonDebugCollision, 0);
  321.     /////////////
  322. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement