How can I communicate with my camera animator?

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
gloin92
Posts: 11
Joined: Fri Jan 24, 2014 5:06 pm

How can I communicate with my camera animator?

Post by gloin92 »

Hi,

I wrote a custom scene node animator for my camera for my strategy game. It can do standard stuff like translate through the WASD keys and zoom in and out. Now I would like to have a possibility to communicate with the camera through the class in which it is created (in this case main). For example I would like to be able to lock movement or set a destination for the camera to travel to. How would I do that?

Or should I drop the animator and instead let the main handle the movements?

Here is how I set up my camera:

Code: Select all

scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0, core::vector3df(768, 500, 768), core::vector3df(0, 0, 0));
camera->setFarValue(2000);
 
if (camera)
{
    SceneNodeAnimatorCameraCampaign* anim = new SceneNodeAnimatorCameraCampaign();
    camera->addAnimator(anim);
    anim->drop();
}
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: How can I communicate with my camera animator?

Post by pandoragami »

gloin92 wrote:Hi,

I wrote a custom scene node animator for my camera for my strategy game. It can do standard stuff like translate through the WASD keys and zoom in and out. Now I would like to have a possibility to communicate with the camera through the class in which it is created (in this case main). For example I would like to be able to lock movement or set a destination for the camera to travel to. How would I do that?

Or should I drop the animator and instead let the main handle the movements?

Here is how I set up my camera:

Code: Select all

scene::ICameraSceneNode* camera = smgr->addCameraSceneNode(0, core::vector3df(768, 500, 768), core::vector3df(0, 0, 0));
camera->setFarValue(2000);
 
if (camera)
{
    SceneNodeAnimatorCameraCampaign* anim = new SceneNodeAnimatorCameraCampaign();
    camera->addAnimator(anim);
    anim->drop();
}

Not sure what level of C++ you have but you can easily pass the camera object you created into some other class e.g. for your custom scene node.

Code: Select all

 
class CAMERA
{
  scene::ICameraSceneNode* camera;
  
  CAMERA(scene::ICameraSceneNode* camera)
  {
    this->camera = camera;
  }
  ~CAMERA(){}
  void handle_animation()
  {
    //you would use this method to do whatever animation you'd like.... or move camera using WASD
  }  
 
};
 
But this would just be an extra layer on top of the camera class in Irrlicht which already has its methods.

http://irrlicht.sourceforge.net/docu/cl ... _node.html

You could inherit from the irrlicht camera class and create your own methods as another way. But you might need virtuals if you override the original class methods and that could get ugly for a beginner.
gloin92
Posts: 11
Joined: Fri Jan 24, 2014 5:06 pm

Re: How can I communicate with my camera animator?

Post by gloin92 »

Thanks for your reply. That would work but it would make the animator obsolete. What I'd like to have is all code in one place which I thought would be the animator.

I think I thought about animators the wrong way. Maybe I could make several animators for different modes. One for player control and one for things like automatically traveling to a point etc. It would look like that:

Start with a player controlled camera

Code: Select all

SceneNodeAnimatorCameraPlayer* anim = new SceneNodeAnimatorCameraPlayer();
camera->addAnimator(anim);
anim->drop();
Drop the old animator when I need the camera to travel somewhere and add the travel animator with the destination as parameter

Code: Select all

camera->removeAnimators();
SceneNodeAnimatorCameraTravel* anim = new SceneNodeAnimatorCameraTravel(core::vector3df(200, 200, 200));
camera->addAnimator(anim);
anim->drop();
After the camera travelled to the destination give control to the player again

Code: Select all

if(camera->getAnimators().begin->hasFinished()){
    camera->removeAnimators();
    SceneNodeAnimatorCameraPlayer* anim = new SceneNodeAnimatorCameraPlayer();
    camera->addAnimator(anim);
    anim->drop();
}
Would something like that be a good solution or did I get the concept wrong?
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: How can I communicate with my camera animator?

Post by pandoragami »

Your idea makes sense, but you could also wrap those constructors within that CAMERA class I showed earlier.

Code: Select all

 
 
class CAMERA
{
  private:
 
  scene::ICameraSceneNode* camera;
  SceneNodeAnimatorCameraTravel* anim;
  
  public:
 
  CAMERA(scene::ICameraSceneNode* camera)
  {
    this->camera = camera;
  }
  ~CAMERA(){}
  void handle_player_animation()
  {
    //you would use this method to do whatever animation you'd like.... or move camera using WASD
    anim = new SceneNodeAnimatorCameraPlayer();
    camera->addAnimator(anim);
    anim->drop();
  }  
  void exchange_camera()
  {
       camera->removeAnimators();
       anim = new SceneNodeAnimatorCameraTravel(core::vector3df(200, 200, 200));
       camera->addAnimator(anim);
       anim->drop();
  }
  void  give_camera_to_player()
  {
         if(camera->getAnimators().begin->hasFinished())
         {
                camera->removeAnimators();
                anim = new SceneNodeAnimatorCameraPlayer();
                camera->addAnimator(anim);
                anim->drop();
        }
    }
};
 
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: How can I communicate with my camera animator?

Post by pandoragami »

I'm just a bit unsure what these classes would look like

Code: Select all

 
 SceneNodeAnimatorCameraPlayer
SceneNodeAnimatorCameraTravel
SceneNodeAnimatorCameraPlayer
 
I guess you could just create a single CAMERA object that contains two animators, one for the camera and another for the player instead? And just switch between the two within the CAMERA class.
gloin92
Posts: 11
Joined: Fri Jan 24, 2014 5:06 pm

Re: How can I communicate with my camera animator?

Post by gloin92 »

Yes, that sounds like a good idea. I'll try it out. Still not sure if ISceneNodeAnimators are supposed to be used like that but it should work.

I already wrote the animators. SceneNodeAnimatorCameraTravel just lets the camera fly to the destination in the animateNode function which it has to override. SceneNodeAnimatorCameraPlayer receives the input in the OnEvent function and then adjusts the camera accordingly in the animateNode function.
pandoragami
Posts: 226
Joined: Wed Jan 26, 2011 5:37 pm
Contact:

Re: How can I communicate with my camera animator?

Post by pandoragami »

gloin92 wrote:Yes, that sounds like a good idea. I'll try it out. Still not sure if ISceneNodeAnimators are supposed to be used like that but it should work.
You mean wrapping the ISceneNodeAnimators inside a class, there's nothing wrong with doing this, my syntax may be wrong but generally this is a way to wrap functionality into a class where similar objects are used to make code more organized. I would guess this is the facade design pattern.

Code: Select all

    class CAMERA
    {
      private:
     
      scene::ICameraSceneNode* camera;
      ISceneNodeAnimators* player_anim;
      ISceneNodeAnimators* camera_anim;
     
      public:
     
      CAMERA(scene::ICameraSceneNode* camera)
      {
        this->camera = camera;
        this->player_anim = new ISceneNodeAnimators();//not sure what the parameters are for the animation constructor
        this->camera_anim = new ISceneNodeAnimators();
      }
      ~CAMERA(){}    //may need to drop animators here
    };
     
gloin92
Posts: 11
Joined: Fri Jan 24, 2014 5:06 pm

Re: How can I communicate with my camera animator?

Post by gloin92 »

I did it similarly to what you said now. I created a class CampaignCamera in which I have my camera and different methods which change the animator.

Code: Select all

#include "CampaignCamera.h"
 
CampaignCamera::CampaignCamera(scene::ICameraSceneNode* camera, float farValue)
{   
    camera->setFarValue(farValue);
    this->camera = camera;    
}
 
void CampaignCamera::givePlayerControl(){
    camera->removeAnimators();
    SceneNodeAnimatorCameraPlayer* anim = new SceneNodeAnimatorCameraPlayer();
    camera->addAnimator(anim);
    anim->drop();
}
 
void CampaignCamera::travel(core::vector3df destination){
    camera->removeAnimators();
    SceneNodeAnimatorCameraTravel* anim = new SceneNodeAnimatorCameraTravel(destination);
    camera->addAnimator(anim);
    anim->drop();   
}
I can now initialize my camera like this

Code: Select all

CampaignCamera* campaignCamera = new CampaignCamera(smgr->addCameraSceneNode(0, core::vector3df(1000, 500, 1000), core::vector3df()), 2000);
and give give control to the player

Code: Select all

campaignCamera->givePlayerControl();
or set a destination point to travel to.

Code: Select all

campaignCamera->travel(core::vector3df(1500, 500, 1500));
It works fine for now. Maybe I'll add more functionality like queueing animators if I need to.
Post Reply