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() ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CEnvBeam::UpdateThink( void ) { // Apply damage every 1/10th of a second. if ( ( m_flDamage > 0 ) && ( gpGlobals->curtime >= m_flFireTime + 0.1 ) ) { trace_t tr; UTIL_TraceLine( GetAbsStartPos(), GetAbsEndPos(), MASK_SOLID, NULL, COLLISION_GROUP_NONE, &tr ); BeamDamage( &tr ); // BeamDamage calls RelinkBeam, so no need to call it again. } else { RelinkBeam(); } if( m_TouchType != touch_none ) { trace_t tr; Ray_t ray; ray.Init( GetAbsStartPos(), GetAbsEndPos() ); if( m_TouchType == touch_player_or_npc_or_physicsprop ) { CTraceFilterPlayersNPCsPhysicsProps traceFilter; enginetrace->TraceRay( ray, MASK_SHOT, &traceFilter, &tr ); } else { CTraceFilterPlayersNPCs traceFilter; enginetrace->TraceRay( ray, MASK_SHOT, &traceFilter, &tr ); } if( tr.fraction != 1.0 && PassesTouchFilters( tr.m_pEnt ) ) { m_OnTouchedByEntity.FireOutput( tr.m_pEnt, this, 0 ); return; } } SetNextThink( gpGlobals->curtime ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CEnvLaser::FireAtPoint( trace_t &tr ) { SetAbsEndPos( tr.endpos ); if ( m_pSprite ) { UTIL_SetOrigin( m_pSprite, tr.endpos ); } // Apply damage and do sparks every 1/10th of a second. if ( gpGlobals->curtime >= m_flFireTime + 0.1 ) { BeamDamage( &tr ); DoSparks( GetAbsStartPos(), tr.endpos ); } }
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() ); }
//----------------------------------------------------------------------------- // Purpose: Turns the lightning on. If it is set for interval refiring, it will // begin doing so. If it is set to be continually on, it will do so. //----------------------------------------------------------------------------- void CEnvBeam::TurnOn( void ) { m_active = 1; if ( ServerSide() ) { RemoveEffects( EF_NODRAW ); DoSparks( GetAbsStartPos(), GetAbsEndPos() ); SetThink( &CEnvBeam::UpdateThink ); SetNextThink( gpGlobals->curtime ); SetFireTime( gpGlobals->curtime ); } else { SetThink( &CEnvBeam::StrikeThink ); SetNextThink( gpGlobals->curtime ); } }
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() ); }
//----------------------------------------------------------------------------- // Computes the bounding box of a beam local to the origin of the beam //----------------------------------------------------------------------------- void CBeam::ComputeBounds( Vector& mins, Vector& maxs ) { Vector vecAbsStart = GetAbsStartPos(); Vector vecAbsEnd = GetAbsEndPos(); // May need extra points for creating the min/max bounds bool bUseExtraPoints = false; Vector vecAbsExtra1, vecAbsExtra2; #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, vecAbsStart, vecAbsEnd, vecAbsExtra1, vecAbsExtra2, &traceFilterChain ); #endif switch( GetType() ) { case BEAM_LASER: case BEAM_ENTS: case BEAM_SPLINE: case BEAM_ENTPOINT: { // Compute the bounds here... Vector attachmentPoint( 0, 0, 0 ); mins.Init( 99999, 99999, 99999 ); maxs.Init( -99999, -99999, -99999 ); for (int i = 0; i < m_nNumBeamEnts; ++i ) { C_BaseEntity *pTestEnt = m_hAttachEntity[i].Get(); if ( pTestEnt ) { if ( pTestEnt == this ) { mins = maxs = GetAbsOrigin(); } else { // We do this so we don't have to calculate attachments (and do expensive bone-setup calculations) on our attachments. Vector attMins, attMaxs; m_hAttachEntity[i]->GetRenderBoundsWorldspace( attMins, attMaxs ); mins = mins.Min( attMins ); mins = mins.Min( attMaxs ); maxs = maxs.Max( attMins ); maxs = maxs.Max( attMaxs ); } //ASSERT_COORD( mins ); //ASSERT_COORD( maxs ); } else { if (i == 0) { VectorCopy( vecAbsStart, attachmentPoint ); } else if (i == 1) { VectorCopy( vecAbsEnd, attachmentPoint ); } else { Assert(0); } mins = mins.Min( attachmentPoint ); maxs = maxs.Max( attachmentPoint ); } } } break; case BEAM_POINTS: default: { for (int i = 0; i < 3; ++i) { if (vecAbsStart[i] < vecAbsEnd[i]) { mins[i] = vecAbsStart[i]; maxs[i] = vecAbsEnd[i]; } else { mins[i] = vecAbsEnd[i]; maxs[i] = vecAbsStart[i]; } } } break; } if ( bUseExtraPoints ) { mins = mins.Min( vecAbsExtra1 ); mins = mins.Min( vecAbsExtra2 ); maxs = maxs.Max( vecAbsExtra1 ); maxs = maxs.Max( vecAbsExtra2 ); } // Make sure the bounds are measured in *relative coords* Vector vecAbsOrigin = GetAbsOrigin(); mins -= vecAbsOrigin; maxs -= vecAbsOrigin; }
//----------------------------------------------------------------------------- // Computes the bounding box of a beam local to the origin of the beam //----------------------------------------------------------------------------- void CBeam::ComputeBounds( Vector& mins, Vector& maxs ) { Vector vecAbsStart = GetAbsStartPos(); Vector vecAbsEnd = GetAbsEndPos(); // May need extra points for creating the min/max bounds bool bUseExtraPoints = false; Vector vecAbsExtra1, vecAbsExtra2; switch( GetType() ) { case BEAM_LASER: case BEAM_ENTS: case BEAM_SPLINE: case BEAM_ENTPOINT: { // Compute the bounds here... Vector attachmentPoint( 0, 0, 0 ); mins.Init( 99999, 99999, 99999 ); maxs.Init( -99999, -99999, -99999 ); for (int i = 0; i < m_nNumBeamEnts; ++i ) { C_BaseEntity *pTestEnt = m_hAttachEntity[i].Get(); if ( pTestEnt ) { if ( pTestEnt == this ) { mins = maxs = GetAbsOrigin(); } else { // We do this so we don't have to calculate attachments (and do expensive bone-setup calculations) on our attachments. Vector attMins, attMaxs; m_hAttachEntity[i]->GetRenderBoundsWorldspace( attMins, attMaxs ); mins = mins.Min( attMins ); mins = mins.Min( attMaxs ); maxs = maxs.Max( attMins ); maxs = maxs.Max( attMaxs ); } //ASSERT_COORD( mins ); //ASSERT_COORD( maxs ); } else { if (i == 0) { VectorCopy( vecAbsStart, attachmentPoint ); } else if (i == 1) { VectorCopy( vecAbsEnd, attachmentPoint ); } else { Assert(0); } mins = mins.Min( attachmentPoint ); maxs = maxs.Max( attachmentPoint ); } } } break; case BEAM_POINTS: default: { for (int i = 0; i < 3; ++i) { if (vecAbsStart[i] < vecAbsEnd[i]) { mins[i] = vecAbsStart[i]; maxs[i] = vecAbsEnd[i]; } else { mins[i] = vecAbsEnd[i]; maxs[i] = vecAbsStart[i]; } } } break; } if ( bUseExtraPoints ) { mins = mins.Min( vecAbsExtra1 ); mins = mins.Min( vecAbsExtra2 ); maxs = maxs.Max( vecAbsExtra1 ); maxs = maxs.Max( vecAbsExtra2 ); } // bloat the bounding box by the width of the beam float rad = 0.5f * MAX( m_fWidth.Get(), m_fEndWidth.Get() ); Vector vecRad( rad, rad, rad ); mins -= vecRad; maxs += vecRad; // Make sure the bounds are measured in *relative coords* Vector vecAbsOrigin = GetAbsOrigin(); mins -= vecAbsOrigin; maxs -= vecAbsOrigin; }
//----------------------------------------------------------------------------- // Computes the bounding box of a beam local to the origin of the beam //----------------------------------------------------------------------------- void CBeam::ComputeBounds( Vector& mins, Vector& maxs ) { switch( GetType() ) { case BEAM_LASER: case BEAM_ENTS: case BEAM_SPLINE: case BEAM_ENTPOINT: { // Compute the bounds here... Vector attachmentPoint( 0, 0, 0 ); mins.Init( 99999, 99999, 99999 ); maxs.Init( -99999, -99999, -99999 ); for (int i = 0; i < m_nNumBeamEnts; ++i ) { C_BaseEntity *pTestEnt = m_hAttachEntity[i].Get(); if ( pTestEnt ) { if ( pTestEnt == this ) { mins = maxs = GetAbsOrigin(); } else { // We do this so we don't have to calculate attachments (and do expensive bone-setup calculations) on our attachments. Vector attMins, attMaxs; m_hAttachEntity[i]->GetRenderBoundsWorldspace( attMins, attMaxs ); mins = mins.Min( attMins ); mins = mins.Min( attMaxs ); maxs = maxs.Max( attMins ); maxs = maxs.Max( attMaxs ); } //ASSERT_COORD( mins ); //ASSERT_COORD( maxs ); } else { if (i == 0) { VectorCopy( GetAbsStartPos(), attachmentPoint ); } else if (i == 1) { VectorCopy( GetAbsEndPos(), attachmentPoint ); } else { Assert(0); } mins = mins.Min( attachmentPoint ); maxs = maxs.Max( attachmentPoint ); } } } break; case BEAM_POINTS: default: { Vector vecAbsStart = GetAbsStartPos(); Vector vecAbsEnd = GetAbsEndPos(); for (int i = 0; i < 3; ++i) { if (vecAbsStart[i] < vecAbsEnd[i]) { mins[i] = vecAbsStart[i]; maxs[i] = vecAbsEnd[i]; } else { mins[i] = vecAbsEnd[i]; maxs[i] = vecAbsStart[i]; } } } break; } // Make sure the bounds are measured in *relative coords* Vector vecAbsOrigin = GetAbsOrigin(); mins -= vecAbsOrigin; maxs -= vecAbsOrigin; }