//--------------------------------------------------------------------------------------
// 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
XMFLOAT4 Weapon::GetWeaponOffsetRotation()
{
	XMVECTOR quat = XMQuaternionIdentity();

	XMFLOAT3 direction = GetFloat3Value( Direction );

	XMFLOAT3 aimPos;
	XMFLOAT3 pipePos;

	if (GetJointPosition("PipeAim", aimPos) && GetJointPosition("Pipe", pipePos))
	{
		//handPos.y = pipePos.y;
		XMVECTOR directionV	= XMLoadFloat3(&direction);
		XMVECTOR handPosV	= XMLoadFloat3(&aimPos);
		XMVECTOR pipePosV	= XMLoadFloat3(&pipePos);

		XMVECTOR offsetDirectionV = pipePosV - handPosV;

		XMVECTOR angleV = XMVector3AngleBetweenVectors(directionV, offsetDirectionV);
		float angle;
		XMStoreFloat(&angle, angleV);

		if (angle != 0)
		{
			XMVECTOR axis = XMVector3Cross(directionV, offsetDirectionV);
			quat = XMQuaternionRotationAxis(axis, angle);
		}
	}

	XMFLOAT4 result;
	XMStoreFloat4(&result, quat);

	return result;
}
Beispiel #3
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 #5
0
	float DistanceEstimated(const XMVECTOR& v1, const XMVECTOR& v2)
	{
		XMVECTOR& vectorSub = XMVectorSubtract(v1, v2);
		XMVECTOR& length = XMVector3LengthEst(vectorSub);

		float Distance = 0.0f;
		XMStoreFloat(&Distance, length);
		return Distance;
	}
Beispiel #6
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;
}
Beispiel #7
0
float LineConnection::Distance(const XMVECTOR& vector1,const XMVECTOR& vector2)
{
    XMVECTOR vectorSub = XMVectorSubtract(vector1,vector2);
    XMVECTOR length = XMVector3Length(vectorSub);

    float distance = 0.0f;
    XMStoreFloat(&distance,length);
    return distance;
}
Beispiel #8
0
bool Collider::IsColliding(GameObject* other) {
	auto otherTransform = other->transform;
	auto v1 = XMLoadFloat3(&transform->position);
	auto v2 = XMLoadFloat3(&otherTransform->position);
	auto vectorDiff = XMVectorSubtract(v1, v2);
	auto distVector = XMVector3LengthSq(vectorDiff);
	float dist;
	XMStoreFloat(&dist, distVector);
	float radSq = transform->scale.x * transform->scale.x*.56 + otherTransform->scale.x * otherTransform->scale.x*.56;
	return dist <= radSq;
}
Beispiel #9
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;

}
//--------------------------------------------------------------------------------------
// 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;
}
Beispiel #11
0
DWORD WINAPI ThreadedRaytracing (void* ptr)
{
	ThreadData_t& data = *reinterpret_cast<ThreadData_t*> (ptr);
	ThreadData_t copy = data;
	data.read = true;
	XMVECTOR curPos = *copy.currentPos;
	float distance = 0.0f;
	for (uint64_t i = 0; i < copy.size; i++)
	{
		XMVECTOR d = XMVector3Length (XMVectorSet (copy.data[i].r,
												   copy.data[i].g,
												   copy.data[i].b,
												   0.0f) - curPos);
		XMStoreFloat (&distance, d);
		if (distance < copy.range &&
			(distance < copy.data[i].a ||
			 copy.data[i].a < -0.5f))
			 copy.data[i].a = distance;
	}
	data.done++;
	return 0;
}
	vector KinectMeshAnimator::GetSkeletonOrientation(NUI_SKELETON_DATA& skeleton, int index1, int index2)
	{
		vector orientation;
		Joint* joint1 = bindings[index1];
		Joint* joint2 = bindings[index2];
		if (!joint1 || !joint2) return XMVectorSet(0.0, 1.0, 0.0, 0.0);

		// INVERT Z
		orientation = XMVectorSet(	skeleton.SkeletonPositions[index2].x - skeleton.SkeletonPositions[index1].x,
									skeleton.SkeletonPositions[index2].y - skeleton.SkeletonPositions[index1].y,
									skeleton.SkeletonPositions[index1].z - skeleton.SkeletonPositions[index2].z,
									0.0);

		vector bindOrientation = bindOrientations[index1];
		vector axis = XMVector3Normalize(XMVector3Cross(bindOrientation, orientation));

		if (XMVector3Equal(axis, XMVectorZero()))
			return XMVectorSet(0.0, 1.0, 0.0, 0.0);

		float angle;
		XMStoreFloat(&angle, XMVector3Dot(bindOrientation, orientation));
		angle = acos(angle);
		return XMQuaternionRotationAxis(axis, angle);
	}
Beispiel #13
0
void Unit::Update(float DeltaTime, Terrain* TerrainInstance)
{
	if ( IsAlive() && gHealth.first <= 0 )
	{
		SetWeaponState( Hold );
		DropWeapon();
		Kill();
		StopAllAnimations();
		PlayAnimation("Death");
		PlayAnimationAfter("Death", "Dead");
		SoundManager::GetInstance()->Play( gDeathSound, SFX, false );

		if (!PlayingAnimation("Death"))
		{
			SetState( Dead );
			return;
		}		
	}

	GameObject::Update(DeltaTime, TerrainInstance);

	if ( GetState() == Dying )
		return;

	XMVECTOR vel = XMLoadFloat3(&GetFloat3Value( Velocity ));
	if (!XMVector3Equal(vel, XMVectorZero()))
	{
		XMVECTOR dir  = XMLoadFloat3(&GetFloat3Value( Direction ));
		XMVECTOR angleV = XMVector3AngleBetweenVectors(dir, vel);

		float angle;
		XMStoreFloat(&angle, angleV);

		XMVECTOR crossV = XMVector3Cross(dir, vel);

		if (XMVectorGetY(crossV) < 0)
			angle *= -1;

		//cout << 180 * angle / PI << endl;

		if (fabs(angle) <= PI * 0.25f)
			gMoveDirection = Forward;

		else if (fabs(angle) > PI * 0.75f)
			gMoveDirection = Back;

		else if (angle < 0)
			gMoveDirection = Left;

		else if (angle > 0)
			gMoveDirection = Right;

		XMVECTOR L = XMVector3Length(vel);
		float speed;
		XMStoreFloat(&speed, L);
		speed /= UnitsPerMeter;

		switch (gMoveDirection)
		{
		case Forward:
			if (speed > 1.05f * gWalkSpeed)
			{
				SetMoveState(Run);	
				SetAnimationSpeed("Run", speed);
				SetAnimationSpeed(GetAnimation("UpperRun"), speed);							
			}
			else
			{
				SetMoveState(Walk);
				SetAnimationSpeed("Walk", speed);
			}
			break;
		case Back:
			SetMoveState(Walk);
			SetAnimationSpeed("Back", speed);
			break;
		case Right:
			SetMoveState(Walk);
			SetAnimationSpeed("SideStepRight", speed);
			break;
		case Left:
			SetMoveState(Walk);
			SetAnimationSpeed("SideStepLeft", speed);
			break;
		}
	}
	else
	{
		gMoveDirection = None;

		if (!Crouching())
			SetMoveState(Stand);
	}

	if ( gCurrentWeapon )
	{
		XMFLOAT3 handPos;
		XMFLOAT4 handRot;
		
		XMVECTOR pos = XMLoadFloat3(&GetFloat3Value( Position ));
		XMVECTOR dir = XMLoadFloat3(&GetFloat3Value( Direction ));
		XMVECTOR lv = XMVector3Length(dir);

		bool gotJointPos = false;
		bool gotJointRot = false;
		if (m_ModelInstance)
		{
			gotJointPos = GetJointPosition("RightHand", handPos);
			gotJointRot = GetJointRotation("RightHand", handRot);
		}

		if (!gotJointPos)
		{
			pos += dir * (GetRadius() - 10);
			XMStoreFloat3(&handPos, pos);
		}
		
		if (gCurrentWeapon->NeedReload())
		{
			ReloadWeapon();
		}
		
		//gWeapon->Update(DeltaTime);
		//gWeapon->MoveTo( position );
		gCurrentWeapon->MoveTo( handPos );

		XMFLOAT3 weaponPos;
		if (gCurrentWeapon->GetJointPosition("RightHand", weaponPos))
		{
			XMStoreFloat3(&handPos, XMLoadFloat3(&handPos) + (XMLoadFloat3(&handPos) - XMLoadFloat3(&weaponPos)));
			gCurrentWeapon->MoveTo( handPos );
		}
		
		if (gotJointRot)
		{
			gCurrentWeapon->SetRotation( handRot );
		}
		else
			gCurrentWeapon->SetRotation( GetQuaternation() );
	}
	/*
	else
	{
		LoopAnimation("PistolUpperWalk");
	}
	*/
}
Beispiel #14
0
//-----------------------------------------------------------------------------
// Compute the intersection of a ray (Origin, Direction) with an axis aligned 
// box using the slabs method.
//-----------------------------------------------------------------------------
BOOL GLibIntersectRayAxisAlignedBox( FXMVECTOR Origin, FXMVECTOR Direction, const XNA::AxisAlignedBox* pVolume, FLOAT* pDist )
{
	XMASSERT( pVolume );
	XMASSERT( pDist );
	//XMASSERT( XMVector3IsUnit( Direction ) );

	static const XMVECTOR Epsilon =
	{
		1e-20f, 1e-20f, 1e-20f, 1e-20f
	};
	static const XMVECTOR FltMin =
	{
		-FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX
	};
	static const XMVECTOR FltMax =
	{
		FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX
	};

	// Load the box.
	XMVECTOR Center = XMLoadFloat3( &pVolume->Center );
	XMVECTOR Extents = XMLoadFloat3( &pVolume->Extents );

	// Adjust ray origin to be relative to center of the box.
	XMVECTOR TOrigin = Center - Origin;

	// Compute the dot product againt each axis of the box.
	// Since the axii are (1,0,0), (0,1,0), (0,0,1) no computation is necessary.
	XMVECTOR AxisDotOrigin = TOrigin;
	XMVECTOR AxisDotDirection = Direction;

	// if (fabs(AxisDotDirection) <= Epsilon) the ray is nearly parallel to the slab.
	XMVECTOR IsParallel = XMVectorLessOrEqual( XMVectorAbs( AxisDotDirection ), Epsilon );

	// Test against all three axii simultaneously.
	XMVECTOR InverseAxisDotDirection = XMVectorReciprocal( AxisDotDirection );
	XMVECTOR t1 = ( AxisDotOrigin - Extents ) * InverseAxisDotDirection;
	XMVECTOR t2 = ( AxisDotOrigin + Extents ) * InverseAxisDotDirection;

	// Compute the max of min(t1,t2) and the min of max(t1,t2) ensuring we don't
	// use the results from any directions parallel to the slab.
	XMVECTOR t_min = XMVectorSelect( XMVectorMin( t1, t2 ), FltMin, IsParallel );
	XMVECTOR t_max = XMVectorSelect( XMVectorMax( t1, t2 ), FltMax, IsParallel );

	// t_min.x = maximum( t_min.x, t_min.y, t_min.z );
	// t_max.x = minimum( t_max.x, t_max.y, t_max.z );
	t_min = XMVectorMax( t_min, XMVectorSplatY( t_min ) );  // x = max(x,y)
	t_min = XMVectorMax( t_min, XMVectorSplatZ( t_min ) );  // x = max(max(x,y),z)
	t_max = XMVectorMin( t_max, XMVectorSplatY( t_max ) );  // x = min(x,y)
	t_max = XMVectorMin( t_max, XMVectorSplatZ( t_max ) );  // x = min(min(x,y),z)

	// if ( t_min > t_max ) return FALSE;
	XMVECTOR NoIntersection = XMVectorGreater( XMVectorSplatX( t_min ), XMVectorSplatX( t_max ) );

	// if ( t_max < 0.0f ) return FALSE;
	NoIntersection = XMVectorOrInt( NoIntersection, XMVectorLess( XMVectorSplatX( t_max ), XMVectorZero() ) );

	// if (IsParallel && (-Extents > AxisDotOrigin || Extents < AxisDotOrigin)) return FALSE;
	XMVECTOR ParallelOverlap = XMVectorInBounds( AxisDotOrigin, Extents );
	NoIntersection = XMVectorOrInt( NoIntersection, XMVectorAndCInt( IsParallel, ParallelOverlap ) );

	if(!GLibXMVector3AnyTrue( NoIntersection ) )
	{
		// Store the x-component to *pDist
		XMStoreFloat( pDist, t_min );
		return TRUE;
	}

	return FALSE;
}
Beispiel #15
0
//-----------------------------------------------------------------------------
// Compute the intersection of a ray (Origin, Direction) with a triangle 
// (V0, V1, V2).  Return TRUE if there is an intersection and also set *pDist 
// to the distance along the ray to the intersection.
// 
// The algorithm is based on Moller, Tomas and Trumbore, "Fast, Minimum Storage 
// Ray-Triangle Intersection", Journal of Graphics Tools, vol. 2, no. 1, 
// pp 21-28, 1997.
//-----------------------------------------------------------------------------
BOOL GLibIntersectRayTriangle( FXMVECTOR Origin, FXMVECTOR Direction, FXMVECTOR V0, CXMVECTOR V1, CXMVECTOR V2,
							  FLOAT* pDist )
{
	XMASSERT( pDist );
	//XMASSERT( XMVector3IsUnit( Direction ) );

	static const XMVECTOR Epsilon =
	{
		1e-20f, 1e-20f, 1e-20f, 1e-20f
	};

	XMVECTOR Zero = XMVectorZero();

	XMVECTOR e1 = V1 - V0;
	XMVECTOR e2 = V2 - V0;

	// p = Direction ^ e2;
	XMVECTOR p = XMVector3Cross( Direction, e2 );

	// det = e1 * p;
	XMVECTOR det = XMVector3Dot( e1, p );

	XMVECTOR u, v, t;

	if( XMVector3GreaterOrEqual( det, Epsilon ) )
	{
		// Determinate is positive (front side of the triangle).
		XMVECTOR s = Origin - V0;

		// u = s * p;
		u = XMVector3Dot( s, p );

		XMVECTOR NoIntersection = XMVectorLess( u, Zero );
		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorGreater( u, det ) );

		// q = s ^ e1;
		XMVECTOR q = XMVector3Cross( s, e1 );

		// v = Direction * q;
		v = XMVector3Dot( Direction, q );

		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorLess( v, Zero ) );
		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorGreater( u + v, det ) );

		// t = e2 * q;
		t = XMVector3Dot( e2, q );

		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorLess( t, Zero ) );

		if( XMVector4EqualInt( NoIntersection, XMVectorTrueInt() ) )
			return FALSE;
	}
	else if( XMVector3LessOrEqual( det, -Epsilon ) )
	{
		// Determinate is negative (back side of the triangle).
		XMVECTOR s = Origin - V0;

		// u = s * p;
		u = XMVector3Dot( s, p );

		XMVECTOR NoIntersection = XMVectorGreater( u, Zero );
		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorLess( u, det ) );

		// q = s ^ e1;
		XMVECTOR q = XMVector3Cross( s, e1 );

		// v = Direction * q;
		v = XMVector3Dot( Direction, q );

		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorGreater( v, Zero ) );
		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorLess( u + v, det ) );

		// t = e2 * q;
		t = XMVector3Dot( e2, q );

		NoIntersection = XMVectorOrInt( NoIntersection, XMVectorGreater( t, Zero ) );

		if ( XMVector4EqualInt( NoIntersection, XMVectorTrueInt() ) )
			return FALSE;
	}
	else
	{
		// Parallel ray.
		return FALSE;
	}

	XMVECTOR inv_det = XMVectorReciprocal( det );

	t *= inv_det;

	// u * inv_det and v * inv_det are the barycentric cooridinates of the intersection.

	// Store the x-component to *pDist
	XMStoreFloat( pDist, t );

	return TRUE;
}
Beispiel #16
0
BSphere ComputeBoundingSphereFromPoints(const XMFLOAT3* points, uint32 numPoints, uint32 stride, BBox *optionalBBoxOut)
{
	BSphere sphere;

	Assert_(numPoints > 0);
	Assert_(points);

	// Find the points with minimum and maximum x, y, and z
	XMVECTOR MinX, MaxX, MinY, MaxY, MinZ, MaxZ;

	MinX = MaxX = MinY = MaxY = MinZ = MaxZ = XMLoadFloat3(points);
	GetBoundCornersFromPoints(points, numPoints, stride, MinX, MaxX, MinY, MaxY, MinZ, MaxZ);

	/*for (uint32 i = 1; i < numPoints; i++)
	{
		XMVECTOR Point = XMLoadFloat3((XMFLOAT3*)((BYTE*)points + i * stride));

		float px = XMVectorGetX(Point);
		float py = XMVectorGetY(Point);
		float pz = XMVectorGetZ(Point);

		if (px < XMVectorGetX(MinX))
			MinX = Point;

		if (px > XMVectorGetX(MaxX))
			MaxX = Point;

		if (py < XMVectorGetY(MinY))
			MinY = Point;

		if (py > XMVectorGetY(MaxY))
			MaxY = Point;

		if (pz < XMVectorGetZ(MinZ))
			MinZ = Point;

		if (pz > XMVectorGetZ(MaxZ))
			MaxZ = Point;
	}*/

	if (optionalBBoxOut != NULL)
	{
		float maxx = XMVectorGetX(MaxX);
		float maxy = XMVectorGetY(MaxY);
		float maxz = XMVectorGetZ(MaxZ);

		float minx = XMVectorGetX(MinX);
		float miny = XMVectorGetY(MinY);
		float minz = XMVectorGetZ(MinZ);

		optionalBBoxOut->Max.x = maxx;
		optionalBBoxOut->Max.y = maxy;
		optionalBBoxOut->Max.z = maxz;

		optionalBBoxOut->Min.x = minx;
		optionalBBoxOut->Min.y = miny;
		optionalBBoxOut->Min.z = minz;
	}

	// Use the min/max pair that are farthest apart to form the initial sphere.
	XMVECTOR DeltaX = MaxX - MinX;
	XMVECTOR DistX = XMVector3Length(DeltaX);

	XMVECTOR DeltaY = MaxY - MinY;
	XMVECTOR DistY = XMVector3Length(DeltaY);

	XMVECTOR DeltaZ = MaxZ - MinZ;
	XMVECTOR DistZ = XMVector3Length(DeltaZ);

	XMVECTOR Center;
	XMVECTOR Radius;

	if (XMVector3Greater(DistX, DistY))
	{
		if (XMVector3Greater(DistX, DistZ))
		{
			// Use min/max x.
			Center = (MaxX + MinX) * 0.5f;
			Radius = DistX * 0.5f;
		}
		else
		{
			// Use min/max z.
			Center = (MaxZ + MinZ) * 0.5f;
			Radius = DistZ * 0.5f;
		}
	}
	else // Y >= X
	{
		if (XMVector3Greater(DistY, DistZ))
		{
			// Use min/max y.
			Center = (MaxY + MinY) * 0.5f;
			Radius = DistY * 0.5f;
		}
		else
		{
			// Use min/max z.
			Center = (MaxZ + MinZ) * 0.5f;
			Radius = DistZ * 0.5f;
		}
	}

	// Add any points not inside the sphere.
	for (uint32 i = 0; i < numPoints; i++)
	{
		XMVECTOR Point = XMLoadFloat3((XMFLOAT3*)((BYTE*)points + i * stride));

		XMVECTOR Delta = Point - Center;

		XMVECTOR Dist = XMVector3Length(Delta);

		if (XMVector3Greater(Dist, Radius))
		{
			// Adjust sphere to include the new point.
			Radius = (Radius + Dist) * 0.5f;
			Center += (XMVectorReplicate(1.0f) - Radius * XMVectorReciprocal(Dist)) * Delta;
		}
	}

	XMStoreFloat3(&sphere.Center, Center);
	XMStoreFloat(&sphere.Radius, Radius);

	return sphere;
}