void gr_GetEulerVectors( const LTVector vAngles, LTVector &vRight, LTVector &vUp, LTVector &vForward) { LTMatrix mTemp; gr_SetupMatrixEuler(vAngles, mTemp.m); mTemp.GetBasisVectors(&vRight, &vUp, &vForward); }
bool CTrackedNodeMgr::GetOrientationSpace( HTRACKEDNODE ID, LTVector& vRight, LTVector& vUp, LTVector& vForward) { if(!CheckValidity(ID)) return false; //read in the vectors LTMatrix mTargetTransform = ID->m_mInvTargetTransform; mTargetTransform.Transpose(); mTargetTransform.GetBasisVectors(&vRight, &vUp, &vForward); return true; }
// returns true if intersection happened, plus fills hit dist param with // the parametric position of the intersection on the ray dir. // the obb must be within ray-origin + ray-dir. So ray-dir isn't normalized. // source : Real-time rendering moller&haines inline bool i_OrientedBoundingBoxTest(const ModelOBB &mobb, const LTransform &tf, const LTVector &origin, const LTVector &dir, float &t) { float tmin = -999999999999.0f; float tmax = 999999999999.0f; LTVector vObbPos = mobb.m_Pos; // Setup our OBB's translated position LTMatrix obb_mat; obb_mat.Identity(); obb_mat.SetBasisVectors( &tf.m_Rot.Right(), &tf.m_Rot.Up(), &tf.m_Rot.Forward() ); obb_mat.SetTranslation( tf.m_Pos ); obb_mat.Apply(vObbPos); LTVector p = vObbPos - origin; float e ; float f; float hi; float t1,t2; // Setup OBB rotation tranforms LTMatrix mObbMat; mObbMat.SetBasisVectors(&mobb.m_Basis[0], &mobb.m_Basis[1], &mobb.m_Basis[2]); // Get matrix of our Node's rotation LTMatrix mTrMat; tf.m_Rot.ConvertToMatrix(mTrMat); // Apply our node rotation to our obb rotation mTrMat.Apply(mObbMat); // Get our translated basis vectors LTVector axis[3]; mObbMat.GetBasisVectors(&axis[0], &axis[1], &axis[2]); LTVector vSize = mobb.m_Size * 0.5f ; // we want the 1/2 size of the box. for( int i = 0 ; i < 3 ; i++ ) { e = axis[i].Dot(p); f = axis[i].Dot(dir); hi= vSize[i] ; // if( fabs(f) > 0.00015 ) { t1 = ( e + hi ) / f ; t2 = ( e - hi ) / f ; if( t1 > t2 ) {float v = t2 ; t2 = t1 ; t1 = v ; } if(t1 > tmin ) {tmin = t1 ;} if(t2 < tmax ) {tmax = t2 ;} if(tmin > tmax ) { return false ; } if(tmax < 0 ) { return false ; } } else if( ((-e - hi) > 0 ) || ( (-e + hi) < 0 )) { t = 0 ; return false ; } } if( tmin > 0 ) { t = tmin ; return true ; } else { t = tmax ; return true ;} }
static void d3d_DrawRotatableSprite(const ViewParams& Params, SpriteInstance *pInstance, SharedTexture *pShared) { if(!d3d_SetTexture(pShared, 0, eFS_SpriteTexMemory)) return; float fWidth = (float)((RTexture*)pShared->m_pRenderData)->GetBaseWidth(); float fHeight = (float)((RTexture*)pShared->m_pRenderData)->GetBaseHeight(); //cache the object position LTVector vPos = pInstance->GetPos(); LTMatrix mRotation; d3d_SetupTransformation(&vPos, (float*)&pInstance->m_Rotation, &pInstance->m_Scale, &mRotation); //get our basis vectors LTVector vRight, vUp, vForward; mRotation.GetBasisVectors(&vRight, &vUp, &vForward); //scale the vectors to be the appropriate size vRight *= fWidth; vUp *= fHeight; // Setup the points. RGBColor Color; d3d_GetSpriteColor(pInstance, &Color); uint32 nColor = Color.color; CSpriteVertex SpriteVerts[4]; SpriteVerts[0].SetupVert(vPos + vUp - vRight, nColor, 0.0f, 0.0f); SpriteVerts[1].SetupVert(vPos + vUp + vRight, nColor, 1.0f, 0.0f); SpriteVerts[2].SetupVert(vPos + vRight - vUp, nColor, 1.0f, 1.0f); SpriteVerts[3].SetupVert(vPos - vRight - vUp, nColor, 0.0f, 1.0f); //figure out our final vertices to use CSpriteVertex *pPoints; uint32 nPoints; CSpriteVertex ClippedSpriteVerts[40 + 5]; if(pInstance->m_ClipperPoly != INVALID_HPOLY) { if(!d3d_ClipSprite(pInstance, pInstance->m_ClipperPoly, &pPoints, &nPoints, ClippedSpriteVerts)) { return; } } else { pPoints = SpriteVerts; nPoints = 4; } if((pInstance->m_Flags & FLAG_SPRITEBIAS) && !(pInstance->m_Flags & FLAG_REALLYCLOSE)) { //adjust the points for(uint32 nCurrPt = 0; nCurrPt < nPoints; nCurrPt++) { //get the sprite vertex that we are modifying LTVector& vPt = SpriteVerts[nCurrPt].m_Vec; //find a point relative to the viewer position LTVector vPtRelCamera = vPt - Params.m_Pos; //determine the distance from the camera float fZ = vPtRelCamera.Dot(Params.m_Forward); if(fZ <= NEARZ) continue; //find the bias, up to, but not including the near plane float fBiasDist = SPRITE_POSITION_ZBIAS; if((fZ + fBiasDist) < NEARZ) fBiasDist = NEARZ - fZ; //now adjust our vectors accordingly so that we can move it forward //but have it be the same size float fScale = 1 + fBiasDist / fZ; vPt = Params.m_Right * vPtRelCamera.Dot(Params.m_Right) * fScale + Params.m_Up * vPtRelCamera.Dot(Params.m_Up) * fScale + (fZ + fBiasDist) * Params.m_Forward + Params.m_Pos; } } LTEffectImpl* pEffect = (LTEffectImpl*)LTEffectShaderMgr::GetSingleton().GetEffectShader(pInstance->m_nEffectShaderID); if(pEffect) { pEffect->UploadVertexDeclaration(); ID3DXEffect* pD3DEffect = pEffect->GetEffect(); if(pD3DEffect) { RTexture* pTexture = (RTexture*)pShared->m_pRenderData; pD3DEffect->SetTexture("texture0", pTexture->m_pD3DTexture); i_client_shell->OnEffectShaderSetParams(pEffect, NULL, NULL, LTShaderDeviceStateImp::GetSingleton()); UINT nPasses = 0; pD3DEffect->Begin(&nPasses, 0); for(UINT i = 0; i < nPasses; ++i) { pD3DEffect->BeginPass(i); D3D_CALL(PD3DDEVICE->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, nPoints-2, pPoints, sizeof(CSpriteVertex))); pD3DEffect->EndPass(); } pD3DEffect->End(); } } else { D3D_CALL(PD3DDEVICE->SetVertexShader(NULL)); D3D_CALL(PD3DDEVICE->SetFVF(SPRITEVERTEX_FORMAT)); D3D_CALL(PD3DDEVICE->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, nPoints-2, pPoints, sizeof(CSpriteVertex))); } d3d_DisableTexture(0); }
float ModelDraw::GetDirLightAmount(ModelInstance* pInstance, const LTVector& vInstancePosition) { const WorldTreeNode* pWTRoot = world_bsp_client->ClientTree()->GetRootNode(); //the maximum distance we would ever need to cast a node float fLongestDist = (pWTRoot->GetBBoxMax() - pWTRoot->GetBBoxMin()).Mag(); //figure out the segment that we will now intersect (opposite direction that the sun is going //since we are shooting towards it) LTVector vDir = g_pStruct->m_GlobalLightDir * -fLongestDist; // Just do a single intersection in the middle out if the variance calculation's turned off if (!g_CV_ModelSunVariance.m_Val) return CastRayAtSky(vInstancePosition, vDir) ? 1.0f : 0.0f; // Get the orienation of the model instance LTMatrix mInstanceTransform; pInstance->SetupTransform(mInstanceTransform); // Figure out the shadow in/out direction LTVector vUp, vForward, vRight; mInstanceTransform.GetBasisVectors(&vRight, &vUp, &vForward); LTVector vLightUp = g_pStruct->m_GlobalLightDir.Cross(vRight); // Apply the size of the model to the shadow direction vLightUp *= pInstance->GetRadius(); // Get top/bottom light states bool bTopInLight = CastRayAtSky(vInstancePosition + vLightUp, vDir); bool bBottomInLight = CastRayAtSky(vInstancePosition - vLightUp, vDir); // Jump out if they're the same if (bTopInLight == bBottomInLight) return (bTopInLight) ? 1.0f : 0.0f; // Do a binary subdivision to try and find the point of cross-over bool bMiddleInLight; float fVariance = 1.0f, fTop = 1.0f, fBottom = -1.0f, fMiddle; float fLight = 1.0f; while ((fVariance > g_CV_ModelSunVariance.m_Val) && (bBottomInLight != bTopInLight)) { // Find the middle state fMiddle = (fTop + fBottom) * 0.5f; bMiddleInLight = CastRayAtSky(vInstancePosition + (vLightUp * fMiddle), vDir); // Drop the variance fVariance *= 0.5f; // Keep track of the total if (!bMiddleInLight) fLight -= fVariance; // Decide which half to keep if (bMiddleInLight == bTopInLight) { fTop = fMiddle; bTopInLight = bMiddleInLight; } else { fBottom = fMiddle; bBottomInLight = bMiddleInLight; } } return fLight; }