//Set up the world, view, and projection transform matrices. void Graphics::SetupMatrices() { if(!CurrentCamera) return; //^? I'm putting this here to stop the game from crashing when there is no camera... // it's not that we shouldn't crash when there is no camera... obviously thats a hint that // something is horrendously wrong. It's just annoying. //Set the position of the camera. float cameraX = CurrentCamera->transform->Position.x; float cameraY = CurrentCamera->transform->Position.y; float cameraH = -10.0f; //The eye point is the location of the viewer (center of the screen, 10 units away). Vec3 eyePoint( cameraX, cameraY, cameraH ); //The look-at point is where the viewer is looking (center of the screen). Vec3 lookAtPoint( cameraX, cameraY, 0.0f ); //The up vector defines which way is up (the y-direction). Vec3 upVector( 0.0f, 1.0f, 0.0f ); //Create a left-handed view matrix. Mat4 matView; D3DXMatrixLookAtLH(&matView, &eyePoint, &lookAtPoint, &upVector); //Store the view matrix ViewMatrix = matView; //Create an orthogonal left-handed projection matrix. //This will transform everything to the view port with no perspective. //The near and far clipping plains are still needed, but not as important. Mat4 matProj; D3DXMatrixOrthoLH(&matProj, SurfaceSize.x , SurfaceSize.y , 1.0f, 100.0f); //Store the projection matrix; ProjMatrix = matProj; //Store the view projection matrix ViewProjMatrix = ViewMatrix * ProjMatrix; }
VOID InitWorldViewProjMatrix(HWND hwnd) { // Initialize world matrix D3DXMatrixIdentity(&g_mWorld); // Initialize view matrix D3DXVECTOR3 eyePoint(0.0f, 0.0f, -5.0f); g_EyePos = eyePoint; D3DXVECTOR3 lookAt(0.0f, 0.0f, 0.0f); D3DXVECTOR3 Up(0.0f, 1.0f, 0.0f); D3DXMatrixLookAtLH(&g_mView, &eyePoint, &lookAt, &Up); // Initialize projection matrix float fov = (float)(D3DX_PI / 4); // Calculate aspect ratio RECT rc; GetClientRect(hwnd, &rc); UINT width = rc.right - rc.left; UINT height = rc.bottom - rc.top; float aspectRatio = width / (float)height; D3DXMatrixPerspectiveFovLH(&g_mProj, fov, aspectRatio, 1.0f, 1000.0f); g_mWorldViewPorj = g_mWorld * g_mView * g_mProj; }
// the eye point for a perspective view will not be at infinity (x,y,z,1) Vector ViewInformation::getEyePointPerspective() const { float distance; // the distance of the eye from the target based on the fov and // windowsize distance = m_WindowSize / 2.0f / (float)tan( m_Fov/2.0f ); Vector eyePoint(m_Orientation.applyRotation(Vector(0.0f, 0.0f, distance, 1.0f))); return eyePoint; }
static void SetTransform (const NewtonBody* body, const dFloat* matrix, int threadId) { NewtonUserJoint* player; PlayerController* controller; // find the player joint; player = NULL; for (NewtonJoint* joint = NewtonBodyGetFirstJoint(body); joint; joint = NewtonBodyGetNextJoint(body, joint)) { NewtonUserJoint* tmp; tmp = (NewtonUserJoint*) NewtonJointGetUserData(joint); if (CustomGetJointID (tmp) == PLAYER_JOINT_ID) { player = tmp; break; } } // call the generic transform callback controller = (PlayerController*) CustomGetUserData(player); #if 1 // this will project the visual mesh to the ground dMatrix visualMatrix; CustomPlayerControllerGetVisualMaTrix (player, &visualMatrix[0][0]); #else // this will display the player at the collision shape position const dMatrix& visualMatrix = *((dMatrix*) matrix); #endif controller->m_setTransformOriginal (body, &visualMatrix[0][0], threadId); // now we will set the camera to follow the player dVector eyePoint (visualMatrix.TransformVector(controller->m_point)); // check if the player wants third person view static int prevCKeyDown = IsKeyDown ('C'); int isCkeyDwon = IsKeyDown ('C'); if (isCkeyDwon && !prevCKeyDown) { controller->m_isThirdView = !controller->m_isThirdView; } prevCKeyDown = isCkeyDwon; if (controller->m_isThirdView) { dVector dir (GetCameraDir ()); eyePoint -= dir.Scale (8.0f); } SetCameraEyePoint (eyePoint); // NewtonBodyGetMatrix (body, &matrix[0][0]); // cameraEyepoint = matrix.m_posit; // cameraEyepoint.m_y += 1.0f; }
static void GenericContactProcess (const NewtonJoint* contactJoint, dFloat timestep, int threadIndex) { dFloat contactBestSpeed; dVector contactPosit; SoundEffect* bestSound; bestSound = NULL; contactBestSpeed = 0.5f; NewtonBody* const body0 = NewtonJointGetBody0(contactJoint); for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dFloat contactNormalSpeed; NewtonMaterial* material; // get the material for this contact; material = NewtonContactGetMaterial (contact); contactNormalSpeed = NewtonMaterialGetContactNormalSpeed (material); if (contactNormalSpeed > contactBestSpeed){ dVector normal; contactBestSpeed = contactNormalSpeed; NewtonMaterialGetContactPositionAndNormal (material, body0, &contactPosit[0], &normal[0]); bestSound = (SoundEffect *)NewtonMaterialGetMaterialPairUserData (material); } } // now that we found we can play then if (bestSound) { // calculate the volume; dFloat volume; dFloat dist2; dVector eyePoint (GetCameraEyePoint() - contactPosit); dist2 = eyePoint % eyePoint; if (dist2 < (MAX_SOUND_DISTANCE * MAX_SOUND_DISTANCE)) { volume = 1.0f; if (dist2 > (MIN_SOUND_DISTANCE * MIN_SOUND_DISTANCE)) { volume = 1.0f - (dSqrt (dist2) - MIN_SOUND_DISTANCE) / (MAX_SOUND_DISTANCE - MIN_SOUND_DISTANCE); } bestSound->m_manager->Play(bestSound->m_sound, volume, 0); } } }
// the eye point for an orthographic view will be at infinity (x,y,z,0) Vector ViewInformation::getEyePointOrthographic() const { Vector eyePoint(m_Orientation.applyRotation(Vector(0.0f, 0.0f, 1.0f, 0.0f))); return eyePoint; }
////////////////////////////////////////////////////////////////////////// // 행렬 세팅 // // World, View, Projection ////////////////////////////////////////////////////////////////////////// VOID SetupMatrices() { // World D3DXMATRIXA16 worldMatrix; // float 연산의 정밀도를 위해서 1000으로 나머지 연산 UINT time = timeGetTime() % 1000; // 1초마다 한바퀴씩(2 * pi) 회전 할 각도 FLOAT angle = time * ( 2.0f * D3DX_PI ) / 1000.0f; // Y축 기준으로 회전하는 행렬 생성 D3DXMatrixRotationY( &worldMatrix, angle ); // 생성한 회전 행렬을 World 행렬로 디바이스에 설정 g_pd3dDevice->SetTransform( D3DTS_WORLD, &worldMatrix ); ////////////////////////////////////////////////////////////////////////// // View 행렬을 정의하기 위해서 세가지 값이 필요하다. // 원점, 시점, 업벡터 ////////////////////////////////////////////////////////////////////////// // 1. 눈의 위치 ( 0, 3.0, -5) D3DXVECTOR3 eyePoint( 0.0f, 3.0f, -5.0f ); // 2. 눈이 바라보는 위치 ( 0, 0, 0 ) D3DXVECTOR3 lookAtPoint( 0.0f, 0.0f, 0.0f ); // 3. 업벡터 ( 0, 1, 0 ) D3DXVECTOR3 upVector( 0.0f, 1.0f, 0.0f ); D3DXMATRIXA16 viewMatrix; // 1, 2, 3의 값으로 View 행렬 생성 D3DXMatrixLookAtLH( &viewMatrix, &eyePoint, &lookAtPoint, &upVector ); // 생성한 View 행렬을 디바이스에 설정 g_pd3dDevice->SetTransform( D3DTS_VIEW, &viewMatrix ); // Projection 행렬을 정의하기 위해서는 시야각(FOV=Field Of View)과 종횡비(aspect ratio), 클리핑 평면 값이 필요하다. D3DXMATRIXA16 projMatrix; /// matProj : 값이 설정될 행렬 /// D3DX_PI/4 : FOV(D3DX_PI/4 = 45도) /// 1.0f : 종횡비 /// 1.0f : 근접 클리핑 평면(near clipping plane) /// 100.0f : 원거리 클리핑 평면(far clipping plane) D3DXMatrixPerspectiveFovLH( // 행렬을 얻어올 변수 &projMatrix, // FOV(D3DX_PI/4 = 45도) D3DX_PI / 4, // 종횡비 1:1 1.0f, // Near Plane 1.0f, // Far Plane 100.0f ); // 생성한 Projection 행렬을 디바이스에 설정 g_pd3dDevice->SetTransform( D3DTS_PROJECTION, &projMatrix ); }
/// \brief Drawing the DynamicTerrain Action::ResultE DynamicTerrain::drawPrimitives( DrawActionBase* action ) { // do frustum culling here.. extract frustum from the current camera: RenderAction* renderAction = dynamic_cast< RenderAction* >( action ); if( needInitialize_ ) { if( getHeightData() != NullFC ) { if( getLevelSize() < 3 ) { SWARNING << "DynamicTerrain: LevelSize is below minimum (using default)!" << std::endl; setLevelSize( 63 ); } // todo: choose the correct height-/texturedata source: geoClipmaps_.initialize( getLevelSize(), &imageHeightSource_, getTextureSource() ); } needInitialize_ = false; } if( !geoClipmaps_.isValid() ) { // no valid data yet return Action::Continue; } // todo: get the viewport of the RenderAction, check if the camera already has a terrain attachment: // if not: create a new TerrainView and attach it to the camera // update/render the view if( renderAction ) { // frustum culling const FrustumVolume& frustum = renderAction->getFrustum(); // make an update right here: Matrix camera = renderAction->getCameraToWorld(); Matrix toworld = renderAction->top_matrix(); toworld.invert(); camera.multLeft(toworld); Pnt3f eyePoint( camera[ 3 ][ 0 ], camera[ 3 ][ 1 ], camera[ 3 ][ 2 ] ); // transform the eyePoint to the unscaled sample space: const WorldTransformation worldTransform = getWorldTransform(); const Pnt3f worldOffset( worldTransform.offset[ 0 ], 0.0f, worldTransform.offset[ 1 ] ); const Pnt3f localEyePoint = componentDivide( ( eyePoint - worldOffset ), worldTransform.sampleDistance ); if( !getDisableUpdate() ) { geoClipmaps_.update( localEyePoint ); } // and now draw what we have: ClipmapRenderParameters renderParams; renderParams.renderAction = renderAction; renderParams.window = renderAction->getWindow(); renderParams.viewFrustum = frustum; renderParams.enableFrustumCulling = getEnableFrustumCulling(); renderParams.showTransitionRegions = getShowTransitionRegions(); renderParams.useVboExtension = getUseVboExtension(); renderParams.globalTexture = globalTexture_; renderParams.heightColorTexture = getHeightColorTexture(); renderParams.worldTransform = worldTransform; ClipmapRenderStatistics renderStats; geoClipmaps_.render( renderParams, renderStats ); if( getShowBoundingBoxes() ) { //drawBox( } // update stats: StatCollector* statCollector = action->getStatistics(); if( statCollector ) { StatIntElem* statTriangleCount = statCollector->getElem( Drawable::statNTriangles, false ); StatIntElem* statVertexCount = statCollector->getElem( Drawable::statNVertices, false ); if( statTriangleCount ) { statTriangleCount->add( renderStats.drawnTriangleCount ); } if( statVertexCount ) { statVertexCount->add( renderStats.transformedVertexCount ); } } } else { //todo: can this ever happen?! SLOG << "Test\n"; } return Action::Continue; }