This code is not only my only changed and improved Altor not know what it was a topic of the forum's irrlicht I believe it is in the public domain.
The code follows the attachment.
He not yet completed all this because I do not have time to finish below you explain what you missed.
He is only missing virtually all full impact of the camera.
In Tomb Raider legend realized that the camera when it collides approaches humor.
So just working on a collision detection of more clashes and when she comes closest.
On this camera there is only physically there is a slight collision detection.
Source Here.
3dp.h
Code: Select all
#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
//! distance: The initial Distanciaance from the player
//! initAngleY: The initial horizontal rotatation
//! initAngleZ: The initial vertical rotation
//! RotatePlayer Set rotation of the player with the camera!//Bylucian
//! targetOffset: The offset from the object's center at which the camera looks
//! mindistance/maxdistance: 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 distance = 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 mindistance = 20.0f,
irr::f32 maxdistance = 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(irr::scene::ISceneNode *node, irr::u32 timeMs);
//! Process an input event
// virtual bool OnEvent(irr::SEvent event);
bool OnEvent(const irr::SEvent& event);
//! Get/set active status
int isActive();
void setActive(bool status);
//! 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 mindistance;
irr::f32 maxdistance;
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
Code: Select all
#include "3DP.h"
CScene3PCamera::CScene3PCamera(
irr::scene::ISceneManager *manager,
irr::gui::ICursorControl *cursor,
irr::scene::ISceneNode *player,
irr::f32 distance,irr::f32 initAngleY,
irr::f32 initAngleZ,
bool RotatePlayer,
irr::core::vector3df targetOffset,
irr::f32 mindistance,
irr::f32 maxdistance,
irr::f32 minAngle,
irr::f32 maxAngle,
irr::f32 boxSize,
irr::f32 rotationSpeed)
: Active(true), Manager(manager), Cursor(cursor), Player(player),
Distancia(distance),AngleY(initAngleY),AngleZ(initAngleZ),XRotatePlayer(RotatePlayer),
TargetOffset(targetOffset),
mindistance(mindistance), maxdistance(maxdistance), MinAngle(-maxAngle), MaxAngle(-minAngle),
BoxSize(boxSize), RotationSpeed(rotationSpeed)
{
Cursor->setPosition(0.5f,0.5f);
// Ensure Distanciaance is bounded correctly
if(Distancia < mindistance) Distancia = mindistance;
else if(Distancia > maxdistance) Distancia = maxdistance;
// 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);
}
main.cpp
Code: Select all
/*
Tomb Raider Camera Exemple
*/
#include <iostream>
#include <irrlicht.h>
using namespace std;
using namespace irr;
using namespace core;
using namespace scene;
using namespace video;
using namespace io;
using namespace gui;
#pragma comment(lib, "Irrlicht.lib")
#pragma comment(linker, "/subsystem:windows /ENTRY:mainCRTStartup")
#include <windows.h>
#include "3DP.h"
float char_speed= 0.3;
float char_direc=0;
float char_direcY=0;
float mouse_sensitivity=3;
float grav_force=9;
float Distanciaance3= 30;
int char_standing=0;
int char_walking=0;
int screen_width=1024;
int screen_height=768;
int mousex_init=screen_width/2;
int mousey_init=screen_height/6;
int full_screen=0;
int cursor_visible=0;
int anim = 0;
int Shadow = 0;
IrrlichtDevice *device = createDevice(video::EDT_DIRECT3D9, dimension2d<s32>(screen_width, screen_height), 32, full_screen, true, true);
position2d<s32> mousePos = device->getCursorControl()->getPosition();
position2d<s32> lastMousePos = device->getCursorControl()->getPosition();
int main()
{
device->getCursorControl()->setVisible(cursor_visible);
device->getCursorControl()->setPosition(mousex_init,mousey_init);
video::IVideoDriver *driver = device->getVideoDriver();
ISceneManager *smgr = device->getSceneManager();
IGUIEnvironment *guienv = device->getGUIEnvironment();
driver->setTextureCreationFlag(video::ETCF_ALWAYS_32_BIT, true);
scene::IAnimatedMesh *mesh = (IAnimatedMesh*) smgr->getMesh("player.x");
scene::IAnimatedMeshSceneNode *skelNode = (IAnimatedMeshSceneNode*) smgr->addAnimatedMeshSceneNode(mesh);
skelNode->addShadowVolumeSceneNode(-1,false, 100.f);
// create input class
video::SLight l;
scene::ILightSceneNode *light = smgr->addLightSceneNode(0,core::vector3df(50,50,50),video::SColorf(1,1,1,.1f),1000);
l = light->getLightData();
l.Type = video::ELT_POINT;
l.AmbientColor = video::SColorf(96,96,96);
l.SpecularColor = video::SColorf(0.5,0.5,0.5);
l.DiffuseColor = video::SColorf(1,1,1);
l.CastShadows = Shadow;
light->setLightData( l );
gui::IGUIEnvironment* env = device->getGUIEnvironment();
// setup camera
ICameraSceneNode *cam = smgr->addCameraSceneNode(0,core::vector3df(0,0,0),core::vector3df(0,0,0));
scene::ISceneNode* cube = smgr->addCubeSceneNode();
cube->setScale( core::vector3df(50,0,50) );
cube->setPosition( core::vector3df(0,-7.05,0) );
cube->setMaterialTexture(0, device->getVideoDriver()->getTexture("cube.jpg"));
cube->setMaterialTexture(1, device->getVideoDriver()->getTexture("MaPZone[Lava_Rock_normal].jpg"));
CScene3PCamera *camAnim;
camAnim = new CScene3PCamera(smgr,device->getCursorControl(),
skelNode,Distanciaance3,180,0,false,irr::core::vector3df(0,0,0),10);
cam->addAnimator(camAnim);
u32 i=1;
s32 fps, fpsTemp;
f32 cosAlphaTwo;
f32 alpha;
f32 rad;
u32 a;
scene::ISceneNode *node;
driver->setTextureCreationFlag(video::ETCF_CREATE_MIP_MAPS, true);
while((device->run()))
{
char_direc = skelNode->getRotation().Y;
driver->beginScene(true, true, SColor(255,255,255,255));
smgr->drawAll();
driver->endScene();
}
return 0;
}
Download The Full Functionally Version Windows VC++ 2008 Express Projct Files.
http://www.gamedev-br.net/IrrDev/tombraidercamera.rar