• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
dxCUDA

Rotating camera around player origin

8 posts in this topic

I can't quite figure out current how to Transform the lookAt and up vector by the rotation matrix so the view is rotated about the player origin.

Cheers

[CODE]
up.x = 0.0f;
up.y = 1.0f;
up.z = 0.0f;
// Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
pitch = m_rotationX * 0.0174532925f;
yaw = m_rotationY * 0.0174532925f;
roll = m_rotationZ * 0.0174532925f;
D3DXVECTOR3 rotation = D3DXVECTOR3(m_rotationX, m_rotationY, m_rotationZ);
D3DXVECTOR3 camera[3] = { D3DXVECTOR3(m_fCameraX, m_fCameraY, m_fCameraZ),//Eye
D3DXVECTOR3(m_fLookatX, m_fLookatY, m_fLookatZ),//LookAt
up };//Up
// Create the rotation matrix from the yaw, pitch, and roll values.
D3DXMatrixRotationYawPitchRoll(&rotationMatrix, yaw, pitch, roll);
//Translate in the direction of player rotation
D3DXVec3TransformCoord(&camera[0], &camera[0], &rotationMatrix);
// Transform the lookAt and up vector by the rotation matrix so the view is correctly rotated at the origin.
D3DXVec3TransformCoord(&camera[1], &camera[1], &rotationMatrix);
D3DXVec3TransformCoord(&camera[2], &camera[2], &rotationMatrix);
camera[1] = camera[0] + camera[1];
D3DXMatrixLookAtLH(&in_viewMatrix, &camera[0], &camera[1], &camera[2]);
[/CODE]
0

Share this post


Link to post
Share on other sites
Do you need a 3rd person camera rotating around the player?

If so, I recommend you to use quaternions. It's much easier.

If not, can you describe what you want more clearly?

Btw, I don't recommend you to deal with LookAt and Eye vectors. You can define a world transform for your camera because it's quite easy to perform some transformations (translate, rotate etc.) over a world matrix. And when you need a view matrix, just take the inverse of this world matrix. Edited by programci_84
0

Share this post


Link to post
Share on other sites
Thanks for the reply!

I'm trying to implement an FPS-style camera. I am able to move on a set axis, and rotate about the local camera origin, but I cannot update the movement direction in relation to the camera facing angle. So what I want to achieve, is look in a direction and translate in that direction.

Here is my revised code I've been working on.

[CODE]
float yaw, pitch, roll;
//D3DXMATRIX rotationMatrix;
D3DXMATRIX yawMatrix;
D3DXMATRIX pitchMatrix;
D3DXMATRIX rollMatrix;
D3DXMATRIX upLocal;
D3DXVECTOR3 Direction;
// Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
pitch = m_rotationX * 0.0174532925f;
yaw = m_rotationY * 0.0174532925f;
roll = m_rotationZ * 0.0174532925f;
position.x = m_fCameraX;
position.y = m_fCameraY;
position.z = m_fCameraZ;
up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);//Create the up vector
right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
lookat = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
rotation = D3DXVECTOR3(m_rotationX, m_rotationY, m_rotationZ);
// Setup matrices to rotate around axes
D3DXMatrixRotationAxis(&yawMatrix, &up, yaw);
D3DXMatrixRotationAxis(&pitchMatrix, &right, pitch);
//D3DXMatrixRotationAxis(&rollMatrix, &lookat, roll);
//move lookat vector
D3DXVec3TransformCoord(&lookat, &lookat, &pitchMatrix);
D3DXVec3TransformCoord(&lookat, &lookat, &yawMatrix);
D3DXVec3Normalize(&lookat, &lookat);
//Get the direction vector from camera to target, normalise it.
D3DXVec3Normalize(&Direction, &(lookat - right));
//Get the UP vector (in the world) and determine the cross product, to give us our right (left) hand vector.
D3DXVec3Cross(&right, &up, &lookat);
D3DXVec3Normalize(&right, &right);
//Cross product the right vector and direction vector, to determine up relative to the camera.
D3DXVec3Cross(&up, &lookat, &right);//Should be direction instead of lookat
//lookat = Direction + right;//Avoid gimble locking
D3DXMatrixIdentity(&in_viewMatrix);
in_viewMatrix._11 = right.x;
in_viewMatrix._21 = right.y;
in_viewMatrix._31 = right.z;
in_viewMatrix._12 = up.x;
in_viewMatrix._22 = up.y;
in_viewMatrix._32 = up.z;
in_viewMatrix._13 = lookat.x;
in_viewMatrix._23 =lookat.y;
in_viewMatrix._33 = lookat.z;
in_viewMatrix._41 = -D3DXVec3Dot(&position, &right);
in_viewMatrix._42 = -D3DXVec3Dot(&position, &up);
in_viewMatrix._43 = -D3DXVec3Dot(&position, &lookat);
[/CODE]
0

Share this post


Link to post
Share on other sites
Update:

So I was aware that I needed to create a direction from the position and rotation, but unsure of the method. Here is the progress I have made with that:

[CODE]
direction = atan2((double)rotation.x, (double)position.x);
velocity.x = (sin(direction) * 5.0f);
velocity.z = (cos(direction ) * 5.0f);
[/CODE]
And then I apply the velocity to the right vector as such:
[CODE]
in_viewMatrix._41 = -D3DXVec3Dot(&(position + velocity), &right);
[/CODE]

So the final result I am trying to accomplish is create a new position based off of the rotation. It however doesn't accomplish this. Edited by dxCUDA
0

Share this post


Link to post
Share on other sites
Use parenting so that the player's avatar model is the parent of the camera. Then the camera's world transformation [b]C[/b][sub]W[/sub] is
[b]C[/b][sub]W[/sub] = [b]C[/b][sub]L[/sub] * [b]P[/b][sub]W[/sub]
where [b]C[/b][sub]L[/sub] means the camera's local position and orientation w.r.t. the avatar's model, and [b]P[/b][sub]W[/sub] means the model's position and orientation in the world. Hence, if you alter the model, the camera will follow automatically.

You may want to use variations, e.g. a constant height of the camera above the ground. This can be done by setting the respective component manually.

If you want to change the camera's relation to the model, i.e. [b]C[/b][sub]L[/sub], then use orbiting. In orbiting you rotate both the orientation as well as the position of the camera. That means
[b]C[/b][sub]L[/sub]' = [b]C[/b][sub]L[/sub] * [b]R[/b]
perhaps using negated angles when computing [b]R[/b].

It may be that the origin of the model shouldn't be exactly the center of rotation / orbiting, e.g. in the models's head instead of the center of body. In that case you may want to have a distant rotational center [b]O[/b] (also relative to the model's space) and hence will do orbiting like so:
[b]C[/b][sub]L[/sub]' = [b]C[/b][sub]L[/sub] * [b]O[/b][sup]-1[/sup] * [b]R[/b] * [b]O[/b]
Herein [b]O[/b] is simply the translation matrix from the model's origin to the center of rotation.

If you want to compute the direction where the model should move, please avoid the use of angles. It is much more convenient and efficient to use the forward vector of the model (or perhaps the camera) instead. You can use a projection of it if you want the movement vector parallel to the ground. You can further apply a small rotation for curved movement. Edited by haegarr
1

Share this post


Link to post
Share on other sites
I always have yaw, pitch, and roll variables, then every frame I update them with the controller or whatever, then I create a quaternion using those variables, then I transform the "backward" vector with that quaternion. Make the camera position that vector (multiply it by whatever distance you want it to be from the player), add the player position to that vector, then set the target to the character position.

It's really not hard to do, and I would provide some sample code, but I'm a little lazy right now :P

Aww, hell, here's some pseudo-code:
[code]
float yaw, pitch, roll;//Some variables that will be in your camera class or wherever you want them
//You could also just use a quaternion rather than those variables, then just multiply the quaternions.
//I feel it's a little better to use yaw, pitch, and roll since you can keep track of your camera's rotations a little better (doesn't really matter if it's a free camera anyway)

//I really don't know which is which with yaw pitch roll, but only two are important (I think yaw and pitch, yaw being up/down, pitch being rotation?)
//Anyway, doesn't matter. Just find out which is which, add to them using input from a controller/keyboard, then create your quaternion

Quaternion rotator = Quaternion.FromYawPitchRoll(yaw,pitch,roll);

float camDistance = 5.0f;
vector3 back = Vector3.Backward;

back = Vector3.Transform(back, rotator);//Rotate our vector
rotator *= distance;//Push it out a distance from the player)
rotator += playerPosition;//Add the position

View = Matrix.CreateLookAt(back, playerPosition, upVector);

[/code]
1

Share this post


Link to post
Share on other sites
[quote name='Nyxenon' timestamp='1337489291' post='4941580']
I always have yaw, pitch, and roll variables, then every frame I update them with the controller or whatever, then I create a quaternion using those variables, then I transform the "backward" vector with that quaternion. Make the camera position that vector (multiply it by whatever distance you want it to be from the player), add the player position to that vector, then set the target to the character position.

It's really not hard to do, and I would provide some sample code, but I'm a little lazy right now [img]http://public.gamedev.net//public/style_emoticons/default/tongue.png[/img]

Aww, hell, here's some pseudo-code:
[code]
float yaw, pitch, roll;//Some variables that will be in your camera class or wherever you want them
//You could also just use a quaternion rather than those variables, then just multiply the quaternions.
//I feel it's a little better to use yaw, pitch, and roll since you can keep track of your camera's rotations a little better (doesn't really matter if it's a free camera anyway)

//I really don't know which is which with yaw pitch roll, but only two are important (I think yaw and pitch, yaw being up/down, pitch being rotation?)
//Anyway, doesn't matter. Just find out which is which, add to them using input from a controller/keyboard, then create your quaternion

Quaternion rotator = Quaternion.FromYawPitchRoll(yaw,pitch,roll);

float camDistance = 5.0f;
vector3 back = Vector3.Backward;

back = Vector3.Transform(back, rotator);//Rotate our vector
rotator *= distance;//Push it out a distance from the player)
rotator += playerPosition;//Add the position

View = Matrix.CreateLookAt(back, playerPosition, upVector);

[/code]
[/quote]

Thanks for this, really helpful. I have managed to create an orbit and FPS camera, but there is room for improvement, I will factor in this concept.
I solved my problems however, and I created my FPS camera with head bobbing. This is the final code:

[CODE]
bool dxCamera::keyHeldA;
bool dxCamera::keyHeldS;
bool dxCamera::keyHeldW;
bool dxCamera::keyHeldD;
void dxCamera::perspectiveCamera(D3DXMATRIX &in_projectionMatrix, D3D10_VIEWPORT &in_viewPort, D3DXMATRIX &in_worldMatrix,
D3DXMATRIX &in_viewMatrix)
{
float yaw, pitch, roll;
D3DXMATRIX yawMatrix;
D3DXMATRIX pitchMatrix;
D3DXMATRIX rollMatrix;
D3DXMATRIX upLocal;
D3DXVECTOR3 Direction;
D3DXMATRIX directionMatrix;
// Set the yaw (Y axis), pitch (X axis), and roll (Z axis) rotations in radians.
rotation.x = m_rotationX * 0.0174532925f;
rotation.y = m_rotationY * 0.0174532925f;
rotation.z = m_rotationZ * 0.0174532925f;
//rotation.x = pitch;
//rotation.y = yaw;
//rotation.z = roll;
up = D3DXVECTOR3(0.0f, 1.0f, 0.0f);//Create the up vector
right = D3DXVECTOR3(1.0f, 0.0f, 0.0f);
lookat = D3DXVECTOR3(0.0f, 0.0f, 1.0f);
//D3DXVECTOR3 inputMoveVec[2] = {position, rotation};
// Setup matrices to rotate around axes
D3DXMatrixRotationAxis(&yawMatrix, &up, rotation.y);
D3DXMatrixRotationAxis(&pitchMatrix, &right, rotation.x);
//move lookat vector
D3DXVec3TransformCoord(&lookat, &lookat, &pitchMatrix);
D3DXVec3TransformCoord(&lookat, &lookat, &yawMatrix);
D3DXVec3Normalize(&lookat, &lookat);
//Get the direction vector from camera to target, normalise it.
//D3DXVec3Normalize(&Direction, &(lookat - right));
//Get the UP vector (in the world) and determine the cross product, to give us our right (left) hand vector.
D3DXVec3Cross(&right, &up, &lookat);
D3DXVec3Normalize(&right, &right);
//Cross product the right vector and direction vector, to determine up relative to the camera.
D3DXVec3Cross(&up, &lookat, &right);
//Useful for generation of direction looking at for future cameras
direction = atan2((double)lookat.z, (double)lookat.x);
velocity.x = (sin(direction));
velocity.y = 30.0f;
velocity.z = (cos(direction ));
D3DXMatrixIdentity(&in_viewMatrix);
in_viewMatrix._11 = right.x;
in_viewMatrix._21 = right.y;
in_viewMatrix._31 = right.z;
in_viewMatrix._12 = up.x;
in_viewMatrix._22 = up.y;
in_viewMatrix._32 = up.z;
in_viewMatrix._13 = lookat.x;
in_viewMatrix._23 = lookat.y;
in_viewMatrix._33 = lookat.z;
in_viewMatrix._41 = -D3DXVec3Dot(&(position), &right);
in_viewMatrix._42 = -D3DXVec3Dot(&(position), &up);
in_viewMatrix._43 = -D3DXVec3Dot(&(position), &lookat);
D3DXMatrixPerspectiveFovLH(&in_projectionMatrix, (float)D3DX_PI * 0.5f,
(float)in_viewPort.Width/(float)in_viewPort.Height, 0.1f, 5000.0f);
}
void dxCamera::initialiseFPSCamera(float in_headHeight, float in_bobPeriod, float in_bobScale)
{
bobPeriod = in_bobPeriod;
bobScale = in_bobScale;
headHeight = in_headHeight;
}
void dxCamera::walk(float speed, float sin)
{
bob = headHeight + sinf(sin * bobPeriod) * bobScale;
if(keyHeldW == true)
{
position.x += lookat.x * speed;
position.y = bob;
position.z += lookat.z * speed;
}
if(keyHeldS == true)
{
position.x -= lookat.x * speed;
position.y = bob;
position.z -= lookat.z * speed;
}
keyHeldW = false;
keyHeldS = false;
}
void dxCamera::strafe(float speed)
{
if(keyHeldA == true)
{
position -= right * speed;
}
if(keyHeldD == true)
{
position += right * speed;
}
keyHeldA = false;
keyHeldD = false;
}
void dxCamera::translateCamera(float &in_CameraX, float in_CameraY, float in_CameraZ)
{
position.x = in_CameraX;
position.y = in_CameraY;
position.z = in_CameraZ;
}
void dxCamera::rotateCamera(float &in_rotationX, float & in_rotationY, float &in_rotationZ)
{
m_rotationX = in_rotationX;
m_rotationY = in_rotationY;
m_rotationZ = in_rotationZ;
}
[/CODE] Edited by dxCUDA
0

Share this post


Link to post
Share on other sites
elegant technique to ratate cemara around point is to first rotate it at the point and then offset camera postion in that direction back. This could also solve your movement direction computation.
1- rotate camera at position: DXLookAt(at,position,up)
2- offset camera in the direction it is looking at : DXLookAt(at,position-normalize(position-at)*length,up)
3- if you want to move in the direction camera is looking , add the normalize(position-at)*length vector to camera position vector, or some other desired position vector. DXLookAt() functions wants vectors in world space, so you can use these vectors to update world space vectors such as positions of objects.
1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0