Ejemplo n.º 1
0
VOID Bound::Merge( const Bound& Other )
{
    Sphere OtherSphere;
    OtherSphere.Center = Other.GetCenter();
    OtherSphere.Radius = Other.GetMaxRadius();

    if( m_Type == Bound::No_Bound )
    {
        SetSphere( OtherSphere );
        return;
    }

    Sphere ThisSphere;
    if( m_Type != Bound::Sphere_Bound )
    {
        // convert this bound into a sphere
        ThisSphere.Center = GetCenter();
        ThisSphere.Radius = GetMaxRadius();
    }
    else
    {
        ThisSphere = GetSphere();
    }

    XMVECTOR vThisCenter = XMLoadFloat3( &ThisSphere.Center );
    XMVECTOR vOtherCenter = XMLoadFloat3( &OtherSphere.Center );
    XMVECTOR vThisToOther = XMVectorSubtract( vOtherCenter, vThisCenter );
    XMVECTOR vDistance = XMVector3LengthEst( vThisToOther );

    FLOAT fCombinedDiameter = XMVectorGetX( vDistance ) + ThisSphere.Radius + OtherSphere.Radius;
    if( fCombinedDiameter <= ( ThisSphere.Radius * 2 ) )
    {
        SetSphere( ThisSphere );
        return;
    }
    if( fCombinedDiameter <= ( OtherSphere.Radius * 2 ) )
    {
        SetSphere( OtherSphere );
        return;
    }

    XMVECTOR vDirectionNorm = XMVector3Normalize( vThisToOther );

    XMVECTOR vRadius = XMVectorSet( ThisSphere.Radius, OtherSphere.Radius, 0, 0 );
    XMVECTOR vThisRadius = XMVectorSplatX( vRadius );
    XMVECTOR vOtherRadius = XMVectorSplatY( vRadius );
    XMVECTOR vCombinedDiameter = vThisRadius + vDistance + vOtherRadius;
    XMVECTOR vMaxDiameter = XMVectorMax( vCombinedDiameter, vThisRadius * 2 );
    vMaxDiameter = XMVectorMax( vMaxDiameter, vOtherRadius * 2 );
    XMVECTOR vMaxRadius = vMaxDiameter * 0.5f;
    ThisSphere.Radius = XMVectorGetX( vMaxRadius );
    vMaxRadius -= vThisRadius;
    XMVECTOR vCombinedCenter = vThisCenter + vMaxRadius * vDirectionNorm;
    XMStoreFloat3( &ThisSphere.Center, vCombinedCenter );
    SetSphere( ThisSphere );
}
Ejemplo n.º 2
0
//----------------------------------------------------------------------------
void Bound::GrowToContain (const Bound& bound)
{
	if (bound.GetRadius() == 0.0f)
	{
		// The node is a dummy node and cannot affect growth.
		return;
	}

	if (GetRadius() == 0.0f)
	{
		mCenter = bound.GetCenter();
		mRadius = bound.GetRadius();
		
		return;
	}

	AVector centerDiff = bound.mCenter - mCenter;
	float lengthSqr = centerDiff.SquaredLength();
	float radiusDiff = bound.mRadius - mRadius;
	float radiusDiffSqr = radiusDiff*radiusDiff;

	if (radiusDiffSqr >= lengthSqr)
	{
		if (radiusDiff >= 0.0f)
		{
			mCenter = bound.mCenter;
			mRadius = bound.mRadius;
		}
		return;
	}

	float length = Mathf::Sqrt(lengthSqr);
	if (length > Mathf::ZERO_TOLERANCE)
	{
		float coeff = (length + radiusDiff)/(2.0f*length);
		mCenter += coeff*centerDiff;
	}

	mRadius = 0.5f*(length + mRadius + bound.mRadius);
}
Ejemplo n.º 3
0
bool OutStream::WriteAggregate (const Bound& datum)
{
    APoint center = datum.GetCenter();
    float radius = datum.GetRadius();
    return WriteAggregate(center) && Write(radius);
}
Ejemplo n.º 4
0
//----------------------------------------------------------------------------
void BoundCtrl::UpdateCtrl()
{
	mCtrlsGroup->SetActiveChild(1);

	int numObjscts = PX2_SELECTION.GetNumObjects();

	if (numObjscts > 0)
	{
		Bound bound;
		int firstBound = true;

		APoint pos;

		for (int i = 0; i < numObjscts; i++)
		{
			Object *obj = PX2_SELECTION.GetObjectAt(i);
			Actor *actor = DynamicCast<Actor>(obj);
			Movable *movable = DynamicCast<Movable>(obj);

			if (movable)
			{
				mCtrlsGroup->SetActiveChild(0);
				pos += movable->WorldTransform.GetTranslate();

				if (0.0f != movable->WorldBound.GetRadius())
				{
					if (firstBound)
					{
						bound = movable->WorldBound;
						firstBound = false;
					}
					else
					{
						bound.GrowToContain(movable->WorldBound);
					}
				}
			}
		}

		pos = pos / (float)numObjscts;

		float radius = bound.GetRadius();
		if (0.0f == radius)
		{
			radius = 1.0f;

			mCtrlsGroup->WorldTransform.SetUniformScale(radius);
			mCtrlsGroup->WorldTransform.SetTranslate(pos);
		}
		else
		{
			mCtrlsGroup->WorldTransform.SetUniformScale(radius);
			mCtrlsGroup->WorldTransform.SetTranslate(bound.GetCenter());
		}
	}
	else
	{
		mCtrlsGroup->SetActiveChild(1);
	}

	mCtrlsGroup->Update(Time::GetTimeInSeconds(), false);
}