Positioning Policy for new nodes
Posted: Thu Nov 20, 2014 9:14 pm
I have written some code that I am willing to offer to the engine when an update is in the works. It allows the use of a positioning policy relative to the parent node to calculate the final coordinates of a new node. I haven't debugged it yet but it is fairly straightforward. Here is the basic idea. (I will change the code if necessary later).
Each axis gets assigned a positioning policy using an enum:
none = relative to 0 (no actual delta)
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:
the inline constructor basically does this for each axis (using the x axis as an example):
In my own code I use the centering policy as default.
finally... the method that repositions the object based on the policy:
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.
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.