Page 1 of 1

Standing up and bending down in the map

Posted: Mon Aug 29, 2005 5:27 pm
by Didine
Since 2 days, i'm trying to bend down an FPS camera (the player is crouching) when the CTRL key is pressed. And when the key is release, the player stands up. But my program craches at the line where i wrote "// PROBLEM"
Compilation is ok.
This is the latest version :

Code: Select all

IVideoDriver* driver;                      //pointer to the driver
ISceneManager* smgr;                       //pointer to the scenemanager
ICameraSceneNode* camera;                  //camera
ISceneNode* node;                          //dummy node
ISceneNodeAnimator* anim;
ITriangleSelector* selector;	

bool finProg = false;                      //ending the program with the ESC key

void changeCamera(vector3df vCoord)
{
    //modify the view height of the player 
    smgr->createCollisionResponseAnimator(
                  selector, camera, vCoord, // vCoord<30, Height, 30>
                  vector3df(0,-3,0), 
                  vector3df(0,50,0 ));
    camera->addAnimator(anim);
    anim->drop();
}

class MyEventReceiver : public IEventReceiver
{
public:
	virtual bool OnEvent(SEvent event)
	{
    if(event.EventType == EET_KEY_INPUT_EVENT && !event.KeyInput.PressedDown){     
          switch(event.KeyInput.Key){     
            case KEY_ESCAPE:{
                             return finProg = true; 
                             } break;
          } 
     }

    if(event.EventType == EET_KEY_INPUT_EVENT && event.KeyInput.PressedDown){     
          switch(event.KeyInput.Key){     
            case KEY_CONTROL :{    // crouch
                    changeCamera(vector3df(30,50,30));
                             } break;                             
          } 
        }
return false;
	}
};

int main()
{
// (...)
   changeCamera(vector3df(30,90,30));  // PROBLEM !

   while(device->run() && driver && !finProg)
   {
     if (device->isWindowActive())
        {                       
        driver->beginScene(true, true, SColor(0,160,200,255));
        smgr->drawAll();
        env->drawAll();
        driver->endScene();
        }
   }
   device->drop();
   return 0;
}
Someone can help me or have an other solution to do that ?

Posted: Mon Aug 29, 2005 8:59 pm
by evo
The program probably crashes when you try to add a second createCollisionResponseAnimator.
You can change the position of the camera directly. Use this in your MyEventReceiver class:

Code: Select all

camera->setPosition(core::vector3df(30,50,30));
I assume you only want to change the 'height' of the camera position.

Posted: Tue Aug 30, 2005 3:00 am
by bitplane

Code: Select all

    //modify the view height of the player
    smgr->createCollisionResponseAnimator(
should be

Code: Select all

    //drop the animator
    camera->removeAnimators();
    //modify the view height of the player
    anim = smgr->createCollisionResponseAnimator(

Posted: Tue Aug 30, 2005 7:02 am
by Didine
Sorry Bitplane et evo, none of the solutions work :cry:
By adding

Code: Select all

//drop the animator
    camera->removeAnimators(); 
the program always crashes

And modifying the position of the camera doesn't work in the vertical axe because createCollisionResponseAnimator manage the gravity and the distance from the ground.
An other idea ? :idea:

Posted: Tue Aug 30, 2005 10:32 am
by evo
You are right. My mistake. :oops: You need to use the setEllipsoidRadius and the setEllipsoidTranslation method instead.

I am pretty sure that crash is caused by reusing 'anim' to create another collisionresponseanimator. Test it by removing the calls to 'changeCamera'.

Posted: Tue Aug 30, 2005 1:18 pm
by bitplane
like evo said, the program crashes when you try to add the animator. this is because "anim == NULL" ... you didn't set it equal to anything!
a crude but effective debugging method: put printf's around the code in question, then "read the tape" when it crashes like so-

Code: Select all

    //drop the animator
    camera->removeAnimators();
    printf("it didn't crash when we remove all animators\n"); 
    //modify the view height of the player
    smgr->createCollisionResponseAnimator(
                  selector, camera, vCoord, // vCoord<30, Height, 30>
                  vector3df(0,-3,0),
                  vector3df(0,50,0 ));
    printf("it didn't crash when we create the animator\n");
    camera->addAnimator(anim); 
    printf("it never gets this far because we're adding an empty animator\n");
    anim->drop();
    printf("or here because we can't drop an empty animator\n");
like i said, you're missing anim =

Posted: Tue Aug 30, 2005 2:02 pm
by Didine
We are making progress ! I rewrote the changeCamera function.

Code: Select all

void changeCamera(ISceneNodeAnimatorCollisionResponse* anim, vector3df vCoord)
{
   //drop the animator
   //camera->removeAnimators();
   anim->setEllipsoidRadius(vCoord);
   //anim->drop();
}
and in main() :

Code: Select all

  ISceneNodeAnimatorCollisionResponse* anim = smgr->createCollisionResponseAnimator(
                  selector, camera, vector3df(30,90,30), // <30, Height, 30>
                  vector3df(0,-3,0), 
                  vector3df(0,50,0 ));
 
   camera->addAnimator(anim);
   changeCamera(anim, vector3df(30,100,30));
   changeCamera(anim, vector3df(30,50,30)); //just for testing twice the function, it works now.
I replaced ISceneNodeAnimator** by ISceneNodeAnimatorCollisionResponse*. But the program always crashes in the key event section when changeCamera is called. I don't know if there is the same problem but when I add device->getCursorControl()->setVisible(false);, the program also crashes.

:x

Have an other idea ?

Posted: Tue Aug 30, 2005 5:42 pm
by bitplane
very messy... giving everything the same name is bound to cause confusion.
now you have 3 variables all called "anim":
a global variable, a local variable inside main, and a local parameter of changeCamera.
inside main: you make a new local variable, set it, then pass it as changeCamera's parameter (no crash)
inside eventreciever: you pass the global variable (which is empty) to changeCamera - causing a crash.

my guess is you're doing the same thing for the driver.

this code might help you understand:

Code: Select all

int a;
int b;

int f()
{
  printf("function: a plus b is %d\n",a+b); // global_a + global_b
}

int main()
{
  int a = 3;  // this makes a new local variable
  b = 2;  // this sets the already existing variable
  printf("main: a plus b is %d\n",a+b); // local_a + global_b
  f();
  std::system("pause");
}

Posted: Tue Aug 30, 2005 5:48 pm
by bitplane
edit: double double post post

you're welcome :)

Posted: Wed Aug 31, 2005 6:46 am
by Didine
bitplane, you are the best ! Thank you for your programm example. Now, it works when I remove the type of anim in main function :

Code: Select all

   anim = smgr->createCollisionResponseAnimator(...
and not

Code: Select all

ISceneNodeAnimatorCollisionResponse* anim = smgr->createCollisionResponseAnimator(...
My mistake : I declared twice the anim variable.
:D