Page 1 of 1

Need help (camera)

Posted: Sun Jun 06, 2010 8:14 am
by full_newbie
Hello my camera incorect work, please help me.
This code:
main.cpp:

Code: Select all

#include <irrlicht.h>
#include "cam/3DP.h"
//#include "terrain/ShTlTerrainSceneNode.h"
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;

enum {UP, PRESSED, DOWN, RELEASED};
int keyState[KEY_KEY_CODES_COUNT] = {0};
bool paused = false;
bool quitGame = false;
IrrlichtDevice  *Device=createDevice(EDT_OPENGL, dimension2d<u32>(1024, 768), 32, true, false, false, 0);
IVideoDriver    *Driver=Device->getVideoDriver();
ISceneManager   *SceneManager=Device->getSceneManager();
IGUIEnvironment *Gui=Device->getGUIEnvironment();
scene::IAnimatedMeshSceneNode* playerNode = NULL;
scene::EMD2_ANIMATION_TYPE playerAnim;
void resetKeys() {

	for (int i = 0 ; i < KEY_KEY_CODES_COUNT ; ++i)
		keyState[i] = UP;

}
void updateKeys() {

	for(int i = 0 ; i < KEY_KEY_CODES_COUNT ; ++i)
		if (keyState[i] == RELEASED)
			keyState[i] = UP;
		else if (keyState[i] == PRESSED)
			keyState[i] = DOWN;

}
class MyEventReceiver : public IEventReceiver {

	public:
		virtual bool OnEvent(const SEvent& event) {

			if (event.EventType == EET_KEY_INPUT_EVENT) {

				// update keyStates
				if (event.KeyInput.PressedDown) {
					// If key was not down before
					if (keyState[event.KeyInput.Key] != DOWN)
						keyState[event.KeyInput.Key] = PRESSED; // Set to Pressed
					else
						// if key was down before
						keyState[event.KeyInput.Key] = DOWN; // Set to Down
				} else {
					// if the key is down
					if (keyState[event.KeyInput.Key] != UP)
						keyState[event.KeyInput.Key] = RELEASED; // Set to Released
				}

				switch(event.KeyInput.Key) {
					case KEY_ESCAPE: {
						if (!event.KeyInput.PressedDown) {
							quitGame = true;
							return true;
						}
						break;
					}

					case KEY_KEY_P: {
						if (!event.KeyInput.PressedDown) {
							// Pause the scene
							paused = !paused;
//							if (pausedText) pausedText->setVisible(paused);
							if (Device)
								if (paused) // Freezes animators
									Device->getTimer()->setSpeed(0);
								else // Unfreezes animators
									Device->getTimer()->setSpeed(1);
							return true;
						}
						break;
					}

				}
			}

			return false;

		}

};

void processKeys(int elapsedTime) {

	bool turning = false;
	bool walking = false;

	if (keyState[KEY_KEY_W] == PRESSED || keyState[KEY_KEY_W] == DOWN) {
		// Move forward
		core::vector3df move = core::vector3df(5,0,0);
		core::matrix4 mat;
		mat.setRotationDegrees(playerNode->getRotation());
		mat.transformVect(move);
		move *= 0.1f * elapsedTime;
		playerNode->setPosition(playerNode->getPosition() + move);
		if (playerAnim != scene::EMAT_RUN) {
			playerNode->setMD2Animation(scene::EMAT_RUN);
			playerAnim = scene::EMAT_RUN;
		}
		walking = true;
	}

	if(keyState[KEY_KEY_S] == PRESSED || keyState[KEY_KEY_S] == DOWN) {
		// Move backward
		core::vector3df move = core::vector3df(5,0,0);
		core::matrix4 mat;
		mat.setRotationDegrees(playerNode->getRotation());
		mat.transformVect(move);
		move *= 0.1f * elapsedTime;
		playerNode->setPosition(playerNode->getPosition() - move);
		if (playerAnim != scene::EMAT_RUN) {
			playerNode->setMD2Animation(scene::EMAT_RUN);
			playerAnim = scene::EMAT_RUN;
		}
		walking = true;
	}

	if(keyState[KEY_KEY_A] == PRESSED || keyState[KEY_KEY_A] == DOWN) {
		// Turn left
		core::vector3df rot = core::vector3df(0,10,0) * 0.1f * (f32)elapsedTime;
		playerNode->setRotation(playerNode->getRotation() - rot);
		if (!walking && playerAnim != scene::EMAT_STAND) {
			playerNode->setMD2Animation(scene::EMAT_STAND);
			playerAnim = scene::EMAT_STAND;
		}
		turning = true;
	}

	if(keyState[KEY_KEY_D] == PRESSED || keyState[KEY_KEY_D] == DOWN) {
		// Turn right
		core::vector3df rot = core::vector3df(0,10,0) * 0.1f * (f32)elapsedTime;
		playerNode->setRotation(playerNode->getRotation() + rot);
		if (!walking && playerAnim != scene::EMAT_STAND) {
			playerNode->setMD2Animation(scene::EMAT_STAND);
			playerAnim = scene::EMAT_STAND;
		}
		turning = true;
	}

	if (!walking && !turning && playerAnim != scene::EMAT_STAND) {
		// Stand still
		playerNode->setMD2Animation(scene::EMAT_STAND);
		playerAnim = scene::EMAT_STAND;
	}

}
int main(int argc, char** argv)
{
MyEventReceiver receiver;
Device->setEventReceiver(&receiver);
//ShTlTerrainSceneNode* terrain;
 scene::IAnimatedMesh* mesh = SceneManager->getMesh("data/avatar/sydney.md2");
	if (!mesh) printf("couldn't load player mesh\n");
	playerNode = SceneManager->addAnimatedMeshSceneNode(mesh);
	if (!playerNode) printf("couldn't create player node\n");
	playerNode->setMaterialFlag(video::EMF_LIGHTING, false);
	playerNode->setMD2Animation(scene::EMAT_STAND);
	playerAnim = scene::EMAT_STAND;
	playerNode->setMaterialTexture(0, Driver->getTexture("data/avatar/sydney.jpg"));
	playerNode->OnAnimate(0);
	playerNode->setPosition(vector3df(-1200,-50,-1400));
	core::aabbox3d<f32> box = playerNode->getTransformedBoundingBox();
	playerNode->setPosition(box.MaxEdge - box.getCenter());
	scene::ICameraSceneNode* camera = SceneManager->addCameraSceneNode(playerNode);
	if (!camera) printf("Failed camera creation\n");
	camera->setPosition(((box.MaxEdge - box.getCenter())*2.0f)+core::vector3df(-100,25,0));
	camera->setTarget(playerNode->getPosition());
	float Distanciaance3= 30;
	CScene3PCamera *camAnim = new CScene3PCamera(SceneManager,Device->getCursorControl(),
    playerNode,Distanciaance3,-90,-30,false,irr::core::vector3df(0,0,0),10);
    camera->addAnimator(camAnim);

    scene::ITerrainSceneNode* terrain = SceneManager->addTerrainSceneNode(
		"data/world/111.bmp",
		0,					// parent node
		-1,					// node id
		core::vector3df(0.f, 0.f, 0.f),		// position
		core::vector3df(0.f, 0.f, 0.f),		// rotation
		core::vector3df(40.f, 4.4f, 40.f),	// scale
		video::SColor ( 255, 255, 255, 255 ),	// vertexColor
		5,					// maxLOD
		scene::ETPS_17,				// patchSize
		4					// smoothFactor
		);

	terrain->setMaterialFlag(video::EMF_LIGHTING, false);

	terrain->setMaterialTexture(0,
			Driver->getTexture("data/world/terrain-texture.jpg"));
	terrain->setMaterialTexture(1,
			Driver->getTexture("data/world/detail_grass.jpg"));

	terrain->setMaterialType(video::EMT_DETAIL_MAP);

	terrain->scaleTexture(1.0f, 20.0f);

		scene::ISceneNode* skydome=SceneManager->addSkyDomeSceneNode(Driver->getTexture("data/world/skyd1.jpg"),16,8,0.95f,2.0f);

    int startTime = Device->getTimer()->getTime();
	int elapsedTime = 0;
    while(Device->run())
    {
        elapsedTime = Device->getTimer()->getTime() - startTime;
		startTime = Device->getTimer()->getTime();
		processKeys(elapsedTime);

		// Update third person cam
camera->setTarget(playerNode->getPosition());
        Driver->beginScene(true, true, SColor(0,200,200,200));

        SceneManager->drawAll();
        Gui->drawAll();

        Driver->endScene();
    }

    Device->drop();

    return 0;
}


3DP.h:

Code: Select all

/*Particular Zlib License /LIBRARY(C).

3DP.h
3DP.cpp

Licenзa ZLIB/LIBPNG
Disponнvel, no original, em: http://www.opensource.org/licenses/zlib-license.php
Versгo 1.01
Licenзa ZLIB/LIBPNG

Direitos autorais Copyright (C) 2008 Lucian. 2009 Lucian,cуdigo original encontrado em um forum.

Este programa de computador й fornecido "como estб",
 sem garantias de qualquer espйcie, expressas ou tбcitas. 
Em nenhuma hipуtese os autores serгo responsбveis por 
quaisquer danos decorrentes do uso deste programa de computador.
Outorga-se permissгo para qualquer um usar este programa de 
computador para quaisquer fins, incluindo utilizaзхes comerciais,
e para o modificar e redistribuir livremente, sujeita аs seguintes restriзхes:


1. A origem deste programa de computador nгo pode ser apresentada
de forma errфnea; vocк nгo pode reivindicar ter escrito o programa
de computador original. Se vocк usar esse programa de computador em
um produto, um reconhecimento de crйditos na documentaзгo do produto
seria apreciada, mas nгo й exigida.


2. Versхes alteradas do cуdigo-fonte devem estar marcadas como tais,
e nгo podem ser apresentadas forma errфnea, como sendo o programa de
computador original.

3. Este aviso nгo pode ser alterado ou removido de qualquer distribuiзгo de cуdigo fonte.*/

  #ifndef _3DP_h_
  #define _3DP_h_ 
 #include <irrlicht.h>

    #define EPSILON 0.001f

    using namespace irr;
    using namespace core;
    using namespace scene;
    using namespace video;
    using namespace io;
    using namespace gui;


 


	class CScene3PCamera : public irr::scene::ISceneNodeAnimator,public irr::IEventReceiver
    {

    public:

    //! Construtor
    //! player: Objeto a Seguir
    //! Distanciaancia: The initial Distanciaance from the player
    //! initAngleY: The initial horizontal rotatation
    //! initAngleZ: The initial vertical rotation
    //! targetOffset: The offset from the object's center at which the camera looks
    //! minDistancia/maxDistancia: Distanciaance bounding
    //! minAngle/maxAngle: Rotation bounding. -89 ==> looking up at player, 89 ==> looking down
    //! boxSize: The size of the box in which mouse movements do not result in camera movements
  
    CScene3PCamera(
    irr::scene::ISceneManager *manager,
    irr::gui::ICursorControl *cursor,
    irr::scene::ISceneNode *player,
    irr::f32 Distanciaancia = 50.0f,
    irr::f32 initAngleY = 180.0f,
    irr::f32 initAngleZ = 10.0f,
	bool RotatePlayer = false,
    irr::core::vector3df targetOffset = irr::core::vector3df(0,0,0),
    irr::f32 minDistancia = 20.0f,
    irr::f32 maxDistancia = 200.0f,
    irr::f32 minAngle = -45.0f,
    irr::f32 maxAngle = 89.0f,
    irr::f32 boxSize = 0.0f,
    irr::f32 rotationSpeed = 60.0f);

    //! Destructor
    virtual ~CScene3PCamera(void);

    //! animates the scene node
    virtual void animateNode(ISceneNode* node, u32 timeMs);

    //! Process an input event
   virtual ISceneNodeAnimator* createClone (ISceneNode *node, ISceneManager *newManager=0)
    {
        return new CScene3PCamera(Manager,Cursor,Player,Distancia,AngleY,
			AngleZ,false,TargetOffset,MinDistancia,MaxDistancia,MinAngle,
			MaxAngle,BoxSize,RotationSpeed);
    }
   // virtual bool OnEvent(irr::SEvent event);
    virtual bool OnEvent(const SEvent& event);
    //! Get/set active status
    int isActive();
    void setActive(bool status);

	    virtual ESCENE_NODE_ANIMATOR_TYPE getType(void) const
    {
        return ESNAT_UNKNOWN;
    }


		    virtual bool isEventReceiverEnabled(void) const
    {
        return false;
    }
    //! Get/set box size
    irr::f32 getBoxSize();
    void setBoxSize(irr::f32 newSize);

    //! Map zoom in/zoom out buttons

    //! Access the camera's current orientation
    irr::f32 getOrientation();
	bool XRotatePlayer;

	   // current states
    irr::f32 Distancia;
    irr::f32 AngleY;
    irr::f32 AngleZ;

    private:

    int Active;//bool Active;
/*
    // current states
    irr::f32 Distancia;
    irr::f32 AngleY;
    irr::f32 AngleZ;
*/


    // boundaries
    irr::core::vector3df TargetOffset;
    irr::f32 MinDistancia;
    irr::f32 MaxDistancia;
    irr::f32 MinAngle;
    irr::f32 MaxAngle;
    irr::f32 BoxSize;

    // Motion
    irr::f32 RotationSpeed;
  

    //! Node to follow
    irr::scene::ISceneNode *Player;

    irr::scene::ISceneManager *Manager;
    irr::gui::ICursorControl *Cursor;

	
    //! Puts the cursor back in the box
    void updateCursorPosition();
    };





#endif
3DP.cpp:

Code: Select all

#include "3DP.h"
    CScene3PCamera::CScene3PCamera(
    irr::scene::ISceneManager *manager,
    irr::gui::ICursorControl *cursor,
    irr::scene::ISceneNode *player,
    irr::f32 Distanciaancia,irr::f32 initAngleY,
    irr::f32 initAngleZ,
	bool RotatePlayer,
    irr::core::vector3df targetOffset,
    irr::f32 minDistancia,
    irr::f32 maxDistancia,
    irr::f32 minAngle,
    irr::f32 maxAngle,
    irr::f32 boxSize,
    irr::f32 rotationSpeed)
    : Active(true), Manager(manager), Cursor(cursor), Player(player),
    Distancia(Distanciaancia),AngleY(initAngleY),AngleZ(initAngleZ),XRotatePlayer(RotatePlayer),
    TargetOffset(targetOffset),
    MinDistancia(minDistancia), MaxDistancia(maxDistancia), MinAngle(-maxAngle), MaxAngle(-minAngle),
    BoxSize(boxSize), RotationSpeed(rotationSpeed)
    {


    Cursor->setPosition(0.5f,0.5f);

    // Ensure Distanciaance is bounded correctly
    if(Distancia < MinDistancia) Distancia = MinDistancia;
    else if(Distancia > MaxDistancia) Distancia = MaxDistancia;

    // Bound MinAngle/MaxAngle to avoid problematic areas
    if(MinAngle < -89.0f) MinAngle = -89.0f;
    if(MinAngle > 89.0f) MinAngle = 89.0f;
    if(MaxAngle < -89.0f) MaxAngle = -89.0f;
    if(MaxAngle > 89.0f) MaxAngle = 89.0f;
    if(minAngle > maxAngle) MaxAngle = MinAngle+1.0f;

    // Ensure Vertical Rotation Angle is bounded correctly
    if(AngleZ < MinAngle) AngleZ = MinAngle;
    else if(AngleZ > MaxAngle) AngleZ = MaxAngle;
    }

    //! Destructor
    CScene3PCamera::~CScene3PCamera(void)
    {
    }

    //! Puts the cursor back in the box
    void CScene3PCamera::updateCursorPosition()
    {
    irr::core::position2d<irr::f32> pos = Cursor->getRelativePosition();

    if(pos.X < (0.5f-BoxSize)) pos.X = (0.5f-BoxSize);
    if(pos.X > (0.5f+BoxSize)) pos.X = (0.5f+BoxSize);

    if(pos.Y < (0.5f-BoxSize)) pos.Y = (0.5f-BoxSize);
    if(pos.Y > (0.5f+BoxSize)) pos.Y = (0.5f+BoxSize);

    Cursor->setPosition(pos);
    }

    //! Process an input event
  bool CScene3PCamera::OnEvent(const irr::SEvent& event)
    {
    if(!Active)
    {
    return false;
    }

    if(event.EventType == irr::EET_KEY_INPUT_EVENT)
    {

    }

    return false;
    }

    //! Get/set active status
    int CScene3PCamera::isActive()
    {
    return Active;
    }

    void CScene3PCamera::setActive(bool status)
    {
    // reset the cursor only if we are switching back to active from inactive
    if(!Active && status)
    {
    updateCursorPosition();
    }

    Active = status;
    }

    //! Get/set box size
    irr::f32 CScene3PCamera::getBoxSize()
    {
    return BoxSize;
    }

    void CScene3PCamera::setBoxSize(irr::f32 newSize)
    {
    BoxSize = newSize;
    updateCursorPosition();
    }



    //! Access the camera's current orientation
    irr::f32 CScene3PCamera::getOrientation()
    {
    return AngleY;
    }


    //! animates the scene node
    void CScene3PCamera::animateNode(irr::scene::ISceneNode *node, irr::u32 timeMs)
    {
    // make sure you don't go attaching this animator to anything other than a camera
    irr::scene::ICameraSceneNode *camera = (irr::scene::ICameraSceneNode*)node;

    if(Manager->getActiveCamera() != camera)
    {
    return;
    }

    if(Active)
    {
    // Camera is active, rotate as necessary
    irr::core::position2d<irr::f32> pos = Cursor->getRelativePosition();

    if(pos.X < 0.5f-BoxSize-EPSILON)
    {
    AngleY -= (pos.X-(0.5f-BoxSize))*RotationSpeed;//Decrement of this statement gives the correct movement to the mouse.... by smartwhiz
    }

    if(pos.X > 0.5f+BoxSize+EPSILON)
    {
    AngleY -= (pos.X-(0.5f+BoxSize))*RotationSpeed;//Decrement of this statement gives the correct movement to the mouse.... by smartwhiz
    }

    // So we don't get huge rotation numbers
    if(AngleY > 360.0f)
    {
    AngleY += 360.0f;
    }

    if(AngleY < 0.0f)
    {
    AngleY -= 360.0f;
    }

    if(pos.Y < 0.5f-BoxSize-EPSILON)
    {
    AngleZ -= (pos.Y-(0.5f-BoxSize))*RotationSpeed;
    }

    if(pos.Y > 0.5f+BoxSize+EPSILON)
    {
    AngleZ -= (pos.Y-(0.5f+BoxSize))*RotationSpeed;
    }

    // Ensure Vertical Rotation Angle is bounded correctly
    if(AngleZ < MinAngle) AngleZ = MinAngle;
    else if(AngleZ > MaxAngle) AngleZ = MaxAngle;

    //keep the player in the view angle that of the camera, this is the change made......... by smartwhiz
	if (XRotatePlayer == true){
	Player->setRotation(irr::core::vector3df(0,-(AngleY+180),0));
	}


    updateCursorPosition();
    }

    // Create translation vector
    irr::core::vector3df translation(Distancia,0,0);
    translation.rotateXYBy(-AngleZ,irr::core::vector3df(0,0,0));
    translation.rotateXZBy(AngleY,irr::core::vector3df(0,0,0));

    // Assumes the camera is *not* a child of the player node
    camera->setTarget(Player->getPosition()+TargetOffset);
    camera->setPosition(Player->getPosition()+translation+TargetOffset);
    }




Posted: Sun Jun 06, 2010 9:16 am
by DtD
"It doesn't work."

Nobody really wants to read your code and try to figure out what you want done or what is wrong, describe us the situation!

Posted: Sun Jun 06, 2010 11:03 am
by full_newbie
The code works, but works not correctly. The camera incorrectly rotates and when start to run the camera escapes.