IMotionEvent::simresult_e CPhysicsNPCSolver::Simulate( IPhysicsMotionController *pController, IPhysicsObject *pObject, 
													  float deltaTime, Vector &linear, AngularImpulse &angular )
{
	if ( IsIntersecting() )
	{
		const float PUSH_SPEED = 150.0f;

		if ( pObject->GetGameFlags() & FVPHYSICS_PLAYER_HELD )
		{
			CBasePlayer *pPlayer = UTIL_GetLocalPlayer();
			if ( pPlayer )
			{
				pPlayer->ForceDropOfCarriedPhysObjects( m_hEntity );
			}
		}

		ResetCancelTime();
		angular.Init();
		linear.Init();
		
		// Don't push on vehicles because they won't move
		if ( pObject->GetGameFlags() & FVPHYSICS_MULTIOBJECT_ENTITY )
		{
			if ( m_hEntity->GetServerVehicle() )
				return SIM_NOTHING;
		}

		Vector origin, vel;
		pObject->GetPosition( &origin, NULL );
		pObject->GetVelocity( &vel, NULL );
		Vector dir = origin - m_hNPC->GetAbsOrigin();
		dir.z = dir.z > 0 ? 0.1f : -0.1f;
		VectorNormalize(dir);
		AngularImpulse angVel;
		angVel.Init();

		// NOTE: Iterate this object's contact points 
		// if it can't move in this direction, try sliding along the plane/crease
		Vector pushImpulse;
		PhysComputeSlideDirection( pObject, dir * PUSH_SPEED, angVel, &pushImpulse, NULL, 0 );

		dir = pushImpulse;
		VectorNormalize(dir);

		if ( DotProduct( vel, dir ) < PUSH_SPEED * 0.5f )
		{
			linear = pushImpulse;
			if ( pObject->GetContactPoint(NULL,NULL) )
			{
				linear.z += GetCurrentGravity();
			}
		}
		return SIM_GLOBAL_ACCELERATION;
	}
	return SIM_NOTHING;
}
bool CPhysicsNPCSolver::CheckTouching()
{
	CAI_BaseNPC *pNPC = m_hNPC.Get();
	if ( !pNPC )
		return false;

	CBaseEntity *pPhysicsEnt = m_hEntity.Get();
	if ( !pPhysicsEnt )
		return false;

	IPhysicsObject *pPhysics = pPhysicsEnt->VPhysicsGetObject();
	IPhysicsObject *pNPCPhysics = pNPC->VPhysicsGetObject();
	if ( !pNPCPhysics || !pPhysics )
		return false;

	IPhysicsFrictionSnapshot *pSnapshot = pPhysics->CreateFrictionSnapshot();
	bool found = false;
	bool penetrate = false;

	while ( pSnapshot->IsValid() )
	{
		IPhysicsObject *pOther = pSnapshot->GetObject(1);
		if ( pOther == pNPCPhysics )
		{
			found = true;
			if ( IsContactOnNPCHead(pSnapshot, pPhysics, pNPC ) )
			{
				penetrate = true;
				pSnapshot->MarkContactForDelete();
			}
			break;
		}
		pSnapshot->NextFrictionData();
	}
	pSnapshot->DeleteAllMarkedContacts( true );
	pPhysics->DestroyFrictionSnapshot( pSnapshot );

	// if the object is penetrating something, check to see if it's intersecting this NPC
	// if so, go ahead and switch over to penetration solver mode
	if ( !penetrate && (pPhysics->GetGameFlags() & FVPHYSICS_PENETRATING) )
	{
		penetrate = IsIntersecting();
	}

	if ( penetrate )
	{
		pPhysicsEnt->ClearNavIgnore();
		BecomePenetrationSolver();
	}

	return found;
}
Beispiel #3
0
bool BedUtils::InBedRegion(std::string chromosome, long unsigned start_coordinate, long unsigned end_coordinate)
{
	// convert the parameters into a genomic region
	GenomicRegion query;
	query.chromosome = chromosome;
	query.start = start_coordinate;
	query.end = end_coordinate;

	for (std::vector<GenomicRegion>::iterator region_iterator = this->bed_regions.begin(); region_iterator != this->bed_regions.end(); region_iterator++)
	{
		if(IsIntersecting(query, *region_iterator))
			return true;
	}
	return false;
}
void CPhysicsNPCSolver::Think()
{
	bool finished = m_allowIntersection ? !IsIntersecting() : !CheckTouching();

	if ( finished )
	{
		UTIL_Remove(this);
		return;
	}
	if ( m_allowIntersection )
	{
		IPhysicsObject *pObject = m_hEntity->VPhysicsGetObject();
		if ( !pObject )
		{
			UTIL_Remove(this);
			return;
		}
		pObject->Wake();
	}
	ResetCancelTime();
}
Beispiel #5
0
void PlaySpace::update(float time)
{
	if(time > 0.25f)
	{
		ParticleBudget = 0;
		time = 0.25f;
	}
	else
		ParticleBudget = 500;
	
	LastDeltaTime = time;
	GameTime += time;
	GameFrame += 1;
	
	if(!Player)
		TimeSincePlayerDestruction += time;
	
	SoundManager* manager = SoundManager::GetInstance();
	manager->setListenerPosition(CameraPos);
	
	if(IsStressTesting)
		time = 1.f / 30;
	
	if(!IsStressTesting)
		for(int i = 0; i < Systems.UsedLength; ++i)
		{
			Systems[i]->update(time, this);
		}
	
	for(int i = 0; i < Bullets.UsedLength; ++i)
	{
		if(Bullets[i].canBeDespawned())
			Bullets.quickRemove(i--);
	}
	
	for(int i = 0; i < Particles.UsedLength; ++i)
	{
		if(Particles[i].canBeDespawned())
			Particles.quickRemove(i--);
	}
	
	
	for(int i = 0; i < Ships.UsedLength; ++i)
	{
		if(Ships[i]->canBeDespawned())
		{
			ObjectPointer<Ship>(Ships[i]).destroy(); // Object pointer lets other object pointers know that the object got deleted.
			Objects.quickRemove(Objects.findIndex(Ships[i]));
			Ships.quickRemove(i--);
		}
	}
	
	for(PhysicsObject* obj : Objects)
		obj->update(time, this);
	for(GravitySource& src : GravitySources)
		src.update(time, this);
	for(Bullet& obj : Bullets)
		obj.update(time, this);
	
	// The more particles exist the faster time passes for them, the faster they die
	float particleTimeFactor = Max(float(Particles.UsedLength) / SoftMaxParticleCount, 1.0f);
	for(Particle& particle : Particles)
		particle.update(time * particleTimeFactor, this);
	
	// Physics
	for(PhysicsObject* obj : Objects)
		applyPhysics(obj, time);
	for(Bullet& obj : Bullets)
		applyPhysics(&obj, time);
	for(Particle& particle : Particles)
		applyPhysics(&particle, time * particleTimeFactor);
	
	// Add gravity
	for(GravitySource& src : GravitySources)
	{
		float start = src.Position.X - src.Range*2;
		float end = src.Position.X + src.Range*2;
		
		for(auto* obj : Objects)
			src.influence(obj, time);
		for(auto& obj : Bullets)
			src.influence(&obj, time);
		for(auto& obj : Particles)
			src.influence(&obj, time);
	}
	
	
	for(Bullet& bullet : Bullets)
		for(Ship* ship : Ships)
			if(ship->Faction != bullet.Faction)
				if(ship->Status != Ship::Destroyed)
					if(IsIntersecting(bullet.Bounds, ship->Bounds))
						ship->onHit(&bullet, this);
		
	if(Player)
	{
		CameraPos = Player->Position;
		Renderer.Context.Camera.Position = CameraPos;
	
		// Will be reset to true before next PlaySpace::update
		Player->IsShooting = false;
		Player->IsShootingSecondary = false;
		Player->IsBraking = false;
		Player->IsStabilizing = false;
		Player->IsBoosting = false;
		Player->Steering = 0.0f;
	
		if(!IsStressTesting)
		{
			checkSectorGeneration(Player->Position);
			checkSectorGeneration(Player->Position + Vec2F(SectorLookAhead, 0));
			checkSectorGeneration(Player->Position + Vec2F(0, SectorLookAhead));
			checkSectorGeneration(Player->Position - Vec2F(SectorLookAhead, 0));
			checkSectorGeneration(Player->Position - Vec2F(0, SectorLookAhead));
			checkSectorGeneration(Player->Position + Vec2F(SectorLookAhead));
			checkSectorGeneration(Player->Position - Vec2F(SectorLookAhead));
			
			checkSectorGeneration(Player->Position + Vec2F(SectorLookAhead/2, 0));
			checkSectorGeneration(Player->Position + Vec2F(0, SectorLookAhead/2));
			checkSectorGeneration(Player->Position - Vec2F(SectorLookAhead/2, 0));
			checkSectorGeneration(Player->Position - Vec2F(0, SectorLookAhead/2));
			checkSectorGeneration(Player->Position + Vec2F(SectorLookAhead/2));
			checkSectorGeneration(Player->Position - Vec2F(SectorLookAhead/2));
		}
	}
	ParticleBudget = 0;
	
	if(Music->isFinished()){ Music->setOffset(0); Music->resume(); };
}
//-------------------------------------------------
//	process a click and detect clicks on/off our render node. return SyncWait if we didnt process it and want to process again
//-------------------------------------------------
SyncBool TLGui::TWidgetThumbStick::ProcessClick(TClick& Click,TLRender::TScreen& Screen,TLRender::TRenderTarget& RenderTarget,TLRender::TRenderNode& RenderNode,const TLMaths::TShapeSphere2D& BoundsDatum,const TLMaths::TShape* pClickDatum)
{
	Bool bClickAction = TLGui::g_pWidgetManager->IsClickActionRef(Click.GetActionRef());
	Bool bMoveAction = TLGui::g_pWidgetManager->IsMoveActionRef(Click.GetActionRef());
	Bool bCurrentAction = FALSE;
	Bool bActionPair = FALSE;
	
	if(m_ActionBeingProcessedRef.IsValid())
	{
		bCurrentAction = (Click.GetActionRef() == m_ActionBeingProcessedRef);
		bActionPair = TLGui::g_pWidgetManager->IsActionPair(m_ActionBeingProcessedRef, Click.GetActionRef());
	}
	
	Bool bTestIntersection = FALSE;
	
	if(m_ActionBeingProcessedRef.IsValid())
	{
		if(bClickAction && bCurrentAction)
		{
			if(Click.GetActionType() == TLGui_WidgetActionType_Up )
			{
				OnClickEnd( Click );
				m_ActionBeingProcessedRef.SetInvalid();
				return SyncTrue;
			}
		}
		else if(bMoveAction && bActionPair)
		{
			bTestIntersection = TRUE;
		}
	}
	else if(bClickAction)
	{
		if(Click.GetActionType() == TLGui_WidgetActionType_Up )
		{
			if(bCurrentAction)
			{
				OnClickEnd( Click );
				m_ActionBeingProcessedRef.SetInvalid();
				return SyncTrue;
			}
		}
		else 
		{
			// No 'click' action in progress yet.  Test intersection
			bTestIntersection = TRUE;
		}
	}
	
	
	if(!bTestIntersection)
		return SyncFalse;

	//	see if ray intersects our object, and creates a valid ray
	SyncBool Intersection = IsIntersecting(Screen, RenderTarget, RenderNode, BoundsDatum, pClickDatum, Click );

	if ( Intersection == SyncTrue )
	{
		if(bClickAction)
			m_ActionBeingProcessedRef = Click.GetActionRef();
	}
	else if ( Intersection == SyncFalse )
	{
		OnClickEnd( Click );
		
		if(bClickAction)
			m_ActionBeingProcessedRef.SetInvalid();
		
		return SyncFalse;
	}
	else if ( Intersection == SyncWait )
	{
		return SyncWait;
	}

	 /*
	SyncBool Result = TWidget::ProcessClick(Click, Screen, RenderTarget, RenderNode);
	
	if(Result != SyncTrue)
		return Result;
	*/
	
	// Custom OnClick effectively...

	//	get the 2d circle bounds as the thumbstick
	//	if not valid, wait till next frame (off-screen?)
	const TLMaths::TShapeSphere2D& BoundsSphere = RenderNode.GetWorldBoundsSphere2D();
	if ( !BoundsSphere.IsValid() )
		return SyncWait;

	//	get vector from center of the sphere to the click point
	float2 ClickVector = Click.GetWorldRay().GetStart().xy() - BoundsSphere.GetCenter().xy();

	//	normalise vector to 0..1 in the sphere
	ClickVector /= BoundsSphere.GetSphere().GetRadius();

	//	get length to work out normalised vector and if we're in the deadzone
	float VectorLen = ClickVector.Length();

	//	in the dead zone, return TRUE (processed click) but don't send out a message
	//	this "ignores" the click
	if ( VectorLen <= m_DeadZone )
		return SyncTrue;

	//	send out thumb stick message
	TRef ActionOutRef = m_ActionOutDown;


	if ( ActionOutRef.IsValid() )
	{
	#ifdef _DEBUG
		TTempString Debug_String("WidgetThumbstick (");
		m_RenderNodeRef.GetString( Debug_String );
		Debug_String.Append(") sending thumbstick message: ");
		ActionOutRef.GetString( Debug_String );
		Debug_String.Appendf(": %.2f, %.2f", ClickVector.x, ClickVector.y );
		TLDebug_Print( Debug_String );
	#endif		
		
		//	make up fake input message
		TLMessaging::TMessage Message(TRef_Static(A,c,t,i,o));
		Message.Write( ActionOutRef );
		Message.ExportData("RawData", ClickVector );

		//	send message
		PublishMessage( Message );
	}

	return SyncTrue;
}