static int test_angle (const vec3_t angles) { int i; quat_t rotation, r; vec3_t scale, shear; mat3_t mat; AngleQuat (angles, rotation); QuatToMatrix (rotation, mat, 0, 1); Mat3Decompose (mat, r, shear, scale); for (i = 0; i < 4; i++) if (!compare (rotation[i], r[i])) goto negate; return 1; negate: // Mat3Decompose always sets the rotation quaternion's scalar to +ve // but AngleQuat might produce a -ve scalar. QuatNegate (r, r); for (i = 0; i < 4; i++) if (!compare (rotation[i], r[i])) goto fail; return 1; fail: printf ("\n\n(%g %g %g)\n", VectorExpand (angles)); printf (" [%g %g %g %g]\n", QuatExpand (rotation)); printf (" [%g %g %g %g] [%g %g %g] [%g %g %g]\n", QuatExpand (r), VectorExpand (scale), VectorExpand (shear)); return 0; }
static int test_transform (const vec3_t angles, const vec3_t scale) { int i; const vec3_t v = {4,5,6}; vec3_t x, y; quat_t rotation; mat3_t mat; VectorCopy (v, x); AngleQuat (angles, rotation); VectorCompMult (scale, x, x); QuatMultVec (rotation, x, x); Mat3Init (rotation, scale, mat); Mat3MultVec (mat, v, y); for (i = 0; i < 3; i++) if (!compare (x[i], y[i])) goto fail; return 1; fail: printf ("\n\n(%g %g %g) (%g %g %g)\n", VectorExpand (angles), VectorExpand (scale)); printf (" (%g %g %g)\n", VectorExpand (x)); printf (" (%g %g %g)\n", VectorExpand (y)); return 0; }
static int test_inverse (const vec3_t angles, const vec3_t scale) { int i; quat_t rotation; mat3_t mat, inv, I, res; AngleQuat (angles, rotation); Mat3Init (rotation, scale, mat); Mat3Identity (I); Mat3Inverse (mat, inv); Mat3Mult (mat, inv, res); for (i = 0; i < 3 * 3; i++) if (!compare (I[i], res[i])) goto fail; return 1; fail: printf ("\n\n(%g %g %g) (%g %g %g)\n", VectorExpand (angles), VectorExpand (scale)); printf (" [%g %g %g]\n [%g %g %g]\n [%g %g %g]\n\n", Mat3Expand (mat)); printf (" [%g %g %g]\n [%g %g %g]\n [%g %g %g]\n\n", Mat3Expand (inv)); printf (" [%g %g %g]\n [%g %g %g]\n [%g %g %g]\n\n", Mat3Expand (res)); return 0; }
void CASW_Path_Utils::DebugDrawRoute( const Vector &vecStartPos, AI_Waypoint_t *pWaypoint ) { Vector vecLastPos = vecStartPos; Msg(" Pathstart = %f %f %f\n", VectorExpand( g_vecPathStart ) ); while ( pWaypoint ) { Msg(" waypoint = %f %f %f\n", VectorExpand( pWaypoint->GetPos() ) ); DebugDrawLine( vecLastPos + Vector( 0, 0, 10 ) , pWaypoint->GetPos() + Vector( 0, 0, 10 ), 255, 0, 255, true, 30.0f ); vecLastPos = pWaypoint->GetPos(); pWaypoint = pWaypoint->GetNext(); } }
void CASW_Spawn_Manager::Update() { if ( m_iHordeToSpawn > 0 ) { if ( m_vecHordePosition != vec3_origin && ( !m_batchInterval.HasStarted() || m_batchInterval.IsElapsed() ) ) { int iToSpawn = MIN( m_iHordeToSpawn, asw_max_alien_batch.GetInt() ); int iSpawned = SpawnAlienBatch( asw_horde_class.GetString(), iToSpawn, m_vecHordePosition, m_angHordeAngle, 0 ); if (asw_director_debug.GetInt() >= 4) Msg("spawned %d/%d %s (horde) at (%f, %f, %f)\n", iSpawned, m_iHordeToSpawn, asw_horde_class.GetString(), VectorExpand(m_vecHordePosition)); m_iHordeToSpawn -= iSpawned; for (int i = 0; i < iSpawned; i++) { if (RandomFloat() < asw_horde_wanderers.GetFloat()) { KeyValues *pWanderer = RandomWanderer(); if (pWanderer) { FOR_EACH_TRUE_SUBKEY(pWanderer, pNPC) { if (V_stricmp(pNPC->GetName(), "NPC")) { Warning("Spawn Manager ignoring non-NPC key in WANDERER definition: %s\n", pNPC->GetName()); continue; } const char *szAlienClass = pNPC->GetString("AlienClass"); if (SpawnAlienAt(szAlienClass, m_vecHordePosition + Vector(0, 0, !V_stricmp(szAlienClass, "asw_buzzer") ? 128 : 32), m_angHordeAngle, pNPC)) { if (asw_director_debug.GetInt() >= 4) { Msg("spawned %s (horde wanderer) at (%f, %f, %f)\n", szAlienClass, VectorExpand(m_vecHordePosition)); } } } } else { const char *szAlienClass = asw_wanderer_class.GetString(); if (SpawnAlienAt(szAlienClass, m_vecHordePosition + Vector(0, 0, !V_stricmp(szAlienClass, "asw_buzzer") ? 128 : 32), m_angHordeAngle)) { if (asw_director_debug.GetInt() >= 4) { Msg("spawned %s (horde wanderer) at (%f, %f, %f)\n", szAlienClass, VectorExpand(m_vecHordePosition)); } } } } }
void R_DrawPortals() { // Draw the portals. if( !r_DrawPortals.GetInt() ) return; IMaterial *pMaterial = materialSystemInterface->FindMaterial( "debug\\debugportals", NULL ); IMesh *pMesh = materialSystemInterface->GetDynamicMesh( true, NULL, NULL, pMaterial ); brushdata_t *pBrush = &host_state.worldmodel->brush; for( int i=0; i < pBrush->m_nAreaPortals; i++ ) { dareaportal_t *pAreaPortal = &pBrush->m_pAreaPortals[i]; if( !R_IsAreaVisible( pAreaPortal->otherarea ) ) continue; CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_LINES, pAreaPortal->m_nClipPortalVerts ); for( int j=0; j < pAreaPortal->m_nClipPortalVerts; j++ ) { unsigned short iVert; iVert = pAreaPortal->m_FirstClipPortalVert + j; builder.Position3f( VectorExpand( pBrush->m_pClipPortalVerts[iVert] ) ); builder.Color4f( 0, 0, 0, 1 ); builder.AdvanceVertex(); iVert = pAreaPortal->m_FirstClipPortalVert + (j+1) % pAreaPortal->m_nClipPortalVerts; builder.Position3f( VectorExpand( pBrush->m_pClipPortalVerts[iVert] ) ); builder.Color4f( 0, 0, 0, 1 ); builder.AdvanceVertex(); } builder.End( false, true ); } // Draw the clip rectangles. for( i=0; i < g_PortalRects.Size(); i++ ) { CPortalRect *pRect = &g_PortalRects[i]; R_DrawScreenRect( pRect->left, pRect->top, pRect->right, pRect->bottom ); } g_PortalRects.Purge(); }
void CASW_Weapon_Sniper_Rifle::UpdateDynamicLight() { // DLIGHT disabled, since it looks bad return; C_ASW_Marine *pMarine =GetMarine(); C_ASW_Player *pPlayer = pMarine ? pMarine->GetCommander() : NULL; if ( !pMarine || pMarine->GetActiveWeapon() != this || !pPlayer || !pMarine->IsInhabited() || !pPlayer->IsLocalPlayer() ) { if (m_pSniperDynamicLight) { m_pSniperDynamicLight->die = gpGlobals->curtime + 0.001; m_pSniperDynamicLight = NULL; } return; } if ( !m_pSniperDynamicLight || (m_pSniperDynamicLight->key != index) ) { m_pSniperDynamicLight = effects->CL_AllocDlight ( index ); } //m_fAmbientLight = asw_flashlight_marine_ambient.GetFloat(); //m_fLightingScale = asw_flashlight_marine_lightscale.GetFloat(); Vector vecForward, vecRight, vecUp; if (m_pSniperDynamicLight) { AngleVectors( GetLocalAngles(), &vecForward, &vecRight, &vecUp ); m_pSniperDynamicLight->origin = pPlayer->GetCrosshairTracePos() + Vector( 0, 0, 10 ); Msg( "crosshair trace pos is %f %f %f\n", VectorExpand( pPlayer->GetCrosshairTracePos() ) ); debugoverlay->AddTextOverlay( m_pSniperDynamicLight->origin, 0.01f, "Light" ); m_pSniperDynamicLight->color.r = asw_sniper_dlight_r.GetInt(); m_pSniperDynamicLight->color.g = asw_sniper_dlight_g.GetInt(); m_pSniperDynamicLight->color.b = asw_sniper_dlight_b.GetInt(); m_pSniperDynamicLight->radius = asw_sniper_dlight_radius.GetFloat(); m_pSniperDynamicLight->color.exponent = asw_sniper_dlight_exponent.GetFloat(); //m_pSniperDynamicLight->decay = 0; m_pSniperDynamicLight->die = gpGlobals->curtime + 30.0f; } }
void CDispInfo::ApplyTerrainMod( ITerrainMod *pMod ) { // New bbox. Vector bbMin( 1e24, 1e24, 1e24 ); Vector bbMax( -1e24, -1e24, -1e24 ); int nVerts, nIndices; CalcMaxNumVertsAndIndices( m_Power, &nVerts, &nIndices ); // Ok, it probably touches us. Lock our buffer and change the verts. CMeshBuilder mb; mb.BeginModify( m_pMesh->m_pMesh, m_iVertOffset, nVerts ); for( int iVert=0; iVert < nVerts; iVert++ ) { if( m_AllowedVerts.Get( iVert ) ) { Vector &vPos = m_Verts[iVert].m_vPos; Vector &vOriginalPos = m_Verts[iVert].m_vOriginalPos; if( pMod->ApplyMod( vPos, vOriginalPos ) ) mb.Position3f( VectorExpand( vPos ) ); VectorMin( vPos, bbMin, bbMin ); VectorMax( vPos, bbMax, bbMax ); } mb.AdvanceVertex(); } mb.EndModify(); // Set our new bounding box. m_BBoxMin = bbMin; m_BBoxMax = bbMax; UpdateCenterAndRadius(); // Next time this displacement is seen, force it to rebuild and retesselate. m_bForceRebuild = true; }
static int test_transform2 (const vec3_t angles, const vec3_t scale, const vec3_t translation) { int i; const vec3_t v = {4,5,6}; vec3_t x, y; quat_t rotation; mat4_t mat; vec3_t rot, sc, sh, tr; VectorCopy (v, x); AngleQuat (angles, rotation); VectorCompMult (scale, x, x); QuatMultVec (rotation, x, x); VectorAdd (translation, x, x); Mat4Init (rotation, scale, translation, mat); Mat4Decompose (mat, rot, sh, sc, tr); VectorCopy (v, y); QuatMultVec (rot, y, y); VectorShear (sh, y, y); VectorCompMult (sc, y, y);//scale VectorAdd (tr, y, y); for (i = 0; i < 3; i++) if (!compare (x[i], y[i])) goto fail; return 1; fail: printf ("\n\n(%g %g %g) (%g %g %g) (%g %g %g) (%g %g %g)\n", VectorExpand (angles), VectorExpand (scale), VectorExpand (translation), VectorExpand (v)); printf (" (%g %g %g)\n", VectorExpand (x)); printf (" (%g %g %g)\n", VectorExpand (y)); return 0; }
void CGlowOverlay::Draw( bool bCacheFullSceneState ) { extern ConVar r_drawsprites; if( !r_drawsprites.GetBool() ) return; // Get the vector to the sun. Vector vToGlow; if( m_bDirectional ) vToGlow = m_vDirection; else vToGlow = m_vPos - CurrentViewOrigin(); VectorNormalize( vToGlow ); float flDot = vToGlow.Dot( CurrentViewForward() ); UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); if( m_flGlowObstructionScale == 0 ) return; bool bWireframe = ShouldDrawInWireFrameMode() || (r_drawsprites.GetInt() == 2); CMatRenderContextPtr pRenderContext( materials ); for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) { CGlowSprite *pSprite = &m_Sprites[iSprite]; // Figure out the color and size to draw it. float flHorzSize, flVertSize; Vector vColor; CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); // If we're alpha'd out, then don't bother if ( vColor.LengthSqr() < 0.00001f ) continue; // Setup the basis to draw the sprite. Vector vBasePt, vUp, vRight; CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); //Get our diagonal radius float radius = (vRight+vUp).Length(); if ( R_CullSphere( view->GetFrustum(), 5, &vBasePt, radius ) ) continue; // Get our material (deferred default load) if ( m_Sprites[iSprite].m_pMaterial == NULL ) { m_Sprites[iSprite].m_pMaterial = materials->FindMaterial( "sprites/light_glow02_add_noz", TEXTURE_GROUP_CLIENT_EFFECTS ); } Assert( m_Sprites[iSprite].m_pMaterial ); static unsigned int nHDRColorScaleCache = 0; IMaterialVar *pHDRColorScaleVar = m_Sprites[iSprite].m_pMaterial->FindVarFast( "$hdrcolorscale", &nHDRColorScaleCache ); if( pHDRColorScaleVar ) { pHDRColorScaleVar->SetFloatValue( m_flHDRColorScale ); } // Draw the sprite. IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, m_Sprites[iSprite].m_pMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 0 ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 0 ); builder.AdvanceVertex(); builder.End( false, true ); if( bWireframe ) { IMaterial *pWireframeMaterial = materials->FindMaterial( "debug/debugwireframevertexcolor", TEXTURE_GROUP_OTHER ); pRenderContext->Bind( pWireframeMaterial ); // Draw the sprite. IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pWireframeMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color3f( 1.0f, 0.0f, 0.0f ); builder.AdvanceVertex(); builder.End( false, true ); } } }
CBaseEntity * CASW_Rocket::FindPotentialTarget( void ) const { float bestdist = 0; CBaseEntity *bestent = NULL; Vector v_forward, v_right, v_up; AngleVectors( GetAbsAngles(), &v_forward, &v_right, &v_up ); // find the aimtarget nearest us int count = AimTarget_ListCount(); if ( count ) { CBaseEntity **pList = (CBaseEntity **)stackalloc( sizeof(CBaseEntity *) * count ); AimTarget_ListCopy( pList, count ); CTraceFilterSkipTwoEntities filter(this, GetOwnerEntity(), COLLISION_GROUP_NONE); for ( int i = 0; i < count; i++ ) { CBaseEntity *pEntity = pList[i]; if (!pEntity || !pEntity->IsAlive() || !pEntity->edict() || !pEntity->IsNPC() ) { //Msg("not alive or not an edict, skipping\n"); continue; } if (!pEntity || !pEntity->IsAlive() || !pEntity->edict() || !pEntity->IsNPC() ) { //Msg("not alive or not an edict, skipping\n"); continue; } // don't autoaim onto marines if (pEntity->Classify() == CLASS_ASW_MARINE || pEntity->Classify() == CLASS_ASW_COLONIST) continue; if ( pEntity->Classify() == CLASS_ASW_PARASITE ) { CASW_Parasite *pParasite = static_cast< CASW_Parasite* >( pEntity ); if ( pParasite->m_bInfesting ) { continue; } } Vector center = pEntity->BodyTarget( GetAbsOrigin() ); Vector center_flat = center; center_flat.z = GetAbsOrigin().z; Vector dir = (center - GetAbsOrigin()); VectorNormalize( dir ); Vector dir_flat = (center_flat - GetAbsOrigin()); VectorNormalize( dir_flat ); // make sure it's in front of the rocket float dot = DotProduct (dir, v_forward ); //if (dot < 0) //{ //continue; //} float dist = (pEntity->GetAbsOrigin() - GetAbsOrigin()).LengthSqr(); if (dist > ASW_ROCKET_MAX_HOMING_RANGE) continue; // check another marine isn't between us and the target to reduce FF trace_t tr; UTIL_TraceLine(GetAbsOrigin(), pEntity->WorldSpaceCenter(), MASK_SHOT, &filter, &tr); if (tr.fraction < 1.0f && tr.m_pEnt != pEntity && tr.m_pEnt && tr.m_pEnt->Classify() == CLASS_ASW_MARINE) continue; // does this critter already have enough rockets to kill it? { CASW_DamageAllocationMgr::IndexType_t assignmentIndex = m_RocketAssigner.Find( pEntity ); if ( m_RocketAssigner.IsValid(assignmentIndex) ) { if ( m_RocketAssigner[assignmentIndex].m_flAccumulatedDamage > pEntity->GetHealth() ) { continue; } } } // check another marine isn't between us and the target to reduce FF UTIL_TraceLine(GetAbsOrigin(), pEntity->WorldSpaceCenter(), MASK_SHOT, &filter, &tr); if (tr.fraction < 1.0f && tr.m_pEnt != pEntity && tr.m_pEnt && tr.m_pEnt->Classify() == CLASS_ASW_MARINE) continue; // increase distance if dot isn't towards us dist += (1.0f - dot) * 150; // bias of x units when object is 90 degrees to the side if (bestdist == 0 || dist < bestdist) { bestdist = dist; bestent = pEntity; } } if ( bestent && asw_rocket_debug.GetBool() ) { Vector center = bestent->BodyTarget( GetAbsOrigin() ); Vector center_flat = center; center_flat.z = GetAbsOrigin().z; Vector dir = (center - GetAbsOrigin()); VectorNormalize( dir ); Msg( "Rocket[%d] starting homing in on %s(%d) dir = %f %f %f\n", entindex(), bestent->GetClassname(), bestent->entindex(), VectorExpand( dir ) ); } } return bestent; }
void CASW_Spawn_Manager::Update() { if ( m_iHordeToSpawn > 0 ) { if ( m_vecHordePosition != vec3_origin && ( !m_batchInterval.HasStarted() || m_batchInterval.IsElapsed() ) ) { int iToSpawn = MIN( m_iHordeToSpawn, asw_max_alien_batch.GetInt() ); int iSpawned = SpawnAlienBatch( asw_horde_class.GetString(), iToSpawn, m_vecHordePosition, m_angHordeAngle, 0 ); m_iHordeToSpawn -= iSpawned; if ( m_iHordeToSpawn <= 0 ) { ASWDirector()->OnHordeFinishedSpawning(); m_vecHordePosition = vec3_origin; } else if ( iSpawned == 0 ) // if we failed to spawn any aliens, then try to find a new horde location { if ( asw_director_debug.GetBool() ) { Msg( "Horde failed to spawn any aliens, trying new horde position.\n" ); } if ( !FindHordePosition() ) // if we failed to find a new location, just abort this horde { m_iHordeToSpawn = 0; ASWDirector()->OnHordeFinishedSpawning(); m_vecHordePosition = vec3_origin; } } m_batchInterval.Start( asw_batch_interval.GetFloat() ); } else if ( m_vecHordePosition == vec3_origin ) { Msg( "Warning: Had horde to spawn but no position, clearing.\n" ); m_iHordeToSpawn = 0; ASWDirector()->OnHordeFinishedSpawning(); } } if ( asw_director_debug.GetBool() ) { engine->Con_NPrintf( 14, "SM: Batch interval: %f pos = %f %f %f\n", m_batchInterval.HasStarted() ? m_batchInterval.GetRemainingTime() : -1, VectorExpand( m_vecHordePosition ) ); } if ( m_iAliensToSpawn > 0 ) { if (wandererSize() < WANDERER_QUEUE_SIZE-1) { queueWanderers(); m_iAliensToSpawn--; } } if (wandererQueueStart != wandererQueueEnd) { while ( wandererQueueStart != wandererQueueEnd && SpawnAlientAtRandomNode()); } }
// heuristic to find reasonably open space - searches for areas with high node connectivity CASW_Open_Area* CASW_Spawn_Manager::FindNearbyOpenArea( const Vector &vecSearchOrigin, int nSearchHull ) { CBaseEntity *pStartEntity = gEntList.FindEntityByClassname( NULL, "info_player_start" ); int iNumNodes = g_pBigAINet->NumNodes(); CAI_Node *pHighestConnectivity = NULL; int nHighestLinks = 0; for ( int i=0 ; i<iNumNodes; i++ ) { CAI_Node *pNode = g_pBigAINet->GetNode( i ); if ( !pNode || pNode->GetType() != NODE_GROUND ) continue; Vector vecPos = pNode->GetOrigin(); float flDist = vecPos.DistTo( vecSearchOrigin ); if ( flDist > 400.0f ) continue; // discard if node is too near start location if ( pStartEntity && vecPos.DistTo( pStartEntity->GetAbsOrigin() ) < 1400.0f ) // NOTE: assumes all start points are clustered near one another continue; // discard if node is inside an escape area bool bInsideEscapeArea = false; for ( int d=0; d<m_EscapeTriggers.Count(); d++ ) { if ( m_EscapeTriggers[d]->CollisionProp()->IsPointInBounds( vecPos ) ) { bInsideEscapeArea = true; break; } } if ( bInsideEscapeArea ) continue; // count links that drones could follow int nLinks = pNode->NumLinks(); int nValidLinks = 0; for ( int k = 0; k < nLinks; k++ ) { CAI_Link *pLink = pNode->GetLinkByIndex( k ); if ( !pLink ) continue; if ( !( pLink->m_iAcceptedMoveTypes[nSearchHull] & bits_CAP_MOVE_GROUND ) ) continue; nValidLinks++; } if ( nValidLinks > nHighestLinks ) { nHighestLinks = nValidLinks; pHighestConnectivity = pNode; } if ( asw_director_debug.GetBool() ) { NDebugOverlay::Text( vecPos, UTIL_VarArgs( "%d", nValidLinks ), false, 10.0f ); } } if ( !pHighestConnectivity ) return NULL; // now, starting at the new node, find all nearby nodes with a minimum connectivity CASW_Open_Area *pArea = new CASW_Open_Area(); pArea->m_vecOrigin = pHighestConnectivity->GetOrigin(); pArea->m_pNode = pHighestConnectivity; int nMinLinks = nHighestLinks * 0.3f; nMinLinks = MAX( nMinLinks, 4 ); pArea->m_aAreaNodes.AddToTail( pHighestConnectivity ); if ( asw_director_debug.GetBool() ) { Msg( "minLinks = %d\n", nMinLinks ); } pArea->m_nTotalLinks = 0; for ( int i=0 ; i<iNumNodes; i++ ) { CAI_Node *pNode = g_pBigAINet->GetNode( i ); if ( !pNode || pNode->GetType() != NODE_GROUND ) continue; Vector vecPos = pNode->GetOrigin(); float flDist = vecPos.DistTo( pArea->m_vecOrigin ); if ( flDist > 400.0f ) continue; // discard if node is inside an escape area bool bInsideEscapeArea = false; for ( int d=0; d<m_EscapeTriggers.Count(); d++ ) { if ( m_EscapeTriggers[d]->CollisionProp()->IsPointInBounds( vecPos ) ) { bInsideEscapeArea = true; break; } } if ( bInsideEscapeArea ) continue; // count links that drones could follow int nLinks = pNode->NumLinks(); int nValidLinks = 0; for ( int k = 0; k < nLinks; k++ ) { CAI_Link *pLink = pNode->GetLinkByIndex( k ); if ( !pLink ) continue; if ( !( pLink->m_iAcceptedMoveTypes[nSearchHull] & bits_CAP_MOVE_GROUND ) ) continue; nValidLinks++; } if ( nValidLinks >= nMinLinks ) { pArea->m_aAreaNodes.AddToTail( pNode ); pArea->m_nTotalLinks += nValidLinks; } } // highlight and measure bounds Vector vecAreaMins = Vector( FLT_MAX, FLT_MAX, FLT_MAX ); Vector vecAreaMaxs = Vector( -FLT_MAX, -FLT_MAX, -FLT_MAX ); for ( int i = 0; i < pArea->m_aAreaNodes.Count(); i++ ) { vecAreaMins = VectorMin( vecAreaMins, pArea->m_aAreaNodes[i]->GetOrigin() ); vecAreaMaxs = VectorMax( vecAreaMaxs, pArea->m_aAreaNodes[i]->GetOrigin() ); if ( asw_director_debug.GetBool() ) { if ( i == 0 ) { NDebugOverlay::Cross3D( pArea->m_aAreaNodes[i]->GetOrigin(), 20.0f, 255, 255, 64, true, 10.0f ); } else { NDebugOverlay::Cross3D( pArea->m_aAreaNodes[i]->GetOrigin(), 10.0f, 255, 128, 0, true, 10.0f ); } } } Vector vecArea = ( vecAreaMaxs - vecAreaMins ); float flArea = vecArea.x * vecArea.y; if ( asw_director_debug.GetBool() ) { Msg( "area mins = %f %f %f\n", VectorExpand( vecAreaMins ) ); Msg( "area maxs = %f %f %f\n", VectorExpand( vecAreaMaxs ) ); NDebugOverlay::Box( vec3_origin, vecAreaMins, vecAreaMaxs, 255, 128, 128, 10, 10.0f ); Msg( "Total links = %d Area = %f\n", pArea->m_nTotalLinks, flArea ); } return pArea; }
//----------------------------------------------------------------------------- // Purpose: Special draw for the warped overlay //----------------------------------------------------------------------------- void CWarpOverlay::Draw( bool bCacheFullSceneState ) { // Get the vector to the sun. Vector vToGlow; if( m_bDirectional ) vToGlow = m_vDirection; else vToGlow = m_vPos - CurrentViewOrigin(); VectorNormalize( vToGlow ); float flDot = vToGlow.Dot( CurrentViewForward() ); if( flDot <= g_flOverlayRange ) return; UpdateGlowObstruction( vToGlow, bCacheFullSceneState ); if( m_flGlowObstructionScale == 0 ) return; CMatRenderContextPtr pRenderContext( materials ); //FIXME: Allow multiple? for( int iSprite=0; iSprite < m_nSprites; iSprite++ ) { CGlowSprite *pSprite = &m_Sprites[iSprite]; // Figure out the color and size to draw it. float flHorzSize, flVertSize; Vector vColor; CalcSpriteColorAndSize( flDot, pSprite, &flHorzSize, &flVertSize, &vColor ); // Setup the basis to draw the sprite. Vector vBasePt, vUp, vRight; CalcBasis( vToGlow, flHorzSize, flVertSize, vBasePt, vUp, vRight ); // Draw the sprite. IMaterial *pMaterial = materials->FindMaterial( "sun/overlay", TEXTURE_GROUP_CLIENT_EFFECTS ); IMesh *pMesh = pRenderContext->GetDynamicMesh( false, 0, 0, pMaterial ); CMeshBuilder builder; builder.Begin( pMesh, MATERIAL_QUADS, 1 ); Vector vPt; vPt = vBasePt - vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight + vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 1 ); builder.AdvanceVertex(); vPt = vBasePt + vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 1, 0 ); builder.AdvanceVertex(); vPt = vBasePt - vRight - vUp; builder.Position3fv( vPt.Base() ); builder.Color4f( VectorExpand(vColor), 1 ); builder.TexCoord2f( 0, 0, 0 ); builder.AdvanceVertex(); builder.End( false, true ); } }
static void VerifyNeighborConnections( CCoreDispInfo *pListBase, int nDisps ) { while ( 1 ) { bool bHappy = true; for ( int i=0; i < nDisps; i++ ) { CCoreDispInfo *pDisp = &pListBase[i]; CDispUtilsHelper *pHelper = pDisp; for ( int iEdge=0; iEdge < 4; iEdge++ ) { CDispEdgeIterator it( pHelper, iEdge ); while ( it.Next() ) { if ( !VerifyNeighborVertConnection( pHelper, it.GetVertIndex(), it.GetCurrentNeighbor(), it.GetNBVertIndex(), iEdge ) ) { pDisp->GetEdgeNeighbor( iEdge )->SetInvalid(); Warning( "Warning: invalid neighbor connection on displacement near (%.2f %.2f %.2f)\n", VectorExpand( pDisp->GetCornerPoint(0) ) ); bHappy = false; } } } } if ( bHappy ) break; } }