Search code examples
c++glm-math

How do I use GLM Vector Relational Functions?


I'm trying to create an std::set of GLM vectors (glm::vec3 specifically). Since C++ does not know how to perform < operation on the vectors, I must pass in a Compare funciton.

I can write my own by creating a structure like so:

struct compareVec
{
    bool operator() (const glm::vec3& lhs, const glm::vec3& rhs) const
    {
        return lhs.x < rhs.x && lhs.y < rhs.y && lhs.z < rhs.z;
    }
};
std::set< glm::vec3, compareVec > myset;

However, I'm sure that GLM includes their own vector comparison functions.

I found the following resource, but I'm unsure of how to use it: https://glm.g-truc.net/0.9.4/api/a00137.html

How can I pass one of these comparison functions to my set?


Solution

  • Ok, almost there! The glm::lessThan returns a vector type, not a bool. This is why your comparator does not work. You could use glm::all on it to get a bool. From Documentation of glm::all

    bool glm::all ( vecType< bool > const & v )

    Returns true if all components of x are true.

    Template Parameters vecType Boolean vector types.

    If this makes sense for you, you have to decide for yourself, even if I recommend against it as this, as far as I understand, will lead to the following issue:

    Consider:
    lhs = (1,2,3)
    rhs = (0,1,4)
    
    Than:
    
    lhs < rhs ==> false, since lhs.x and lhs.y are larger than the corresponding components of rhs
    rhs < lhs ==> false, since rhs.z component is larger than lhs.z
    

    Since neither vector can be ordered to be less, this implies that they are equal. I doubt this is the behavior you have in mind (I was already warning you about this).

    If you still decide to use it, here is a minimal working example tested on MSVC2010:

    #include <set>
    #include <glm/vec3.hpp>
    #include <glm/detail/func_vector_relational.hpp>
    
    struct compareVec
    {
        bool operator() (const glm::vec3& lhs, const glm::vec3& rhs) const
        {
            return glm::all(glm::lessThan(lhs, rhs));
        }
    };
    
    int main()
    {
    
        std::set<glm::vec3, compareVec> myset;
    
        return 0;
    }
    

    Maybe this helps.