Пример #1
0
bool CBurnBot::CheckCollision(IBaseObject* pObj)
{
	if(pObj == this)
		return false;

	if(!pObj->GetAlive())
		return false;

	if(!GetAlive())
		return false;

	int nType = pObj->GetID();

	bool bAvoid = nType == OBJ_SMASH || nType == OBJ_SPIDER || nType >= OBJ_VAT && nType <= OBJ_BARREL || nType == OBJ_BOSSINV || nType == OBJ_INVERSION;

	if( bAvoid )
		Utilities::CheckAvoid(this, pObj);

	if(nType >= OBJ_TRASH && nType <= OBJ_AIFIST ||  nType == OBJ_PLAYER ||  nType >= OBJ_VAT && nType <= OBJ_BARREL
		|| nType == OBJ_INVERSION || OBJ_TUNNEL)
	{
		if(SphereToSphere(GetSphere(), pObj->GetSphere()))
		{
			if(OBJ_TUNNEL)
				CollisionResponse(pObj);
			else
				AddToReactVector(pObj);
			//CollisionResponse(pObj);
			return true;
		}
	}

	return false;
}
void BoundingObjectManager::Update(void)
{
	m_vCollidingNames.clear();
	for(int nObject = 0; nObject < m_nObjects; nObject++)
	{
		m_vBoundingObject[nObject]->SetColorOBB(MEWHITE);
		m_vBoundingObject[nObject]->SetVisible(false);
	}
	CollisionCheck();
	CollisionResponse();
}
Пример #3
0
void World::Update(const ObjectList& objList)
{
	// Works each bodies' physics
	for (auto it1 = objList.begin(); it1 != objList.end(); ++it1)
	{
		// 1. If sprite has body and activated body to work.
		if (it1->second->HasRigidBody() && 
			it1->second->GetRigidBody()->GetMoveToggle())
		{
			// Work basic motion
			BodyPipeline(it1->second);
			
			// 2. if 2st sprite's colliders to be worked, check colliders
			if (it1->second->GetRigidBody()->GetColliderToggle())
			{
				// Refresh collision-with info
				it1->second->GetRigidBody()->CheckCollided(false);
				it1->second->GetRigidBody()->SetCollisionWith(nullptr);

				auto new_begin = it1;
				for (auto it2 = new_begin; it2 != objList.end(); ++it2)
				{
					// 3. If both objs are differenct and both bodies has own body, 
					// activated body and collider body,
					if (it1 != it2 && it2->second->HasRigidBody() &&
						it2->second->GetRigidBody()->GetColliderToggle())
					{					
						// 4. then check the colliders.
						// Check two sprites' collision status
						bool collisionIntersect = CollisionIntersect(it1->second, it2->second);
						if (collisionIntersect)
						{
							// Collision response
							if (it1->second->GetRigidBody()->GetResponseToggle() ||
								it2->second->GetRigidBody()->GetResponseToggle())
									CollisionResponse(it1->second, it2->second);

							// Refresh the collision with info
							CollisionRelation(it1->second, it2->second);

						}// 4. Check the colliders
					}// 3. Has Rigid Body, 2 toggles to work
				}
			}// 2. Collider Toggle
		}// 1. Body Toggle
	}
}
bool CBouncingBall::UpdatePhysics(float dt)
{
	if (m_isActive == false)
		return false;

	bool bounce = false;

	m_position += m_velocity * dt + (m_acceleration * dt * dt) * 0.5;
	m_velocity += m_acceleration * dt;
	
	float yPlane = 0.0f;
	if(CollisionDetection(yPlane)) {
		CollisionResponse();
		bounce = true;
	}


	return bounce;

}
Пример #5
0
// This is the generic sweep test for all swept volumes, but not character-controller specific
bool SweepTest::DoSweepTest(void* user_data,
							void* user_data2,
							NxU32 nb_boxes, const NxExtendedBounds3* boxes, const void** box_user_data,
							NxU32 nb_capsules, const NxExtendedCapsule* capsules, const void** capsule_user_data,
							SweptVolume& swept_volume,
							const NxVec3& direction, NxU32 max_iter, NxU32* nb_collisions,
							NxU32 group_flags, float min_dist, const NxGroupsMask* groupsMask, bool down_pass)
{
	// Early exit when motion is zero. Since the motion is decomposed into several vectors
	// and this function is called for each of them, it actually happens quite often.
	if(direction.isZero())
		return false;

	bool HasMoved = false;
	mValidTri = false;

	NxExtendedVec3 CurrentPosition = swept_volume.mCenter;
	NxExtendedVec3 TargetPosition = swept_volume.mCenter;
	TargetPosition += direction;

	NxU32 NbCollisions = 0;
	while(max_iter--)
	{
		gNbIters++;
		// Compute current direction
		NxVec3 CurrentDirection = TargetPosition - CurrentPosition;

		// Make sure the new TBV is still valid
		{
			// Compute temporal bounding box. We could use a capsule or an OBB instead:
			// - the volume would be smaller
			// - but the query would be slower
			// Overall it's unclear whether it's worth it or not.
			// TODO: optimize this part ?
			NxExtendedBounds3 TemporalBox;
			swept_volume.ComputeTemporalBox(*this, TemporalBox, CurrentPosition, CurrentDirection);

			// Gather touched geoms
			UpdateTouchedGeoms(user_data, swept_volume,
								nb_boxes, boxes, box_user_data,
								nb_capsules, capsules, capsule_user_data,
								group_flags, TemporalBox, groupsMask);
		}

		const float Length = CurrentDirection.magnitude();
		if(Length<min_dist)	break;

		CurrentDirection /= Length;

		// From Quake2: "if velocity is against the original velocity, stop dead to avoid tiny occilations in sloping corners"
		if((CurrentDirection|direction) <= 0.0f)	break;

		// From this point, we're going to update the position at least once
		HasMoved = true;

		// Find closest collision
		SweptContact C;
		C.mDistance = Length + mSkinWidth;

		if(!CollideGeoms(this, swept_volume, mGeomStream, CurrentPosition, CurrentDirection, C))
		{
			// no collision found => move to desired position
			CurrentPosition = TargetPosition;
			break;
		}

		ASSERT(C.mGeom);	// If we reach this point, we must have touched a geom

		if(C.mGeom->mType==TOUCHED_USER_BOX || C.mGeom->mType==TOUCHED_USER_CAPSULE)
		{
			// We touched a user object, typically another CCT
			if(mValidateCallback)	UserHitCallback(user_data2, C, CurrentDirection, Length);

			// Trying to solve the following problem:
			// - by default, the CCT "friction" is infinite, i.e. a CCT will not slide on a slope (this is by design)
			// - this produces bad results when a capsule CCT stands on top of another capsule CCT, without sliding. Visually it looks
			//   like the character is standing on the other character's head, it looks bad. So, here, we would like to let the CCT
			//   slide away, i.e. we don't want friction.
			// So here we simply increase the number of iterations (== let the CCT slide) when the first down collision is with another CCT.
			if(down_pass && !NbCollisions)
				max_iter += 9;
		}
		else
		{
			// We touched a normal object
#ifdef USE_CONTACT_NORMAL_FOR_SLOPE_TEST
			mValidTri = true;
			mCN = C.mWorldNormal;
#else
			if(C.mIndex!=INVALID_ID)
			{
				mValidTri = true;
				mTouched = mWorldTriangles[C.mIndex];
			}
#endif
			{
				if(mValidateCallback)	ShapeHitCallback(user_data2, C, CurrentDirection, Length);
			}
		}

		NbCollisions++;
		mContactPointHeight = (float)C.mWorldPos[mUpDirection];	// UBI

		const float DynSkin = mSkinWidth;

		if(C.mDistance>DynSkin/*+0.01f*/)
			CurrentPosition += CurrentDirection*(C.mDistance-DynSkin);

		NxVec3 WorldNormal = C.mWorldNormal;
		if(mWalkExperiment)
		{
			// Make sure the auto-step doesn't bypass this !
			WorldNormal[mUpDirection]=0.0f;
			WorldNormal.normalize();
		}

		const float Bump = 0.0f;	// ### doesn't work when !=0 because of Quake2 hack!
		const float Friction = 1.0f;
		CollisionResponse(TargetPosition, CurrentPosition, CurrentDirection, WorldNormal, Bump, Friction, mNormalizeResponse);
	}

	if(nb_collisions)	*nb_collisions = NbCollisions;

	// Final box position that should be reflected in the graphics engine
	swept_volume.mCenter = CurrentPosition;

	// If we didn't move, don't update the box position at all (keeping possible lazy-evaluated structures valid)
	return HasMoved;
}
Пример #6
0
bool CSmashBot::CheckCollision(IBaseObject* pObj)
{
	if(pObj == this)
		return false;

	int nType = pObj->GetID();

	if(nType == OBJ_SMASH || nType == OBJ_SPIDER || nType == OBJ_INVERSION || nType == OBJ_TUNNEL)
	{
		if(SphereToSphere(this->GetSphere(), pObj->GetSphere()))
		{
			if( m_bIsSmashing == false || nType == OBJ_INVERSION || OBJ_TUNNEL)
			{
				AddToReactVector(pObj);
				//CollisionResponse(pObj);
				return true;
			}
		}
	}
	if(nType == OBJ_PIT)
	{
		Sphere tempSphere = GetSphere();
		tempSphere.m_Radius = 10.0f;
		if(SphereToAABB(tempSphere,((CDeathPit*)pObj)->GetAABB()))
		{
			((CDeathPit*)pObj)->SetTrapCloseTimer(2.0f);
			if(((CDeathPit*)pObj)->GetTrapIsOpen())
			{
				((CDeathPit*)pObj)->SetIsTrapOpen(false);
				((CDeathPit*)pObj)->ChangeAnimation(1);
			}
			return true;
		}
	}
	if(nType == OBJ_PLAYER)
	{
		if(SphereToSphere(this->GetSphere(), ((CPlayerObject*)pObj)->GetSphere()))
		{
			//m_bIsSmashing = true;
			AddToReactVector(pObj);
			//CollisionResponse(pObj);
			return true;
		}
	}
	if(nType == OBJ_CONVEYOR)
	{
		if(SphereToAABB(GetSphere(), ((CConveyor*)pObj)->GetAABB()))
		{
			pObj->AddToReactVector(this);
			//pObj->CollisionResponse(this);
			return true;
		}
	}
	if(nType >= OBJ_VAT && nType <= OBJ_BARREL)
	{
		if(SphereToSphere(GetSphere(),pObj->GetSphere()))
		{
			//AddToReactVector(this);
			CollisionResponse(pObj);
			return true;
		}
	}

	return false;
}
Пример #7
0
bool CExplodingBullet::CheckCollision(IBaseObject* pObj)
{
	if( !GetAlive() || !pObj->GetAlive())
		return false;

	int nType = pObj->GetID();

	switch(m_nType)
	{
	case SPECIALBULLET:
		{
			if( nType == OBJ_BULLET_ENEMY || nType > OBJ_PLAYER && nType <= OBJ_AIFIST || 
				nType >= OBJ_VAT && nType <= OBJ_BARREL || nType == OBJ_INVERSION || nType == OBJ_BOSSINV || nType == OBJ_BOSSTURRET)
			{
				std::list<IBaseObject*>::iterator iter;

				for( iter = m_lEnemies.begin(); iter != m_lEnemies.end(); ++iter )
				{
					if( (*iter) == pObj )
						return false;
				}

				if( SphereToSphere(GetSphere(), pObj->GetSphere()))
				{
					m_lEnemies.push_back(pObj);
					CollisionResponse(pObj);
					CEffect* pEffect = CGameplayState::GetInstance()->GetFX()->CreateEffect(EFFECT_SPECIALHIT,pObj->GetMatrix());
					if(pEffect)
						pEffect->SetColors((D3DXCOLOR)GetColor());
					return true;
				}
			}
		}
		break;
	case SMASHBULLET:
		{
			if( nType == OBJ_PLAYER || nType == OBJ_TRASH )
			{
				if( SphereToSphere(GetSphere(), pObj->GetSphere()))
				{
					CollisionResponse(pObj);
					return true;
				}
			}
		}
		break;
	case BARRELBULLET:
		{
			if( nType == OBJ_PLAYER || nType >= OBJ_TRASH && nType <= OBJ_STEAM)
			{
				if( SphereToSphere(GetSphere(), pObj->GetSphere()))
				{
					CollisionResponse(pObj);
					return true;
				}
			}
			else if( nType == OBJ_BARREL)
			{
				if( SphereToSphere(GetSphere(), pObj->GetSphere()))
				{
					pObj->CollisionResponse(this);
					return true;
				}
			}
		}
		break;
	case INVERSION_BULLET:
		{
			if(nType == OBJ_PLAYER)
			{
				if(SphereToSphere(GetSphere(), pObj->GetSphere()))
				{
					CollisionResponse(pObj);
					return true;
				}
			}
		}
	}
	return false;
}