Jump to content
  • Advertisement
Sign in to follow this  
thmfrnk

Camera rotation around selected object

This topic is 1972 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement

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.

Share this post


Link to post
Share on other sites
Sorry i dont really know what you're doing there. You are sure this will result the same camera movement like in cinema4d?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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
        D3DXMatrixRotationAxis(&mRotation, &vAxis, acl::math::degToRad(D3DXVec3Length(&vDrag)));
        //transform direction and up
        D3DXVec3TransformNormal(&vDir, &vDir, &mRotation);
        //recalculate position
        const float cameraDist = m_pCamera->GetDistance();
        m_pCamera->SetPosition(vLookAt - vDir*cameraDist);

        //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

Share this post


Link to post
Share on other sites

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;
        }

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!