void CE_CBeam::RelinkBeam( void ) { // FIXME: Why doesn't this just define the absbox too? // It seems that we don't need to recompute the absbox // in CBaseEntity::SetObjectCollisionBox, in fact the absbox // computed there seems way too big Vector startPos = GetAbsStartPos(), endPos = GetAbsEndPos(); Vector vecAbsExtra1, vecAbsExtra2; bool bUseExtraPoints = false; // UNDONE: Should we do this to make the boxes smaller? //SetAbsOrigin( startPos ); Vector vecBeamMin, vecBeamMax; VectorMin( startPos, endPos, vecBeamMin ); VectorMax( startPos, endPos, vecBeamMax ); if ( bUseExtraPoints ) { VectorMin( vecBeamMin, vecAbsExtra1, vecBeamMin ); VectorMin( vecBeamMin, vecAbsExtra2, vecBeamMin ); VectorMax( vecBeamMax, vecAbsExtra1, vecBeamMax ); VectorMax( vecBeamMax, vecAbsExtra2, vecBeamMax ); } SetCollisionBounds( vecBeamMin - GetAbsOrigin(), vecBeamMax - GetAbsOrigin() ); }
void CDispInfo::GetIntersectingSurfaces( GetIntersectingSurfaces_Struct *pStruct ) { if ( !m_Verts.Count() || !m_nIndices ) return; // Walk through all of our triangles and add them one by one. unsigned short *pEnd = m_Indices.Base() + m_nIndices; SurfInfo *pOut = &pStruct->m_pInfos[ pStruct->m_nSetInfos ]; for ( unsigned short *pTri = m_Indices.Base(); pTri < pEnd; pTri += 3 ) { // Is the list going to overflow? if ( pStruct->m_nSetInfos >= pStruct->m_nMaxInfos ) return; Vector const &a = m_Verts[pTri[0]].m_vPos; Vector const &b = m_Verts[pTri[1]].m_vPos; Vector const &c = m_Verts[pTri[2]].m_vPos; // Get the boundaries. Vector vMin; VectorMin( a, b, vMin ); VectorMin( c, vMin, vMin ); Vector vMax; VectorMax( a, b, vMax ); VectorMax( c, vMax, vMax ); // See if it touches the sphere. int iDim; for ( iDim=0; iDim < 3; iDim++ ) { if ( ((*pStruct->m_pCenter)[iDim]+pStruct->m_Radius) < vMin[iDim] || ((*pStruct->m_pCenter)[iDim]-pStruct->m_Radius) > vMax[iDim] ) { break; } } if ( iDim == 3 ) { // Couldn't reject the sphere in the loop above, so add this surface. pOut->m_nVerts = 3; pOut->m_Verts[0] = a; pOut->m_Verts[1] = b; pOut->m_Verts[2] = c; pOut->m_Plane.m_Normal = ( c - a ).Cross( b - a ); VectorNormalize( pOut->m_Plane.m_Normal ); pOut->m_Plane.m_Dist = pOut->m_Plane.m_Normal.Dot( a ); ++pStruct->m_nSetInfos; ++pOut; } } }
void C_BaseAnimatingOverlay::GetRenderBounds( Vector& theMins, Vector& theMaxs ) { BaseClass::GetRenderBounds( theMins, theMaxs ); if ( !IsRagdoll() ) { CStudioHdr *pStudioHdr = GetModelPtr(); if ( !pStudioHdr || !pStudioHdr->SequencesAvailable() ) return; int nSequences = pStudioHdr->GetNumSeq(); int i; for (i = 0; i < m_AnimOverlay.Count(); i++) { if (m_AnimOverlay[i].m_flWeight > 0.0) { if ( m_AnimOverlay[i].m_nSequence >= nSequences ) { continue; } mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_AnimOverlay[i].m_nSequence ); VectorMin( seqdesc.bbmin, theMins, theMins ); VectorMax( seqdesc.bbmax, theMaxs, theMaxs ); } } } }
void SetupDispBoxes( const CCoreDispInfo *pListBase, int listSize, CUtlVector<CDispBox> &out ) { out.SetSize( listSize ); for ( int i=0; i < listSize; i++ ) { const CCoreDispInfo *pDisp = &pListBase[i]; // Calculate the bbox for this displacement. Vector vMin( 1e24, 1e24, 1e24 ); Vector vMax( -1e24, -1e24, -1e24 ); for ( int iVert=0; iVert < 4; iVert++ ) { const Vector &vTest = pDisp->GetSurface()->GetPoint( iVert ); VectorMin( vTest, vMin, vMin ); VectorMax( vTest, vMax, vMax ); } // Puff the box out a little. static float flPuff = 0.1f; vMin -= Vector( flPuff, flPuff, flPuff ); vMax += Vector( flPuff, flPuff, flPuff ); out[i].m_Min = vMin; out[i].m_Max = vMax; } }
//----------------------------------------------------------------------------- // Computes the surrounding collision bounds from the current sequence box //----------------------------------------------------------------------------- void CCollisionProperty::ComputeRotationExpandedSequenceBounds( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) { CBaseAnimating *pAnim = GetOuter()->GetBaseAnimating(); if ( !pAnim ) { ComputeOBBBounds( pVecWorldMins, pVecWorldMaxs ); return; } Vector mins, maxs; pAnim->ExtractBbox( pAnim->GetSequence(), mins, maxs ); float flRadius = MAX( MAX( FloatMakePositive( mins.x ), FloatMakePositive( maxs.x ) ), MAX( FloatMakePositive( mins.y ), FloatMakePositive( maxs.y ) ) ); mins.x = mins.y = -flRadius; maxs.x = maxs.y = flRadius; // Add bloat to account for gesture sequences Vector vecBloat( 6, 6, 0 ); mins -= vecBloat; maxs += vecBloat; // NOTE: This is necessary because the server doesn't know how to blend // animations together. Therefore, we have to just pick a box that can // surround all of our potential sequences. This should be something we // should be able to compute @ tool time instead, however. VectorMin( mins, m_vecSurroundingMins, mins ); VectorMax( maxs, m_vecSurroundingMaxs, maxs ); VectorAdd( mins, GetCollisionOrigin(), *pVecWorldMins ); VectorAdd( maxs, GetCollisionOrigin(), *pVecWorldMaxs ); }
//----------------------------------------------------------------------------- // Compute position + bounding box //----------------------------------------------------------------------------- void CSpriteTrail::UpdateBoundingBox( void ) { Vector vecRenderOrigin = GetRenderOrigin(); m_vecRenderMins = vecRenderOrigin; m_vecRenderMaxs = vecRenderOrigin; float flMaxWidth = m_flStartWidth; if (( m_flEndWidth >= 0.0f ) && ( m_flEndWidth > m_flStartWidth )) { flMaxWidth = m_flEndWidth; } Vector mins, maxs; for ( int i = 0; i < m_nStepCount; ++i ) { TrailPoint_t *pPoint = GetTrailPoint(i); float flActualWidth = (flMaxWidth + pPoint->m_flWidthVariance) * 0.5f; Vector size( flActualWidth, flActualWidth, flActualWidth ); VectorSubtract( pPoint->m_vecScreenPos, size, mins ); VectorAdd( pPoint->m_vecScreenPos, size, maxs ); VectorMin( m_vecRenderMins, mins, m_vecRenderMins ); VectorMax( m_vecRenderMaxs, maxs, m_vecRenderMaxs ); } m_vecRenderMins -= vecRenderOrigin; m_vecRenderMaxs -= vecRenderOrigin; }
void CRopeKeyframe::UpdateBBox( bool bForceRelink ) { Vector v1, v2; Vector vMin, vMax; if ( GetEndPointPos( 0, v1 ) ) { if ( GetEndPointPos( 1, v2 ) ) { VectorMin( v1, v2, vMin ); VectorMax( v1, v2, vMax ); // Set our bounds to enclose both endpoints and relink. vMin -= GetAbsOrigin(); vMax -= GetAbsOrigin(); } else { vMin = vMax = v1 - GetAbsOrigin(); } } else { vMin = vMax = Vector( 0, 0, 0 ); } if ( WorldAlignMins() != vMin || WorldAlignMaxs() != vMax ) { UTIL_SetSize( this, vMin, vMax ); } }
void CBeam::RelinkBeam( void ) { // FIXME: Why doesn't this just define the absbox too? // It seems that we don't need to recompute the absbox // in CBaseEntity::SetObjectCollisionBox, in fact the absbox // computed there seems way too big Vector startPos = GetAbsStartPos(), endPos = GetAbsEndPos(); Vector vecAbsExtra1, vecAbsExtra2; bool bUseExtraPoints = false; #ifdef PORTAL CBaseEntity *pStartEntity = GetStartEntityPtr(); CTraceFilterSkipClassname traceFilter( pStartEntity, "prop_energy_ball", COLLISION_GROUP_NONE ); ITraceFilter *pEntityBeamTraceFilter = NULL; if ( pStartEntity ) pEntityBeamTraceFilter = pStartEntity->GetBeamTraceFilter(); CTraceFilterChain traceFilterChain( &traceFilter, pEntityBeamTraceFilter ); bUseExtraPoints = UTIL_Portal_Trace_Beam( this, startPos, endPos, vecAbsExtra1, vecAbsExtra2, &traceFilterChain ); #endif // UNDONE: Should we do this to make the boxes smaller? //SetAbsOrigin( startPos ); Vector vecBeamMin, vecBeamMax; VectorMin( startPos, endPos, vecBeamMin ); VectorMax( startPos, endPos, vecBeamMax ); if ( bUseExtraPoints ) { VectorMin( vecBeamMin, vecAbsExtra1, vecBeamMin ); VectorMin( vecBeamMin, vecAbsExtra2, vecBeamMin ); VectorMax( vecBeamMax, vecAbsExtra1, vecBeamMax ); VectorMax( vecBeamMax, vecAbsExtra2, vecBeamMax ); } SetCollisionBounds( vecBeamMin - GetAbsOrigin(), vecBeamMax - GetAbsOrigin() ); }
TEST(DSPSingle, TestVectorMax) { float signal[10] = {0.0, -1.0, -0.5, -0.3, 0.0, 1.0, 0.5, 0.3, 0.2, 0.1}; float max = VectorMax(signal, 10); ASSERT_FLOAT_EQ(1.0, max); max = 0.0; unsigned index = 0; VectorMaxVI(&max, &index, signal, 10); ASSERT_FLOAT_EQ(1.0, max); ASSERT_EQ(5, index); }
void CModelInfo::GetModelRenderBounds( const model_t *model, int sequence, Vector& mins, Vector& maxs ) const { if (!model) { mins.Init(0,0,0); maxs.Init(0,0,0); return; } switch( model->type ) { case mod_studio: { studiohdr_t *pStudioHdr = ( studiohdr_t * )modelloader->GetExtraData( (model_t*)model ); Assert( pStudioHdr ); // NOTE: We're not looking at the sequence box here, although we could if (!VectorCompare( vec3_origin, pStudioHdr->view_bbmin )) { // clipping bounding box VectorCopy ( pStudioHdr->view_bbmin, mins); VectorCopy ( pStudioHdr->view_bbmin, maxs); } else { // movement bounding box VectorCopy ( pStudioHdr->hull_min, mins); VectorCopy ( pStudioHdr->hull_max, maxs); } // construct the base bounding box for this frame if ( sequence >= pStudioHdr->numseq) { sequence = 0; } mstudioseqdesc_t *pseqdesc = pStudioHdr->pSeqdesc( sequence ); VectorMin( pseqdesc->bbmin, mins, mins ); VectorMax( pseqdesc->bbmax, maxs, maxs ); } break; case mod_brush: VectorCopy( model->mins, mins ); VectorCopy( model->maxs, maxs ); break; default: mins.Init( 0, 0, 0 ); maxs.Init( 0, 0, 0 ); break; } }
//----------------------------------------------------------------------------- // Purpose: Performs the actual partial rebuilds of the mesh, merging multiple // updates in one. //----------------------------------------------------------------------------- void CRecastMgr::UpdateRebuildPartial() { if( !m_pendingPartialMeshUpdates.Count() ) return; PartialMeshUpdate_t &curUpdate = m_pendingPartialMeshUpdates.Head(); bool bDidMerge; int nTests = 0, nMerges = 0; do { bDidMerge = false; for( int i = m_pendingPartialMeshUpdates.Count() - 1; i >= 1; i-- ) { if( IsBoxIntersectingBox( curUpdate.vMins, curUpdate.vMaxs, m_pendingPartialMeshUpdates[i].vMins, m_pendingPartialMeshUpdates[i].vMaxs ) ) { curUpdate.vMins = VectorMin( curUpdate.vMins, m_pendingPartialMeshUpdates[i].vMins ); curUpdate.vMaxs = VectorMax( curUpdate.vMaxs, m_pendingPartialMeshUpdates[i].vMaxs ); m_pendingPartialMeshUpdates.Remove( i ); bDidMerge = true; nMerges++; } } nTests++; } while( bDidMerge && nTests < 100 ); if( recast_build_partial_debug.GetBool() && nMerges > 0 ) { DevMsg( "CRecastMgr::UpdateRebuildPartial: Merged multiple updates (%d) into one\n", nMerges+1 ); } // Load map mesh if( !LoadMapMesh( recast_build_partial_debug.GetBool(), true, curUpdate.vMins, curUpdate.vMaxs ) ) { Warning( "CRecastMgr::UpdateRebuildPartial: failed to load map data!\n" ); return; } // Perform the update CUtlVector<CRecastMesh *> meshesToBuild; for ( int i = m_Meshes.First(); i != m_Meshes.InvalidIndex(); i = m_Meshes.Next(i ) ) { if( IsMeshBuildDisabled( m_Meshes[i]->GetName() ) ) continue; meshesToBuild.AddToTail( m_Meshes[i] ); } CParallelProcessor<CRecastMesh *, CFuncJobItemProcessor<CRecastMesh *>, 2 > processor; processor.m_ItemProcessor.Init( &ThreadedRebuildPartialMesh, &PreThreadedBuildMesh, &PostThreadedBuildMesh ); processor.Run( meshesToBuild.Base(), meshesToBuild.Count(), 1, recast_build_numthreads.GetInt(), g_pThreadPool ); m_pendingPartialMeshUpdates.Remove( 0 ); }
void CSheetSimulator::ComputeBounds( Vector& mins, Vector& maxs ) { VectorCopy( m_Particle[0].m_Position, mins ); VectorCopy( m_Particle[0].m_Position, maxs ); for (int i = 1; i < NumParticles(); ++i) { VectorMin( mins, m_Particle[i].m_Position, mins ); VectorMax( maxs, m_Particle[i].m_Position, maxs ); } mins -= m_Origin; maxs -= m_Origin; }
int main(void) { int i = 0; fractional *p_real = &sigCmpx[0].real ; fractcomplex *p_cmpx = &sigCmpx[0] ; #ifndef FFTTWIDCOEFFS_IN_PROGMEM /* Generate TwiddleFactor Coefficients */ TwidFactorInit (LOG2_BLOCK_LENGTH, &twiddleFactors[0], 0); /* We need to do this only once at start-up */ #endif for ( i = 0; i < FFT_BLOCK_LENGTH; i++ )/* The FFT function requires input data */ { /* to be in the fractional fixed-point range [-0.5, +0.5]*/ *p_real = *p_real >>1 ; /* So, we shift all data samples by 1 bit to the right. */ *p_real++; /* Should you desire to optimize this process, perform */ } /* data scaling when first obtaining the time samples */ /* Or within the BitReverseComplex function source code */ p_real = &sigCmpx[(FFT_BLOCK_LENGTH/2)-1].real ; /* Set up pointers to convert real array */ p_cmpx = &sigCmpx[FFT_BLOCK_LENGTH-1] ; /* to a complex array. The input array initially has all */ /* the real input samples followed by a series of zeros */ for ( i = FFT_BLOCK_LENGTH; i > 0; i-- ) /* Convert the Real input sample array */ { /* to a Complex input sample array */ (*p_cmpx).real = (*p_real--); /* We will simpy zero out the imaginary */ (*p_cmpx--).imag = 0x0000; /* part of each data sample */ } /* Perform FFT operation */ #ifndef FFTTWIDCOEFFS_IN_PROGMEM FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], &twiddleFactors[0], COEFFS_IN_DATA); #else FFTComplexIP (LOG2_BLOCK_LENGTH, &sigCmpx[0], (fractcomplex *) __builtin_psvoffset(&twiddleFactors[0]), (int) __builtin_psvpage(&twiddleFactors[0])); #endif /* Store output samples in bit-reversed order of their addresses */ BitReverseComplex (LOG2_BLOCK_LENGTH, &sigCmpx[0]); /* Compute the square magnitude of the complex FFT output array so we have a Real output vetor */ SquareMagnitudeCplx(FFT_BLOCK_LENGTH, &sigCmpx[0], &sigCmpx[0].real); /* Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy*/ /* i.e., the largest spectral component */ VectorMax(FFT_BLOCK_LENGTH/2, &sigCmpx[0].real, &peakFrequencyBin); /* Compute the frequency (in Hz) of the largest spectral component */ peakFrequency = peakFrequencyBin*(SAMPLING_RATE/FFT_BLOCK_LENGTH); while (1); /* Place a breakpoint here and observe the watch window variables */ }
void CMapzoneEdit::Build(Vector *aimpos, int type, int forcestage) { if (mom_zone_grid.GetInt() > 0) VectorSnapToGrid(aimpos, (float) mom_zone_grid.GetInt()); switch ((forcestage != BUILDSTAGE_NONE) ? forcestage : ++m_nBuildStage) { case BUILDSTAGE_START: m_vecBuildStart = *aimpos; break; case BUILDSTAGE_END: m_vecBuildEnd = *aimpos; break; case BUILDSTAGE_HEIGHT: { char szClass[64]; if (ZoneTypeToClass(type, szClass)) { CBaseEntity *pEnt = CreateEntityByName(szClass); Vector vecOrigin, vecSize, vecMinsRel; int i; VectorMin(m_vecBuildStart, m_vecBuildEnd, vecMinsRel); VectorMax(m_vecBuildStart, m_vecBuildEnd, vecSize); for (i = 0; i < 3; i++) vecSize[i] = (vecSize[i] - vecMinsRel[i]) / 2.0f; for (i = 0; i < 3; i++) vecOrigin[i] = vecMinsRel[i] + vecSize[i]; pEnt->Spawn(); pEnt->SetAbsOrigin(vecOrigin); pEnt->SetSize(Vector(-vecSize.x, -vecSize.y, -vecSize.z), vecSize); pEnt->SetEffects(EF_NODRAW); pEnt->SetSolid(SOLID_BBOX); pEnt->Activate(); SetZoneProps(pEnt); } } default: m_nBuildStage = BUILDSTAGE_NONE; } }
//----------------------------------------------------------------------------- // bounding box for collision //----------------------------------------------------------------------------- void CShieldEffect::ComputeBounds( Vector& mins, Vector& maxs ) { VectorCopy( m_pControlPoint[0], mins ); VectorCopy( m_pControlPoint[0], maxs ); for (int i = 1; i < SHIELD_NUM_CONTROL_POINTS; ++i) { VectorMin( mins, m_pControlPoint[i], mins ); VectorMax( maxs, m_pControlPoint[i], maxs ); } // Bounds are in local coords mins -= m_Position; maxs -= m_Position; }
inline bool IntersectWithLine( const Vector3& rayOrigin, Vector3 rayDirection, float &distanceToFrontCollisionOfCube , float &distanceToBackCollisionOfCube ) const { rayDirection.x = ( rayDirection.x == 0.f ) ? 0.0000001f : rayDirection.x; rayDirection.y = ( rayDirection.y == 0.f ) ? 0.0000001f : rayDirection.y; rayDirection.z = ( rayDirection.z == 0.f ) ? 0.0000001f : rayDirection.z; Vector3 divisor = 1.f / rayDirection; Vector3 oMin = (m_Min - rayOrigin) * divisor; Vector3 oMax = (m_Max - rayOrigin) * divisor; Vector3 bMax = VectorMax(oMax, oMin); Vector3 bMin = VectorMin(oMax, oMin); distanceToBackCollisionOfCube = getMinimum(bMax.x, bMax.y, bMax.z); distanceToBackCollisionOfCube = getMinimum(bMax.x, bMax.y, bMax.z); distanceToFrontCollisionOfCube = getMaximum(bMin.x, 0.0f, bMin.y, bMin.z ); return distanceToBackCollisionOfCube > distanceToFrontCollisionOfCube; }
void CBeam::RelinkBeam( void ) { // FIXME: Why doesn't this just define the absbox too? // It seems that we don't need to recompute the absbox // in CBaseEntity::SetObjectCollisionBox, in fact the absbox // computed there seems way too big const Vector &startPos = GetAbsStartPos(), &endPos = GetAbsEndPos(); // UNDONE: Should we do this to make the boxes smaller? //SetAbsOrigin( startPos ); Vector vecBeamMin, vecBeamMax; VectorMin( startPos, endPos, vecBeamMin ); VectorMax( startPos, endPos, vecBeamMax ); SetCollisionBounds( vecBeamMin - GetAbsOrigin(), vecBeamMax - GetAbsOrigin() ); }
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; }
//----------------------------------------------------------------------------- // compute rest positions of the springs //----------------------------------------------------------------------------- void CShieldEffect::ComputeRestPositions() { int i; m_vecRenderMins.Init( FLT_MAX, FLT_MAX, FLT_MAX ); m_vecRenderMaxs.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); // Set the initial directions and distances (in shield space)... for ( i = 0; i < SHIELD_NUM_VERTICAL_POINTS; ++i) { // Choose phi centered at pi/2 float phi = (M_PI - m_ShieldPhi) * 0.5f + m_ShieldPhi * (float)i / (float)(SHIELD_NUM_VERTICAL_POINTS - 1); for (int j = 0; j < SHIELD_NUM_HORIZONTAL_POINTS; ++j) { // Choose theta centered at pi/2 also (y, or forward axis) float theta = (M_PI - m_ShieldTheta) * 0.5f + m_ShieldTheta * (float)j / (float)(SHIELD_NUM_HORIZONTAL_POINTS - 1); int idx = i * SHIELD_NUM_HORIZONTAL_POINTS + j; m_pFixedDirection[idx].x = cos(theta) * sin(phi); m_pFixedDirection[idx].y = sin(theta) * sin(phi); m_pFixedDirection[idx].z = cos(phi); m_pFixedDirection[idx] *= m_RestLength; VectorMin( m_vecRenderMins, m_pFixedDirection[idx], m_vecRenderMins ); VectorMax( m_vecRenderMaxs, m_pFixedDirection[idx], m_vecRenderMaxs ); } } // Compute box for fake volume testing Vector dist = m_pFixedDirection[0] - m_pFixedDirection[1]; float l = dist.Length(); // * m_RestLength; SetShieldPanelSize( Vector( -l * 0.25f, -l * 0.25f, -l * 0.25f), Vector( l * 0.25f, l * 0.25f, l * 0.25f) ); }
void C_NPC_Surface::GetRenderBounds( Vector& theMins, Vector& theMaxs ) { // BaseClass::GetRenderBounds( theMins, theMaxs ); if(sv_surface_testshape.GetBool()) { theMins.Init(-300.0f, 0.0f, 100.0f); theMaxs.Init(0.0f, 100.0f, 200.0f); } else { theMins = m_vecSurfacePos[0]; theMaxs = m_vecSurfacePos[0]; float surfaceRadius = m_flRadius * 3.0f; for (int i = 0; i < m_nActiveParticles; i++) { VectorMin( m_vecSurfacePos[i] - Vector( surfaceRadius, surfaceRadius, surfaceRadius ), theMins, theMins ); VectorMax( m_vecSurfacePos[i] + Vector( surfaceRadius, surfaceRadius, surfaceRadius ), theMaxs, theMaxs ); } } theMins -= GetRenderOrigin(); theMaxs -= GetRenderOrigin(); #if 0 Vector avg = (theMins + theMaxs) * 0.5f; theMins = theMins - ((theMins - avg) * 0.75f); theMaxs = theMaxs - ((theMaxs - avg) * 0.75f); #endif #if 0 Vector fountainOrigin(-1980, -1792, 1); theMins = fountainOrigin + Vector(-10, -10, -20); theMaxs = fountainOrigin + Vector(10, 10, 50); #endif // Msg( "origin %.2f %.2f %.2f : mins %.2f %.2f %.2f : maxs %.2f %.2f %.2f\n", GetRenderOrigin().x, GetRenderOrigin().y, GetRenderOrigin().z, theMins.x, theMins.y, theMins.z, theMaxs.x, theMaxs.y, theMaxs.z ); //debugoverlay->AddBoxOverlay( GetRenderOrigin(), theMins, theMaxs, QAngle( 0, 0, 0 ), 0, 255, 0, 0, 0 ); }
//----------------------------------------------------------------------------- // Returns the bounding box for the model //----------------------------------------------------------------------------- void CDmeMDL::GetBoundingBox( Vector *pMins, Vector *pMaxs ) const { if ( !g_pMaterialSystem || !g_pMDLCache || !g_pStudioRender ) { pMins->Init(); pMaxs->Init(); return; } if ( m_MDLHandle == MDLHANDLE_INVALID ) { pMins->Init(); pMaxs->Init(); return; } pMins->Init( FLT_MAX, FLT_MAX ); pMaxs->Init( -FLT_MAX, -FLT_MAX ); studiohdr_t *pStudioHdr = g_pMDLCache->GetStudioHdr( m_MDLHandle ); if ( !VectorCompare( vec3_origin, pStudioHdr->view_bbmin ) || !VectorCompare( vec3_origin, pStudioHdr->view_bbmax )) { // look for view clip *pMins = pStudioHdr->view_bbmin; *pMaxs = pStudioHdr->view_bbmax; } else if ( !VectorCompare( vec3_origin, pStudioHdr->hull_min ) || !VectorCompare( vec3_origin, pStudioHdr->hull_max )) { // look for hull *pMins = pStudioHdr->hull_min; *pMaxs = pStudioHdr->hull_max; } // Else use the sequence box mstudioseqdesc_t &seqdesc = pStudioHdr->pSeqdesc( m_nSequence ); VectorMin( seqdesc.bbmin, *pMins, *pMins ); VectorMax( seqdesc.bbmax, *pMaxs, *pMaxs ); }
//----------------------------------------------------------------------------- // Expand trigger bounds.. //----------------------------------------------------------------------------- void CCollisionProperty::ComputeVPhysicsSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) { bool bSetBounds = false; IPhysicsObject *pPhysicsObject = GetOuter()->VPhysicsGetObject(); if ( pPhysicsObject ) { if ( pPhysicsObject->GetCollide() ) { physcollision->CollideGetAABB( pVecWorldMins, pVecWorldMaxs, pPhysicsObject->GetCollide(), GetCollisionOrigin(), GetCollisionAngles() ); bSetBounds = true; } else if ( pPhysicsObject->GetSphereRadius( ) ) { float flRadius = pPhysicsObject->GetSphereRadius( ); Vector vecExtents( flRadius, flRadius, flRadius ); VectorSubtract( GetCollisionOrigin(), vecExtents, *pVecWorldMins ); VectorAdd( GetCollisionOrigin(), vecExtents, *pVecWorldMaxs ); bSetBounds = true; } } if ( !bSetBounds ) { *pVecWorldMins = GetCollisionOrigin(); *pVecWorldMaxs = *pVecWorldMins; } // Also, lets expand for the trigger bounds also if ( IsSolidFlagSet( FSOLID_USE_TRIGGER_BOUNDS ) ) { Vector vecWorldTriggerMins, vecWorldTriggerMaxs; WorldSpaceTriggerBounds( &vecWorldTriggerMins, &vecWorldTriggerMaxs ); VectorMin( vecWorldTriggerMins, *pVecWorldMins, *pVecWorldMins ); VectorMax( vecWorldTriggerMaxs, *pVecWorldMaxs, *pVecWorldMaxs ); } }
bool CAnimating::ComputeHitboxSurroundingBox( Vector *pVecWorldMins, Vector *pVecWorldMaxs ) { // Note that this currently should not be called during Relink because of IK. // The code below recomputes bones so as to get at the hitboxes, // which causes IK to trigger, which causes raycasts against the other entities to occur, // which is illegal to do while in the Relink phase. CStudioHdr *pStudioHdr = GetModelPtr(); if (!pStudioHdr) return false; mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( m_nHitboxSet ); if ( !set || !set->numhitboxes ) return false; CBoneCache *pCache = GetBoneCache(); // Compute a box in world space that surrounds this entity pVecWorldMins->Init( FLT_MAX, FLT_MAX, FLT_MAX ); pVecWorldMaxs->Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); Vector vecBoxAbsMins, vecBoxAbsMaxs; for ( int i = 0; i < set->numhitboxes; i++ ) { mstudiobbox_t *pbox = set->pHitbox(i); matrix3x4_t *pMatrix = pCache->GetCachedBone(pbox->bone); if ( pMatrix ) { TransformAABB( *pMatrix, pbox->bbmin, pbox->bbmax, vecBoxAbsMins, vecBoxAbsMaxs ); VectorMin( *pVecWorldMins, vecBoxAbsMins, *pVecWorldMins ); VectorMax( *pVecWorldMaxs, vecBoxAbsMaxs, *pVecWorldMaxs ); } } return true; }
bool CGutModel::LoadMesh_ASCII(void) { char szBuffer[128]; char sz_Tag[64]; fgets(szBuffer, 128, m_pFile); // { fgets(szBuffer, 128, m_pFile); // meshes n sscanf(szBuffer, "%s %d", sz_Tag, &m_iNumMeshes); m_iNumFaces = 0; m_iNumVertices = 0; m_pMeshArray = new sModelMesh[m_iNumMeshes]; if ( m_pMeshArray==NULL ) return false; m_vMin.Set(FLT_MAX); m_vMax.Set(-FLT_MAX); for ( int i=0; i<m_iNumMeshes; i++ ) { printf("Loading mesh %d/%d\n", i+1, m_iNumMeshes); m_pMeshArray[i].Load_ASCII(m_pFile); m_iNumFaces += m_pMeshArray[i].m_iNumFaces; m_iNumVertices += m_pMeshArray[i].m_iNumVertices; m_vMin = VectorMin(m_vMin, m_pMeshArray[i].m_vMin); m_vMax = VectorMax(m_vMax, m_pMeshArray[i].m_vMax); } fgets(szBuffer, 128, m_pFile); // } return true; }
float vu_peak(float* signal, unsigned n_samples, MeterScale scale) { float peak = VectorMax(signal, n_samples); return 20.0 * log10f(peak / ref[scale]); }
FBox FBox::TransformBy(const FMatrix& M) const { // if we are not valid, return another invalid box. if (!IsValid) { return FBox(0); } VectorRegister Vertices[8]; VectorRegister m0 = VectorLoadAligned(M.M[0]); VectorRegister m1 = VectorLoadAligned(M.M[1]); VectorRegister m2 = VectorLoadAligned(M.M[2]); VectorRegister m3 = VectorLoadAligned(M.M[3]); Vertices[0] = VectorLoadFloat3(&Min); Vertices[1] = VectorSetFloat3(Min.X, Min.Y, Max.Z); Vertices[2] = VectorSetFloat3(Min.X, Max.Y, Min.Z); Vertices[3] = VectorSetFloat3(Max.X, Min.Y, Min.Z); Vertices[4] = VectorSetFloat3(Max.X, Max.Y, Min.Z); Vertices[5] = VectorSetFloat3(Max.X, Min.Y, Max.Z); Vertices[6] = VectorSetFloat3(Min.X, Max.Y, Max.Z); Vertices[7] = VectorLoadFloat3(&Max); VectorRegister r0 = VectorMultiply(VectorReplicate(Vertices[0],0), m0); VectorRegister r1 = VectorMultiply(VectorReplicate(Vertices[1],0), m0); VectorRegister r2 = VectorMultiply(VectorReplicate(Vertices[2],0), m0); VectorRegister r3 = VectorMultiply(VectorReplicate(Vertices[3],0), m0); VectorRegister r4 = VectorMultiply(VectorReplicate(Vertices[4],0), m0); VectorRegister r5 = VectorMultiply(VectorReplicate(Vertices[5],0), m0); VectorRegister r6 = VectorMultiply(VectorReplicate(Vertices[6],0), m0); VectorRegister r7 = VectorMultiply(VectorReplicate(Vertices[7],0), m0); r0 = VectorMultiplyAdd( VectorReplicate(Vertices[0],1), m1, r0); r1 = VectorMultiplyAdd( VectorReplicate(Vertices[1],1), m1, r1); r2 = VectorMultiplyAdd( VectorReplicate(Vertices[2],1), m1, r2); r3 = VectorMultiplyAdd( VectorReplicate(Vertices[3],1), m1, r3); r4 = VectorMultiplyAdd( VectorReplicate(Vertices[4],1), m1, r4); r5 = VectorMultiplyAdd( VectorReplicate(Vertices[5],1), m1, r5); r6 = VectorMultiplyAdd( VectorReplicate(Vertices[6],1), m1, r6); r7 = VectorMultiplyAdd( VectorReplicate(Vertices[7],1), m1, r7); r0 = VectorMultiplyAdd( VectorReplicate(Vertices[0],2), m2, r0); r1 = VectorMultiplyAdd( VectorReplicate(Vertices[1],2), m2, r1); r2 = VectorMultiplyAdd( VectorReplicate(Vertices[2],2), m2, r2); r3 = VectorMultiplyAdd( VectorReplicate(Vertices[3],2), m2, r3); r4 = VectorMultiplyAdd( VectorReplicate(Vertices[4],2), m2, r4); r5 = VectorMultiplyAdd( VectorReplicate(Vertices[5],2), m2, r5); r6 = VectorMultiplyAdd( VectorReplicate(Vertices[6],2), m2, r6); r7 = VectorMultiplyAdd( VectorReplicate(Vertices[7],2), m2, r7); r0 = VectorAdd(r0, m3); r1 = VectorAdd(r1, m3); r2 = VectorAdd(r2, m3); r3 = VectorAdd(r3, m3); r4 = VectorAdd(r4, m3); r5 = VectorAdd(r5, m3); r6 = VectorAdd(r6, m3); r7 = VectorAdd(r7, m3); FBox NewBox; VectorRegister min0 = VectorMin(r0, r1); VectorRegister min1 = VectorMin(r2, r3); VectorRegister min2 = VectorMin(r4, r5); VectorRegister min3 = VectorMin(r6, r7); VectorRegister max0 = VectorMax(r0, r1); VectorRegister max1 = VectorMax(r2, r3); VectorRegister max2 = VectorMax(r4, r5); VectorRegister max3 = VectorMax(r6, r7); min0 = VectorMin(min0, min1); min1 = VectorMin(min2, min3); max0 = VectorMax(max0, max1); max1 = VectorMax(max2, max3); min0 = VectorMin(min0, min1); max0 = VectorMax(max0, max1); VectorStoreFloat3(min0, &NewBox.Min); VectorStoreFloat3(max0, &NewBox.Max); NewBox.IsValid = 1; return NewBox; }
void sModelMesh::Load_ASCII(FILE *pFile) { const int BufferSize = 256; char szBuffer[BufferSize]; char sz_Tag[BufferSize]; char sz_Content[BufferSize]; int i,j; fgets(szBuffer, BufferSize, pFile); // { fgets(szBuffer, BufferSize, pFile); // matrix fgets(szBuffer, BufferSize, pFile); // { for ( int r=0; r<4; r++ ) { fgets(szBuffer, BufferSize, pFile); // x,y,z sscanf(szBuffer, "%f,%f,%f", &m_Matrix[r][0], &m_Matrix[r][1], &m_Matrix[r][2]); } fgets(szBuffer, BufferSize, pFile); // } fgets(szBuffer, BufferSize, pFile); // buffers n sscanf(szBuffer, "%s %d", sz_Tag, &m_iNumVertexChunks); m_iNumFaces = 0; m_iNumVertices = 0; m_vMin.Set(FLT_MAX); m_vMax.Set(-FLT_MAX); if ( m_iNumVertexChunks ) { m_pVertexChunks = new sModelVertexChunk[m_iNumVertexChunks]; for ( i=0; i<m_iNumVertexChunks; i++ ) { fgets(szBuffer, BufferSize, pFile); // { sModelVertexChunk *pBuffer = m_pVertexChunks + i; fgets(szBuffer, BufferSize, pFile); // vertices n sscanf(szBuffer, "%s %d", sz_Tag, &pBuffer->m_iNumVertices); fgets(szBuffer, BufferSize, pFile); // format sscanf(szBuffer, "%s %s", sz_Tag, sz_Content); fgets(szBuffer, BufferSize, pFile); // { m_iNumVertices += pBuffer->m_iNumVertices; bool bVertex = false; bool bNormal = false; bool bColor = false; bool bTangentSpace = false; int iNumUVs = 0; int strLen = strlen(sz_Content); for ( int s=0; s<strLen; s++ ) { switch(sz_Content[s]) { case 'v': bVertex = true; break; case 'n': bNormal = true; break; case 'c': bColor = true; break; case 't': iNumUVs = sz_Content[++s] - '0'; break; case '_': break; case 'p': case 'q': bTangentSpace = true; break; default: break; } } int vsize = 0; if ( bVertex ) { pBuffer->m_VertexDecl.m_iPositionOffset = vsize; pBuffer->m_VertexDecl.m_iNumPositionElements = 3; vsize += 4*3; } if ( bNormal ) { pBuffer->m_VertexDecl.m_iNormalOffset = vsize; pBuffer->m_VertexDecl.m_iNumNormalElements = 3; vsize += 4*3; } if ( bColor ) { pBuffer->m_VertexDecl.m_iColorOffset = vsize; pBuffer->m_VertexDecl.m_iNumColorElements = 4; vsize += 4; } for ( j=0; j<iNumUVs; j++ ) { pBuffer->m_VertexDecl.m_iTexcoordOffset[j] = vsize; pBuffer->m_VertexDecl.m_iNumTexcoordElements[j] = 2; vsize += 4*2; } if ( bTangentSpace ) { pBuffer->m_VertexDecl.m_iTangentOffset = vsize; pBuffer->m_VertexDecl.m_iNumTangentElements = 3; vsize += 4 * 3; pBuffer->m_VertexDecl.m_iBiNormalOffset = vsize; pBuffer->m_VertexDecl.m_iBiNormalElements = 3; vsize += 4 * 3; } if ( vsize==0 ) { int a=0; } pBuffer->m_VertexDecl.m_iVertexSize = vsize; if ( pBuffer->m_iNumVertices ) { pBuffer->m_pVertexArray = new sModelVertex[pBuffer->m_iNumVertices]; } printf("."); for ( j=0; j<pBuffer->m_iNumVertices; j++ ) { sModelVertex *pVertex = pBuffer->m_pVertexArray + j; Vector4 &position = pVertex->m_Position; Vector4 &normal = pVertex->m_Normal; Vector4 &color = pVertex->m_Color; Vector4 *pUV = pVertex->m_Texcoord; Vector4 &tangent = pVertex->m_Tangent; Vector4 &binormal = pVertex->m_BiNormal; fgets(szBuffer, BufferSize, pFile); char *pLoc = szBuffer; if ( bVertex ) { pLoc = strstr(pLoc, " "); sscanf(pLoc, "%f,%f,%f", &position[0], &position[1], &position[2]); position[3] = 1.0f; m_vMin = VectorMin(m_vMin, position); m_vMax = VectorMax(m_vMax, position); } if ( bNormal ) { pLoc = strstr(pLoc+1, " "); pLoc = strstr(pLoc+1, " "); sscanf(pLoc, "%f,%f,%f", &normal[0], &normal[1], &normal[2]); normal[3] = 1.0f; } if ( bColor ) { pLoc = strstr(pLoc+1, " "); pLoc = strstr(pLoc+1, " "); sscanf(pLoc, "%f,%f,%f,%f", &color[0], &color[1], &color[2], &color[3]); } for ( int t=0; t<iNumUVs && t<MAX_TEXCOORDS; t++ ) { pLoc = strstr(pLoc+1, " "); pLoc = strstr(pLoc+1, " "); sscanf(pLoc, "%f,%f", &pUV[t][0], &pUV[t][1]); } if ( bTangentSpace ) { pLoc = strstr(pLoc+1, " "); pLoc = strstr(pLoc+1, " "); sscanf(pLoc, "%f,%f,%f", &tangent[0], &tangent[1], &tangent[2]); pLoc = strstr(pLoc+1, " "); pLoc = strstr(pLoc+1, " "); sscanf(pLoc, "%f,%f,%f", &binormal[0], &binormal[1], &binormal[2]); } if ( (j & 0xff)==0 ) printf("."); } fgets(szBuffer, BufferSize, pFile); // } fgets(szBuffer, BufferSize, pFile); // triangle_list_indices n sscanf(szBuffer, "%s %d", sz_Tag, &pBuffer->m_iNumIndices); if ( pBuffer->m_iNumIndices ) pBuffer->m_pIndexArray = new unsigned short[pBuffer->m_iNumIndices]; fgets(szBuffer, BufferSize, pFile); // { for ( j=0; j<pBuffer->m_iNumIndices/3; j++ ) { int a,b,c; fgets(szBuffer, BufferSize, pFile); sscanf(szBuffer, "%d %d %d", &a, &b, &c); unsigned short *p = pBuffer->m_pIndexArray + j*3; p[0] = a; p[1] = b; p[2] = c; } fgets(szBuffer, BufferSize, pFile); // } fgets(szBuffer, BufferSize, pFile); // batches n sscanf(szBuffer, "%s %d", sz_Tag, &pBuffer->m_iNumBatches); if ( pBuffer->m_iNumBatches ) pBuffer->m_pBatchArray = new sModelBatch[pBuffer->m_iNumBatches]; fgets(szBuffer, BufferSize, pFile); // { for ( j=0; j<pBuffer->m_iNumBatches; j++ ) { sModelBatch *pBatch = pBuffer->m_pBatchArray + j; fgets(szBuffer, BufferSize, pFile); // material n sscanf(szBuffer, "%s %d", sz_Tag, &pBatch->m_iMaterialID); fgets(szBuffer, BufferSize, pFile); // faces n sscanf(szBuffer, "%s %d", sz_Tag, &pBatch->m_iNumPrimitives); fgets(szBuffer, BufferSize, pFile); // index_begin n sscanf(szBuffer, "%s %d", sz_Tag, &pBatch->m_iIndexArrayBegin); pBatch->m_iNumIndices = pBatch->m_iNumPrimitives * 3; pBatch->m_iIndexArrayEnd = pBatch->m_iIndexArrayBegin + pBatch->m_iNumIndices; m_iNumFaces += pBatch->m_iNumPrimitives; } fgets(szBuffer, BufferSize, pFile); // } fgets(szBuffer, BufferSize, pFile); // } } } printf(".\n"); fgets(szBuffer, BufferSize, pFile); // } }
//----------------------------------------------------------------------------- // Emits occluder brushes //----------------------------------------------------------------------------- static void EmitOccluderBrushes() { char str[64]; g_OccluderData.RemoveAll(); g_OccluderPolyData.RemoveAll(); g_OccluderVertexIndices.RemoveAll(); tree_t *pOccluderTree = ClipOccluderBrushes(); if (!pOccluderTree) return; CUtlVector<face_t*> faceList( 1024, 1024 ); CUtlVector<side_t*> sideList( 1024, 1024 ); GenerateOccluderFaceList( pOccluderTree->headnode, faceList ); #ifdef _DEBUG int *pEmitted = (int*)stackalloc( faceList.Count() * sizeof(int) ); memset( pEmitted, 0, faceList.Count() * sizeof(int) ); #endif for ( entity_num=1; entity_num < num_entities; ++entity_num ) { if (!IsFuncOccluder(entity_num)) continue; // Output only those parts of the occluder tree which are a part of the brush int nOccluder = g_OccluderData.AddToTail(); doccluderdata_t &occluderData = g_OccluderData[ nOccluder ]; occluderData.firstpoly = g_OccluderPolyData.Count(); occluderData.mins.Init( FLT_MAX, FLT_MAX, FLT_MAX ); occluderData.maxs.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); occluderData.flags = 0; occluderData.area = -1; // NOTE: If you change the algorithm by which occluder numbers are allocated, // then you must also change FixupOnlyEntsOccluderEntities() below sprintf (str, "%i", nOccluder); SetKeyValue (&entities[entity_num], "occludernumber", str); int nIndex = g_OccluderInfo.AddToTail(); g_OccluderInfo[nIndex].m_nOccluderEntityIndex = entity_num; sideList.RemoveAll(); GenerateOccluderSideList( entity_num, sideList ); for ( int i = faceList.Count(); --i >= 0; ) { // Skip nodraw surfaces, but not triggers that have been marked as nodraw face_t *f = faceList[i]; if ( ( texinfo[f->texinfo].flags & SURF_NODRAW ) && (( texinfo[f->texinfo].flags & SURF_TRIGGER ) == 0 ) ) continue; // Only emit faces that appear in the side list of the occluder for ( int j = sideList.Count(); --j >= 0; ) { if ( sideList[j] != f->originalface ) continue; if ( f->numpoints < 3 ) continue; // not a final face Assert ( !f->merged && !f->split[0] && !f->split[1] ); #ifdef _DEBUG Assert( !pEmitted[i] ); pEmitted[i] = entity_num; #endif int k = g_OccluderPolyData.AddToTail(); doccluderpolydata_t *pOccluderPoly = &g_OccluderPolyData[k]; pOccluderPoly->planenum = f->planenum; pOccluderPoly->vertexcount = f->numpoints; pOccluderPoly->firstvertexindex = g_OccluderVertexIndices.Count(); for( k = 0; k < f->numpoints; ++k ) { g_OccluderVertexIndices.AddToTail( f->vertexnums[k] ); const Vector &p = dvertexes[f->vertexnums[k]].point; VectorMin( occluderData.mins, p, occluderData.mins ); VectorMax( occluderData.maxs, p, occluderData.maxs ); } break; } } occluderData.polycount = g_OccluderPolyData.Count() - occluderData.firstpoly; // Mark this brush as not having brush geometry so it won't be re-emitted with a brush model entities[entity_num].numbrushes = 0; } FreeTree( pOccluderTree ); }
void C_EnvProjectedTexture::UpdateLight( void ) { VPROF("C_EnvProjectedTexture::UpdateLight"); bool bVisible = true; Vector vLinearFloatLightColor( m_LightColor.r, m_LightColor.g, m_LightColor.b ); float flLinearFloatLightAlpha = m_LightColor.a; if ( m_bAlwaysUpdate ) { m_bForceUpdate = true; } if ( m_CurrentLinearFloatLightColor != vLinearFloatLightColor || m_flCurrentLinearFloatLightAlpha != flLinearFloatLightAlpha ) { float flColorTransitionSpeed = gpGlobals->frametime * m_flColorTransitionTime * 255.0f; m_CurrentLinearFloatLightColor.x = Approach( vLinearFloatLightColor.x, m_CurrentLinearFloatLightColor.x, flColorTransitionSpeed ); m_CurrentLinearFloatLightColor.y = Approach( vLinearFloatLightColor.y, m_CurrentLinearFloatLightColor.y, flColorTransitionSpeed ); m_CurrentLinearFloatLightColor.z = Approach( vLinearFloatLightColor.z, m_CurrentLinearFloatLightColor.z, flColorTransitionSpeed ); m_flCurrentLinearFloatLightAlpha = Approach( flLinearFloatLightAlpha, m_flCurrentLinearFloatLightAlpha, flColorTransitionSpeed ); m_bForceUpdate = true; } if ( !m_bForceUpdate ) { bVisible = IsBBoxVisible(); } if ( m_bState == false || !bVisible ) { // Spotlight's extents aren't in view ShutDownLightHandle(); return; } if ( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE || m_hTargetEntity != NULL || m_bForceUpdate ) { Vector vForward, vRight, vUp, vPos = GetAbsOrigin(); FlashlightState_t state; if ( m_hTargetEntity != NULL ) { if ( m_bCameraSpace ) { const QAngle &angles = GetLocalAngles(); C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer(); if( pPlayer ) { const QAngle playerAngles = pPlayer->GetAbsAngles(); Vector vPlayerForward, vPlayerRight, vPlayerUp; AngleVectors( playerAngles, &vPlayerForward, &vPlayerRight, &vPlayerUp ); matrix3x4_t mRotMatrix; AngleMatrix( angles, mRotMatrix ); VectorITransform( vPlayerForward, mRotMatrix, vForward ); VectorITransform( vPlayerRight, mRotMatrix, vRight ); VectorITransform( vPlayerUp, mRotMatrix, vUp ); float dist = (m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin()).Length(); vPos = m_hTargetEntity->GetAbsOrigin() - vForward*dist; VectorNormalize( vForward ); VectorNormalize( vRight ); VectorNormalize( vUp ); } } else { vForward = m_hTargetEntity->GetAbsOrigin() - GetAbsOrigin(); VectorNormalize( vForward ); // JasonM - unimplemented Assert (0); //Quaternion q = DirectionToOrientation( dir ); // // JasonM - set up vRight, vUp // // VectorNormalize( vRight ); // VectorNormalize( vUp ); } } else { AngleVectors( GetAbsAngles(), &vForward, &vRight, &vUp ); } state.m_fHorizontalFOVDegrees = m_flLightFOV; state.m_fVerticalFOVDegrees = m_flLightFOV; state.m_vecLightOrigin = vPos; BasisToQuaternion( vForward, vRight, vUp, state.m_quatOrientation ); state.m_NearZ = m_flNearZ; state.m_FarZ = m_flFarZ; // quickly check the proposed light's bbox against the view frustum to determine whether we // should bother to create it, if it doesn't exist, or cull it, if it does. if ( m_bSimpleProjection == false ) { #pragma message("OPTIMIZATION: this should be made SIMD") // get the half-widths of the near and far planes, // based on the FOV which is in degrees. Remember that // on planet Valve, x is forward, y left, and z up. const float tanHalfAngle = tan( m_flLightFOV * ( M_PI/180.0f ) * 0.5f ); const float halfWidthNear = tanHalfAngle * m_flNearZ; const float halfWidthFar = tanHalfAngle * m_flFarZ; // now we can build coordinates in local space: the near rectangle is eg // (0, -halfWidthNear, -halfWidthNear), (0, halfWidthNear, -halfWidthNear), // (0, halfWidthNear, halfWidthNear), (0, -halfWidthNear, halfWidthNear) VectorAligned vNearRect[4] = { VectorAligned( m_flNearZ, -halfWidthNear, -halfWidthNear), VectorAligned( m_flNearZ, halfWidthNear, -halfWidthNear), VectorAligned( m_flNearZ, halfWidthNear, halfWidthNear), VectorAligned( m_flNearZ, -halfWidthNear, halfWidthNear) }; VectorAligned vFarRect[4] = { VectorAligned( m_flFarZ, -halfWidthFar, -halfWidthFar), VectorAligned( m_flFarZ, halfWidthFar, -halfWidthFar), VectorAligned( m_flFarZ, halfWidthFar, halfWidthFar), VectorAligned( m_flFarZ, -halfWidthFar, halfWidthFar) }; matrix3x4_t matOrientation( vForward, -vRight, vUp, vPos ); enum { kNEAR = 0, kFAR = 1, }; VectorAligned vOutRects[2][4]; for ( int i = 0 ; i < 4 ; ++i ) { VectorTransform( vNearRect[i].Base(), matOrientation, vOutRects[0][i].Base() ); } for ( int i = 0 ; i < 4 ; ++i ) { VectorTransform( vFarRect[i].Base(), matOrientation, vOutRects[1][i].Base() ); } // now take the MIN and MAX extents for the bbox, and see if it is visible. Vector mins = **vOutRects; Vector maxs = **vOutRects; for ( int i = 1; i < 8 ; ++i ) { VectorMin( mins, *(*vOutRects+i), mins ); VectorMax( maxs, *(*vOutRects+i), maxs ); } #if 0 //for debugging the visibility frustum we just calculated NDebugOverlay::Triangle( vOutRects[0][0], vOutRects[0][1], vOutRects[0][2], 255, 0, 0, 100, true, 0.0f ); //first tri NDebugOverlay::Triangle( vOutRects[0][2], vOutRects[0][1], vOutRects[0][0], 255, 0, 0, 100, true, 0.0f ); //make it double sided NDebugOverlay::Triangle( vOutRects[0][2], vOutRects[0][3], vOutRects[0][0], 255, 0, 0, 100, true, 0.0f ); //second tri NDebugOverlay::Triangle( vOutRects[0][0], vOutRects[0][3], vOutRects[0][2], 255, 0, 0, 100, true, 0.0f ); //make it double sided NDebugOverlay::Triangle( vOutRects[1][0], vOutRects[1][1], vOutRects[1][2], 0, 0, 255, 100, true, 0.0f ); //first tri NDebugOverlay::Triangle( vOutRects[1][2], vOutRects[1][1], vOutRects[1][0], 0, 0, 255, 100, true, 0.0f ); //make it double sided NDebugOverlay::Triangle( vOutRects[1][2], vOutRects[1][3], vOutRects[1][0], 0, 0, 255, 100, true, 0.0f ); //second tri NDebugOverlay::Triangle( vOutRects[1][0], vOutRects[1][3], vOutRects[1][2], 0, 0, 255, 100, true, 0.0f ); //make it double sided NDebugOverlay::Box( vec3_origin, mins, maxs, 0, 255, 0, 100, 0.0f ); #endif bool bVisible = IsBBoxVisible( mins, maxs ); if (!bVisible) { // Spotlight's extents aren't in view if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) { ShutDownLightHandle(); } return; } } float flAlpha = m_flCurrentLinearFloatLightAlpha * ( 1.0f / 255.0f ); state.m_fQuadraticAtten = 0.0; state.m_fLinearAtten = 100; state.m_fConstantAtten = 0.0f; state.m_FarZAtten = m_flFarZ; state.m_fBrightnessScale = m_flBrightnessScale; state.m_Color[0] = m_CurrentLinearFloatLightColor.x * ( 1.0f / 255.0f ) * flAlpha; state.m_Color[1] = m_CurrentLinearFloatLightColor.y * ( 1.0f / 255.0f ) * flAlpha; state.m_Color[2] = m_CurrentLinearFloatLightColor.z * ( 1.0f / 255.0f ) * flAlpha; state.m_Color[3] = 0.0f; // fixme: need to make ambient work m_flAmbient; state.m_flShadowSlopeScaleDepthBias = g_pMaterialSystemHardwareConfig->GetShadowSlopeScaleDepthBias(); state.m_flShadowDepthBias = g_pMaterialSystemHardwareConfig->GetShadowDepthBias(); state.m_bEnableShadows = m_bEnableShadows; state.m_pSpotlightTexture = m_SpotlightTexture; state.m_pProjectedMaterial = NULL; // only complain if we're using material projection state.m_nSpotlightTextureFrame = m_nSpotlightTextureFrame; state.m_flProjectionSize = m_flProjectionSize; state.m_flProjectionRotation = m_flRotation; state.m_nShadowQuality = m_nShadowQuality; // Allow entity to affect shadow quality if ( m_bSimpleProjection == true ) { state.m_bSimpleProjection = true; state.m_bOrtho = true; state.m_fOrthoLeft = -m_flProjectionSize; state.m_fOrthoTop = -m_flProjectionSize; state.m_fOrthoRight = m_flProjectionSize; state.m_fOrthoBottom = m_flProjectionSize; } if( m_LightHandle == CLIENTSHADOW_INVALID_HANDLE ) { // Hack: env projected textures don't work like normal flashlights; they're not assigned to a given splitscreen slot, // but the flashlight code requires this HACK_GETLOCALPLAYER_GUARD( "Env projected texture" ); if ( m_bSimpleProjection == true ) { m_LightHandle = g_pClientShadowMgr->CreateProjection( state ); } else { m_LightHandle = g_pClientShadowMgr->CreateFlashlight( state ); } if ( m_LightHandle != CLIENTSHADOW_INVALID_HANDLE ) { m_bForceUpdate = false; } } else { if ( m_bSimpleProjection == true ) { g_pClientShadowMgr->UpdateProjectionState( m_LightHandle, state ); } else { g_pClientShadowMgr->UpdateFlashlightState( m_LightHandle, state ); } m_bForceUpdate = false; } g_pClientShadowMgr->GetFrustumExtents( m_LightHandle, m_vecExtentsMin, m_vecExtentsMax ); m_vecExtentsMin = m_vecExtentsMin - GetAbsOrigin(); m_vecExtentsMax = m_vecExtentsMax - GetAbsOrigin(); } if( m_bLightOnlyTarget ) { g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, m_hTargetEntity ); } else { g_pClientShadowMgr->SetFlashlightTarget( m_LightHandle, NULL ); } g_pClientShadowMgr->SetFlashlightLightWorld( m_LightHandle, m_bLightWorld ); if ( !asw_perf_wtf.GetBool() && !m_bForceUpdate ) { g_pClientShadowMgr->UpdateProjectedTexture( m_LightHandle, true ); } }
int main(void) { ex_sask_init(); /*Initialise Audio input and output function*/ ADCChannelInit(pADCChannelHandle, adcBuffer); OCPWMInit(pOCPWMHandle, ocPWMBuffer); /*Start Audio input and output function*/ ADCChannelStart(pADCChannelHandle); OCPWMStart(pOCPWMHandle); /*Initialising variables that are needed for calculating the peak frequency*/ int peakFrequency = 0; int peakFrequencyBin = 0; while (1) { /*Wait till the ADC has a new frame available*/ while (ADCChannelIsBusy(pADCChannelHandle)); /*Read in the Audio Samples from the ADC*/ ADCChannelRead(pADCChannelHandle, frctAudioIn, FRAME_SIZE); /*Computing the FFT of the raw signal*/ fourierTransform(FRAME_SIZE, compX, frctAudioIn); /*Removing the negative part of the FFT output (imaginary part) by zeroing it out*/ filterNegativeFreq(FRAME_SIZE, compXfiltered, compX); /*Compute the square magnitude of the complex FFT output array so we have a Real output vetor*/ SquareMagnitudeCplx(FRAME_SIZE / 2, &compXfiltered[0], &compXfiltered[0].real); /*Find the frequency Bin ( = index into the SigCmpx[] array) that has the largest energy*/ /*i.e., the largest spectral component*/ VectorMax(FRAME_SIZE / 2, &compXfiltered[0].real, &peakFrequencyBin); /*Compute the frequency (in Hz) of the largest spectral component*/ peakFrequency = peakFrequencyBin * (8000 / FRAME_SIZE); /*Uses the peak frequency variable to turn on the corresponding LEDs*/ turnOnLEDs(peakFrequency); /* Used for checking whether the user wants to record */ if (CheckSwitchS1() == PRESSED) { if (switchState == 0) { //startRecording(); Code works, but doesn't record much, only a fraction of a second } else if (switchState == 1) { int i = 0; for (i; i < (FRAME_SIZE)*5; i++) { frctAudioOut[i] = 0; } switchState = 0; firstPartExecutedDecision = 0; } } /* Switch two is just used to toggle between different modes */ if (CheckSwitchS2() == PRESSED) { if (switchState2 == 0) { switchState2 = 1; } else if (switchState2 == 1) { switchState2 = 2; } else if (switchState2 == 2) { switchState2 = 0; } } /* Checking whether the peak frequency is above 800 and if so calling the function playPureSignal() */ if (peakFrequency >= 800) { playPureSignal(peakFrequency); } else if (switchState2 != 2) { int i = 0; for (i; i < FRAME_SIZE; i++) { if (switchState2 == 0) { frctAudioOut[i] = frctAudioIn[i]; //Used for the mode that allows for outputting of the original signal } else if (switchState2 == 1) { frctAudioOut[i] = 0; //Used for the mode that requests silence if the threshold has not been met } } } if (switchState2 == 2) { int i = 0; for (i; i < FRAME_SIZE; i++) { frctAudioOut[i] = 0; } } /* Outputting the pure signal or original sound or silence, depending on what's inside frctAudioOut*/ while (OCPWMIsBusy(pOCPWMHandle)); OCPWMWrite(pOCPWMHandle, frctAudioOut, FRAME_SIZE); } /*============================================================================= | Function used for recording the input signal, a snapshot of the frame | is stored inside the frctAudioOut array, this is done five times as that | was the largest possible size for frctAudioOut array as anything larger would | lead to exhausting the memory, the function records correctly but the recording | is not long enough, hence the code was retired as it requires more work. *===========================================================================*/ void startRecording() { if (firstPartExecutedDecision == 0) { int i = 0; for (i; i < FRAME_SIZE; i++) { frctAudioOut[i] = frctAudioIn[i]*0.5; } firstPartExecutedDecision = 1; } if (firstPartExecutedDecision == 1) { int i = FRAME_SIZE; int iFrameSize = 0; for (i; i < (FRAME_SIZE)*2; i++) { frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5; iFrameSize++; } firstPartExecutedDecision = 2; } if (firstPartExecutedDecision == 2) { int i = (FRAME_SIZE)*2; int iFrameSize = 0; for (i; i < (FRAME_SIZE)*3; i++) { frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5; iFrameSize++; } firstPartExecutedDecision = 3; } if (firstPartExecutedDecision == 3) { int i = (FRAME_SIZE)*3; int iFrameSize = 0; for (i; i < (FRAME_SIZE)*4; i++) { frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5; iFrameSize++; } firstPartExecutedDecision = 4; } if (firstPartExecutedDecision == 4) { int i = (FRAME_SIZE)*4; int iFrameSize = 0; for (i; i < (FRAME_SIZE)*5; i++) { frctAudioOut[i] = frctAudioIn[iFrameSize]*0.5; iFrameSize++; } firstPartExecutedDecision = -1; switchState = 1; } } /*============================================================================= | Function used to generate the pure signal using the createSimpleSignal() | function available in the modulate.h header - this function uses the peak | frequency handed through the parameter call to decide what signal to generate. | The output signal is stored inside the frctAudioOut array which is then | later used for the OCPWMWrite() function to output the sound. *===========================================================================*/ void playPureSignal(int peakFrequency) { int simpleSignalFrequency = 0; if (peakFrequency <= 1600) { simpleSignalFrequency = 500; createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut); } else if (peakFrequency <= 2400) { simpleSignalFrequency = 800; createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut); } else if (peakFrequency <= 3200) { simpleSignalFrequency = 1000; createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut); } else if (peakFrequency <= 4000) { simpleSignalFrequency = 1500; createSimpleSignal(simpleSignalFrequency, FRAME_SIZE, frctAudioOut); } }