//--------------------------------------------------------------------------------------
// Updates the position and velocity of the entity associated to this movement manager
// using the accumulated sum of all forces impacting the entity.
// Param1: The time in seconds passed since the last frame.
// Param2: The maximal speed of the entity.
// Param3: The maximal size of the accumulated forces.
// Param4: The handicap to use if the entity is currently being handicapped.
//--------------------------------------------------------------------------------------
void EntityMovementManager::UpdatePosition(float deltaTime, float maxSpeed, float maxForce, float handicap)
{
	// Truncate steering force to not be greater than the maximal allowed force
	float magnitude = 0.0f;
	XMStoreFloat(&magnitude, XMVector2Length(XMLoadFloat2(&m_steeringForce)));

	if(magnitude > maxForce)
	{
		// Truncate the vector to be of the magnitude corresponding to the maximal allowed force
		XMStoreFloat2(&m_steeringForce, XMVector2Normalize(XMLoadFloat2(&m_steeringForce)) * maxForce);
	}

	// Calculate the new velocity for the entity
	XMFLOAT2 newVelocity;
	XMStoreFloat2(&newVelocity, XMLoadFloat2(&m_velocity) + XMLoadFloat2(&m_steeringForce));

	// Truncate the velocity if it is greater than the maximally allowed velocity for the entity
	XMStoreFloat(&magnitude, XMVector2Length(XMLoadFloat2(&newVelocity)));

	if(magnitude > maxSpeed)
	{
		// Truncate the vector to be of the magnitude corresponding to the maximal allowed velocity
		XMStoreFloat2(&newVelocity, XMVector2Normalize(XMLoadFloat2(&newVelocity)) * maxSpeed);
	}

	// Set the new velocity and position on the entity

	m_velocity = newVelocity;
		
	XMFLOAT2 newPosition;

	if(m_pEntity->IsHandicapped())
	{
		XMStoreFloat2(&newPosition, XMLoadFloat2(&m_pEntity->GetPosition()) + XMLoadFloat2(&newVelocity) * deltaTime * handicap);
	}else
	{
		XMStoreFloat2(&newPosition, XMLoadFloat2(&m_pEntity->GetPosition()) + XMLoadFloat2(&newVelocity) * deltaTime);
	}

	m_pEntity->SetPosition(newPosition);
	m_pEntity->UpdateColliderPosition(newPosition);

	// Update the rotation to make the entity face the direction, in which it is moving
	if(!(newVelocity.x == 0.0f && newVelocity.y == 0.0f))
	{
		XMFLOAT2 lookAtPoint(0.0f, 0.0f);
		XMStoreFloat2(&lookAtPoint, XMLoadFloat2(&m_pEntity->GetPosition()) + XMLoadFloat2(&newVelocity));
		LookAt(lookAtPoint);
	}

	// Reset the steering force for the next frame
	m_steeringForce.x = 0.0f;
	m_steeringForce.y = 0.0f;
}
Beispiel #2
0
//--------------------------------------------------------------------------------------
// Tells whether a soldier is at a certain target or not. Accounts for the target reached
// radius used by the soldier.
// Param1: The target position, for which to check if the soldier has reached it.
// Returns true if the soldier has reached the target, false otherwise. 
//--------------------------------------------------------------------------------------
bool Soldier::IsAtTarget(const XMFLOAT2& target)
{
	float distance(0.0f);
	XMStoreFloat(&distance, XMVector2Length(XMLoadFloat2(&target) - XMLoadFloat2(&GetPosition())));

	return (distance <= m_soldierProperties.m_targetReachedRadius);
}
//--------------------------------------------------------------------------------------
// Move the entity to a specified target position.
// Param1: The target position of the entity.
// Param2: The radius around the target position from which the target counts as reached.
// Param3: The speed, at which the entity should seek the target.
// Returns true if the target was reached, false if there is still way to go.
//--------------------------------------------------------------------------------------
bool EntityMovementManager::Seek(const XMFLOAT2& targetPosition, float targetReachedRadius, float speed)
{
	XMFLOAT2 desiredVelocity;
	XMStoreFloat2(&desiredVelocity, XMLoadFloat2(&targetPosition) - XMLoadFloat2(&m_pEntity->GetPosition()));

	// Get the distance from the current position of the entity to the target
	float distance;
	XMStoreFloat(&distance, XMVector2Length(XMLoadFloat2(&desiredVelocity)));

	// Normalise the desired velocity
	XMStoreFloat2(&desiredVelocity, XMVector2Normalize(XMLoadFloat2(&desiredVelocity)));

	XMStoreFloat2(&desiredVelocity, XMLoadFloat2(&desiredVelocity) * speed);
	
	bool targetReached = false;

	// Target reached
	if(distance <= targetReachedRadius)
	{
		desiredVelocity = XMFLOAT2(0.0f, 0.0f);
		targetReached = true;
	}

	XMFLOAT2 force;
	XMStoreFloat2(&force, XMLoadFloat2(&desiredVelocity) - XMLoadFloat2(&m_velocity));

	// Add the seek force to the accumulated steering force
	XMStoreFloat2(&m_steeringForce, XMLoadFloat2(&m_steeringForce) + XMLoadFloat2(&force));

	return targetReached;
}
Beispiel #4
0
void Small::BigDetect()
{
	if (TeamID != RED)
	{
		for (int i = 0; i < RedList->size(); i++)
		{
			XMVECTOR tempvector = {XMVectorGetX(RedList->at(i)->Location), XMVectorGetY(RedList->at(i)->Location), 0, 0};
			XMVECTOR tempdifference = Location - tempvector;

			if (XMVectorGetX(XMVector2Length(tempdifference)) < 40)
			{
				SetChaseTarget(RedList->at(i));
				TeamID = Target->TeamID;
				Chasing = true;
				Flocking = true;
			}
		}
	}

	if (TeamID != BLUE)
	{
		for (int i = 0; i < BlueList->size(); i++)
		{
			XMVECTOR tempvector = {XMVectorGetX(BlueList->at(i)->Location), XMVectorGetY(BlueList->at(i)->Location), 0, 0};
			XMVECTOR tempdifference = Location - tempvector;

			if (XMVectorGetX(XMVector2Length(tempdifference)) < 40)
			{
				SetChaseTarget(BlueList->at(i));
				TeamID = Target->TeamID;
				Chasing = true;
				Flocking = true;
			}
		}
	}
}
//--------------------------------------------------------------------------------------
// Calculate the path following force and add it to the total force.
// Param1: A pointer to the path to follow.
// Param2: When the entity has approached the target by this distance, it counts as reached.
// Param3: The speed, at which the entity should follow the path.
// Returns true if the end of the current path was reached, false if there is still way to go.
//--------------------------------------------------------------------------------------
bool EntityMovementManager::FollowPath(std::vector<XMFLOAT2>* pPath, float nodeReachedRadius, float speed)
{
	if(!pPath)
	{
		return false;
	}

	if(!pPath->empty())
	{
		// There is an active path
		XMFLOAT2 target = (*pPath)[m_currentNode];
	
		// Calculate the distance between the current position of the entity and the target
		float distance = 0.0f;
		XMStoreFloat(&distance, XMVector2Length(XMLoadFloat2(&target) - XMLoadFloat2(&m_pEntity->GetPosition())));

		if(distance <= nodeReachedRadius)
		{
			// The entity has reached the node
			++m_currentNode;

			if(m_currentNode >= pPath->size())
			{
				// Final destination reached, clear the path
				pPath->clear();
				m_velocity = XMFLOAT2(0.0f, 0.0f);
			
				return true;
			}else
			{
				Seek((*pPath)[m_currentNode], nodeReachedRadius, speed);
				return false;
			}
		}else
		{
			Seek((*pPath)[m_currentNode], nodeReachedRadius, speed);
			return false;
		}
	}

	return true;
}
std::vector<std::pair<float, XMFLOAT4*>> Terrain::getBlendmapDataWithinRadius(const XMFLOAT3 position, const UINT radius)
{
	const int col = (int)floorf( position.x + 0.5f * m_width);
	const int row = (int)floorf(-position.z + 0.5f * m_depth);

	const UINT width = m_width;
	const UINT depth = m_depth;

	const float halfWidth = 0.5f * (float)width;
	const float halfDepth = 0.5f * (float)depth;

	const float dx = (float)width / ((float)width - 1);
	const float dz = (float)depth / ((float)depth - 1);

	XMVECTOR p = XMVectorSet(position.x, position.z, 0.f, 0.f);

	std::vector<std::pair<float, XMFLOAT4*>> blendmapData;
	for (int i = row - (int)radius; i < row + (int)radius + 1; i++)
	{
		if (i >= 0 && i < (int)depth)
		{
			for (int j = col - (int)radius; j < col + (int)radius + 1; j++)
			{
				if (j >= 0 && j < (int)width)
				{
					XMVECTOR v = XMVectorSet(-halfWidth + j * dx, halfDepth - i * dz, 0.f, 0.f);
					const float length = XMVectorGetX(XMVector2Length(v - p)) / radius;
					if (length <= 1.f)
						blendmapData.push_back(
							std::pair<float, XMFLOAT4*>(length, &m_blendmap.texels[i * width + j]));
				}
			}
		}
	}
	return blendmapData;
}
Beispiel #7
0
//--------------------------------------------------------------------------------------
// Checks for collision of a line with this collider.
// Param1: The start point of the line.
// Param2: The end point of the line.
// Returns true if the line intersects with the collider, that includes touching it and
// being fully encompassed by it, false otherwise.
//--------------------------------------------------------------------------------------
bool CircleCollider::CheckLineCollision(const XMFLOAT2& lineStart, const XMFLOAT2& lineEnd) const
{
	if(lineStart.x == lineEnd.x && lineStart.y == lineEnd.y)
	{
		// If the points are identical, check whether that shared point lies within the collider.
		return CheckPointCollision(lineStart);
	}

	XMVECTOR lineSegment = XMLoadFloat2(&lineEnd) - XMLoadFloat2(&lineStart);
	XMVECTOR startToCollider = XMLoadFloat2(&GetCentre()) - XMLoadFloat2(&lineStart);

	float segmentLength = 0.0f;
	XMStoreFloat(&segmentLength, XMVector2Length(lineSegment));

	XMVECTOR normLineSegment = lineSegment / segmentLength;

	float projection = 0.0f;
	XMStoreFloat(&projection, XMVector2Dot(startToCollider, normLineSegment));

	if((projection < 0.0f) || (projection > segmentLength))
	{
		// Projection is beyond the start or end point of the segment
		return false;
	}

	// Get the projected point
	XMVECTOR projectedPoint = XMLoadFloat2(&lineStart) + normLineSegment * projection;

	// Check if the projected point lies within the radius of the collider
	float squareRadius = GetRadius() * GetRadius();
	float squareDistance = 0.0f;
	XMStoreFloat(&squareDistance, XMVector2Dot(XMLoadFloat2(&GetCentre()) - projectedPoint, XMLoadFloat2(&GetCentre()) - projectedPoint));

	return squareRadius >= squareDistance;

}
Beispiel #8
0
void Small::Separation(float weight)
{
	XMMATRIX rotationmatrix;
	XMVECTOR closestflockmatedifference = {-1000.0f, -1000.0f, 0, 0};

	bool isalone = true;

	for (int i = 0; i < SmallVector->size(); i++)
	{
		if (SmallVector->at(i)->ID != this->ID)
		{
			if (SmallVector->at(i)->Chasing)
			{
				if (Target->ID == SmallVector->at(i)->Target->ID)
				{
					XMVECTOR tempvector = {XMVectorGetX(SmallVector->at(i)->Location), XMVectorGetY(SmallVector->at(i)->Location), 0, 0};
					XMVECTOR tempdifference = Location - tempvector;

					if (XMVectorGetX(XMVector2Length(tempdifference)) < XMVectorGetX(XMVector2Length(closestflockmatedifference)))
					{
						closestflockmatedifference = tempdifference;
						isalone = false;
					}
				}
			}
		}
	}

	if (!isalone)
	{
		XMVECTOR leftvector = {0, 0, 0, 0};
		XMVECTOR rightvector = {0, 0, 0, 0};

		XMMATRIX rotationmatrixleft = XMMatrixRotationZ(float(M_PI)/2.0f);
		XMMATRIX rotationmatrixright = XMMatrixRotationZ(float(M_PI)/-2.0f);

		leftvector = XMVector3Transform(Direction, rotationmatrixleft);
		rightvector = XMVector3Transform(Direction, rotationmatrixright);

		Direction = XMVector2Normalize(Direction);

		XMVECTOR differencevector = closestflockmatedifference;

		differencevector = XMVector2Normalize(differencevector);

		float radiandifference = XMVectorGetX(XMVector2AngleBetweenNormals(leftvector, differencevector));
		float epsilon = XMVectorGetX(XMVector2AngleBetweenNormals(Direction, differencevector));

		if (radiandifference <= float(M_PI/2.0f)) 
		{
			rotationmatrix = XMMatrixRotationZ(weight);

			if (epsilon <= (1.25f * weight))
			{
				Direction = differencevector;
				Direction = XMVector2Normalize(Direction);

			}
			else
			{
				Direction = XMVector3Transform(Direction, rotationmatrix);
				Direction = XMVector2Normalize(Direction);
			}
		}
		else if (radiandifference > float(M_PI/2.0f)) 
		{
			rotationmatrix = XMMatrixRotationZ(-weight);

			if (epsilon <= (1.25f * weight))
			{
				Direction = differencevector;
				Direction = XMVector2Normalize(Direction);

			}
			else
			{
				Direction = XMVector3Transform(Direction, rotationmatrix);
				Direction = XMVector2Normalize(Direction);
			}
		}
	}
}
Beispiel #9
0
float VectorMath::Magnitude(const Vec2* vec)
{
	XMVECTOR xmVec = XMLoadFloat2((_XMFLOAT2*) vec);
	return XMVector2Length(xmVec).m128_f32[0];
}