Public Group

Vector cast

This topic is 1091 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I missed the "For example I have meshes that use a Vertex with only the position and some meshes that have position, texture and normals components." part of the post. That sounds like it should use composition, rather than inheritance.

In that case, I probably *would* use pointer-to-members.

Each vertex would be a different type. If a model uses positions, texcoords, and normals, that vertex should be a different type (without inheritance) from one that just uses positions. While they serve similar purposes, and have similar names, they are holding different data.

struct Vertex_Pos
{
Position pos;
};

//No inheritance.
struct Vertex_PosTexNorm
{
Position pos;
TexCoords texCoords;
Normal norm;
};


I'd then go like this:

//No templates needed thus far.
BoundingBox CreateCollisionAABB(const XVector<Position> &positions)
{
BoundingBox boundingBox;

for(const Position &position : positions)
{
boundingBox.ExtendToContain(position);
}

return boundingBox;
}


And then write this template function to transform the data into a uniform format:

template<typename VertexType>
XVector<Position> GetPositionsFromVertices(const XVector<VertexType> &vertices, Position VertexType::*ptrToMember)
{
XVector<Position> positions(vertices.size());

size_t index = 0;
for(const VertexType &vertex : vertices)
{
positions[index++] = (vertex.*ptrToMember);
}

return positions;
}

NOTE: Because positions are small, and references take time, I just copy the positions. Intuition says it's probably faster (cache misses and etc... from following the references for only a few bytes). Not that AABB's are called every frame anyway, but in this case the simpler solution (without reference_wrapper) is probably the superior one.

It's used like this:

XVector<Vertex_Pos> verticesOfOneType;
XVector<Position> somePositions = GetPositionsFromVertices(verticesOfOneType,  &Vertex_Pos::pos);

XVector<Vertex_PosTexNorm> verticesOfAnotherType;
XVector<Position> morePositions = GetPositionsFromVertices(verticesOfAnotherType,  &Vertex_PosTexNorm::pos);

//Then we can just use them (either one) in your function:
BoundingBox boxFromModelA = CreateCollisionAABB(somePositions);
BoundingBox boxFromModelB = CreateCollisionAABB(morePositions);


[Edit:] And here's the more general-purpose version to add to my own code library.

Edited by Servant of the Lord

Share on other sites
Note that there's a very good chance that you're going to _want_ value semantics for your vector types and never pass around references to them. Some popular compilers will end up disabling many of their vector optimizations, e.g. the reference may result in the compiling copying the vecotrs into and out of memory instead of keeping them in SIMD registers even with full optimization.

If you're only targeting the latest versions of compilers for the PC, this may not be an issue for you, but I'd double check.

I generally _strongly_ suggest that you model your math libraries after DirectX Math. It is very optimal with all compilers and all major hardware platforms supported by Microsoft (x86/SSE for Windows and XBone, ARM/NEON for Windows RT and CE, and PPC/AltiVec for Xbox360). At least some versions of the library were explicitly designed to be easily usable on non-Microsoft platforms, btw, so you might even be able to just use DirectX Math even if you target Android/iOS/OSX/Linux.

The library isn't always the easiest or most obvious to use, but the extra complexity is worth it when we're talking about the performance of your code math library.

1. 1
Rutin
24
2. 2
3. 3
4. 4
JoeJ
18
5. 5

• 14
• 19
• 11
• 11
• 9
• Forum Statistics

• Total Topics
631761
• Total Posts
3002179
×