Each axis gets assigned a positioning policy using an enum:
Code: Select all
enum PositioningPolicy3D { none, min, max, centered, weighted };
min = (minimum is used as delta)
max = (maximum used as delta)
centered = (maximum + minimum) / 2 as delta
weighted = sum / count as delta (coordinate values are summed).
The structure used in determining the offset is as follows:
Code: Select all
struct PositioningFlags3D
{
int xMin : 1;
int xMax : 1;
int xWeighted : 1;
int yMin : 1;
int yMax : 1;
int yWeighted : 1;
int zMin : 1;
int zMax;
int zWeighted : 1;
inline PositioningFlags3D(PositioningPolicy3D xPolicy, PositioningPolicy3D yPolicy, PositioningPolicy3D zPolicy);
};
Code: Select all
switch (xPolicy)
{
case PositioningPolicy3D::min:
xMin = 1;
xMax = 0;
xWeighted = 0;
break;
case PositioningPolicy3D::max:
xMin = 0;
xMax = 1;
xWeighted = 0;
break;
case PositioningPolicy3D::centered:
xMin = 1;
xMax = 1;
xWeighted = 0;
break;
case PositioningPolicy3D::weighted:
xMin = 0;
xMax = 0;
xWeighted = 1;
break;
default:
xMin = 0;
xMax = 0;
xWeighted = 0;
}
In my own code I use the centering policy as default.
Code: Select all
PositioningFlags3D alignmentPolicy = PositioningFlags3D(PositioningPolicy3D::centered, PositioningPolicy3D::centered, PositioningPolicy3D::centered)
Code: Select all
resposition(vector3df* vertexArray, const int vertexCount, PositioningFlags3D alignmentPolicy)
{
vector3df* vertex = vertexArray;
float xMin = FLT_MAX;
float yMin = FLT_MAX;
float zMin = FLT_MAX;
float xMax = FLT_MIN;
float yMax = FLT_MIN;
float zMax = FLT_MIN;
int count;
float xSum = 0.0f;
float ySum = 0.0f;
float zSum = 0.0f;
// get positioning data
for (int i = 0; i < vertexCount; ++i)
{
if (vertex->X > xMax)
xMax = vertex->X;
if (vertex->X < xMin)
xMin = vertex->X;
if (vertex->Y > yMax)
yMax = vertex->Y;
if (vertex->Y < yMin)
yMin = vertex->Y;
if (vertex->Z > zMax)
zMax = vertex->Z;
if (vertex->Z < zMin)
zMin = vertex->Z;
xSum += vertex->X;
ySum += vertex->Y;
zSum += vertex->Z;
vertex += sizeof(vector3df);
}
// determine offset based on the alignment policy and positioning data
vector3df offset;
if (alignmentPolicy.xWeighted)
offset.X = xSum / (float)vertexCount;
else
{
if (alignmentPolicy.xMax & alignmentPolicy.xMin)
offset.X = (xMax + xMin) / 2.0f;
else if (alignmentPolicy.xMax)
offset.X = xMax;
else if (alignmentPolicy.xMin)
offset.X = xMin;
else
offset.X = 0.0f;
}
if (alignmentPolicy.yWeighted)
offset.Y = ySum / (float)vertexCount;
else
{
if (alignmentPolicy.yMax & alignmentPolicy.yMin)
offset.Y = (yMax + yMin) / 2.0f;
else if (alignmentPolicy.xMax)
offset.Y = yMax;
else if (alignmentPolicy.xMin)
offset.Y = yMin;
else
offset.Y = 0.0f;
}
if (alignmentPolicy.zWeighted)
offset.Z = zSum / (float)vertexCount;
else
{
if (alignmentPolicy.zMax & alignmentPolicy.zMin)
offset.Z = (zMax + zMin) / 2.0f;
else if (alignmentPolicy.xMax)
offset.Z = zMax;
else if (alignmentPolicy.xMin)
offset.Z = zMin;
else
offset.Z = 0.0f;
}
// reposition vertices
for (int i = 0; i < vertexCount; ++i)
vertexArray[i] -= offset;
}
EDIT/NOTE: In my code, the vertex array and the way those vertices are used depends on the object being created. I basically wrote this code as part of a generic set of 3D shapes. My algorithm first calculates one of each vertex in the mesh before creating the mesh vertices since points will be duplicated in order to allow for multiple textures to be used on each face of certain meshes. That is why I am sending an array of coordinates rather than an array of vertices.