//----------------------------------------------------------------------------- // Purpose: "Physics" simulation. //----------------------------------------------------------------------------- void CBaseEntity::ProcessMovement( void ) { // Test new position. Vector vecNewOrigin = m_vecOrigin + m_vecVelocity * g_FrameTime; Vector vecMins = vecNewOrigin + m_vecMins; Vector vecMaxs = vecNewOrigin + m_vecMaxs; // Test collision against other entities. // Since movement amount depends on frame time and we only test the final position // this whole system goes out of the window at low framerates. bool bCanMove = true; if ( GetSolidType() != SOLID_NO ) { // World bounds! if ( !g_ScreenRect.contains( vecMins ) || !g_ScreenRect.contains( vecMaxs ) ) { TouchScreenEdge( vecNewOrigin ); // Screen edges are always solid. if ( IsSolid() ) { bCanMove = false; } } for ( int i = 0; i < MAX_ENTITIES; i++ ) { CBaseEntity *pEntity = g_EntityList[i]; if ( !pEntity || pEntity == this || pEntity->GetSolidType() == SOLID_NO ) continue; Vector vecOtherMins, vecOtherMaxs; pEntity->GetAbsBounds( &vecOtherMins, &vecOtherMaxs ); if ( IsBoxIntersectingBox( vecMins, vecMaxs, vecOtherMins, vecOtherMaxs ) ) { OnCollide( pEntity ); if ( IsSolid() && pEntity->IsSolid() ) { bCanMove = false; } } } } if ( bCanMove ) m_vecOrigin = vecNewOrigin; // Move the sprite if we have one. if ( m_pSprite ) { m_pSprite->setPosition( m_vecOrigin ); m_pSprite->setRotation( m_flAngle ); } }
void Actor::Collide(COL_ID id, Actor& other){ //CapsulevsCapsule(); CollisionParameter colpara = colFunc[id](other); if (colpara.colFlag) { OnCollide(other, colpara); other.OnCollide(*this, colpara); } }
//----------------------------------------------------------------------------- // Purpose: Checks collisions against other entities //----------------------------------------------------------------------------- void CTFFlameEntity::CheckCollision( CBaseEntity *pOther, bool *pbHitWorld ) { *pbHitWorld = false; // if we've already burnt this entity, don't do more damage, so skip even checking for collision with the entity int iIndex = m_hEntitiesBurnt.Find( pOther ); if ( iIndex != m_hEntitiesBurnt.InvalidIndex() ) return; // Do a bounding box check against the entity Vector vecMins, vecMaxs; pOther->GetCollideable()->WorldSpaceSurroundingBounds( &vecMins, &vecMaxs ); CBaseTrace trace; Ray_t ray; float flFractionLeftSolid; ray.Init( m_vecPrevPos, GetAbsOrigin(), WorldAlignMins(), WorldAlignMaxs() ); if ( IntersectRayWithBox( ray, vecMins, vecMaxs, 0.0, &trace, &flFractionLeftSolid ) ) { // if bounding box check passes, check player hitboxes trace_t trHitbox; trace_t trWorld; bool bTested = pOther->GetCollideable()->TestHitboxes( ray, MASK_SOLID | CONTENTS_HITBOX, trHitbox ); if ( !bTested || !trHitbox.DidHit() ) return; // now, let's see if the flame visual could have actually hit this player. Trace backward from the // point of impact to where the flame was fired, see if we hit anything. Since the point of impact was // determined using the flame's bounding box and we're just doing a ray test here, we extend the // start point out by the radius of the box. Vector vDir = ray.m_Delta; vDir.NormalizeInPlace(); UTIL_TraceLine( GetAbsOrigin() + vDir * WorldAlignMaxs().x, m_vecInitialPos, MASK_SOLID, this, COLLISION_GROUP_DEBRIS, &trWorld ); if ( tf_debug_flamethrower.GetInt() ) { NDebugOverlay::Line( trWorld.startpos, trWorld.endpos, 0, 255, 0, true, 3.0f ); } if ( trWorld.fraction == 1.0 ) { // if there is nothing solid in the way, damage the entity OnCollide( pOther ); } else { // we hit the world, remove ourselves *pbHitWorld = true; UTIL_Remove( this ); } } }
void IActor::Collide(ActorPtr const& actor) { // Own vs Other if (IsCollide(actor)) { OnCollide(actor); } // Own vs Other Child for (auto&& other : m_children) { if (IsCollide(other)) { OnCollide(other); } } // Own Child vs Other for (auto&& child : m_children) { child->Collide(actor); } }
void Actor::Collide(Actor& other) { HitInfo hitInfo; //衝突したか? if (IsCollide(other, hitInfo)) { //衝突したお互いのアクターのOnCollide()を呼ぶ hitInfo.collideActor = &other; OnCollide(hitInfo); hitInfo.collideActor = this; other.OnCollide(hitInfo); } //子の衝突判定を行う EachChildren([&](Actor& actor) { actor.Collide(other); }); }
void Physics::OnCollideEnter(btPersistentManifold* manifold) { OnCollide("Enter", manifold); }