Sign in to follow this  

problem with "adding obstacle(triangle) to the camera's offset position

This topic is 3486 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

Hi friends, I have a general, multi purpose quaternion based camera class(for flight simulations). The camera's position(x,y,z) represents my position. I want to add obstacles(rectangles) to my front with an offset, say, for example 3 cm away, according to my orientation(according to the camera's position and orientation). I wrote some code to do this but failed. The obstacles are not in front of me, somewhere else. The camera class is long but I thought it will be good to post it here. Also my code to accomplish this task is below. struct CUSTOMVERTEX koridor_vert[804]; static int totalObstNumber = 0; void putObstacleToMyFront(LPDIRECT3DDEVICE9 & device,float x,float y,float z) { koridor_vert[4*(2*totalObstNumber-1)-4].assign(x+/*plus*/TheCamera.GetViewMatrix()->_13*5+0.1, -10, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,0,1); // koridor_vert[4*(2*totalObstNumber-1)-3].assign(x-TheCamera.GetViewMatrix()->_13*5+0.1, -10, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,1,1); // koridor_vert[4*(2*totalObstNumber-1)-2].assign(x+TheCamera.GetViewMatrix()->_13*5+0.1, -12, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,0,0); // koridor_vert[4*(2*totalObstNumber-1)-1].assign(x-TheCamera.GetViewMatrix()->_13*5+0.1, -12, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,1,0); // koridor_vert[4*(2*totalObstNumber)-4].assign(x+TheCamera.GetViewMatrix()->_13*5+0.1, -12, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,0,1); // koridor_vert[4*(2*totalObstNumber)-3].assign(x-TheCamera.GetViewMatrix()->_13*5+0.1, -12, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,1,1); // koridor_vert[4*(2*totalObstNumber)-2].assign(x+TheCamera.GetViewMatrix()->_11*5+0.1, -10, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,0,0); // koridor_vert[4*(2*totalObstNumber)-1].assign(x-TheCamera.GetViewMatrix()->_11*5+0.1, -10, z+TheCamera.GetViewMatrix()->_33*5+0.1, 0xffffffff,1,0); // // create a vertex buffer interface called koridor_buffer device->CreateVertexBuffer(804*sizeof(CUSTOMVERTEX), 0, CUSTOMFVF, D3DPOOL_MANAGED, &koridor_buffer, NULL); VOID* pVoid; // a void pointer // lock on_engel_buffer and load the vertices into it koridor_buffer->Lock(0, 0, (void**)&pVoid, 0); memcpy(pVoid, koridor_vert, sizeof(koridor_vert)); koridor_buffer->Unlock(); } function call: ... while(TRUE) { // Check to see if any messages are waiting in the queue if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { // If the message is WM_QUIT, exit the while loop if (msg.message == WM_QUIT) break; // translate keystroke messages into the right format TranslateMessage(&msg); // send the message to the WindowProc function DispatchMessage(&msg); } preRender(dxObj.getD3DDevice()); // prerenders the scene - starts the //rendering renderQuaterionCamera(dxObj.getD3DDevice()); postRender(dxObj.getD3DDevice()); // completing the rendering process // camera controls here, move, up, left, rotate etc. if (KEY_DOWN(VK_F4)) { ++totalObsNumber; putObstacle(dxObj.getD3DDevice(),TheCamera.GetPos().x,TheCamera.GetPos().y,TheCamera.GetPos().z); } } // And renders the vertices... //ChaseCamera.h // ChaseCamera.h: interface for the CChaseCamera class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_CHASECAMERA_H__C86626FD_FB7C_4CDC_BC7D_E11ABF79E1E4__INCLUDED_) #define AFX_CHASECAMERA_H__C86626FD_FB7C_4CDC_BC7D_E11ABF79E1E4__INCLUDED_ #if _MSC_VER > 1000 #pragma once #endif // _MSC_VER > 1000 #include <d3dx9math.h> namespace wiChaseCam { const D3DXVECTOR3 vDefCamOffset(0.0f , 10.0f , -10.0f); class CCamera { private: enum eDir { ceMove, ceStraf, ceUp }; enum eOrient { cePitch , ceRoll , ceYaw }; public: CCamera(); CCamera( D3DXVECTOR3 /*vPos*/ , D3DXVECTOR3 /*vCamOffset*/ ); virtual ~CCamera(); void SetOrientation(D3DXQUATERNION /*quatOrient*/); void SetPos(D3DXVECTOR3 /*vNewPos*/); void SetCameraOffset( D3DXVECTOR3 /*vOffset*/); D3DXVECTOR3 GetPos() const { return m_vectPosition; } void Pitch(float fAngle) { ApplyRotate(fAngle , cePitch); } void Roll(float fAngle) { ApplyRotate(fAngle , ceRoll); } void Yaw(float fAngle) { ApplyRotate(fAngle , ceYaw); } void Move(float fDistance ) { ApplyTranslation(fDistance , ceMove); } void Strafe(float fDistance ) { ApplyTranslation(fDistance , ceStraf); } void Up(float fDistance) { ApplyTranslation(fDistance , ceUp); } const D3DXMATRIX * GetViewMatrix(); // const; const D3DXVECTOR3 GetAxisZ() const; const D3DXVECTOR3 GetAxisY() const; const D3DXVECTOR3 GetAxisX() const; const D3DXQUATERNION CCamera::GetRotation() const { return m_quatOrientation; } static bool RotateZAxis(D3DXQUATERNION* /*pOrientation*/, float /*Angle*/); static bool RotateYAxis(D3DXQUATERNION* /*pOrientation*/, float /*Angle*/); static bool RotateXAxis(D3DXQUATERNION* /*pOrientation*/, float /*Angle*/); static bool RotateAxis(D3DXQUATERNION* /*pOrientation*/, D3DXVECTOR3* /*pAxis*/, float /*Angle*/); static D3DXVECTOR3* TransformVector(D3DXQUATERNION* /*pOrientation*/, D3DXVECTOR3* /*pAxis*/); bool Slerp(D3DXQUATERNION* /*pOrientation*/); void SetSpeed(float fSpeed) { m_fSpeed = (fSpeed < 0.0f) ? 0.0f : fSpeed; } void SetRPM(float fRPM) { m_fRPM = (fRPM < 0.0f) ? 0.0f : fRPM; } void SetSlerpSpeed(float fSlerpSpeed) { m_fSlerpSpeed = (fSlerpSpeed >= 0.0f && fSlerpSpeed <= 1.0) ? fSlerpSpeed : m_fSlerpSpeed; } float GetSpeed () const { return m_fSpeed; } float GetRPM() const { return m_fRPM; } float GetSlerpSpeed() const { return m_fSlerpSpeed; } protected: void Init(); void Update(); private: void ApplyTranslation(float /*fDistance*/ , eDir /*ceDir*/); void ApplyRotate(float /*fAngle*/ , eOrient /*oeOrient*/); private: D3DXVECTOR3 m_vectPosition; D3DXVECTOR3 m_vectCamOffset; D3DXQUATERNION m_quatOrientation; D3DXMATRIX m_matView; bool m_bNeedUpdated; float m_fSlerpSpeed; float m_fSpeed; float m_fRPM; }; } #endif // !defined(AFX_CHASECAMERA_H__C86626FD_FB7C_4CDC_BC7D_E11ABF79E1E4__INCLUDED_) // ChaseCamera.cpp // ChaseCamera.cpp: implementation of the CCamera class. // ////////////////////////////////////////////////////////////////////// //#include "stdafx.h" #include "ChaseCamera.h" ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// namespace wiChaseCam { CCamera::CCamera() { m_vectCamOffset = vDefCamOffset; m_vectPosition = D3DXVECTOR3( 0.0f , 0 , 0.0f ); // Initial position Init(); } CCamera::CCamera( D3DXVECTOR3 vPos , D3DXVECTOR3 vCamOffset ) { m_vectCamOffset = vCamOffset; m_vectPosition = vPos; Init(); } CCamera::~CCamera() {} void CCamera::Init() { m_fSlerpSpeed = 0.1f; m_fSpeed = 10.0f; m_fRPM = 60.0f; // 60 rotations per minute m_vectPosition -= m_vectCamOffset; D3DXQuaternionIdentity( &m_quatOrientation ); D3DXMatrixIdentity( & m_matView ); m_bNeedUpdated = true; } void CCamera::SetPos(D3DXVECTOR3 vNewPos) { m_vectPosition = vNewPos; m_bNeedUpdated = true; } const D3DXVECTOR3 CCamera::GetAxisX() const { D3DXVECTOR3 vAxis; vAxis.x = m_matView._11; vAxis.y = m_matView._21; vAxis.z = m_matView._31; return vAxis; } const D3DXVECTOR3 CCamera::GetAxisY() const { D3DXVECTOR3 vAxis; vAxis.x = m_matView._12; vAxis.y = m_matView._22; vAxis.z = m_matView._32; return vAxis; } const D3DXVECTOR3 CCamera::GetAxisZ() const { D3DXVECTOR3 vAxis; vAxis.x = m_matView._13; vAxis.y = m_matView._23; vAxis.z = m_matView._33; return vAxis; } const D3DXMATRIX * CCamera::GetViewMatrix() { if (m_bNeedUpdated) { Update(); } return &m_matView; } void CCamera::Update() { // 1) Build a new view matrix // 1.1) First calcuate Translation D3DXMATRIX matTranslation; D3DXMatrixTranslation( &matTranslation , -m_vectPosition.x , -m_vectPosition.y , -m_vectPosition.z ); // 1.2) Now calculate rotation, by taking the conjucate of the quaternion D3DXMATRIX matRotation; D3DXMatrixRotationQuaternion( &matRotation, &D3DXQUATERNION( -m_quatOrientation.x , -m_quatOrientation.y , -m_quatOrientation.z , m_quatOrientation.w )); // 2) Apply rotation & translation matrix at view matrix D3DXMatrixMultiply(&m_matView , &matTranslation , &matRotation ); // 3) Set flag to false, to save CPU m_bNeedUpdated = false; } void CCamera::SetCameraOffset(D3DXVECTOR3 vOffset) { m_vectCamOffset = vOffset; m_vectPosition -= vOffset; m_bNeedUpdated = true; } void CCamera::SetOrientation(D3DXQUATERNION quatOrient) { m_quatOrientation = quatOrient; m_bNeedUpdated = true; } void CCamera::ApplyTranslation(float fDistance , eDir ceDir) { D3DXVECTOR3 vDir; switch (ceDir) { case ceMove: { vDir = GetAxisZ(); break; } case ceStraf: { vDir = GetAxisX(); break; } case ceUp: { vDir = GetAxisY(); break; } } m_vectPosition += vDir * fDistance * m_fSpeed; m_bNeedUpdated = true; } void CCamera::ApplyRotate(float fAngle, eOrient oeOrient) { fAngle *= (m_fRPM / 60); // angle * per minute rotation switch( oeOrient ) { case cePitch: { RotateXAxis(&m_quatOrientation , fAngle); break; } case ceRoll: { RotateZAxis(&m_quatOrientation , fAngle); break; } case ceYaw: { RotateYAxis(&m_quatOrientation , fAngle); break; } } D3DXQuaternionNormalize(&m_quatOrientation , &m_quatOrientation); m_bNeedUpdated = true; } bool CCamera::RotateAxis(D3DXQUATERNION *pOrientation, D3DXVECTOR3 *pAxis, float fAngle) { bool Success=false; if(pOrientation && pAxis) { D3DXQUATERNION Rotation; D3DXQuaternionRotationAxis( &Rotation, TransformVector(pOrientation, pAxis), fAngle); *pOrientation *= Rotation; Success = true; } return(Success); } bool CCamera::RotateXAxis(D3DXQUATERNION *pOrientation, float fAngle) { bool bSuccess = false; if(pOrientation) { D3DXQUATERNION Rotation; D3DXQuaternionRotationAxis( &Rotation, TransformVector(pOrientation, &D3DXVECTOR3(1.0f, 0.0f, 0.0f)), fAngle); *pOrientation *= Rotation; bSuccess = true; } return(bSuccess); } bool CCamera::RotateYAxis(D3DXQUATERNION *pOrientation, float fAngle) { bool bSuccess = false; if(pOrientation) { D3DXQUATERNION Rotation; D3DXQuaternionRotationAxis( &Rotation, TransformVector(pOrientation, &D3DXVECTOR3(0.0f, 1.0f, 0.0f)), fAngle); *pOrientation *= Rotation; bSuccess = true; } return(bSuccess); } bool CCamera::RotateZAxis(D3DXQUATERNION *pOrientation, float fAngle) { bool bSuccess = false; if(pOrientation) { D3DXQUATERNION Rotation; D3DXQuaternionRotationAxis( &Rotation, TransformVector( pOrientation, &D3DXVECTOR3(0.0f, 0.0f, 1.0f)), fAngle); *pOrientation *= Rotation; bSuccess = true; } return(bSuccess); } bool CCamera::Slerp(D3DXQUATERNION *pOrientation) { bool bSuccess = false; if(pOrientation) // This is the orientation of the target { if (m_quatOrientation == *pOrientation) return false; D3DXQUATERNION quatInterpotedRotation; // Calculate SLERP D3DXQuaternionSlerp( &quatInterpotedRotation , &m_quatOrientation , pOrientation , m_fSlerpSpeed ); // Apply interpolted rotation m_quatOrientation = quatInterpotedRotation; D3DXQuaternionNormalize(&m_quatOrientation , &m_quatOrientation); bSuccess = true; m_bNeedUpdated = true; } return(bSuccess); } D3DXVECTOR3* CCamera::TransformVector(D3DXQUATERNION *pOrientation, D3DXVECTOR3 *pAxis) { D3DVECTOR vNewAxis; D3DXMATRIX matRotation; // Build a matrix from the quaternion. D3DXMatrixRotationQuaternion(&matRotation, pOrientation); // Transform the queried axis vector by the matrix. vNewAxis.x = pAxis->x * matRotation._11 + pAxis->y * matRotation._21 + pAxis->z * matRotation._31 + matRotation._41; vNewAxis.y = pAxis->x * matRotation._12 + pAxis->y * matRotation._22 + pAxis->z * matRotation._32 + matRotation._42; vNewAxis.z = pAxis->x * matRotation._13 + pAxis->y * matRotation._23 + pAxis->z * matRotation._33 + matRotation._43; memcpy(pAxis, &vNewAxis, sizeof(vNewAxis)); // Copy axis. return(pAxis); } }

Share this post


Link to post
Share on other sites
This is actually pretty easy to do. Say for instance you want something 5 units in front of the camera:


D3DXVECTOR3 obstaclePos;
D3DXMATRIXA16 cameraTransform;
D3DXMatrixInverse(&cameraTransform, NULL, TheCamera.GetViewMatrix());
D3DXVec3TransformCoord(obstaclePos, &D3DXVECTOR3(0, 0, 5), &cameraTransform);


See the camera's view matrix is just the inverse of a matrix representing the camera's total transformations (basically its world matrix). If you apply that matrix to any point, that point will now be relative to the camera's position and orientation. This applies to any object with a transform matrix, of course.

Oh and btw, if you need to post lots of code I'd suggest using the "source" tags. You can see how to use them in the forum FAQ.

Share this post


Link to post
Share on other sites
Thank you for your help MJP. I put your code in a function and called this function when a key was pressed. But nothing appeared on the screen. :(

I am used to draw these obstacles(say rectangle) with the function DrawPrimitive. I give 4 vertices, and assign these vertices their own x,y,z. Tedious.
(device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2))

I did not use your code before. If you can explain briefly,give some useful tips and show how to add obstacles to camera's left,right, or front, I would be very gratefull.

As I said before, I used vertex buffers but I want to use your clean and pure code.

Share this post


Link to post
Share on other sites
Well that code just gives you a position...you'd have to apply it by making a transformation matrix from it. You could make one by using D3DXMatrixTranslation and using obstaclePos as the x, y, z values. Then you could apply it as your world transform before drawing the obstacle.

Share this post


Link to post
Share on other sites

This topic is 3486 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.

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