# make c++ more like glsl

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

## Recommended Posts

if i have

struct vec3
{
float x;
float y;
float z;
};


how could i do something like

vec3 a;

vec3 b;

b = a.xy; ?

##### Share on other sites

Here's a long discussion on that topic with a couple of possible solutions.

http://www.cplusplus.com/forum/general/72912/

But the bottom line is that there is no good way to do it in C++ without extending the language.

##### Share on other sites

Naively, something like this:

vec3 xy(){
vec3 v;
v.x=x;
v.y=y;
v.z=0; // or whatever you want for a non-asked-for swizzle
return v;
}


It'd be kind of tedious, but you could write out whatever swizzles you want as functions like that - there are only so many permutations for a 3D vector, and with a decent constructor defined, they would be one-liners.

In C#, this would probably be something I'd do with some read-only properties, which is effectively the same thing, just lets you do it without writing parentheses.

##### Share on other sites
The library linked above provides an exact match so the following is but a humble exercise.

The prior discussions in the thread below also seemed to avoid the "naive" approach so I thought I'd give it the 'ol newbie try...

http://www.gamedev.net/topic/650045-vector-swizzling-in-c/

#include
#include
#include
#include

enum axis {
x = 0, y = 1, z = 2
};

template< typename T >
class vec3
{
public:
vec3(){}
vec3(T in_x, T in_y, T in_z)
{
_values[0] = in_x;
_values[1] = in_y;
_values[2] = in_z;
}
vec3(const vec3 &in)
{
*this = in;
}
vec3& operator=(const vec3 &in)
{
if(this != &in) {
_values[0] = in._values[0];
_values[1] = in._values[1];
_values[2] = in._values[2];
}
return *this;
}
T& operator[](axis in_a);
const T& operator[](axis in_a) const;
constexpr vec3< T > operator()(axis in_01, axis in_1, axis in_2) const;
private:
T _values[3] {
std::numeric_limits::quiet_NaN(),
std::numeric_limits::quiet_NaN(),
std::numeric_limits::quiet_NaN()
};
};

template< typename T >
T& vec3< T >::operator[](axis in_a)
{
return _values[static_cast< size_t >(in_a)];
}

template< typename T >
const T& vec3< T >::operator[](axis in_a) const
{
return _values[static_cast< size_t >(in_a)];
}

template< typename T >
constexpr vec3< T > vec3< T >::operator()(axis in_0, axis in_1, axis in_2) const
{
return vec3< T >(
_values[in_0],
_values[in_1],
_values[in_2]
);
}

template< typename T >
void vec3_print(const char *in_name, const vec3< T > &in_v)
{
std::cout << in_name << "{"
<< in_v[x] << ", "
<< in_v[y]<< ", "
<< in_v[z]<< " }\n"
;
}

int main()
{
typedef vec3< float > vec3f;

vec3f v1{1.1f, 1.2f, 1.3f};
vec3f v2{2.1f, 2.2f, 2.3f};
vec3f v3;

vec3_print("v1", v1);
vec3_print("v2", v2);
vec3_print("v3", v3);

v1[x] = v2[y];
v2[z] = v1[y];

std::cout << "> v1[x] = v2[y]; v2[z] = v1[y];\n";

vec3_print("v1", v1);
vec3_print("v2", v2);

v3[y] = v2[z];

std::cout << "> v3[y] = v2[z];\n";

vec3_print("v3", v3);

vec3_print("> v3(y, z, x)\n", v3(y, z, x));

vec3_print("v3", v3);

v3 = v2(z, y, x);

std::cout << "> v3 = v2(z, y, x);\n";

vec3_print("v3", v3);
vec3_print("v2", v2);

return 0;
}


##### Share on other sites

Naively, something like this:

vec3 xy(){
vec3 v;
v.x=x;
v.y=y;
v.z=0; // or whatever you want for a non-asked-for swizzle
return v;
}


It'd be kind of tedious, but you could write out whatever swizzles you want as functions like that - there are only so many permutations for a 3D vector, and with a decent constructor defined, they would be one-liners.

In C#, this would probably be something I'd do with some read-only properties, which is effectively the same thing, just lets you do it without writing parentheses.

Honestly the function variety makes things eight thousand percent easier. That's what I did in my code, rather than play the ridiculous games required to get native-looking swizzles.

##### Share on other sites

I'm assuming here that storage is not an issue, IE, you will not be storing this vector directly into a file.

class Ref2Floats
{
Ref2Floats(float& r0, float& r1) { ref0= r0; ref1 = r1; }
float& ref0;
float& ref1;
Ref2Floats& operator=(Ref2Floats& a, const Ref2Floats& b) { a.ref0 = b.ref0;  a.ref1 = b.ref1; return a; }

};

in vector class:
class Vec3
{
float x;
float y;
float z;
Ref2Floats xy;
Ref2Floats xz;
Ref2Floats yz;

}
in vector constructor:
Vec3::Vec3(): xy(x, y), xz(x, z), yz(y, z)
{

Didn't actually test, but should work, but will increase memory use of each Vec3 instance. I've done stuff along the same vein to simplify some situations.

EDIT: Sorry, just realized I misunderstood what you were trying to do. I'll leave the code because you might also find it useful.

Edited by nfries88

##### Share on other sites

https://github.com/gwiazdorrr/CxxSwizzle

Good god that is some voodoo right there... I pity the compiler.

Comment from the code:

//! Array needs to be like a steak - the rawest possible
//! (Wow - I managed to WTF myself upon reading the above after a week or two)

Edited by Nypyren

1. 1
2. 2
khawk
19
3. 3
Rutin
19
4. 4
5. 5
A4L
11

• 9
• 12
• 16
• 26
• 10
• ### Forum Statistics

• Total Topics
633771
• Total Posts
3013761
×