cs_Mick7
Messages postés54Date d'inscriptionsamedi 11 septembre 2004StatutMembreDernière intervention18 avril 2007
-
14 févr. 2006 à 12:19
Utilisateur anonyme -
21 juil. 2006 à 17:23
bon voila je veux faire une camera comme dans un fps le probleme c'est
que je ne sait pas comment on fait des rotation autour des axes x et y
de la camera car mes rotation s'effectuent autour des axes de la carte
void CCamera::SetCamera(float x, float y, float z,
float xv, float yv, float zv,
float xu, float yu, float zu)
{
// Here we set the camera to the values sent in to us. This is mostly used to set up a
// default position.
mPos = CVector4(x, y, z);
mView = CVector4(xv, yv, zv);
mUp = CVector4(xu, yu, zu);
}
void CCamera::GetDirection(CVector4 &Direction)
{
// The look direction is the view (where we are looking) minus the position (where we are).
Direction = mView - mPos;
}
void CCamera::MoveCamera(float speed)
{
// Moving the camera requires a little more then adding 1 to the z or subracting 1.
// First we need to get the direction at which we are looking.
CVector4 Direction;
// Get the direction and store it in the object Direction.
GetDirection(Direction);
Direction.Normal();
// Call UpdateCamera to move our camera in the direction we want.
UpdateCamera(Direction, speed);
// NOTE if the camera moves too slow try increasing the UP and DOWN values in the header.
// The camera is frame based so it will move differently for you.
}
void CCamera::UpdateCamera(CVector4 Direction, float speed)
{
// Move the camera on the X and Z axis.
mPos.x += Direction.x * speed;
mPos.y += Direction.y * speed;
mPos.z += Direction.z * speed;
// Move the view along with the position
mView.x += Direction.x * speed;
mView.y += Direction.y * speed;
mView.z += Direction.z * speed;
}
void CCamera::StrafeCam(float speed)
{
CalculateStrafe(); // Calculate the straft direction.
UpdateCamera(mStrafe, speed); // Then add it to the camera's position.
}
// Strafing is just like moving the camera forward and backward. First we will get the
// direction we are looking.
GetDirection(Direction);
// Now if we were to call UpdateCamera() we will be moving the camera foward or backwards.
// We don't want that here. We want to strafe. To do so we have to get the cross product
// of our direction and Up direction view. The up was set in SetCamera to be 1 positive
// y. That is because anything positive on the y is considered up. After we get the
// cross product we can save it to the strafe variables so that can be added to the
// camera using UpdateCamera().
// Get the cross product of the direction we are looking and the up direction.
Cross.CrossProduct(Direction, mUp);
// Normalize it.
Cross.Normal();
// Save our strafe (cross product) values in the mStrafe object.
mStrafe = Cross;
}
// First we will need to calculate the cos and sine of our angle. I created two macros to
// do this in the CCamera.h header file called GET_COS and GET_SINE. To use the macros
// we just send in the variable we ant to store the results and the angle we need to
// calculate.
GET_COS(CosineAngle, AngleDir);
GET_SINE(SineAngle, AngleDir);
// Next get the look direction (where we are looking) just like in the move camera function.
GetDirection(LookDirection);
// Last we add the new rotations to the old view to correctly rotate the camera.
mView = mPos + newDir;
}
void CCamera::RotateByMouse(int mousePosX, int mousePosY, int midX, int midY)
{
float yDirection = 0.0f; // Direction angle.
float yRotation = 0.0f; // Rotation angle.
// If the mouseX and mouseY are at the middle of the screen then we can't rotate the view.
if((mousePosX midX) && (mousePosY midY))
return;
// Next we get the direction of each axis. We divide by 1000 to get a smaller value back.
yDirection = (float)((midX - mousePosX)) / 1000.0f;
yRotation = (float)((midY - mousePosY)) / 1000.0f;
// We use curentRotX to help use keep the camera from rotating too far in either direction.
currentRotationAngle -= yRotation;
// Stop the camera from going to high...
if(currentRotationAngle > 1.5f)
{
currentRotationAngle = 1.5f;
return;
}
// Stop the camera from going to low...
if(currentRotationAngle < -1.5f)
{
currentRotationAngle = -1.5f;
return;
}
// Next we get the axis which is a perpendicular vector of the view direction and up values.
// We use the cross product of that to get the axis then we normalize it.
CVector4 Axis;
Axis.CrossProduct(mView - mPos, mUp);
Axis.Normal();
wxccxw
Messages postés755Date d'inscriptionsamedi 15 mai 2004StatutMembreDernière intervention30 janvier 2011 14 févr. 2006 à 12:30
la haut ct CCamera.cpp et la
CCamera.H
#ifndef CCAMERA_H
#define CCAMERA_H
#include<math.h> // Math header that allows us to use cos() and sin().
#include"CVector.h" // CVector3 class.
#define FORWARD 1.0 // Forward speed.
#define BACKWARD -1.0 // Backward speed.
#define UP 0.03 // Up speed.
#define DOWN -0.03 // Down speed.
#define LEFT 0.03 // Left speed.
#define RIGHT -0.03 // Right speed.
#define STRAFE_LEFT -1.0 // Left straft speed.
#define STRAFE_RIGHT 1.0 // Right straft speed.
#define GET_COS(a, b) a = (float)cos(b) // Get the cos angle of b and store it in a.
#define GET_SINE(a, b) a = (float)sin(b) // Get the sine angle of b and store it in a.
class CCamera
{
public:
CCamera(); // Constructor.
void SetCamera(float x, float y, float z, // Set the camera's position.
float xv, float yv, float zv,
float xu, float yu, float zu);
void GetDirection(CVector4 &Direction); // Get the view direction.
void MoveCamera(float speed); // Move the camera forwards and backwards.
void UpdateCamera(CVector4 Direction, float speed);// Update the camera's position.
void StrafeCam(float speed);
void CalculateStrafe(); // Calculate the direction of the straft.
void RotateCamera(float AngleDir, CVector4 Speed); // Rotate the camera around a point.
void RotateByMouse(int mousePosX, int mousePosY, int midX, int midY);
CVector4 mPos; // Camera position.
CVector4 mView; // Look at position.
CVector4 mUp; // Up direction.
CVector4 mStrafe; // Strafe direction.
float currentRotationAngle; // Keeps us from going too far up or down.
};
Juste un petit rappel. Le code que l'on t'a proposé fonctionnera
pleinement si tu te contentes vraiment de tourner autour de 2 axes mais
si un jour, tu veux faire tourner un objet en fonction de 3 axes, cette
méthode ne marche pas. C'est due à une limitation de l'utilisation des
transformations Eulériennes. Cette limitation est appelée "verrou de
Cardan" et aussi "gimbal lock". J'ai eu beaucoup de problème à cause de
ça et il y a un tas d'inepsies qui circulent sur le net à propos des
façons de résoudre ce problème. Alors, si ça t'intéresse, fais moi
signe (je précise que j'ai fait vérifier mes travaux par plusieurs
professeurs d'informatique graphique).