Archived

This topic is now archived and is closed to further replies.

Vector Swizzling in C++

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

If you intended to correct an error in the post then please contact us.

Recommended Posts

I'm currently reorganizing my vector/matrix library and I was just curious if there is anyway to do vector swizzling, a la the majority of shading languages out there. I want to do something like
vec4d a(1.0, 2.0, 3.0, 4.0);
vec3d b = a.yxz;
Clearly I could enumerate simple functions and return what is being asked for. Here's that code:
vec4d a(1.0, 2.0, 3.0, 4.0);
vec3d b = a.yxz();
Is there any straightforward way to implement the first case? Thanks, TT EDIT - The source boxes are huge! [edited by - TThirion on March 21, 2004 9:14:57 PM]

Share this post


Link to post
Share on other sites
No, C++ syntax does not allow overriding member access like that. You can make each of the swizzles members that return something swizzled, and initialize them all to point to your vector on construction, if you want. That would be hideously expensive, adding a "this" pointer per swizzle you support.

Best is to use the functions.

Share this post


Link to post
Share on other sites
By far, the most straightforward way is the functions, you could also perhaps think of some other ways using operator overloading and strings, but again, you said straightforward, so the functions are the best way.

Share this post


Link to post
Share on other sites
The only reason I created this post was because a long time ago (a
year, plus) I saw someone who did exactly what I want using
template metaprogramming techniques. Has anyone seen anything
like that?

TT

Share this post


Link to post
Share on other sites
edit : put in source marker

try this:

(it can be expanded to create a temporary dummy object to support lvalue swizzles too)

#include "stdafx.h"
#include <iostream>

using namespace std;

#define xyzw GetSwizzle<0,1,2,3>()
#define yzwx GetSwizzle<1,2,3,0>()
#define zwxy GetSwizzle<2,3,0,1>()
#define wxyz GetSwizzle<3,0,1,2>()
//etc..

#define wzyx GetSwizzle<3,2,1,0>()


class vector4
{
float tab[4];
public:
vector4(float x, float y, float z, float w)
{
tab[0] = x;
tab[1] = y;
tab[2] = z;
tab[3] = w;
}
float & operator[](int index)
{
return tab[index];
}
template<int a,int b, int c, int d>
vector4 GetSwizzle()
{
return vector4(tab<A href='http://, tab[b], tab[c], tab[d]);

}
};

int main(int argc, char* argv[])
{
vector4 vi(4,5,6,7);

//vector4 v = vi.GetSwizzle<3,2,1,0>();

vector4 v = vi.wzyx;
cout << v[0] << ',' << v[1] << ',' << v[2] << ',' << v[3] << endl;
char cc;
cin >> cc;
return 0;
}


[edited by - janos on March 22, 2004 6:01:48 AM]

[edited by - janos on March 22, 2004 6:10:52 AM]

Share this post


Link to post
Share on other sites
Thanks for the idea, Janos. That would work great but what happens
if the user wants to define a variable with the name "x" or "xxyx"?

That would certainly fail and give strange errors.

Is there anyway to avoid the defines?

Thanks,
TT

Share this post


Link to post
Share on other sites
you could have an empty object, that has an operator Vector() in, and be in your Vector class, named xxxx, returning the vectors x,x,x,x items, and same for all others..

now how can an empty class access it''s "daddy"?.. that, i guess, needs some asm:D or other stack-hack :D

else, tons of functions can do it:D




If that''s not the help you''re after then you''re going to have to explain the problem better than what you have. - joanusdmentia

davepermen.net

Share this post


Link to post
Share on other sites
the included object would work fine, I agree if it could just be empty.
Otherwise, you''ll have to bear with notations like:
xyzw(v)
or
v.xyzw()
or, if you want to use the defines
v._xyzw
, using the underscore to avoid name clashes.

To make error messages more explicit, you could try to give a name to the swizzle function that tells what the error is.

Share this post


Link to post
Share on other sites