GLM の vec 系の変数で GLSL の .xyz みたいな指定方法(swizzle)をできるようにする

試した環境

本題

vector.xyzwのようなドット演算子の後に指定したい要素を順に並べる表現方法を swizzle または Swizzling と呼ぶそうです。 この swizzle 表現は GLSL ではデフォルトでできるようになっていますが、 GLM ではglm/glm.hppを include するだけでは利用できません。
GLM の vec 系の変数で swizzle 表現を利用するためには、#include <glm/glm.hpp>の前に#define GLM_FORCE_SWIZZLEを記述します。

#include <iostream>

#define GLM_FORCE_SWIZZLE
#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>

int main(int argc, char* argv[]) {
    glm::vec4 v4(1.f, 2.f, 3.f, 4.f);
    glm::vec3 v3 = v4.xyz;
    std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 2.000000, 3.000000)
    v3.yz = v4.xw;
    std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 1.000000, 4.000000)
}

ただし、glm の文字列化関数glm::to_string関数に直接の引数にすることは出来ませんでした。

//std::cout << glm::to_string(v4.xyz) << std::endl; // NG
std::cout << glm::to_string(glm::vec3(v4.xyz)) << std::endl; // OK

#define GLM_SWIZZLEは非推奨

ちなみに、#include <glm/glm.hpp> の前に#define GLM_SWIZZLE を記述することでも swizzle 表現が利用できるのですが、 GLM_FORCE_SWIZZLE が推奨されています。

https://github.com/g-truc/glm#deprecation-1

Removed GLM_SWIZZLE, use GLM_FORCE_SWIZZLE instead

おまけ:glm/gtx/vec_swizzle.hppを使う方法

GLSL の swizzle 表現とは違うのですが、 glm/gtx/vec_swizzle.hppを include することで、glm::xyz() などが使えるようになります。 こちらはglm::to_string関数の引数にできますが、左辺値に使用しての値の書き換えはできません。

#include <iostream>

#include <glm/glm.hpp>
#include <glm/gtx/string_cast.hpp>
#include <glm/gtx/vec_swizzle.hpp>

int main(int argc, char* argv[]) {
    glm::vec4 v4(1.f, 2.f, 3.f, 4.f);
    glm::vec3 v3 = glm::xyz(v4);
    std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 2.000000, 3.000000)
    glm::yz(v3) = glm::xw(v4);
    std::cout << glm::to_string(v3) << std::endl; // vec3(1.000000, 2.000000, 3.000000)
                                                  // vec3(1.000000, 1.000000, 4.000000) ではない!
    std::cout << glm::to_string(glm::xyz(v4)) << std::endl; // vec3(1.000000, 2.000000, 3.000000)
}

参考

https://github.com/g-truc/glm/blob/master/manual.md#section2_14

https://www.khronos.org/opengl/wiki/Data_Type_(GLSL)#Swizzling