Jump to content

  • Log In with Google      Sign In   
  • 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.

  • You cannot reply to this topic
6 replies to this topic

#1 thmfrnk   Members   -  Reputation: 109

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



Sponsor:

#2 imoogiBG   Members   -  Reputation: 1024

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.


#3 thmfrnk   Members   -  Reputation: 109

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?

#4 Norman Barrows   Crossbones+   -  Reputation: 1849

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 1988"

 

rocklandsoftware.net

 


#5 Juliean   GDNet+   -  Reputation: 2244

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
        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, 27 April 2013 - 02:39 PM.


#6 thmfrnk   Members   -  Reputation: 109

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



#7 Juliean   GDNet+   -  Reputation: 2244

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