//----------------------------------------------------------------------------- // Purpose: Generates a view matrix based on our current yaw, pitch, and roll. // The view matrix does not consider FOV or clip plane distances. //----------------------------------------------------------------------------- void CCamera::BuildViewMatrix() { // The camera transformation is produced by multiplying roll * yaw * pitch. // This will transform a point from world space into quake camera space, // which is exactly what we want for our view matrix. However, quake // camera space isn't the same as material system camera space, so // we're going to have to apply a transformation that goes from quake // camera space to material system camera space. CameraIdentityMatrix( m_ViewMatrix ); RotateAroundAxis(m_ViewMatrix, m_fPitch, 0 ); RotateAroundAxis(m_ViewMatrix, m_fRoll, 1); RotateAroundAxis(m_ViewMatrix, m_fYaw, 2); // Translate the viewpoint to the world origin. VMatrix TempMatrix; TempMatrix.Identity(); TempMatrix.SetTranslation( -m_ViewPoint ); m_ViewMatrix = m_ViewMatrix * TempMatrix; m_ViewProjMatrix = m_ProjMatrix * m_ViewMatrix; m_ViewProjMatrix.InverseGeneral( m_InvViewProjMatrix ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTFArrowPanel::Paint() { if ( !m_hEntity.Get() ) return; C_BaseEntity *pEnt = m_hEntity.Get(); IMaterial *pMaterial = m_NeutralMaterial; C_TFPlayer *pLocalPlayer = C_TFPlayer::GetLocalTFPlayer(); // figure out what material we need to use if ( pEnt->GetTeamNumber() == TF_TEAM_RED ) { pMaterial = m_RedMaterial; if ( pLocalPlayer && ( pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) ) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if ( pTargetEnt && pTargetEnt->IsPlayer() ) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >( pTargetEnt ); if ( pTarget->HasTheFlag() && ( pTarget->GetItem() == pEnt ) ) { pMaterial = m_RedMaterialNoArrow; } } } } else if ( pEnt->GetTeamNumber() == TF_TEAM_BLUE ) { pMaterial = m_BlueMaterial; if ( pLocalPlayer && ( pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE ) ) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if ( pTargetEnt && pTargetEnt->IsPlayer() ) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >( pTargetEnt ); if ( pTarget->HasTheFlag() && ( pTarget->GetItem() == pEnt ) ) { pMaterial = m_BlueMaterialNoArrow; } } } } else if (pEnt->GetTeamNumber() == TF_TEAM_GREEN) { pMaterial = m_GreenMaterial; if (pLocalPlayer && (pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE)) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if (pTargetEnt && pTargetEnt->IsPlayer()) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >(pTargetEnt); if (pTarget->HasTheFlag() && (pTarget->GetItem() == pEnt)) { pMaterial = m_GreenMaterialNoArrow; } } } } else if (pEnt->GetTeamNumber() == TF_TEAM_YELLOW) { pMaterial = m_YellowMaterial; if (pLocalPlayer && (pLocalPlayer->GetObserverMode() == OBS_MODE_IN_EYE)) { // is our target a player? C_BaseEntity *pTargetEnt = pLocalPlayer->GetObserverTarget(); if (pTargetEnt && pTargetEnt->IsPlayer()) { // does our target have the flag and are they carrying the flag we're currently drawing? C_TFPlayer *pTarget = static_cast< C_TFPlayer* >(pTargetEnt); if (pTarget->HasTheFlag() && (pTarget->GetItem() == pEnt)) { pMaterial = m_YellowMaterialNoArrow; } } } } int x = 0; int y = 0; ipanel()->GetAbsPos( GetVPanel(), x, y ); int nWidth = GetWide(); int nHeight = GetTall(); CMatRenderContextPtr pRenderContext( materials ); pRenderContext->MatrixMode( MATERIAL_MODEL ); pRenderContext->PushMatrix(); VMatrix panelRotation; panelRotation.Identity(); MatrixBuildRotationAboutAxis( panelRotation, Vector( 0, 0, 1 ), GetAngleRotation() ); // MatrixRotate( panelRotation, Vector( 1, 0, 0 ), 5 ); panelRotation.SetTranslation( Vector( x + nWidth/2, y + nHeight/2, 0 ) ); pRenderContext->LoadMatrix( panelRotation ); IMesh *pMesh = pRenderContext->GetDynamicMesh( true, NULL, NULL, pMaterial ); CMeshBuilder meshBuilder; meshBuilder.Begin( pMesh, MATERIAL_QUADS, 1 ); meshBuilder.TexCoord2f( 0, 0, 0 ); meshBuilder.Position3f( -nWidth/2, -nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.TexCoord2f( 0, 1, 0 ); meshBuilder.Position3f( nWidth/2, -nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.TexCoord2f( 0, 1, 1 ); meshBuilder.Position3f( nWidth/2, nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.TexCoord2f( 0, 0, 1 ); meshBuilder.Position3f( -nWidth/2, nHeight/2, 0 ); meshBuilder.Color4ub( 255, 255, 255, 255 ); meshBuilder.AdvanceVertex(); meshBuilder.End(); pMesh->Draw(); pRenderContext->PopMatrix(); }
//----------------------------------------------------------------------------- // Got a detail! Place it on the surface... //----------------------------------------------------------------------------- // BUGBUG: When the global optimizer is on, "normal" gets trashed in this function // (only when not in the debugger?) // Printing the values of normal at the bottom of the function fixes it as does // disabling global optimizations. static void PlaceDetail( DetailModel_t const& model, const Vector& pt, const Vector& normal ) { // But only place it on the surface if it meets the angle constraints... float cosAngle = normal.z; // Never emit if the angle's too steep if (cosAngle < model.m_MaxCosAngle) return; // If it's between min + max, flip a coin... if (cosAngle < model.m_MinCosAngle) { float probability = (cosAngle - model.m_MaxCosAngle) / (model.m_MinCosAngle - model.m_MaxCosAngle); float t = rand() / (float)RAND_MAX; if (t > probability) return; } // Compute the orientation of the detail QAngle angles; if (model.m_Flags & MODELFLAG_UPRIGHT) { // If it's upright, we just select a random yaw angles.Init( 0, 360.0f * rand() / (float)RAND_MAX, 0.0f ); } else { // It's not upright, so it must conform to the ground. Choose // a random orientation based on the surface normal Vector zaxis; VectorCopy( normal, zaxis ); VectorNormalize( zaxis ); // Choose any two arbitrary axes which are perpendicular to the normal Vector xaxis( 1, 0, 0 ); if (fabs(xaxis.Dot(zaxis)) - 1.0 > -1e-3) xaxis.Init( 0, 1, 0 ); Vector yaxis; CrossProduct( zaxis, xaxis, yaxis ); VectorNormalize( yaxis ); CrossProduct( yaxis, zaxis, xaxis ); VectorNormalize( xaxis ); VMatrix matrix; matrix.SetBasisVectors( xaxis, yaxis, zaxis ); matrix.SetTranslation( vec3_origin ); float rotAngle = 360.0f * rand() / (float)RAND_MAX; VMatrix rot = SetupMatrixAxisRot( Vector( 0, 0, 1 ), rotAngle ); matrix = matrix * rot; MatrixToAngles( matrix, angles ); } // FIXME: We may also want a purely random rotation too // Insert an element into the object dictionary if it aint there... switch ( model.m_Type ) { case DETAIL_PROP_TYPE_MODEL: AddDetailToLump( model.m_ModelName.String(), pt, angles, model.m_Orientation ); break; // Sprites and procedural models made from sprites case DETAIL_PROP_TYPE_SPRITE: default: { float flScale = 1.0f; if ( model.m_flRandomScaleStdDev != 0.0f ) { flScale = fabs( RandomGaussianFloat( 1.0f, model.m_flRandomScaleStdDev ) ); } AddDetailSpriteToLump( pt, angles, model, flScale ); } break; } }