I need to have the camera move on the axis, but move relative to the world not the object. I modified the Path Finding Tutorial to create an RTS Cam, but my issue is my Camera when moving forward also move up following the Pitch Angle of the Camera Object. How can I circumvent this issue?
Code:
/******************************************************************************/
#include "stdafx.h"
#include "../../../../../data/enum/_enums.h"
/******************************************************************************/
Game::ObjMemx<Game::Chr > Chrs ;
Game::ObjMemx<Game::Static> Statics;
Decal decal; // decal pointing character destination target
/******************************************************************************/
void InitPre()
{
App.name("Pathfind");
App.flag=APP_FULL_TOGGLE;
DataPath("../data");
Paks.add("engine.pak");
D.full(true).sync(true).hpRt(true).viewRange(50);
Cam.dist = 10;
Cam.yaw =-PI_4;
Cam.pitch=-PI_3;
}
/******************************************************************************/
Bool Init()
{
Physics.create(CSS_NONE,true,"../Installation/PhysX");
Sky .atmospheric();
Sun.image=Images("gfx/sky/sun.gfx"); Sun.light_color=1-D.ambColor();
decal.terrain_only=true;
decal.color.set(1,1,0,1);
decal.material(Materials.ptrRequire("Decal/star.mtrl"));
Game::World.init ( )
.setObjType(Chrs ,OBJ_PLAYER)
.setObjType(Statics,OBJ_STATIC)
.New ("world/path.world")
.update (Cam.at );
return true;
}
/******************************************************************************/
void Shut()
{
}
/******************************************************************************/
Bool Update()
{
int moveMult = 1;
if(Kb.bp(KB_ESC))return false;
Game::World.update(Cam.at);
// move player
if(Ms.bp(0) && Chrs.elms()) // on LMB pressed
{
Vec pos,dir ; ScreenToPosDir(Ms.pos(),pos,dir); // convert screen mouse position to world position and direction
PhysHit phys_hit;
if(Physics.ray(pos,dir*D.viewRange(),&phys_hit)) // if ray-test hit something
{
Chrs[0].actionMoveTo(phys_hit.plane.pos); // order character to move to that location
decal.matrix.setPosDir(phys_hit.plane.pos,Vec(0,1,0));
}
}
//Boost cam movement while holding either shift.
if((Kb.b(KB_LSHIFT)))
{
moveMult = 2;
}
if((Kb.b(KB_RSHIFT)))
{
moveMult = 2;
}
Cam.matrix.
//Save old Z Position
Vec oldZ = Cam.matrix.z;
//CAM MOVEMENT
if(Kb.b(KB_LEFT ))Cam.at-=Cam.matrix.x*Time.d()*2*moveMult; // move camera left on left arrow key
if(Kb.b(KB_RIGHT))Cam.at+=Cam.matrix.x*Time.d()*2*moveMult; // move camera right on right arrow key
if(Kb.b(KB_UP ))Cam.at+=Cam.matrix.y*Time.d()*2*moveMult; // move camera up on up arrow key
if(Kb.b(KB_DOWN ))Cam.at-=Cam.matrix.y*Time.d()*2*moveMult; // move camera down on down arrow key
Cam.dist -=Ms.wheel()*0.4f; // modify distance according to mouse wheel
//Clamp(Cam.dist,10,10); // clamp distance to minimum and maximum values
// rotate camera
if(Ms.b(1))
{
Cam.yaw -=Ms.d().x;
Cam.pitch+=Ms.d().y;
}
//Cam.dist = 10;
Cam.setFromAt (Cam.at,Cam.at,Cam.roll); // set spherical camera with 'look at' position, angles and distance
//Cam.setSpherical (Cam.at,Cam.yaw,Cam.pitch,Cam.roll,Cam.dist); // set spherical camera with 'look at' position, angles and distance
Cam.updateVelocities();
Cam.set();
//if(Chrs.elms())Cam.setSpherical(Chrs[0].pos(),Cam.yaw,Cam.pitch,0,Cam.dist*ScaleFactor(Ms.wheel()*-0.2f)).updateVelocities().set();
// rotate decal around its z axis
decal.matrix.rotateZVec(Time.d());
return true;
}
/******************************************************************************/
void Render()
{
Game::World.draw();
switch(Renderer())
{
case RM_BLEND:
{
if(Chrs.elms())
if(Chrs[0].action==Game::ACTION_MOVE_TO)decal.drawStatic();
}break;
}
}
void Draw()
{
Renderer(Render);
// show blocked places
if(Kb.b(KB_SPACE)) // if space pressed
if(Chrs.elms()) // if at least one character is available
{
Vec pos =Chrs[0].pos(); // get character position
VecI2 area_pos=Game::World.worldToAreaPos(pos); // convert from world position to area coordinates
if(Game::AreaPath *path=Game::World.pathGet(area_pos)) // if found paths at given coordinates
{
D.clearZ (); // clear Z Buffer
SetMatrix(); // reset drawing matrix
Vec world_pos=Game::World.areaToWorldPos(area_pos).x0y(); // convert 2D Area Coordinates to 3D World Position
Flt cell_size=(1.0f/Game::World.pathRes())*Game::World.areaSize(); // get size of a single path cell
VI.color(ColorAlpha(RED,0.5f)); // set drawing color to transparent RED
REPD(y,Game::World.pathRes())
REPD(x,Game::World.pathRes())if(!path->walkable(x,y)) // if current cell isn't walkable
{
Vec pos=world_pos+Vec(x,0,y)*cell_size; // get world position of a single path cell
VI.quad(pos+Vec( 0,0,cell_size), // draw a quad which extends 'pos' to right and forward by 'cell_size'
pos+Vec(cell_size,0,cell_size),
pos+Vec(cell_size,0, 0),
pos+Vec( 0,0, 0));
}
VI.end();
}
}
// informations
D.text(0,0.9f,"Press LMB to move player, RMB to rotate camera");
D.text(0,0.8f,"Press Space to show blocked places at character position");
}
/******************************************************************************/