void UTIL_GetScreenMinsMaxs( const Vector &origin, const QAngle &angle, const Vector &mins, const Vector &maxs, int &minsx, int &minsy, int &maxsx, int &maxsy ) { Vector vTestPoint, vTransformedMins, vTransformedMaxs; matrix3x4_t xform; // Transform AngleMatrix( angle, origin, xform ); TransformAABB( xform, mins, maxs, vTransformedMins, vTransformedMaxs ); //NDebugOverlay::BoxAngles( origin, mins, maxs, angle, 255, 0, 0, 200, 0.1 ); NDebugOverlay::Cross3D( vTransformedMins, -Vector(16, 16, 16), Vector(16, 16, 16), 255, 0, 0, false, 0.1 ); NDebugOverlay::Cross3D( vTransformedMaxs, -Vector(16, 16, 16), Vector(16, 16, 16), 0, 255, 0, false, 0.1 ); // Init points minsx = INT_MAX; maxsx = -1; minsy = INT_MAX; maxsy = -1; // Test points // find the smallest and biggest values TestPoints( vTransformedMins, minsx, minsy, maxsx, maxsy ); TestPoints( vTransformedMaxs, minsx, minsy, maxsx, maxsy ); /*TestPoints( Vector(vTransformedMins.x, vTransformedMins.y, vTransformedMaxs.z), minsx, minsy, maxsx, maxsy ); TestPoints( Vector(vTransformedMaxs.x, vTransformedMins.y, vTransformedMaxs.z), minsx, minsy, maxsx, maxsy ); TestPoints( Vector(vTransformedMins.x, vTransformedMaxs.y, vTransformedMaxs.z), minsx, minsy, maxsx, maxsy ); */ TestPoints( Vector(vTransformedMaxs.x, vTransformedMaxs.y, vTransformedMins.z), minsx, minsy, maxsx, maxsy ); TestPoints( Vector(vTransformedMaxs.x, vTransformedMins.y, vTransformedMins.z), minsx, minsy, maxsx, maxsy ); TestPoints( Vector(vTransformedMins.x, vTransformedMaxs.y, vTransformedMins.z), minsx, minsy, maxsx, maxsy ); }
virtual void ComputeWorldSpaceSurroundingBox( Vector *mins, Vector *maxs ) { Assert( mins != NULL && maxs != NULL ); if ( !mins || !maxs ) return; // Take our saved collision bounds, and transform into world space TransformAABB( EntityToWorldTransform(), m_collisionMins, m_collisionMaxs, *mins, *maxs ); }
void C_PortalGhostRenderable::GetRenderBoundsWorldspace( Vector& mins, Vector& maxs ) { if( m_pGhostedRenderable == NULL ) { mins = maxs = vec3_origin; return; } m_pGhostedRenderable->GetRenderBoundsWorldspace( mins, maxs ); TransformAABB( m_matGhostTransform.As3x4(), mins, maxs, mins, maxs ); }
//----------------------------------------------------------------------------- // Transforms an AABB measured in entity space to a box that surrounds it in world space //----------------------------------------------------------------------------- void CCollisionProperty::CollisionAABBToWorldAABB( const Vector &entityMins, const Vector &entityMaxs, Vector *pWorldMins, Vector *pWorldMaxs ) const { if ( !IsBoundsDefinedInEntitySpace() || (GetCollisionAngles() == vec3_angle) ) { VectorAdd( entityMins, GetCollisionOrigin(), *pWorldMins ); VectorAdd( entityMaxs, GetCollisionOrigin(), *pWorldMaxs ); } else { TransformAABB( CollisionToWorldTransform(), entityMins, entityMaxs, *pWorldMins, *pWorldMaxs ); } }
//----------------------------------------------------------------------------- // Helper functions. //----------------------------------------------------------------------------- void DefaultRenderBoundsWorldspace( IClientRenderable *pRenderable, Vector &absMins, Vector &absMaxs ) { // Tracker 37433: This fixes a bug where if the stunstick is being wielded by a combine soldier, the fact that the stick was // attached to the soldier's hand would move it such that it would get frustum culled near the edge of the screen. C_BaseEntity *pEnt = pRenderable->GetIClientUnknown()->GetBaseEntity(); if ( pEnt && pEnt->IsFollowingEntity() ) { C_BaseEntity *pParent = pEnt->GetFollowedEntity(); if ( pParent ) { // Get the parent's abs space world bounds. CalcRenderableWorldSpaceAABB_Fast( pParent, absMins, absMaxs ); // Add the maximum of our local render bounds. This is making the assumption that we can be at any // point and at any angle within the parent's world space bounds. Vector vAddMins, vAddMaxs; pEnt->GetRenderBounds( vAddMins, vAddMaxs ); // if our origin is actually farther away than that, expand again float radius = pEnt->GetLocalOrigin().Length(); float flBloatSize = max( vAddMins.Length(), vAddMaxs.Length() ); flBloatSize = max(flBloatSize, radius); absMins -= Vector( flBloatSize, flBloatSize, flBloatSize ); absMaxs += Vector( flBloatSize, flBloatSize, flBloatSize ); return; } } Vector mins, maxs; pRenderable->GetRenderBounds( mins, maxs ); // FIXME: Should I just use a sphere here? // Another option is to pass the OBB down the tree; makes for a better fit // Generate a world-aligned AABB const QAngle& angles = pRenderable->GetRenderAngles(); const Vector& origin = pRenderable->GetRenderOrigin(); if (angles == vec3_angle) { VectorAdd( mins, origin, absMins ); VectorAdd( maxs, origin, absMaxs ); } else { matrix3x4_t boxToWorld; AngleMatrix( angles, origin, boxToWorld ); TransformAABB( boxToWorld, mins, maxs, absMins, absMaxs ); } Assert( absMins.IsValid() && absMaxs.IsValid() ); }
void CParticleEffectBinding::BBoxCalcEnd( bool bFullBBoxUpdate, bool bboxSet, Vector &bbMin, Vector &bbMax ) { if ( !GetAutoUpdateBBox() ) return; // Get the bbox into world space. Vector bbMinWorld, bbMaxWorld; if ( m_bLocalSpaceTransformIdentity ) { bbMinWorld = bbMin; bbMaxWorld = bbMax; } else { TransformAABB( m_LocalSpaceTransform.As3x4(), bbMin, bbMax, bbMinWorld, bbMaxWorld ); } if( bFullBBoxUpdate ) { // If there were ANY particles in the system, then we've got a valid bbox here. Otherwise, // we don't have anything, so leave m_Min and m_Max at the sort origin. if ( bboxSet ) { m_Min = bbMinWorld; m_Max = bbMaxWorld; } else { m_Min = m_Max = m_pSim->GetSortOrigin(); } } else { // Take whatever our bbox was + pushing out from other particles. m_Min = bbMinWorld; m_Max = bbMaxWorld; } }
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; }
void C_PortalGhostRenderable::GetShadowRenderBounds( Vector &mins, Vector &maxs, ShadowType_t shadowType ) { m_pGhostedRenderable->GetShadowRenderBounds( mins, maxs, shadowType ); TransformAABB( m_matGhostTransform.As3x4(), mins, maxs, mins, maxs ); }
//----------------------------------------------------------------------------- // Purpose: Recompute my rendering box //----------------------------------------------------------------------------- void C_QUA_Strider::ClientThink() { int i; Vector vecMins, vecMaxs; Vector vecAbsMins, vecAbsMaxs; matrix3x4_t worldToStrider, hitboxToStrider; Vector vecBoxMins, vecBoxMaxs; Vector vecBoxAbsMins, vecBoxAbsMaxs; mstudiohitboxset_t *set; CBoneCache *pCache = NULL; // The reason why this is here, as opposed to in SetObjectCollisionBox, // is 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. studiohdr_t *pStudioHdr = GetModel()?modelinfo->GetStudiomodel( GetModel() ):NULL; if (!pStudioHdr) goto doneWithComputation; set = pStudioHdr->pHitboxSet( m_nHitboxSet ); if ( !set || !set->numhitboxes ) goto doneWithComputation; CStudioHdr *hdr = GetModelPtr(); pCache = GetBoneCache( hdr ); matrix3x4_t *hitboxbones[MAXSTUDIOBONES]; pCache->ReadCachedBonePointers( hitboxbones, pStudioHdr->numbones ); // // Compute a box in world space that surrounds this entity m_vecRenderMins.Init( FLT_MAX, FLT_MAX, FLT_MAX ); m_vecRenderMaxs.Init( -FLT_MAX, -FLT_MAX, -FLT_MAX ); // MatrixInvert( EntityToWorldTransform(), worldToStrider ); // for ( i = 0; i < set->numhitboxes; i++ ) { mstudiobbox_t *pbox = set->pHitbox(i); ConcatTransforms( worldToStrider, *hitboxbones[pbox->bone], hitboxToStrider ); TransformAABB( hitboxToStrider, pbox->bbmin, pbox->bbmax, vecBoxMins, vecBoxMaxs ); VectorMin( m_vecRenderMins, vecBoxMins, m_vecRenderMins ); VectorMax( m_vecRenderMaxs, vecBoxMaxs, m_vecRenderMaxs ); } // // Deberiamos poner aqui lo de la vista?? // // // UNDONE: Disabled this until we can get closer to a final map and tune //#if 0 // // Cut ropes. // if ( gpGlobals->curtime >= m_flNextRopeCutTime ) // { // // Blow the bbox out a little. // Vector vExtendedMins = vecMins - Vector( 50, 50, 50 ); // Vector vExtendedMaxs = vecMaxs + Vector( 50, 50, 50 ); // // C_RopeKeyframe *ropes[512]; // int nRopes = C_RopeKeyframe::GetRopesIntersectingAABB( ropes, ARRAYSIZE( ropes ), GetAbsOrigin() + vExtendedMins, GetAbsOrigin() + vExtendedMaxs ); // for ( int i=0; i < nRopes; i++ ) // { // C_RopeKeyframe *pRope = ropes[i]; // // if ( pRope->GetEndEntity() ) // { // Vector vPos; // if ( pRope->GetEndPointPos( 1, vPos ) ) // { // // Detach the endpoint. // pRope->SetEndEntity( NULL ); // // // Make some spark effect here.. // g_pEffects->Sparks( vPos ); // } // } // } // // m_flNextRopeCutTime = gpGlobals->curtime + 0.5; // } //#endif doneWithComputation: // True argument because the origin may have stayed the same, but the size is expected to always change g_pClientShadowMgr->AddToDirtyShadowList( this, true ); }
void CRagdollProp::VPhysicsUpdate( IPhysicsObject *pPhysics ) { if ( m_lastUpdateTickCount == (unsigned int)gpGlobals->tickcount ) return; m_lastUpdateTickCount = gpGlobals->tickcount; //NetworkStateChanged(); matrix3x4_t boneToWorld[MAXSTUDIOBONES]; QAngle angles; Vector surroundingMins, surroundingMaxs; if ( m_ragdoll.pGroup->IsInErrorState() ) { RagdollSolveSeparation( m_ragdoll, this ); } int i; for ( i = 0; i < m_ragdoll.listCount; i++ ) { CBoneAccessor boneaccessor( boneToWorld ); RagdollGetBoneMatrix( m_ragdoll, boneaccessor, i ); Vector vNewPos; MatrixAngles( boneToWorld[m_ragdoll.boneIndex[i]], angles, vNewPos ); m_ragPos.Set( i, vNewPos ); m_ragAngles.Set( i, angles ); } // BUGBUG: Use the ragdollmins/maxs to do this instead of the collides m_allAsleep = RagdollIsAsleep( m_ragdoll ); // Don't scream after you've come to rest if ( m_allAsleep ) { m_strSourceClassName = NULL_STRING; } // Interactive debris converts back to debris when it comes to rest if ( m_allAsleep && GetCollisionGroup() == COLLISION_GROUP_INTERACTIVE_DEBRIS ) { SetCollisionGroup( COLLISION_GROUP_DEBRIS ); RecheckCollisionFilter(); SetContextThink( NULL, gpGlobals->curtime, s_pDebrisContext ); } Vector vecFullMins, vecFullMaxs; vecFullMins = m_ragPos[0]; vecFullMaxs = m_ragPos[0]; for ( i = 0; i < m_ragdoll.listCount; i++ ) { Vector mins, maxs; matrix3x4_t update; m_ragdoll.list[i].pObject->GetPositionMatrix( &update ); TransformAABB( update, m_ragdollMins[i], m_ragdollMaxs[i], mins, maxs ); for ( int j = 0; j < 3; j++ ) { if ( mins[j] < vecFullMins[j] ) { vecFullMins[j] = mins[j]; } if ( maxs[j] > vecFullMaxs[j] ) { vecFullMaxs[j] = maxs[j]; } } } SetAbsOrigin( m_ragPos[0] ); SetAbsAngles( vec3_angle ); const Vector &vecOrigin = CollisionProp()->GetCollisionOrigin(); CollisionProp()->AddSolidFlags( FSOLID_FORCE_WORLD_ALIGNED ); CollisionProp()->SetSurroundingBoundsType( USE_COLLISION_BOUNDS_NEVER_VPHYSICS ); SetCollisionBounds( vecFullMins - vecOrigin, vecFullMaxs - vecOrigin ); CollisionProp()->MarkSurroundingBoundsDirty(); PhysicsTouchTriggers(); }