void CDecal :: StaticDecal( void ) { trace_t trace; int entityIndex, modelIndex = 0; Vector position = GetAbsOrigin(); UTIL_TraceLine( position - Vector(5,5,5), position + Vector(5,5,5), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace ); entityIndex = (short)trace.m_pEnt ? trace.m_pEnt->entindex() : 0; if ( entityIndex ) { CBaseEntity *ent = trace.m_pEnt; if ( ent ) { modelIndex = ent->GetModelIndex(); VectorITransform( GetAbsOrigin(), ent->EntityToWorldTransform(), position ); } } engine->StaticDecal( position, m_nTexture, entityIndex, modelIndex ); // CRecipientFilter initFilter; // initFilter.MakeInitMessage(); // TE_BSPDecal( initFilter, GetAbsOrigin(), entityIndex, (int)pev->skin ); SUB_Remove(); }
//----------------------------------------------------------------------------- // Purpose: Prepares for running movement // Input : *player - // *ucmd - // *pHelper - // *move - // time - //----------------------------------------------------------------------------- void CPlayerMove::SetupMove( CBasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) { VPROF( "CPlayerMove::SetupMove" ); // Allow sound, etc. to be created by movement code move->m_bFirstRunOfFunctions = true; // Prepare the usercmd fields move->m_nImpulseCommand = ucmd->impulse; move->m_vecViewAngles = ucmd->viewangles; CBaseEntity *pMoveParent = player->GetMoveParent(); if (!pMoveParent) { move->m_vecAbsViewAngles = move->m_vecViewAngles; } else { matrix3x4_t viewToParent, viewToWorld; AngleMatrix( move->m_vecViewAngles, viewToParent ); ConcatTransforms( pMoveParent->EntityToWorldTransform(), viewToParent, viewToWorld ); MatrixAngles( viewToWorld, move->m_vecAbsViewAngles ); } move->m_nButtons = ucmd->buttons; // Ingore buttons for movement if at controls if ( player->GetFlags() & FL_ATCONTROLS ) { move->m_flForwardMove = 0; move->m_flSideMove = 0; move->m_flUpMove = 0; } else { move->m_flForwardMove = ucmd->forwardmove; move->m_flSideMove = ucmd->sidemove; move->m_flUpMove = ucmd->upmove; } // Prepare remaining fields move->m_flClientMaxSpeed = player->m_flMaxspeed; move->m_nOldButtons = player->m_Local.m_nOldButtons; move->m_vecAngles = player->pl.v_angle; move->m_vecVelocity = player->GetAbsVelocity(); move->m_nPlayerHandle = player; move->m_vecAbsOrigin = player->GetAbsOrigin(); // Copy constraint information if ( player->m_hConstraintEntity.Get() ) move->m_vecConstraintCenter = player->m_hConstraintEntity.Get()->GetAbsOrigin(); else move->m_vecConstraintCenter = player->m_vecConstraintCenter; move->m_flConstraintRadius = player->m_flConstraintRadius; move->m_flConstraintWidth = player->m_flConstraintWidth; move->m_flConstraintSpeedFactor = player->m_flConstraintSpeedFactor; }
//----------------------------------------------------------------------------- // Purpose: Try and find an entity to lock onto //----------------------------------------------------------------------------- CBaseEntity *CWeaponCombat_ChargeablePlasma::GetLockTarget( void ) { CBaseTFPlayer *pPlayer = (CBaseTFPlayer*)GetOwner(); if ( !pPlayer ) return NULL; Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecAiming; pPlayer->EyeVectors( &vecAiming ); Vector vecEnd = vecSrc + vecAiming * MAX_TRACE_LENGTH; trace_t tr; TFGameRules()->WeaponTraceLine( vecSrc, vecEnd, MASK_SHOT, pPlayer, GetDamageType(), &tr ); if ( (tr.fraction < 1.0f) && tr.m_pEnt ) { CBaseEntity *pTargetEntity = tr.m_pEnt; // Don't guide on same team or on anything other than players, objects, and NPCs if ( pTargetEntity->InSameTeam(pPlayer) || (!pTargetEntity->IsPlayer() && (pTargetEntity->MyNPCPointer() == NULL)) ) return NULL; // Compute the target offset relative to the target Vector vecWorldOffset; VectorSubtract( tr.endpos, pTargetEntity->GetAbsOrigin(), vecWorldOffset ); VectorIRotate( vecWorldOffset, pTargetEntity->EntityToWorldTransform(), m_vecTargetOffset ); m_flLockedAt = gpGlobals->curtime + 0.2; return pTargetEntity; } return NULL; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_Prediction::SetupMove( C_BasePlayer *player, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) { // Call the default SetupMove code. BaseClass::SetupMove( player, ucmd, pHelper, move ); CASW_Player *pASWPlayer = static_cast<CASW_Player*>( player ); if ( !asw_allow_detach.GetBool() ) { if ( pASWPlayer && pASWPlayer->GetMarine() ) { // this forces horizontal movement move->m_vecAngles.x = 0; move->m_vecViewAngles.x = 0; } } CBaseEntity *pMoveParent = player->GetMoveParent(); if (!pMoveParent) { move->m_vecAbsViewAngles = move->m_vecViewAngles; } else { matrix3x4_t viewToParent, viewToWorld; AngleMatrix( move->m_vecViewAngles, viewToParent ); ConcatTransforms( pMoveParent->EntityToWorldTransform(), viewToParent, viewToWorld ); MatrixAngles( viewToWorld, move->m_vecAbsViewAngles ); } CASW_MoveData *pASWMove = static_cast<CASW_MoveData*>( move ); pASWMove->m_iForcedAction = ucmd->forced_action; // setup trace optimization g_pGameMovement->SetupMovementBounds( move ); }
//----------------------------------------------------------------------------- // Eye angles //----------------------------------------------------------------------------- const QAngle &CBasePlayer::EyeAngles( ) { // NOTE: Viewangles are measured *relative* to the parent's coordinate system CBaseEntity *pMoveParent = const_cast<CBasePlayer*>(this)->GetMoveParent(); if ( !pMoveParent ) { return pl.v_angle; } // FIXME: Cache off the angles? matrix3x4_t eyesToParent, eyesToWorld; AngleMatrix( pl.v_angle, eyesToParent ); ConcatTransforms( pMoveParent->EntityToWorldTransform(), eyesToParent, eyesToWorld ); static QAngle angEyeWorld; MatrixAngles( eyesToWorld, angEyeWorld ); return angEyeWorld; }
void CDecal::StaticDecal( void ) { Vector position; CBaseEntity *pEntity = GetDecalEntityAndPosition(&position, true); int entityIndex = 0; int modelIndex = 0; if ( pEntity ) { entityIndex = pEntity->entindex(); modelIndex = pEntity->GetModelIndex(); Vector worldspace = position; VectorITransform( worldspace, pEntity->EntityToWorldTransform(), position ); } else { position = GetAbsOrigin(); } engine->StaticDecal( position, m_nTexture, entityIndex, modelIndex, m_bLowPriority ); SUB_Remove(); }
void CMarineMove::SetupMarineMove( const CBasePlayer *player, CBaseEntity *marine, CUserCmd *ucmd, IMoveHelper *pHelper, CMoveData *move ) { VPROF( "CMarineMove::SetupMarineMove" ); // hm, we need it to be a specific swarm marine here, not a generic entity CASW_Marine *aswmarine = static_cast< CASW_Marine * >(marine); if (aswmarine == NULL) return; // Prepare the usercmd fields move->m_nImpulseCommand = ucmd->impulse; move->m_vecViewAngles = ucmd->viewangles; move->m_vecViewAngles.x = 0; // asw always walking horizontally CBaseEntity *pMoveParent = marine->GetMoveParent(); if (!pMoveParent) { move->m_vecAbsViewAngles = move->m_vecViewAngles; } else { matrix3x4_t viewToParent, viewToWorld; AngleMatrix( move->m_vecViewAngles, viewToParent ); ConcatTransforms( pMoveParent->EntityToWorldTransform(), viewToParent, viewToWorld ); MatrixAngles( viewToWorld, move->m_vecAbsViewAngles ); } move->m_nButtons = ucmd->buttons; // Ingore buttons for movement if at controls if ( marine->GetFlags() & FL_ATCONTROLS ) { move->m_flForwardMove = 0; move->m_flSideMove = 0; move->m_flUpMove = 0; } else { move->m_flForwardMove = ucmd->forwardmove; move->m_flSideMove = ucmd->sidemove; move->m_flUpMove = ucmd->upmove; } // Prepare remaining fields move->m_flClientMaxSpeed = aswmarine->MaxSpeed(); //player->MaxSpeed(); #ifdef CLIENT_DLL //Msg("maxspeed = %f\n", move->m_flClientMaxSpeed); #endif //move->m_nOldButtons = player->m_Local.m_nOldButtons; move->m_nOldButtons = aswmarine->m_nOldButtons; move->m_vecAngles = marine->GetAbsAngles(); //player->pl.v_angle; #ifdef GAME_DLL //Msg("S ucmd %d vel %f %f %f\n", ucmd->command_number, move->m_vecVelocity.x, move->m_vecVelocity.y, move->m_vecVelocity.z); #else //Msg("C ucmd %d vel %f %f %f\n", ucmd->command_number, move->m_vecVelocity.x, move->m_vecVelocity.y, move->m_vecVelocity.z); #endif move->m_vecVelocity = marine->GetAbsVelocity(); move->m_nPlayerHandle = marine;//player; #ifdef GAME_DLL move->SetAbsOrigin( marine->GetAbsOrigin() ); #else move->SetAbsOrigin( marine->GetNetworkOrigin() ); /* C_BaseEntity *pEnt = cl_entitylist->FirstBaseEntity(); while (pEnt) { if (FClassnameIs(pEnt, "class C_DynamicProp")) { Msg("Setting z to %f\n", pEnt->GetAbsOrigin().z + 10); move->m_vecAbsOrigin.z = pEnt->GetAbsOrigin().z + 10; marine->SetNetworkOrigin(pEnt->GetAbsOrigin() + Vector(0,0,10)); break; } pEnt = cl_entitylist->NextBaseEntity( pEnt ); } */ #endif //Msg("Move X velocity set to %f forward move = %f origin = %f\n", // move->m_vecVelocity.x, move->m_flForwardMove, move->m_vecAbsOrigin.x); // Copy constraint information /* if ( player->m_hConstraintEntity.Get() ) move->m_vecConstraintCenter = player->m_hConstraintEntity.Get()->GetAbsOrigin(); else move->m_vecConstraintCenter = player->m_vecConstraintCenter; move->m_flConstraintRadius = player->m_flConstraintRadius; move->m_flConstraintWidth = player->m_flConstraintWidth; move->m_flConstraintSpeedFactor = player->m_flConstraintSpeedFactor; */ }
CTraceFilterValidForDecal traceFilter( this, COLLISION_GROUP_NONE ); int entityIndex, modelIndex = 0; Vector position = GetAbsOrigin(); UTIL_TraceLine( position - Vector(5,5,5), position + Vector(5,5,5), MASK_SOLID, &traceFilter, &trace ); bool canDraw = true; entityIndex = trace.m_pEnt ? (short)trace.m_pEnt->entindex() : 0; if ( entityIndex ) { CBaseEntity *ent = trace.m_pEnt; if ( ent ) { modelIndex = ent->GetModelIndex(); VectorITransform( GetAbsOrigin(), ent->EntityToWorldTransform(), position ); canDraw = ( modelIndex != 0 ); if ( !canDraw ) { Warning( "Suppressed StaticDecal which would have hit entity %i (class:%s, name:%s) with modelindex = 0\n", ent->entindex(), ent->GetClassname(), STRING( ent->GetEntityName() ) ); } } } if ( canDraw ) { engine->StaticDecal( position, m_nTexture, entityIndex, modelIndex, m_bLowPriority );
void CNPC_SecobModportal1::Touch( CBaseEntity *pOther ) { BaseClass::Touch( pOther ); // Did the player touch me? if ( pOther->IsPlayer() ) { const char *PlayerSteamID = engine->GetPlayerNetworkIDString(pOther->edict()); //Finds the current players Steam ID. if( PlayerSteamID == NULL) return; char Portal2Name[ 512 ]; Q_strncpy( Portal2Name, "Portal2_" ,sizeof(Portal2Name)); Q_strncat( Portal2Name, PlayerSteamID,sizeof(Portal2Name), COPY_ALL_CHARACTERS ); // We look for Portal2 for our teleport point because we are Portal1. CBaseEntity *pEnt = NULL; pEnt = gEntList.FindEntityByName( pEnt, Portal2Name, NULL, pOther, pOther ); if (!pEnt ) { return; } EmitSound( "PortalPlayer.EnterPortal" ); //PORTAL TRIGGER CODE. // Don't touch entities that came through us and haven't left us yet. /*EHANDLE hHandle; hHandle = pOther; if ( m_hDisabledForEntities.Find(hHandle) != m_hDisabledForEntities.InvalidIndex() ) { Msg(" IGNORED\n", GetDebugName(), pOther->GetDebugName() ); return; } Pickup_ForcePlayerToDropThisObject( pOther );*/ pOther->SetGroundEntity( NULL ); // Build a this --> remote transformation VMatrix matMyModelToWorld, matMyInverse; matMyModelToWorld = pOther->EntityToWorldTransform(); MatrixInverseGeneral ( matMyModelToWorld, matMyInverse ); // Teleport our object VMatrix matRemotePortalTransform = pEnt->EntityToWorldTransform(); Vector ptNewOrigin, vLook, vRight, vUp, vNewLook; pOther->GetVectors( &vLook, &vRight, &vUp ); // Move origin ptNewOrigin = matMyInverse * pOther->GetAbsOrigin(); ptNewOrigin = matRemotePortalTransform * Vector( ptNewOrigin.x, -ptNewOrigin.y, ptNewOrigin.z ); // Re-aim camera vNewLook = matMyInverse.ApplyRotation( vLook ); vNewLook = matRemotePortalTransform.ApplyRotation( Vector( -vNewLook.x, -vNewLook.y, vNewLook.z ) ); // Reorient the physics Vector vVelocity, vOldVelocity; pOther->GetVelocity( &vOldVelocity ); vVelocity = matMyInverse.ApplyRotation( vOldVelocity ); vVelocity = matRemotePortalTransform.ApplyRotation( Vector( -vVelocity.x, -vVelocity.y, vVelocity.z ) ); QAngle qNewAngles; VectorAngles( vNewLook, qNewAngles ); if ( pOther->IsPlayer() ) { ((CBasePlayer*)pOther)->SnapEyeAngles(qNewAngles); } Vector vecOldPos = pOther->WorldSpaceCenter(); // place player at the new destination pOther->Teleport( &ptNewOrigin, &qNewAngles, &vVelocity ); // test collision on the new teleport location Vector vMin, vMax, vCenter; pOther->CollisionProp()->WorldSpaceAABB( &vMin, &vMax ); vCenter = (vMin + vMax) * 0.5f; vMin -= vCenter; vMax -= vCenter; Vector vStart, vEnd; vStart = ptNewOrigin; vEnd = ptNewOrigin; Ray_t ray; ray.Init( vStart, vEnd, vMin, vMax ); trace_t tr; this->TestCollision( ray, pOther->PhysicsSolidMaskForEntity(), tr ); // Teleportation caused us to hit something, deal with it. if ( tr.DidHit() ) { } EmitSound( "PortalPlayer.ExitPortal" ); Vector forward, right, up; Vector oldorigin = pOther->GetAbsOrigin(); AngleVectors ( pOther->GetAbsAngles(), &forward, &right, &up); // Try to move into the world if ( !FindPassableSpace( pOther, forward, 1, oldorigin ) ) { if ( !FindPassableSpace( pOther, right, 1, oldorigin ) ) { if ( !FindPassableSpace( pOther, right, -1, oldorigin ) ) // left { if ( !FindPassableSpace( pOther, up, 1, oldorigin ) ) // up { if ( !FindPassableSpace( pOther, up, -1, oldorigin ) ) // down { if ( !FindPassableSpace( pOther, forward, -1, oldorigin ) ) // back { pOther->TakeDamage( CTakeDamageInfo( this, this, 1000, DMG_DISSOLVE ) ); } } } } } } pOther->SetAbsOrigin( oldorigin ); } }
bool CParticleSystemQuery::IsPointInControllingObjectHitBox( CParticleCollection *pParticles, int nControlPointNumber, Vector vecPos, bool bBBoxOnly ) { bool bSuccess = false; #ifndef GAME_DLL EHANDLE *phMoveParent = reinterpret_cast<EHANDLE *> ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); CBaseEntity *pMoveParent = NULL; if ( phMoveParent ) { pMoveParent = *( phMoveParent ); } if ( pMoveParent ) { s_BoneMutex.Lock(); C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); bool bInBBox = false; Vector vecBBoxMin; Vector vecBBoxMax; Vector vecOrigin; vecBBoxMin = pMoveParent->CollisionProp()->OBBMins(); vecBBoxMax = pMoveParent->CollisionProp()->OBBMaxs(); matrix3x4_t matOrientation; matOrientation = pMoveParent->EntityToWorldTransform(); Vector vecLocalPos; VectorITransform( vecPos, matOrientation, vecLocalPos ); if ( IsPointInBox( vecLocalPos, vecBBoxMin, vecBBoxMax ) ) bInBBox = true; if ( bInBBox && bBBoxOnly ) bSuccess = true; else if ( pAnimating && bInBBox ) { matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) { studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if ( pStudioHdr ) { mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( set ) { // do a point in solid test Ray_t ray; trace_t tr; ray.Init( vecPos, vecPos ); enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); if ( tr.startsolid ) bSuccess = true; } } } } else if ( pMoveParent->IsBrushModel() && bInBBox ) { // do a point in solid test Ray_t ray; trace_t tr; ray.Init( vecPos, vecPos ); enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); if ( tr.startsolid ) bSuccess = true; } s_BoneMutex.Unlock(); } #endif return bSuccess; }
int CParticleSystemQuery::GetControllingObjectHitBoxInfo( CParticleCollection *pParticles, int nControlPointNumber, int nBufSize, // # of output slots available ModelHitBoxInfo_t *pHitBoxOutputBuffer ) { int nRet = 0; #ifndef GAME_DLL s_BoneMutex.Lock(); EHANDLE *phMoveParent = reinterpret_cast<EHANDLE *> ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); CBaseEntity *pMoveParent = NULL; if ( phMoveParent ) { pMoveParent = *( phMoveParent ); } if ( pMoveParent ) { C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); if ( pAnimating ) { matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) { studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if ( pStudioHdr ) { mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( set ) { nRet = min( nBufSize, set->numhitboxes ); for( int i=0 ; i < nRet; i++ ) { mstudiobbox_t *pBox = set->pHitbox( i ); pHitBoxOutputBuffer[i].m_vecBoxMins.x = pBox->bbmin.x; pHitBoxOutputBuffer[i].m_vecBoxMins.y = pBox->bbmin.y; pHitBoxOutputBuffer[i].m_vecBoxMins.z = pBox->bbmin.z; pHitBoxOutputBuffer[i].m_vecBoxMaxes.x = pBox->bbmax.x; pHitBoxOutputBuffer[i].m_vecBoxMaxes.y = pBox->bbmax.y; pHitBoxOutputBuffer[i].m_vecBoxMaxes.z = pBox->bbmax.z; pHitBoxOutputBuffer[i].m_Transform = *hitboxbones[pBox->bone]; } } } } } if ( pMoveParent->IsBrushModel() ) { Vector vecMin; Vector vecMax; matrix3x4_t matOrientation; pMoveParent->GetRenderBounds( vecMin, vecMax ); matOrientation = pMoveParent->EntityToWorldTransform(); pHitBoxOutputBuffer[0].m_vecBoxMins = vecMin; pHitBoxOutputBuffer[0].m_vecBoxMaxes = vecMax; pHitBoxOutputBuffer[0].m_Transform = matOrientation; nRet = 1; } } s_BoneMutex.Unlock(); #endif return nRet; }
void CParticleSystemQuery::GetRandomPointsOnControllingObjectHitBox( CParticleCollection *pParticles, int nControlPointNumber, int nNumPtsOut, float flBBoxScale, int nNumTrysToGetAPointInsideTheModel, Vector *pPntsOut, Vector vecDirectionalBias, Vector *pHitBoxRelativeCoordOut, int *pHitBoxIndexOut ) { bool bSucesss = false; #ifndef GAME_DLL EHANDLE *phMoveParent = reinterpret_cast<EHANDLE *> ( pParticles->m_ControlPoints[nControlPointNumber].m_pObject ); CBaseEntity *pMoveParent = NULL; if ( phMoveParent ) { pMoveParent = *( phMoveParent ); } if ( pMoveParent ) { float flRandMax = flBBoxScale; float flRandMin = 1.0 - flBBoxScale; Vector vecBasePos; pParticles->GetControlPointAtTime( nControlPointNumber, pParticles->m_flCurTime, &vecBasePos ); s_BoneMutex.Lock(); C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); if ( pAnimating ) { matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) { studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if ( pStudioHdr ) { mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( pAnimating->GetHitboxSet() ); if ( set ) { bSucesss = true; Vector vecWorldPosition; float u = 0, v = 0, w = 0; int nHitbox = 0; int nNumIters = nNumTrysToGetAPointInsideTheModel; if (! vecDirectionalBias.IsZero( 0.0001 ) ) nNumIters = max( nNumIters, 5 ); for( int i=0 ; i < nNumPtsOut; i++) { int nTryCnt = nNumIters; float flBestPointGoodness = -1.0e20; do { int nTryHitbox = pParticles->RandomInt( 0, set->numhitboxes - 1 ); mstudiobbox_t *pBox = set->pHitbox(nTryHitbox); float flTryU = pParticles->RandomFloat( flRandMin, flRandMax ); float flTryV = pParticles->RandomFloat( flRandMin, flRandMax ); float flTryW = pParticles->RandomFloat( flRandMin, flRandMax ); Vector vecLocalPosition; vecLocalPosition.x = GetSurfaceCoord( flTryU, pBox->bbmin.x, pBox->bbmax.x ); vecLocalPosition.y = GetSurfaceCoord( flTryV, pBox->bbmin.y, pBox->bbmax.y ); vecLocalPosition.z = GetSurfaceCoord( flTryW, pBox->bbmin.z, pBox->bbmax.z ); Vector vecTryWorldPosition; VectorTransform( vecLocalPosition, *hitboxbones[pBox->bone], vecTryWorldPosition ); float flPointGoodness = pParticles->RandomFloat( 0, 72 ) + DotProduct( vecTryWorldPosition - vecBasePos, vecDirectionalBias ); if ( nNumTrysToGetAPointInsideTheModel ) { // do a point in solid test Ray_t ray; trace_t tr; ray.Init( vecTryWorldPosition, vecTryWorldPosition ); enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); if ( tr.startsolid ) flPointGoodness += 1000.; // got a point inside! } if ( flPointGoodness > flBestPointGoodness ) { u = flTryU; v = flTryV; w = flTryW; vecWorldPosition = vecTryWorldPosition; nHitbox = nTryHitbox; flBestPointGoodness = flPointGoodness; } } while ( nTryCnt-- ); *( pPntsOut++ ) = vecWorldPosition; if ( pHitBoxRelativeCoordOut ) ( pHitBoxRelativeCoordOut++ )->Init( u, v, w ); if ( pHitBoxIndexOut ) *( pHitBoxIndexOut++ ) = nHitbox; } } } } } if ( pMoveParent->IsBrushModel() ) { Vector vecMin; Vector vecMax; matrix3x4_t matOrientation; Vector VecOrigin; pMoveParent->GetRenderBounds( vecMin, vecMax ); VecOrigin = pMoveParent->GetRenderOrigin(); matOrientation = pMoveParent->EntityToWorldTransform(); Vector vecWorldPosition; float u = 0, v = 0, w = 0; int nHitbox = 0; int nNumIters = nNumTrysToGetAPointInsideTheModel; if (! vecDirectionalBias.IsZero( 0.0001 ) ) nNumIters = max( nNumIters, 5 ); for( int i=0 ; i < nNumPtsOut; i++) { int nTryCnt = nNumIters; float flBestPointGoodness = -1.0e20; do { float flTryU = pParticles->RandomFloat( flRandMin, flRandMax ); float flTryV = pParticles->RandomFloat( flRandMin, flRandMax ); float flTryW = pParticles->RandomFloat( flRandMin, flRandMax ); Vector vecLocalPosition; vecLocalPosition.x = GetSurfaceCoord( flTryU, vecMin.x, vecMax.x ); vecLocalPosition.y = GetSurfaceCoord( flTryV, vecMin.y, vecMax.y ); vecLocalPosition.z = GetSurfaceCoord( flTryW, vecMin.z, vecMax.z ); Vector vecTryWorldPosition; VectorTransform( vecLocalPosition, matOrientation, vecTryWorldPosition ); float flPointGoodness = pParticles->RandomFloat( 0, 72 ) + DotProduct( vecTryWorldPosition - vecBasePos, vecDirectionalBias ); if ( nNumTrysToGetAPointInsideTheModel ) { // do a point in solid test Ray_t ray; trace_t tr; ray.Init( vecTryWorldPosition, vecTryWorldPosition ); enginetrace->ClipRayToEntity( ray, MASK_ALL, pMoveParent, &tr ); if ( tr.startsolid ) flPointGoodness += 1000.; // got a point inside! } if ( flPointGoodness > flBestPointGoodness ) { u = flTryU; v = flTryV; w = flTryW; vecWorldPosition = vecTryWorldPosition; nHitbox = 0; flBestPointGoodness = flPointGoodness; } } while ( nTryCnt-- ); *( pPntsOut++ ) = vecWorldPosition; if ( pHitBoxRelativeCoordOut ) ( pHitBoxRelativeCoordOut++ )->Init( u, v, w ); if ( pHitBoxIndexOut ) *( pHitBoxIndexOut++ ) = nHitbox; } } s_BoneMutex.Unlock(); } #endif if (! bSucesss ) { // don't have a model or am in editor or something - fill return with control point for( int i=0 ; i < nNumPtsOut; i++) { pPntsOut[i] = pParticles->m_ControlPoints[nControlPointNumber].m_Position; // fallback if anything goes wrong if ( pHitBoxIndexOut ) pHitBoxIndexOut[i] = 0; if ( pHitBoxRelativeCoordOut ) pHitBoxRelativeCoordOut[i].Init(); } } }
int CParticleSystemQuery::GetControllingObjectHitBoxInfo( CParticleCollection *pParticles, int nControlPointNumber, int nBufSize, // # of output slots available ModelHitBoxInfo_t *pHitBoxOutputBuffer ) { int nRet = 0; #ifndef GAME_DLL s_BoneMutex.Lock(); EHANDLE *phMoveParent = reinterpret_cast<EHANDLE *> ( pParticles->ControlPoint( nControlPointNumber ).m_pObject ); CBaseEntity *pMoveParent = NULL; if ( phMoveParent ) { pMoveParent = *( phMoveParent ); } if ( pMoveParent ) { C_BaseAnimating *pAnimating = pMoveParent->GetBaseAnimating(); if ( pAnimating ) { matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; if ( pAnimating->HitboxToWorldTransforms( hitboxbones ) ) { studiohdr_t *pStudioHdr = modelinfo->GetStudiomodel( pAnimating->GetModel() ); if ( pStudioHdr ) { // Try to get the "effects" set first, otherwise use their current set int nEffectsHitboxSet = FindHitboxSetByName( pAnimating->GetModelPtr(), "effects" ); mstudiohitboxset_t *set = pStudioHdr->pHitboxSet( nEffectsHitboxSet != -1 ? nEffectsHitboxSet : pAnimating->GetHitboxSet() ); if ( set ) { for( int i=0 ; i < set->numhitboxes; i++ ) { mstudiobbox_t *pBox = set->pHitbox( i ); // E3 HACK - check for hitboxes at the origin and ignore those if ( fabs( (*hitboxbones[pBox->bone])[0][3] ) < POINT_AT_ORIGIN_EPSILON && fabs( (*hitboxbones[pBox->bone])[1][3] ) < POINT_AT_ORIGIN_EPSILON && fabs( (*hitboxbones[pBox->bone])[2][3] ) < POINT_AT_ORIGIN_EPSILON ) { continue; } pHitBoxOutputBuffer[nRet].m_vecBoxMins.x = pBox->bbmin.x; pHitBoxOutputBuffer[nRet].m_vecBoxMins.y = pBox->bbmin.y; pHitBoxOutputBuffer[nRet].m_vecBoxMins.z = pBox->bbmin.z; pHitBoxOutputBuffer[nRet].m_vecBoxMaxes.x = pBox->bbmax.x; pHitBoxOutputBuffer[nRet].m_vecBoxMaxes.y = pBox->bbmax.y; pHitBoxOutputBuffer[nRet].m_vecBoxMaxes.z = pBox->bbmax.z; pHitBoxOutputBuffer[nRet].m_Transform = *hitboxbones[pBox->bone]; nRet++; if ( nRet >= nBufSize ) { break; } } } } } } if ( pMoveParent->IsBrushModel() ) { Vector vecMin; Vector vecMax; matrix3x4_t matOrientation; pMoveParent->GetRenderBounds( vecMin, vecMax ); matOrientation = pMoveParent->EntityToWorldTransform(); pHitBoxOutputBuffer[0].m_vecBoxMins = vecMin; pHitBoxOutputBuffer[0].m_vecBoxMaxes = vecMax; pHitBoxOutputBuffer[0].m_Transform = matOrientation; nRet = 1; } } s_BoneMutex.Unlock(); #endif return nRet; }