Пример #1
0
bool PhysicsEngine::CollisionWithMapSimple(PowerBall* b, Map* map, Vector3 &normalPlane)
{
	
	MaloW::Array<MeshStrip*>* temp = map->GetMesh()->GetStrips();
	//int sizeMstrip = temp->size();
	int sizeVertexS0 = temp->get(0)->getNrOfVerts();
	Vertex* verts;
	//Vector3 origin = this->GetPositionVector3();
	Vector3 origin = b->GetTempPosition();
	Vector3 dir = b->GetVelocity();
	Vector3 dirN = dir/dir.GetLength();
	verts = temp->get(0)->getVerts();
	/*
	for(int i = 0;i<sizeMstrip;i++)
	{
		
	}
	*/
	Vector3 p0,p1,p2, normal, v1,v2;
	float smalestTime = -1;
	bool firstHit = false;
	float u, v,t;
	float lengthProjN = 0;
	Vector3 p0Store, p1Store,p2Store, normalStore;
	Vector3 pos = Vector3(map->GetMesh()->GetPosition());
	Vector3 posS = b->GetTempPosition();//this->GetPositionVector3();
	Vector3 rayDirection;
	Vector3 scalingMesh = map->GetMesh()->GetScaling();

	D3DXMATRIX quat;
	D3DXMatrixRotationQuaternion(&quat, &map->GetMesh()->GetRotation()); 
	Matrix4 rotate(quat);
	rotate.TransposeThis();

	Matrix4 scaling;
	scaling.SetScale(scalingMesh);

	Matrix4 translate;
	translate.SetTranslate(pos);
	
	Matrix4 world = translate*rotate*scaling;
	
	for(int i =0; i< sizeVertexS0; i+=3)
	{
		
		/*
		p0 = Vector3(verts[i].pos).GetComponentMultiplication(scalingMesh) + pos;
		p1 = Vector3(verts[i+1].pos).GetComponentMultiplication(scalingMesh) +pos;
		p2 = Vector3(verts[i+2].pos).GetComponentMultiplication(scalingMesh) + pos;
		*/
		p0 = world*Vector3(verts[i].pos);
		p1 = world*Vector3(verts[i+1].pos);
		p2 = world*Vector3(verts[i+2].pos);

		v1 = p1-p0;
		v2 = p2-p0;
		rayDirection = v1.GetCrossProduct(v2);
		rayDirection.normalize();
		float tempLength;
		Vector3 ny;
		Vector3 projN;
		if(RayTriIntersect(origin , rayDirection, p0, p1, p2, u, v, t) )
		{
			normal = rayDirection;
			ny = origin - p0;
			projN = normal*ny.GetDotProduct(normal);
			tempLength = projN.GetLength();
			if(!firstHit)
			{
				firstHit = true;
				smalestTime = t;
				lengthProjN = tempLength;
				p0Store = p0;
				p1Store = p1;
				p2Store = p2;
				normalStore = normal;
			}
			else
			{
				if( tempLength < lengthProjN )
				{
					smalestTime = t;
					lengthProjN = tempLength;
					p0Store = p0;
					p1Store = p1;
					p2Store = p2;
					normalStore = normal;
				}
			}			
		}
		// check agains all edges
		Vector3 lineDirection;
		float scalarProj;
		Vector3 projOnLine;
		Vector3 normalToLine;
		// edge 1:
		ny = origin - p0;
		lineDirection = p1 - p0;
		scalarProj = (ny.GetDotProduct(lineDirection)/lineDirection.GetLengthSquared());
		projOnLine = lineDirection * scalarProj;
		if( (scalarProj >= 0.0f) && (scalarProj <= 1) )
		{
			normalToLine = ny - projOnLine;
			tempLength = normalToLine.GetLength();
			if(!firstHit)
			{
				firstHit = true;
				lengthProjN = tempLength;
				p0Store = p0;
				p1Store = p1;
				p2Store = p2;
				normalStore = normalToLine;
				normalStore.normalize();
			}
			else
			{
				if( tempLength < lengthProjN )
				{
					lengthProjN = tempLength;
					p0Store = p0;
					p1Store = p1;
					p2Store = p2;
					normalStore = normalToLine;
					normalStore.normalize();
				}
			}	

		}
		// edge 2:
		ny = origin - p1;
		lineDirection = p2 - p1;
		scalarProj = (ny.GetDotProduct(lineDirection)/lineDirection.GetLengthSquared());
		projOnLine = lineDirection * scalarProj;
		if( (scalarProj >= 0.0f) && (scalarProj <= 1) )
		{
			normalToLine = ny - projOnLine;
			tempLength = normalToLine.GetLength();
			if(!firstHit)
			{
				firstHit = true;
				lengthProjN = tempLength;
				p0Store = p0;
				p1Store = p1;
				p2Store = p2;
				normalStore = normalToLine;
				normalStore.normalize();
			}
			else
			{
				if( tempLength < lengthProjN )
				{
					lengthProjN = tempLength;
					p0Store = p0;
					p1Store = p1;
					p2Store = p2;
					normalStore = normalToLine;
					normalStore.normalize();
				}
			}	

		}
		// edge 3:
		ny = origin - p2;
		lineDirection = p0 - p2;
		scalarProj = (ny.GetDotProduct(lineDirection)/lineDirection.GetLengthSquared());
		projOnLine = lineDirection * scalarProj;
		if( (scalarProj >= 0.0f) && (scalarProj <= 1) )
		{
			normalToLine = ny - projOnLine;
			tempLength = normalToLine.GetLength();
			if(!firstHit)
			{
				firstHit = true;
				lengthProjN = tempLength;
				p0Store = p0;
				p1Store = p1;
				p2Store = p2;
				normalStore = normalToLine;
				normalStore.normalize();
			}
			else
			{
				if( tempLength < lengthProjN )
				{
					lengthProjN = tempLength;
					p0Store = p0;
					p1Store = p1;
					p2Store = p2;
					normalStore = normal;
				}
			}	

		}
	}
	if(firstHit)
	{
		// for checking if the ball are in the air not turned on at the moment, 
		float eps = 0.5f; //0.001
		if( (lengthProjN < (b->GetRadius() + eps)) && (lengthProjN > (b->GetRadius() - eps)) )
		{
			b->SetNormalContact(normalStore);
			b->SetHasContact(true);
		}
		else 
		{
			b->SetNormalContact(normalStore);
			b->SetHasContact(false);
		}

		if( lengthProjN <= b->GetRadius())
		{
			Vector3 velNorm = b->GetVelocity();
			velNorm.normalize();
			
			if(normalStore.GetDotProduct(velNorm) >=0)
				return false;
	
			float diff = abs(lengthProjN- b->GetRadius());
			
			//Vector3 newPo = origin -dirN*diff;
			//Vector3 projVel = normalStore * this->mVelocity.GetDotProduct(normalStore);
			Vector3 newPo = origin + normalStore*diff;
			/*
			if( projVel.GetDotProduct(normalStore) < 0.0f)
			{
				newPo = origin - normalStore*diff;
				return false;
			}
			else
				newPo = origin + normalStore*diff;
			*/
			
			//this->SetPosition(newPo);
			b->SetTempPosition(newPo);
			normalPlane = normalStore;
			//this->mNormalContact = normalPlane;
			//this->mHasContact  = true;
			return true;
		}
		else
		{
			normalPlane = Vector3(0,0,0);
			//this->mNormalContact = normalPlane;
			//this->mHasContact  = false;
			return false;
		}
		
	}
	normalPlane = Vector3(0,0,0);
	b->SetNormalContact(normalPlane);
	//this->mHasContact  = false;
	return false;
}
Пример #2
0
	//! called during the update of the entity
	void KamikazeAttacker::Update()
	{
		if(m_fHitPoints < 0.0f || !GSETTINGS)
		{
			return;
		}

		auto settings = DYNAMIC_CAST(m_Settings, KamikazeAttackerSettings);
		switch (m_eState)
		{
		case KamikazeAttacker::S_Moving:
			{		
				Vector3 vToHQ = m_TargetHQ->GetAbsolutePosition() - GetAbsolutePosition();
				bool reachedHQ = false;
				if ((int)m_CurrentTarget > (int)m_Path.size() - 3)
				{
					float fDistToHQSq = vToHQ.GetLengthSquared();
					reachedHQ = fDistToHQSq < settings->m_fHQKamikazeRange*settings->m_fHQKamikazeRange;
				}
				if (reachedHQ)
				{
					m_fDecelTimer = 0.0f;
					m_eState = S_PreparingAttack;
					m_bTargetReached = true;
					break;
				}

				if (!m_bTargetReached)
					MoveToTarget();
				else
					SteerToTarget();

				LookAtTarget();
			}
			break;

		case S_PreparingAttack:
			{
				if (m_TargetHQ->GetHitPoints() < 0.0f)
				{
					if (auto nextTarget = WAVEMGR->GetNextHQ())
					{
						m_TargetHQ = nextTarget;
						m_eState = S_Moving;
					}
					else
						m_eState = S_Idle;
				}
				else
				{
					m_vSpeed = Math::Damp(m_vSpeed, Vector3::Zero, g_fDeltaTime, settings->m_fDecelDuration);
					m_fDecelTimer += g_fDeltaTime;
					if (m_fDecelTimer > settings->m_fDecelDuration)
					{
						m_eState = S_AttackingHQ;
						break;
					}

					Translate(m_vSpeed * g_fDeltaTime);

					auto vToHQ = (m_TargetHQ->GetAbsolutePosition() - GetAbsolutePosition()).Normalized();
					m_vLookAt = Math::Damp(m_vLookAt, vToHQ, g_fDeltaTime, 0.1f).Normalized();
					LookAt(m_vLookAt);
				}
			}
			break;

		case KamikazeAttacker::S_AttackingHQ:
			{
				Vector3 vToHQ = (m_TargetHQ->GetAbsolutePosition() - GetAbsolutePosition()).Normalized();
				Vector3 vAcceleration = vToHQ*settings->m_fKamikazeMaxAccel*g_fDeltaTime;
				m_vSpeed += vAcceleration;
				m_vSpeed.Limit(settings->m_fKamikazeMaxSpeed);
				Translate(m_vSpeed * g_fDeltaTime);
			}
			break;		
		}

		super::Update();
	}	
Пример #3
0
bool PhysicsEngine::CollisionWithSphereSimple(PowerBall* b, PowerBall* b1)
{
	Vector3 r = b->GetPositionVector3() - b1->GetPositionVector3();
	r = b->GetTempPosition() - b1->GetTempPosition();

	float distanceBalls = r.GetLength();
	float sumRadius = b->GetRadius() + b1->GetRadius();
	if(distanceBalls > sumRadius)
		return false;

	/*  we have collision but we need to move the balls so they are not inside each other
	*	solve this equation: ((pos1 - t*vel1) - (pos2 - t*vel2)).length = radie1 + radie2
	*
	*	this gives ut the following:
	*	d	 = distance = p1-p2
	*	rV	 = relative velocity = v2-v1
	*	sumR = sumRadius = r1 + r2 
	*
	*	t    = - rV.dot(d)/|rV|^2 +- sqrt( rV.dot(d)^2/|rV|^4 - (sumR^2 - |d|^2) / |rV|^2
	*
	*/
	Vector3 d = b->GetPositionVector3() - b1->GetPositionVector3();
	d = b->GetTempPosition() - b1->GetTempPosition();

	Vector3 rV = b1->GetVelocity() - b->GetVelocity();
	float sumR = b->GetRadius() + b1->GetRadius();
	float tempA = rV.GetDotProduct(d) / rV.GetLengthSquared();
	float tempB = tempA*tempA;
	float tempC = (d.GetLengthSquared() - sumR*sumR) / rV.GetLengthSquared();
	float tempSq = tempB - tempC;
	if( tempSq < 0) // no real solutions
		return false;
	else
	{
		float t1 = - tempA - sqrt(tempSq);
		float t2 = - tempA + sqrt(tempSq);
		Vector3 newPos1, newPos2;
		if(t1 >= 0)
		{
			/*
			newPos1 = this->GetPositionVector3() - this->mVelocity*t1;
			newPos2 = b1->GetPositionVector3() - b1->mVelocity*t1;
								
			this->SetPosition(newPos1);
			b1->SetPosition(newPos2);
			*/

			newPos1 = b->GetTempPosition() - b->GetVelocity()*t1;
			newPos2 = b1->GetTempPosition() - b1->GetVelocity()*t1;
			b->SetTempPosition(newPos1);
			b1->SetTempPosition(newPos2);
		}
		else if(t2 >= 0)
		{
			/*
			newPos1 = this->GetPositionVector3() - this->mVelocity*t2;
			newPos2 = b1->GetPositionVector3() - b1->mVelocity*t2;
			
			this->SetPosition(newPos1);
			b1->SetPosition(newPos2);
			*/
			newPos1 = b->GetTempPosition() - b->GetVelocity()*t2;
			newPos2 = b1->GetTempPosition() - b1->GetVelocity()*t2;
			b->SetTempPosition(newPos1);
			b1->SetTempPosition(newPos2);
		}
		else 
			return false;
	}
	return true;
}