• Create Account

# Camera rotation around selected object

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

6 replies to this topic

### #1thmfrnk  Members   -  Reputation: 147

Like
0Likes
Like

Posted 27 April 2013 - 09:13 AM

Hey,

I have the same problem like this guy here: http://www.gamedev.net/topic/175029-rotate-around-point-ala-cinema4d-problem/

So just want the same camera like in C4D. So i'm doing something like this:

MatCenterRotation * MatRotY * MatRotX * MatCamPos..

It works, but for sure, the camera will not stay at the same position while i'm selecting other objects..

I also tried to subtract the CenterRotationPoint from the MatCamPos, but this seems only work for one axis..

Any Idea to solve this problem?

Thx,

Thomas

### #2imoogiBG  Members   -  Reputation: 2496

Like
0Likes
Like

Posted 27 April 2013 - 10:16 AM

CameraInvDirectionVector; (usually this is vec3(1.f 0.f, 0.f))

Rotate the camera CameraInvDirectionVector;

Create the XYZ (or axis or watever) rotation matrix; try using D3DXMatrixRotationYallPitchRoll (y ,x, z) rotation order

use the D3DXVec3TransformNormal to rotate the CameraInvDirectionVector

the camera position is

CamPos = -CameraInvDirectionVector * CameraDistanceRadius + TargetPoint;

CamLookAtPos = CamPos + CameraInvDirectionVector;

For the most cases the vec3(0,1,0) for up directon will do the job)

Look that  simple tutorial :

void DBOXCameraTP::MoveInDirection(D3DXVECTOR3 Direction , float Units)
{
D3DXVec3Normalize(&Direction , &Direction);
Eye += Direction*Units;
return;
}

/***********************************************************************************************
Camera vector control methods
************************************************************************************************/
void DBOXCameraTP::Yaw(float Angle)
{
D3DXMATRIX Transform;

D3DXMatrixRotationY(&Transform  ,Angle);
D3DXVec3TransformCoord(&Up , &Up , &Transform);

D3DXVec3TransformCoord(&Look , &Look , &Transform);
D3DXVec3TransformCoord(&Right , &Right , &Transform);

YawCnt += Angle;
return;
}

void DBOXCameraTP::Pitch(float Angle)
{
D3DXMATRIX Transform;
D3DXMatrixRotationAxis(&Transform  , &Right , Angle);

D3DXVec3TransformCoord(&Look , &Look , &Transform);
D3DXVec3TransformCoord(&Up , &Up , &Transform);

PitchCnt += Angle;
return;
}

where the default values are :

Right = D3DXVECTOR3(1.0f , 0.0f , 0.0f);
Up = D3DXVECTOR3(0.0f , 1.0f , 0.0f);
Look = D3DXVECTOR3(0.0f , 0.0f , 1.0f);

YawCnt = PitchCnt = 0.0f;

NOTE: I was 15 when I wrote that .... So there are more clever ways to to the job.

### #3thmfrnk  Members   -  Reputation: 147

Like
0Likes
Like

Posted 27 April 2013 - 11:48 AM

Sorry i dont really know what you're doing there. You are sure this will result the same camera movement like in cinema4d?

### #4Norman Barrows  Crossbones+   -  Reputation: 5189

Like
0Likes
Like

Posted 27 April 2013 - 02:19 PM

to make the camera look at some point x,y,z (the lookat point) from some distance d, rotated around x,y,z by xr,yr:

1. translate the camera by 0,0, -d.

2. rotate the camera by xr, then yr.

3. translate the camera by x,y,z to move it out to its proper location in the world.

attach yr to your mousex and xr to your mousey, and d to your mouse wheel to rotate around the lookat point and zoom in and out with the mouse.

Norm Barrows

Rockland Software Productions

"Building PC games since 1989"

rocklandsoftware.net

PLAY CAVEMAN NOW!

http://rocklandsoftware.net/beta.php

### #5Juliean  GDNet+   -  Reputation: 5440

Like
0Likes
Like

Posted 27 April 2013 - 02:38 PM

Since I assume the camera in C4D works somehow like in Maya/3ds, I think my code should work for you:

void SceneWindowCtrl::OnMoveCamera(const Vector2& vDist)
{
//panning
if(Input::KeyHold(Keys::STRG))
{
//access camerea attributes
D3DXVECTOR3 vDir(m_pCamera->GetDirection()), vUp(m_pCamera->GetUp());
D3DXMATRIX mView(m_pCamera->GetViewMatrix());
D3DXMatrixInverse(&mView, nullptr, &mView);

//screen space drag vector
D3DXVECTOR3 vDrag(-(float)vDist.x, (float)vDist.y, 0.0f);
//transform drag vector to world space
D3DXVec3TransformNormal(&vDrag, &vDrag, &mView);
D3DXVec3Normalize(&vDrag, &vDrag);
vDrag /= 5.0f;

m_pCamera->Move(vDrag);
}
//rotating
else
{
//setup vectors
D3DXVECTOR3 vDir(m_pCamera->GetDirection()), vLookAt(m_pCamera->GetLookAt()), vUp(m_pCamera->GetUp());
D3DXVECTOR3 vDrag((float)vDist.x, (float)vDist.y, 0.0f);

D3DXMATRIX mRotation, mView(m_pCamera->GetViewMatrix());
//inverse view
D3DXMatrixInverse(&mView, nullptr, &mView);
//transform mouse drag vector to object space
D3DXVec3TransformNormal(&vDrag, &vDrag, &mView);
D3DXVec3Normalize(&vDrag, &vDrag);

D3DXVECTOR3 vAxis;
//create axis from drag and direction vector
D3DXVec3Cross(&vAxis, &vDrag, &vDir);
D3DXVec3Normalize(&vAxis, &vAxis);

//rotate around axis
//transform direction and up
D3DXVec3TransformNormal(&vDir, &vDir, &mRotation);
//recalculate position
const float cameraDist = m_pCamera->GetDistance();

//recalculate up
D3DXVECTOR3 vUpAxis;
//calculate "rotation" axis for up vector
D3DXVec3Cross(&vUpAxis, &vUp, &vDir);
vUpAxis = D3DXVECTOR3(vUpAxis.x, 0.0f, vUpAxis.z);
D3DXVec3Normalize(&vUpAxis, &vUpAxis);

//cross direction and up axis for up vector
D3DXVec3Cross(&vUp, &vDir, &vUpAxis);
m_pCamera->SetUp(vUp);
}
}


As you can see, in order to get a functional camera as in a 3d editor, its a littel complicated than just a 3rd-person sort of camera. You now only need to position the camera at the object, and give it a certain distance. Then you can rotate and also pan the camera around that object.

Edited by Juliean, 27 April 2013 - 02:39 PM.

### #6thmfrnk  Members   -  Reputation: 147

Like
0Likes
Like

Posted 28 April 2013 - 06:57 AM

Hey Juliean,

can you also please post your code from your camera class?

thx,

Thomas

### #7Juliean  GDNet+   -  Reputation: 5440

Like
0Likes
Like

Posted 28 April 2013 - 08:45 AM

Sure, but its nothing more than a data container with some caching utility functions:

        class Camera
{
public:
Camera(const Vector2& vScreenSize);
virtual ~Camera(void);

float GetDistance(void) const;
D3DXVECTOR3 GetDirection(void) const;
const D3DXVECTOR3& GetPosition(void) const;
const D3DXVECTOR3& GetLookAt(void) const;
const D3DXVECTOR3& GetUp(void) const;
const D3DXMATRIXA16& GetViewMatrix(void) const;
const D3DXMATRIXA16& GetProjectionMatrix(void) const;
const D3DXMATRIXA16& GetViewProjectionMatrix(void) const;
const Frustum& GetFrustum(void) const;

void SetPosition(const D3DXVECTOR3& vPosition);
void SetUp(const D3DXVECTOR3& vUp);

void Move(const D3DXVECTOR3& vDist);

private:

void CalculateMatrices(void);
void CalculateDirection(void);

Vector2 m_vScreenSize;

D3DXMATRIXA16 m_mViewProjection;
D3DXMATRIXA16 m_mProjection;
D3DXMATRIXA16 m_mView;

D3DXVECTOR3 m_vLookAt;
D3DXVECTOR3 m_vPosition;
D3DXVECTOR3 m_vUp;
D3DXVECTOR3 m_vDirection;

Frustum m_frustum;
};


        Camera::Camera(const Vector2& vScreenSize): m_vPosition(10.0f, 0.0f, 0.0f), m_vLookAt(0.0f, 0.0f, 0.0f), m_vUp(0.0f, 1.0f, 0.0f), m_vScreenSize(vScreenSize)
{
CalculateDirection();
CalculateMatrices();
}

Camera::~Camera(void)
{
}

float Camera::GetDistance(void) const
{
return D3DXVec3Length(&m_vDirection);
}

D3DXVECTOR3 Camera::GetDirection(void) const
{
D3DXVECTOR3 vDir = m_vDirection;
D3DXVec3Normalize(&vDir, &vDir);
return vDir;
}

const D3DXVECTOR3& Camera::GetUp(void) const
{
return m_vUp;
}

const D3DXVECTOR3& Camera::GetPosition(void) const
{
return m_vPosition;
}

const D3DXVECTOR3& Camera::GetLookAt(void) const
{
return m_vLookAt;
}

const D3DXMATRIXA16& Camera::GetViewMatrix(void) const
{
return m_mView;
}

const D3DXMATRIXA16& Camera::GetProjectionMatrix(void) const
{
return m_mProjection;
}

const D3DXMATRIXA16& Camera::GetViewProjectionMatrix(void) const
{
return m_mViewProjection;
}

const Frustum& Camera::GetFrustum(void) const
{
return m_frustum;
}

void Camera::SetPosition(const D3DXVECTOR3& vPosition)
{
m_vPosition = vPosition;
CalculateDirection();
CalculateMatrices();
}

void Camera::SetUp(const D3DXVECTOR3& vUp)
{
m_vUp = vUp;
CalculateMatrices();
}

void Camera::Move(const D3DXVECTOR3& vDistance)
{
m_vPosition += vDistance;
m_vLookAt += vDistance;
CalculateDirection();
CalculateMatrices();
}

void Camera::CalculateMatrices(void)
{
D3DXMatrixLookAtLH(&m_mView, &m_vPosition, &m_vLookAt, &m_vUp);
D3DXMatrixPerspectiveFovLH(&m_mProjection, D3DX_PI/4, m_vScreenSize.x / (float)m_vScreenSize.y, 0.5f, 5000.0f );
D3DXMatrixMultiply(&m_mViewProjection, &m_mView, &m_mProjection);
m_frustum.CalculateFrustum(m_mViewProjection);
}

void Camera::CalculateDirection(void)
{
D3DXVECTOR3 vDir(m_vLookAt);
vDir -= m_vPosition;

if(D3DXVec3Length(&vDir) == 0.0f)
return;

m_vDirection = vDir;
}


Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

PARTNERS