Vector Swizzling in C++

Started by
6 comments, last by TThirion 20 years ago
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]
Advertisement
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.
enum Bool { True, False, FileNotFound };
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.
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
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, tab[c], tab[d]);	<br></font><br>	}<br>};<br><br><font color=blue>int</font> main(<font color=blue>int</font> argc, <font color=blue>char</font>* argv[])<br>{<br>	vector4 vi(4,5,6,7);<br><br>	<font color=gray>//vector4 v = vi.GetSwizzle&lt;3,2,1,0&gt;();<br></font><br>	vector4 v = vi.wzyx;<br>	cout &lt;&lt; v[<font color=purple>0</font>] &lt;&lt; ',' &lt;&lt; v[<font color=purple>1</font>] &lt;&lt; ',' &lt;&lt; v[<font color=purple>2</font>] &lt;&lt; ',' &lt;&lt; v[<font color=purple>3</font>] &lt;&lt; endl;<br>	<font color=blue>char</font> cc;<br>	cin &gt;&gt; cc;<br>	<font color=blue>return</font> 0;<br>}<br></pre><!–ENDSCRIPT–>         <br><br><SPAN CLASS=editedby>[edited by - janos on March 22, 2004 6:01:48 AM]</SPAN>   <br><br><SPAN CLASS=editedby>[edited by - janos on March 22, 2004 6:10:52 AM]</SPAN>
Act of War - EugenSystems/Atari
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
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
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

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

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.
Act of War - EugenSystems/Atari

This topic is closed to new replies.

Advertisement