public void UpdateOOBfromOOBs()
{
if (m_partsList.Count == 1)
{
SceneObjectPart part = m_partsList.First();
m_grpOOBsize = part.OOBsize;
m_grpOOBoffset = part.OOBoffset;
m_grpBSphereRadiusSQ = part.BSphereRadiusSQ;
m_ValidgrpOOB = true;
return;
}
Vector3 minScale = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 maxScale = new Vector3(float.MinValue, float.MinValue, float.MinValue);
foreach (SceneObjectPart part in m_partsList)
{
Vector3 partscale = part.OOBsize; // (oobsize == vector with box vertice with all coords positive)
Vector3 partoffset = part.OOBoffset;
// not assuming root is at index 0
Vector3 deltam;
Vector3 deltaM;
if (part.ParentID == 0) // root is in local frame of reference, partscale.? are positive, no rotations
{
//2 vertices in the right extrem sides:
deltam = partoffset - partscale;
deltaM = partoffset + partscale;
// if root is always at index 0 this can be just assigns
if (deltam.X < minScale.X)
minScale.X = deltam.X;
if (deltam.Y < minScale.Y)
minScale.Y = deltam.Y;
if (deltam.Z < minScale.Z)
minScale.Z = deltam.Z;
if (deltaM.X > maxScale.X)
maxScale.X = deltaM.X;
if (deltaM.Y > maxScale.Y)
maxScale.Y = deltaM.Y;
if (deltaM.Z > maxScale.Z)
maxScale.Z = deltaM.Z;
}
else // prims are in their local frame of reference
{
// bring into this frame
Quaternion partrot = part.GetRotationOffset();
partscale *= partrot;
partoffset *= partrot;
partoffset += part.OffsetPosition;
// now just 2 vertices in a diagonal
deltam = partoffset - partscale;
deltaM = partoffset + partscale;
if (deltaM.X > deltam.X) // right vertices order for extrem X
{
if (deltam.X < minScale.X)
minScale.X = deltam.X;
if (deltaM.X > maxScale.X)
maxScale.X = deltaM.X;
}
else // nopes inverse one
{
if (deltaM.X < minScale.X)
minScale.X = deltaM.X;
if (deltam.X > maxScale.X)
maxScale.X = deltam.X;
}
if (deltaM.Y > deltam.Y)
{
if (deltam.Y < minScale.Y)
minScale.Y = deltam.Y;
if (deltaM.Y > maxScale.Y)
maxScale.Y = deltaM.Y;
}
else
{
if (deltaM.Y < minScale.Y)
minScale.Y = deltaM.Y;
if (deltam.Y > maxScale.Y)
maxScale.Y = deltam.Y;
}
if (deltaM.Z > deltam.Z)
{
if (deltam.Z < minScale.Z)
minScale.Z = deltam.Z;
if (deltaM.Z > maxScale.Z)
maxScale.Z = deltaM.Z;
}
else
{
if (deltaM.Z < minScale.Z)
minScale.Z = deltaM.Z;
if (deltam.Z > maxScale.Z)
maxScale.Z = deltam.Z;
}
}
}
// size == the vertice of box with all coords positive
m_grpOOBsize.X = 0.5f*Math.Abs(maxScale.X - minScale.X);
m_grpOOBsize.Y = 0.5f*Math.Abs(maxScale.Y - minScale.Y);
m_grpOOBsize.Z = 0.5f*Math.Abs(maxScale.Z - minScale.Z);
// centroid:
m_grpOOBoffset.X = 0.5f*(maxScale.X + minScale.X);
m_grpOOBoffset.Y = 0.5f*(maxScale.Y + minScale.Y);
m_grpOOBoffset.Z = 0.5f*(maxScale.Z + minScale.Z);
// containing sphere:
m_grpBSphereRadiusSQ = m_grpOOBsize.LengthSquared();
m_ValidgrpOOB = true;
}