//--------------------------------------------------------------------------------------
// Calculate the wall avoidance force and add it to the total force. This force 
// is used to push the entity away from walls (objects) that it is getting too close to.
// Param1: Obstacles within this radius around the entity will be avoided.
// Param2: The maximal size of this force.
//--------------------------------------------------------------------------------------
void EntityMovementManager::StayAwayFromWalls(float avoidWallsRadius, float maximalForce)
{
	// Get nearby obstacles

	std::multimap<float, CollidableObject*> nearbyObjects;
	m_pEnvironment->GetNearbyObjects(m_pEntity->GetPosition(), avoidWallsRadius, GroupObstacles, nearbyObjects);

	if(!nearbyObjects.empty())
	{
		XMVECTOR avoidanceForce = XMVectorZero();

		for(std::multimap<float, CollidableObject*>::iterator it = nearbyObjects.begin(); it != nearbyObjects.end(); ++it)
		{
			// Scale the force according to the proximity of the nearby entity. Thus the push from close objects will be
			// stronger than that from objects that are farther away.
			avoidanceForce += (XMLoadFloat2(&m_pEntity->GetPosition()) - XMLoadFloat2(&(it->second->GetPosition()))) / it->first;
		}

		// Truncate the force according to the maximally allowed wall avoidance force.
		avoidanceForce = XMVector2Normalize(avoidanceForce) * maximalForce;

		// Add the collision avoidance force to the accumulated steering force
		XMStoreFloat2(&m_steeringForce, XMLoadFloat2(&m_steeringForce) + avoidanceForce);
	}
}
Example #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);
}
//--------------------------------------------------------------------------------------
// Calculate the separation force and add it to the total force.
// Param1: The entity will try to move away from entities that are at this distance or closer.
// Param2: The maximal size of this force.
//--------------------------------------------------------------------------------------
void EntityMovementManager::Separate(float separationRadius, float maximalForce)
{
	XMVECTOR separationVector = XMVectorZero(); // The separation force to prevent overlapping of moving entities

	// Find the moving entities that are in close proximity to this one (check both teams)

	std::multimap<float, CollidableObject*> nearbySoldiers;
	m_pEnvironment->GetNearbyObjects(m_pEntity->GetPosition(), separationRadius, GroupAllSoldiers, nearbySoldiers);

	// The entity itself will be included in the list of soldiers -> check if there are others as well
	if(nearbySoldiers.size() > 1)
	{
		for(std::multimap<float, CollidableObject*>::const_iterator it = nearbySoldiers.begin(); it !=  nearbySoldiers.end(); ++it)
		{
			if(it->second->GetId() != m_pEntity->GetId())
			{
				// Scale the force according to the proximity of the nearby entity. Thus the push from close objects will be
				// stronger than that from objects that are farther away.

				// Avoid possible division by zero
				float proximity = (it->first != 0) ? it->first : 0.01f;

				separationVector += (XMLoadFloat2(&m_pEntity->GetPosition()) - XMLoadFloat2(&it->second->GetPosition())) / proximity;
			}
		}

		// Truncate the force according to the maximally allowed separation force.
		separationVector = XMVector2Normalize(separationVector) * maximalForce;

		// Add the separation force to the accumulated steering force
		XMStoreFloat2(&m_steeringForce, XMLoadFloat2(&m_steeringForce) + separationVector);
	}
}
Example #4
0
    XMFLOAT2 Skeleton::CalculatePosition2D(std::vector<XMFLOAT2> &jointPositions2D, std::vector<float> &jointRotations2D, XMFLOAT2 &endEffectorPosition)
    {
        if (jointPositions2D.size() < 2) return XMFLOAT2(0.f, 0.f);

        // Walk through each link and apply the transform
        for (size_t i = 0; i < jointPositions2D.size() - 1; ++i)
        {
            float sumRotations = 0.f;
            for (size_t j = 0; j <= i; ++j)
            {
                sumRotations += jointRotations2D[j];
            }
            XMFLOAT2 direction;
            direction.x = cos(sumRotations);
            direction.y = sin(sumRotations);
            XMStoreFloat2(&jointPositions2D[i + 1], XMVectorAdd(XMLoadFloat2(&jointPositions2D[i]), XMVectorScale(XMLoadFloat2(&direction), m_IKLinkLength)));
        }

        float sumRotations = 0.f;
        for (size_t j = 0; j < jointRotations2D.size(); ++j)
        {
            sumRotations += jointRotations2D[j];
        }
        XMFLOAT2 direction;
        direction.x = cos(sumRotations);
        direction.y = sin(sumRotations);                

        XMStoreFloat2(&endEffectorPosition, XMVectorAdd(XMLoadFloat2(&jointPositions2D.back()), XMVectorScale(XMLoadFloat2(&direction), m_IKLinkLength)));

        return endEffectorPosition;
    }
Example #5
0
//--------------------------------------------------------------------------------------
// Checks for collision of a point with this collider.
// Param1: The point to test.
// Returns true if the point is within the collider, that includes touching its outer line,
// false otherwise.
//--------------------------------------------------------------------------------------
bool CircleCollider::CheckPointCollision(const XMFLOAT2& point) const
{
	float squareRadius = GetRadius() * GetRadius();

	float squareDistance = 0.0f;
	XMStoreFloat(&squareDistance, XMVector2LengthSq(XMLoadFloat2(&GetCentre()) - XMLoadFloat2(&point)));

	return squareRadius >= squareDistance;
}
    void FirstPersonCamera::Update(const GameTime& gameTime)
    {
		XMFLOAT2 movementAmount = Vector2Helper::Zero;
        if (mKeyboard != nullptr)
        {
            if (mKeyboard->IsKeyDown(DIK_W))
            {
                movementAmount.y = 1.0f;
            }

            if (mKeyboard->IsKeyDown(DIK_S))
            {
                movementAmount.y = -1.0f;
            }

            if (mKeyboard->IsKeyDown(DIK_A))
            {
                movementAmount.x = -1.0f;
            }

            if (mKeyboard->IsKeyDown(DIK_D))
            {
                movementAmount.x = 1.0f;
            }
        }

        XMFLOAT2 rotationAmount = Vector2Helper::Zero;
        if ((mMouse != nullptr) && (mMouse->IsButtonHeldDown(MouseButtons::Left)))
        {
            LPDIMOUSESTATE mouseState = mMouse->CurrentState();			
            rotationAmount.x = -mouseState->lX * mMouseSensitivity;
            rotationAmount.y = -mouseState->lY * mMouseSensitivity;
        }

		float elapsedTime = (float)gameTime.ElapsedGameTime();
        XMVECTOR rotationVector = XMLoadFloat2(&rotationAmount) * mRotationRate * elapsedTime;
        XMVECTOR right = XMLoadFloat3(&mRight);

        XMMATRIX pitchMatrix = XMMatrixRotationAxis(right, XMVectorGetY(rotationVector));
        XMMATRIX yawMatrix = XMMatrixRotationY(XMVectorGetX(rotationVector));

        ApplyRotation(XMMatrixMultiply(pitchMatrix, yawMatrix));

        XMVECTOR position = XMLoadFloat3(&mPosition);
		XMVECTOR movement = XMLoadFloat2(&movementAmount) * mMovementRate * elapsedTime;

		XMVECTOR strafe = right * XMVectorGetX(movement);
        position += strafe;

        XMVECTOR forward = XMLoadFloat3(&mDirection) * XMVectorGetY(movement);
        position += forward;
        
        XMStoreFloat3(&mPosition, position);

        Camera::Update(gameTime);
    }
Example #7
0
int Map:: BuildTransform() {
  world_ = XMMatrixTransformation2D(XMLoadFloat2(&XMFLOAT2(0,0)),
    0,
    XMLoadFloat2(&XMFLOAT2(scale_,scale_)),
    XMLoadFloat2(&XMFLOAT2(0,0)),
    angle_,
    XMLoadFloat2(&XMFLOAT2(x_,y_)));
  world_._43 = z_;
  return S_OK;
}
//--------------------------------------------------------------------------------------
// Rotates the entity towards a specific point.
// Param1: The position, the entity should look at.
//--------------------------------------------------------------------------------------
void EntityMovementManager::LookAt(const XMFLOAT2& lookAtPosition)
{
	XMFLOAT2 newViewDirection(0.0f, 1.0f);
	XMStoreFloat2(&newViewDirection, XMVector2Normalize(XMLoadFloat2(&lookAtPosition) - XMLoadFloat2(&m_pEntity->GetPosition())));
	
	m_pEntity->SetViewDirection(newViewDirection);
	
	float rotation = (atan2(m_pEntity->GetViewDirection().x, m_pEntity->GetViewDirection().y)) * 180 / XM_PI;
	m_pEntity->SetRotation(rotation);
}
//--------------------------------------------------------------------------------------
// 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;
}
//--------------------------------------------------------------------------------------
// Calculate the collision avoidance force and add it to the total force. This force 
// is used to avoid collisions of an entity with static obstacles in the environment and
// other entities.
// Param1: Obstacles and entities within this distance in front of the entity will be avoided.
// Param2: The maximal size of this force.
//--------------------------------------------------------------------------------------
void EntityMovementManager::AvoidCollisions(float seeAheadDistance, float maximalForce)
{
	if(m_velocity.x == 0.0f && m_velocity.y == 0.0f)
	{
		return;
	}

	std::multimap<float, CollidableObject*> nearbyObjects;
	m_pEnvironment->GetNearbyObjects(m_pEntity->GetPosition(), seeAheadDistance, GroupAllSoldiersAndObstacles, nearbyObjects);

	// One element is entity itself -> Check if there are more than one
	if(nearbyObjects.size() > 1)
	{
		XMFLOAT2 lineEndPoint(0.0f, 0.0f);
		XMStoreFloat2(&lineEndPoint, XMLoadFloat2(&m_pEntity->GetPosition()) + XMVector2Normalize(XMLoadFloat2(&m_pEntity->GetViewDirection())) * seeAheadDistance);

		for(std::multimap<float, CollidableObject*>::iterator it = nearbyObjects.begin(); it != nearbyObjects.end(); ++it)
		{
			
			if((it->second->GetId() != m_pEntity->GetId()) && reinterpret_cast<CollidableObject*>(it->second)->GetCollider()->CheckLineCollision(m_pEntity->GetPosition(), lineEndPoint))
			{
				// Determine whether the other entity is left or right of this entity

				XMFLOAT2 entityToObject(0.0f, 0.0f);
				XMStoreFloat2(&entityToObject, XMLoadFloat2(&it->second->GetPosition()) - XMLoadFloat2(&m_pEntity->GetPosition()));

				float dot = m_pEntity->GetViewDirection().x * (-entityToObject.y) + m_pEntity->GetViewDirection().y * entityToObject.x;	
					
				XMFLOAT2 avoidanceVector = m_pEntity->GetViewDirection();

				if(dot > 0)
				{
					// Object is right of entity, steer left to avoid
					avoidanceVector.x = -m_pEntity->GetViewDirection().y;
					avoidanceVector.y = m_pEntity->GetViewDirection().x;
				}else
				{
					// Object is left of entity, steer right to avoid
					avoidanceVector.x = m_pEntity->GetViewDirection().y;
					avoidanceVector.y = -m_pEntity->GetViewDirection().x;
				}
					
				XMStoreFloat2(&m_steeringForce, XMLoadFloat2(&m_steeringForce) + XMVector2Normalize(XMLoadFloat2(&avoidanceVector)) * maximalForce);
					
				// Bail out of the function as soon as the first collision is found (the nearby entities are already sorted
				// by their distance from the original entity, thus the first collision found is the closest one)

				return;
			}
			
		}
	}
}
// Transform the triangle coordinates so that they remain centered and at the right scale.
// (mapping a [0,0,1,1] square into a [0,0,1,1] rectangle)
inline XMFLOAT3 D3D12HDR::TransformVertex(XMFLOAT2 point, XMFLOAT2 offset)
{
    auto scale = XMFLOAT2(min(1.0f, 1.0f / m_aspectRatio), min(1.0f, m_aspectRatio));
    auto margin = XMFLOAT2(0.5f * (1.0f - scale.x), 0.5f * (1.0f - scale.y));
    auto v = XMVectorMultiplyAdd(
        XMLoadFloat2(&point),
        XMLoadFloat2(&scale),
        XMVectorAdd(XMLoadFloat2(&margin), XMLoadFloat2(&offset)));

    XMFLOAT3 result;
    XMStoreFloat3(&result, v);
    return result;
}
void RayTracingDemo::draw(const GameTimer & timer)
{
	mTextureSize = { static_cast<float>(mGame->screenWidth()), static_cast<float>(mGame->screenHeight()) };

	ID3D11DeviceContext * deviceContext = mGame->deviceContext();
	mMaterial->TextureSize() << XMLoadFloat2(&mTextureSize);
	mMaterial->BlueColor() << mBlueColor;
	mMaterial->CameraPosition() << mCamera->positionVector();
	mMaterial->InverseViewMatrix() << XMMatrixInverse(nullptr,mCamera->viewMatrix());
	mMaterial->InverseProjectionMatrix() << XMMatrixInverse(nullptr, mCamera->projectionMatrix());
	mMaterial->ViewMatrix() << mCamera->viewMatrix();
	mMaterial->Position() << XMLoadFloat3(&mPosition);
	mMaterial->LightPosition() << XMLoadFloat3(&mLightPosition);
	mMaterial->ProjectionMatrix() << mCamera->projectionMatrix();
	//mMaterial->SpherePosition() << mPosition;

	mMaterial->OutputTexture() << mOutputTexture;
	mComputePass->apply(0, deviceContext);

	deviceContext->Dispatch(mThreadGroupCount.x, mThreadGroupCount.y, 1);
	static ID3D11UnorderedAccessView * emptyUAV = nullptr;
	deviceContext->CSSetUnorderedAccessViews(0, 1, &emptyUAV, nullptr);

	mFullScreenQuad->draw(timer);
}
Example #13
0
Vec2 VectorMath::Normalize(const Vec2* vec)
{
	Vec2 retval;
	XMVECTOR xmVec = XMLoadFloat2((_XMFLOAT2*)vec);
	xmVec = XMVector2Normalize(xmVec);
	XMStoreFloat2((XMFLOAT2*)&retval, xmVec);
	return retval;
}
void DirectionSelector::VerifyDirection()
{
    if (_direction.x * _direction.x + _direction.y * _direction.y >= 1.0f ||
        (_direction.x == 0.0f && _direction.y == 0.0f))
    {
        XMVECTOR vec = XMLoadFloat2(&_direction);
        vec = XMVector2Normalize(vec) * (1.0f - EPSILON);
        XMStoreFloat2(&_direction, vec);
    }
}
Example #15
0
void LineConnection::FormConnection(XMVECTOR node1Pos, XMVECTOR node2Pos, float distance)
{
    m_visible = true;
    // draw a line between 2 nodes. The thickness/alpha varies depending on distance
    m_strokeThickness = Node::Map(distance, 0, MinDist, StrokeWeightMax, StrokeWeightMin);
    
    XMVECTORF32 color = {1, 1, 1, Node::Map(distance, 0, MinDist, 1.0f, 0)};
    m_color = color;

    XMStoreFloat2(&m_start, node1Pos);
    XMStoreFloat2(&m_end, node2Pos);

    m_destRect.left =   (long)m_start.x;
    m_destRect.top =    (long)m_start.y;
    m_destRect.right  = (long)(m_start.x + m_strokeThickness);  
    m_destRect.bottom = (long)(m_start.y + Distance(XMLoadFloat2(&m_start), XMLoadFloat2(&m_end)));

    m_rotation = PIOVER2 - (float)atan2(m_end.y - m_start.y, m_start.x - m_end.x);
}
//--------------------------------------------------------------------------------------
// 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;
}
Example #17
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;

}
Example #18
0
void UIObject::Draw(ID3D11DeviceContext* deviceContext, ID3D11Buffer* cBuffer, VertexShaderConstantBufferLayout* cBufferData) {
	batch->Draw(material->resourceView, XMFLOAT2(position.x, position.y));
	font->DrawString(batch, text, XMLoadFloat2(&textPos));
}
Example #19
0
    DirectX::BoundingOrientedBox GetBoundsInOrientedSpace(_In_ bool findTightestBounds, _In_ function<bool(XMFLOAT3*)> vertGenerator)
    {
        // we find tight bounds by
        // 1. find the convex hull
        // 2. rotating calipers to find the ideal bounding box - http://en.wikipedia.org/wiki/Rotating_calipers

        // The idea behind rotating calipers is that we keep track of some extreme vertices, and slowly rotate our coordinate frame.
        // As we rotate, a vertex may no-longer be extreme in the new rotated coordinate frame, so we increment the index to the next vertex
        // in the convex hull that is now extreme.

        float zmin = FLT_MAX, zmax = -FLT_MAX;
        auto convexHull = FindConvexHull([&](XMFLOAT2 *planarVert, UINT32 *index) -> bool
        {
            *index = 0; // we dont' care about the index here - only useful when exposing the convex hull directly

            XMFLOAT3 vert;
            bool ret = vertGenerator(&vert);
            if (ret)
            {
                if (vert.z < zmin)
                {
                    zmin = vert.z;
                }

                if (vert.z > zmax)
                {
                    zmax = vert.z;
                }
            }
            *planarVert = { vert.x, vert.y };
            return ret;
        });

        // first we need to set up the calipers - extreme vertices that we will incrementally update as we rotate
        XMFLOAT2 maxv = convexHull[0].first;
        XMFLOAT2 minv = convexHull[0].first;
        struct RotatedBoundingBox
        {
            UINT32 maxx, maxy, minx, miny; // these represent the indices of the max/min x and y coordinates in a rotated coordated frame.
            float area;
            float minwidth;
            float angle;
        };

        // find the initial orientation's bounds:
        RotatedBoundingBox best = { 0, 0, 0, 0, FLT_MAX, FLT_MAX, XM_2PI };
        for (UINT32 i = 1; i < convexHull.size(); ++i)
        {
            const auto vertex = convexHull[i].first;
            if (vertex.x > maxv.x)
            {
                maxv.x = vertex.x;
                best.maxx = i;
            }
            else if (vertex.x < minv.x)
            {
                minv.x = vertex.x;
                best.minx = i;
            }

            if (vertex.y > maxv.y)
            {
                maxv.y = vertex.y;
                best.maxy = i;
            }
            else if (vertex.y < minv.y)
            {
                minv.y = vertex.y;
                best.miny = i;
            }
        }
        best.angle = 0;
        best.area = (maxv.x - minv.x) * (maxv.y - minv.y);
        best.minwidth = min(maxv.x - minv.x, maxv.y - minv.y);

        ASSERT(best.minx != best.maxx); // xmin and xmax indices should never be the same
        ASSERT(best.miny != best.maxy);

        ASSERT(best.minx <= best.maxy); // our vertices should be located around the convex hull xmin->ymax->xmax->ymin
        ASSERT(best.maxy <= best.maxx);
        ASSERT(best.maxx <= best.miny || best.minx == best.miny);
        ASSERT(best.miny <= best.minx + convexHull.size());

        ASSERT(best.minx <= convexHull.size()); // all of the indices should be in the convex hull
        ASSERT(best.maxx <= convexHull.size());
        ASSERT(best.miny <= convexHull.size());
        ASSERT(best.maxy <= convexHull.size());

        ASSERT(best.minx == 0); // we expect minx to be the first vertex in the convex hull

                                // Helper to calculate the rotation if we move from the given vertex to the next vertex in the convex hull
        auto getDeltaVectorForIndex = [&](UINT32 vert)
        {
            // return the delta between the given vertex and the subsequent vertex, so we can determine the angle our bounding box
            // would have to rotate to be parallel with this edge
            auto start = convexHull[vert % convexHull.size()].first;
            auto next = convexHull[(vert + 1) % convexHull.size()].first;

            ASSERT(start.x != next.x || start.y != next.y);

            return XMFLOAT2({ next.x - start.x, next.y - start.y });
        };

        // once we have the extreme vertices, we slowly rotate our coordinate system and adjust them
        // we rotate in such a way that only one extreme vertex changes at a time
        float angle = 0;
        RotatedBoundingBox current = best;

        BoundingOrientedBox bestBoxInPlaneSpace;
        bestBoxInPlaneSpace.Center = { (maxv.x + minv.x) / 2, (maxv.y + minv.y) / 2, (zmax + zmin) / 2 };
        bestBoxInPlaneSpace.Extents = { (maxv.x - minv.x) / 2, (maxv.y - minv.y) / 2, (zmax - zmin) / 2 };
        bestBoxInPlaneSpace.Orientation = { 0, 0, 0, 1 };

        if (findTightestBounds)
        {
            RotatedBoundingBox initial = best;

            // The tightest bounding box will share a side with the convex hull.  We start with a candidate bounding box oriented along
            // the x/y axes and iterate through all orientations where the box is aligned with an edge of the convex hull.  The maximum possible rotations
            // we need to consider is convexHull.size(), which would be a rotation of 90 degrees.
            // Each iteration through the loop, we pick the vertex from our extreme vertices that has the smallest incremental rotation along its outgoing edge.
            // A neat trick is that the other extreme vertices remain extreme in the new rotated orientation.
            while (angle <= XM_PIDIV2 + ROTATING_CALIPERS_EPSILON &&
                current.minx <= initial.maxy &&
                current.maxy <= initial.maxx &&
                current.maxx <= initial.miny &&
                current.miny <= convexHull.size())
            {
                const auto vectForXmin = getDeltaVectorForIndex(current.minx);
                const auto vectForXmax = getDeltaVectorForIndex(current.maxx);
                const auto vectForYmin = getDeltaVectorForIndex(current.miny);
                const auto vectForYmax = getDeltaVectorForIndex(current.maxy);

                UINT32* boundIndices[4] = { &current.minx, &current.maxx, &current.miny, &current.maxy };
                float angles[4] = {
                    atan2(vectForXmin.x, vectForXmin.y),
                    atan2(-vectForXmax.x, -vectForXmax.y),
                    atan2(vectForYmin.y, -vectForYmin.x),
                    atan2(-vectForYmax.y, vectForYmax.x) };

                int index = 0;
                float minAngle = XM_PI * 4 + angle;
                for (int i = 0; i < 4; ++i)
                {
                    if (angles[i] > -ROTATING_CALIPERS_EPSILON && angles[i] < 0)
                    {
                        // the vector between vertices are horizontal/vertical, so angle is close to 0, treat it as zero
                        // this can only occur with a rounding error
                        angles[i] = 0;
                    }
                    else if (angles[i] < 0)
                    {
                        angles[i] += XM_PI * 2;
                    }

                    if (angles[i] < minAngle)
                    {
                        minAngle = angles[i];
                        index = i;
                    }
                }

                *(boundIndices[index]) = ((*(boundIndices[index])) + 1);

                ASSERT(current.minx <= current.maxy); // we should remain ordering of vertices xmin->ymax->xmax->ymin as we rotate
                ASSERT(current.maxy <= current.maxx);
                ASSERT(current.maxx <= current.miny || best.minx == best.miny);
                ASSERT(current.miny <= current.minx + convexHull.size());

                ASSERT(current.minx != current.maxx); // and we shouldn't ever have min and max indices equal
                ASSERT(current.miny != current.maxy);


                // now update our box:
                angle = minAngle;
                current.angle = minAngle;
                if (angle < XM_PIDIV2 + ROTATING_CALIPERS_EPSILON)
                {
                    XMVECTOR vertsInRotatedPlaneSpace[4];
                    const XMMATRIX rotationTransform = XMMatrixRotationZ(angle);
                    for (int i = 0; i < 4; ++i)
                    {
                        vertsInRotatedPlaneSpace[i] = XMVector3TransformCoord(XMLoadFloat2(&convexHull[(*(boundIndices[i])) % convexHull.size()].first), rotationTransform);
                    }

                    BoundingOrientedBox xmBoundsInPlaneSpace;
                    xmBoundsInPlaneSpace.Center = { XMVectorGetX(vertsInRotatedPlaneSpace[0] + vertsInRotatedPlaneSpace[1]) / 2, XMVectorGetY(vertsInRotatedPlaneSpace[2] + vertsInRotatedPlaneSpace[3]) / 2, (zmax + zmin) / 2 };
                    xmBoundsInPlaneSpace.Extents = { XMVectorGetX(vertsInRotatedPlaneSpace[1] - vertsInRotatedPlaneSpace[0]) / 2, XMVectorGetY(vertsInRotatedPlaneSpace[3] - vertsInRotatedPlaneSpace[2]) / 2, (zmax - zmin) / 2 };
                    xmBoundsInPlaneSpace.Orientation = { 0, 0, 0, 1 };
                    xmBoundsInPlaneSpace.Transform(xmBoundsInPlaneSpace, XMMatrixTranspose(rotationTransform)); // rotate back to plane space from rotated plane space

                    const XMFLOAT2 size = { xmBoundsInPlaneSpace.Extents.x * 2, xmBoundsInPlaneSpace.Extents.y * 2 };
                    current.area = size.x * size.y;
                    current.minwidth = min(size.x, size.y);
                    if (current.area < best.area || (current.area == best.area && current.minwidth < best.minwidth))
                    {
                        best = current;
                        bestBoxInPlaneSpace = xmBoundsInPlaneSpace;
                    }
                }
            }
        }

        return bestBoxInPlaneSpace;
    }
bool MathHelper::CompareVector2WithEpsilon(const XMFLOAT2& lhs, const XMFLOAT2& rhs)
{
	return XMVector3NearEqual(XMLoadFloat2(&lhs), XMLoadFloat2(&rhs), XMLoadFloat2(&vector2Epsilon)) == TRUE;
}
//--------------------------------------------------------------------------------------
// 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;
}
Example #22
0
XMVECTOR Float2::ToSIMD() const
{
    return XMLoadFloat2(reinterpret_cast<const XMFLOAT2*>(this));
}
Example #23
0
        void MovementManagerServer::Update(double p_dt)
        {
            // Some debug bools just to test various effects. We'll have these read some other way later
            bool iceEffect = false;
            bool fireEffect = false;

            const size_t length = EntityHandler::GetInstance().GetLastEntityIndex();
            int mask = (int)ComponentType::Movement | (int)ComponentType::CharacterController;
            for(size_t i = 0; i < length; i++)
            {
                if(EntityHandler::GetInstance().HasComponents(i, mask))
                {
                    /// 1 Get comp
                    MovementComponent* movementComp = EntityHandler::GetInstance().GetComponentFromStorage<MovementComponent>(i);

                    /// 2 Clamp speed
                    // Clamp down XZ movement to maximum movement speed (we don't mess with y due to jump/gravity)
                    XMVECTOR movementXZVec = XMLoadFloat2(&XMFLOAT2(movementComp->movement.x, movementComp->movement.z));
                    movementXZVec = XMVector2Normalize(movementXZVec) * movementComp->speed * p_dt;
                    // movementXZVec = XMVector2ClampLength(movementXZVec, 0, 0.8f);
                    // Store it back
                    XMFLOAT2 movementXZ;
                    XMStoreFloat2(&movementXZ, movementXZVec);
                    movementComp->movement.x = movementXZ.x;
                    movementComp->movement.z = movementXZ.y;

                    /// 3 Move controller
                    // Perform move
                    bool hitGround = m_sharedContext.GetPhysicsModule().GetCharacterControlManager().MoveController(i, movementComp->movement, p_dt);
                    if(hitGround)
                    {
                        EntityHandler::GetInstance().GetComponentFromStorage<GravityComponent>(i)->travelSpeed = 0;
                        if(EntityHandler::GetInstance().HasComponents(i, (int)ComponentType::Jump)) // temporary fix
                        {
                            EntityHandler::GetInstance().GetComponentFromStorage<JumpComponent>(i)->active = false;
                        }
                    }

                    /// 4 Fix speed for next iteration
                    // If we're sliding around, only reduce speed, don't entierly reset it
                    if(iceEffect)
                    {
                        float iceSlowdownFactor = 0.99f * (1 - p_dt);
                        movementComp->movement.x *= iceSlowdownFactor;
                        movementComp->movement.z *= iceSlowdownFactor;
                    }

                    // If we're not running on fire (or ice) we can stop
                    else if(!fireEffect)
                    {
                        movementComp->movement = XMFLOAT3(0, 0, 0);
                    }

                    // Always reset y movement. Again, we don't mess with y
                    movementComp->movement.y = 0;


                    // RigidBodyComponent* rigidBody = EntityHandler::GetInstance().GetComponentFromStorage<RigidBodyComponent>(i);
                    // XMFLOAT3 currentVelocity = m_sharedContext.GetPhysicsModule().GetRigidBodyManager().GetBodyVelocity(rigidBody->p_bodyID);
                    // XMVECTOR forward = XMLoadFloat3(&movement->direction);
                    // XMVECTOR up = XMLoadFloat3(&XMFLOAT3(0, 1, 0));
                    // XMVECTOR right = XMVector3Cross(up, forward);
                    // right *= movement->rightAcceleration;
                    // forward *= movement->forwardAcceleration;
                    // XMVECTOR moveForce = right + forward;
                    // XMVECTOR currentVel = XMLoadFloat3(&currentVelocity);
                    //// moveForce -= (XMVector3Length(currentVel)/movement->maxSpeed) * moveForce ;
                    // XMFLOAT3 force;
                    // XMStoreFloat3(&force, moveForce);


                    // m_sharedContext.GetPhysicsModule().GetRigidBodyManager().AddForceToBody(rigidBody->p_bodyID, force);
                }
            }
        }
Example #24
0
//--------------------------------------------------------------------------------------
// Processes an inbox message that the manoeuvre received.
// Param1: A pointer to the message to process.
//--------------------------------------------------------------------------------------
void GuardedFlagCapture::ProcessMessage(Message* pMessage)
{
	switch(pMessage->GetType())
	{
	case FlagDroppedMessageType:
	{
		FlagDroppedMessage* pMsg = reinterpret_cast<FlagDroppedMessage*>(pMessage);
		if(pMsg->GetData().m_flagOwner != GetTeamAI()->GetTeam())
		{
			// The flag was dropped, the manoeuvre failed
			SetFailed(true);
		}
		break;
	}
	case ScoreUpdateMessageType:
	{
		ScoreUpdateMessage* pMsg = reinterpret_cast<ScoreUpdateMessage*>(pMessage);
		if(pMsg->GetData().m_team == GetTeamAI()->GetTeam())
		{
			// The flag was captured -> the manoeuvre succeeded
			SetSucceeded(true);
		}
		break;
	}
	case EntityKilledMessageType:
	{
		EntityKilledMessage* pMsg = reinterpret_cast<EntityKilledMessage*>(pMessage);
		if(IsParticipant(pMsg->GetData().m_id) && pMsg->GetData().m_team == GetTeamAI()->GetTeam())
		{
			// Participants that get killed, drop out of the manoeuvre
			m_pTeamAI->ReleaseEntityFromManoeuvre(pMsg->GetData().m_id);
		}
		break;
	}
	case AttackedByEnemyMessageType:
	{
		AttackedByEnemyMessage* pMsg = reinterpret_cast<AttackedByEnemyMessage*>(pMessage);

		if(pMsg->GetData().m_entityId == m_flagCarrierId)
		{
			// The flag carrier is being attacked, protect him.

			// Get the attack direction
			XMFLOAT2 viewDirection(0.0f, 0.0f);
			XMStoreFloat2(&viewDirection, XMLoadFloat2(&pMsg->GetData().m_attackPosition) - XMLoadFloat2(&GetParticipant(pMsg->GetData().m_entityId)->GetPosition()));

			// Send all protectors to the position of the attacker to protect the carrier
			for(std::vector<Entity*>::iterator it = m_participants.begin(); it != m_participants.end(); ++it)
			{
				if((*it)->GetId() != m_flagCarrierId)
				{
					// Change the movement target in the orders for the entities
					reinterpret_cast<MoveOrder*>(m_activeOrders[(*it)->GetId()])->SetTargetPosition(pMsg->GetData().m_attackPosition);
				}
			}

		}

		break;
	}
	case UpdateOrderStateMessageType:
	{
	// Cancel old order, Send Follow-Up Orders, finish manoeuvre etc
	UpdateOrderStateMessage* pMsg = reinterpret_cast<UpdateOrderStateMessage*>(pMessage);
	if(IsParticipant(pMsg->GetData().m_entityId))
	{
		if(pMsg->GetData().m_orderState == SucceededOrderState)
		{
			// Let the entity wait for the next movement update (switch to defend?)
		}else if(pMsg->GetData().m_orderState == FailedOrderState)
		{
			m_pTeamAI->ReleaseEntityFromManoeuvre(pMsg->GetData().m_entityId);
		}
	}
	break;
	}
	default:
		TeamManoeuvre::ProcessMessage(pMessage);
	}
}
Example #25
0
		operator XMVECTOR () const
		{
			return XMLoadFloat2(this);
		}
Example #26
0
	void RenderingGame::init() {
		// input
		if (FAILED(DirectInput8Create(m_instance, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID*)&m_input, nullptr))) {
			throw GameException("DirectInput8Create() failed.");
		}

		m_keyboard = new Keyboard(*this, m_input);
		m_components.push_back(m_keyboard);
		m_services.add_service(Keyboard::TypeIdClass(), m_keyboard);

		m_mouse = new Mouse(*this, m_input);
		m_components.push_back(m_mouse);
		m_services.add_service(Mouse::TypeIdClass(), m_mouse);

		// render
		m_render_state_helper = new RenderStateHelper(*this);
		auto* position = new RenderTarget(*this, true, true, DXGI_FORMAT_R32G32B32A32_FLOAT);
		auto* normal = new RenderTarget(*this, true, false, DXGI_FORMAT_R32G32B32A32_FLOAT);
		auto* albedo_specular = new RenderTarget(*this, true, false);
		auto* color = new RenderTarget(*this, true, false);
		auto* color_down = new RenderTarget(*this, true, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4);
		auto* gaussian_blur_h = new RenderTarget(*this, true, false);
		auto* gaussian_blur_v = new RenderTarget(*this, true, false);
		m_render_targets.push_back(position);
		m_render_targets.push_back(normal);
		m_render_targets.push_back(albedo_specular);
		m_render_targets.push_back(color);
		m_render_targets.push_back(color_down);
		m_render_targets.push_back(gaussian_blur_h);
		m_render_targets.push_back(gaussian_blur_v);
		m_render_targets_raw = new ID3D11RenderTargetView*[m_render_targets.size()];
		for (UINT i = 0; i < m_render_targets.size(); i++) {
			m_render_targets_raw[i] = m_render_targets[i]->render_target();
		}

		// camera
		m_camera = new CameraFirstPerson(*this);
		m_components.push_back(m_camera);

		// scene
		m_components.push_back(new EarthDemo(*this, *m_camera, L"content\\textures\\Earth.dds"));

		// light
		m_sun = new LightDirectional(*this);
		m_components.push_back(m_sun);
		m_point_light = new LightPoint(*this);
		m_components.push_back(m_point_light);
		m_point_light->set_color(1.0f, 0, 0, 1.0f);
		m_point_light->As<LightPoint>()->set_attenuation(1.0f, 0.04f, 0.002f);
		m_point_light->As<LightPoint>()->set_position(0, 10.0f, -40.0f);

		// projectors
		/*m_projector = new Camera(*this);
		m_components.push_back(m_projector);*/

		// stencil
		SetCurrentDirectory(Utility::ExecutableDirectory().c_str());
		m_stencil_effect = new Effect(*this);
		m_stencil_effect->load(L"content\\effects\\deferred_stencil.cso");
		m_stencil_material = new MaterialDeferredStencil();
		m_stencil_material->init(m_stencil_effect);

		// point light volume
		m_light_effect = new Effect(*this);
		m_light_effect->load(L"content\\effects\\deferred_p_light.cso");
		m_light_material = new MaterialDeferredPLight();
		m_light_material->init(m_light_effect);
		m_light_material->As<MaterialDeferredPLight>()->
			ScreenResolution() << XMLoadFloat2(&XMFLOAT2(m_screen_width, m_screen_height));

		m_model = new Model(*this, "content\\models\\Sphere.obj", true);
		Mesh* mesh = m_model->meshes().at(0);
		m_sphere = new Geometry(*this, *mesh);
		m_components.push_back(m_sphere);

		// quad
		m_quad_effect = new Effect(*this);
		m_quad_effect->load(L"content\\effects\\deferred_d_light.cso");
		m_quad_material = new MaterialDeferredDLight();
		m_quad_material->init(m_quad_effect);
		m_quad_material->As<MaterialDeferredDLight>()->
			ScreenResolution() << XMLoadFloat2(&XMFLOAT2(m_screen_width, m_screen_height));

		m_quad = new FullScreenQuad(*this);
		m_components.push_back(m_quad);

		// test
		m_test_effect = new Effect(*this);
		m_test_effect->load(L"content\\effects\\basic.cso");
		m_test_material = new MaterialBasic();
		m_test_material->init(m_test_effect);
		m_test_material->set_curr_technique(1);

		// down-sampling
		m_down_sampling_effect = new Effect(*this);
		m_down_sampling_effect->load(L"content\\effects\\down_sampling.cso");
		m_down_sampling_material = new MaterialDownSampling(4);
		m_down_sampling_material->init(m_down_sampling_effect);

		// gaussian blur
		m_blur_effect = new Effect(*this);
		m_blur_effect->load(L"content\\effects\\gaussian_blur.cso");
		m_blur_material = new MaterialGaussianBlur(1.5f);
		m_blur_material->init(m_blur_effect);

		// dof
		m_dof_effect = new Effect(*this);
		m_dof_effect->load(L"content\\effects\\depth_of_field.cso");
		m_dof_material = new MaterialDoF(m_camera->As<CameraFirstPerson>());
		m_dof_material->init(m_dof_effect);

		// init each component
		Game::init();

		// after init
		m_camera->set_position(0, 0, 20.0f);
		//m_projector->set_position(m_point_light->As<LightPoint>()->positionv());

	}
Example #27
0
float VectorMath::Magnitude(const Vec2* vec)
{
	XMVECTOR xmVec = XMLoadFloat2((_XMFLOAT2*) vec);
	return XMVector2Length(xmVec).m128_f32[0];
}