if i have
struct vec3
{
float x;
float y;
float z;
};
how could i do something like
vec3 a;
vec3 b;
b = a.xy; ?
if i have
struct vec3
{
float x;
float y;
float z;
};
how could i do something like
vec3 a;
vec3 b;
b = a.xy; ?
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.
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.
#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;
}
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.
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; }
(add other operators)
};
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.
//! 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)