Thread overview
Vector math
Apr 14, 2004
billy_zelsnack
Apr 14, 2004
Ben Hinkle
Apr 14, 2004
billy_zelsnack
Apr 15, 2004
billy_zelsnack
Apr 15, 2004
billy_zelsnack
Apr 14, 2004
Alix Pexton
Apr 14, 2004
John Reimer
April 14, 2004
What is considered the best way to layout and manipulate vectors?

(I prefer manipulating with functions rather than operator overloads)

The first thing I tried was using a static array, but the compiler won't let me return a static array from a function..

float[3] add(float[3] vA,float[3] vB) //nope, can't do this

I then tried using a struct like I do in c++.

struct float3
{
float[3] _value;

float opIndex(int i)
{
return _value[i];
}

int opIndex(int i,float value)
{
_value[i]=value;
return i;
}
}

float3 add(float3 vA,float3 vB) //-- yes, this works

The problem is it is really convienient to have a constructor in there and the compiler doesn't like me doing that. A constructor lets you do cool stuff like..

float3 value=add(float3(0,0,0),float3(1,1,1));

Instead of..

float3 posA;
posA.set(0,0,0);
float3 posB;
posB.set(1,1,1);
float3 value=add(posA,posB);

Is there a way to make a constructor work with a struct? I guess I could use a helper function like..

float3 float3_make(float x,float y,float z) //but it is not as nice

Also. Are structs always passed by value to functions? In c++ my vector add function would look something like this..

float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

or even worse..

float3 localToWorld(const float16& mA,const float3& vA);

Is there a way to tell the compiler to pass something by reference, but not allow modification of the variable?



April 14, 2004
On Wed, 14 Apr 2004 07:31:37 +0000 (UTC), billy_zelsnack
<billy_zelsnack_member@pathlink.com> wrote:

>What is considered the best way to layout and manipulate vectors?
>
>(I prefer manipulating with functions rather than operator overloads)
>
>The first thing I tried was using a static array, but the compiler won't let me return a static array from a function..
>
>float[3] add(float[3] vA,float[3] vB) //nope, can't do this
>
>I then tried using a struct like I do in c++.
>
>struct float3
>{
>float[3] _value;
>
>float opIndex(int i)
>{
>return _value[i];
>}
>
>int opIndex(int i,float value)
>{
>_value[i]=value;
>return i;
>}
>}
>
>float3 add(float3 vA,float3 vB) //-- yes, this works
>
>The problem is it is really convienient to have a constructor in there and the compiler doesn't like me doing that. A constructor lets you do cool stuff like..
>
>float3 value=add(float3(0,0,0),float3(1,1,1));
>
>Instead of..
>
>float3 posA;
>posA.set(0,0,0);
>float3 posB;
>posB.set(1,1,1);
>float3 value=add(posA,posB);
>
>Is there a way to make a constructor work with a struct?

I can't remember who first discovered it but a static opCall works:

static float3 opCall(float x, float y, float z)
{
  float3 v;
  v.set(x,y,z);
  return v;
}

> I guess I could use a helper function like..
>
>float3 float3_make(float x,float y,float z) //but it is not as nice
>
>Also. Are structs always passed by value to functions? In c++ my vector add function would look something like this..
>
>float3 add(const float3& vA,const float3& vB)
>{
>return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
>}
>
>or even worse..
>
>float3 localToWorld(const float16& mA,const float3& vA);
>
>Is there a way to tell the compiler to pass something by reference, but not allow modification of the variable?

nope. 'inout' or 'out' will pass by reference but 'const' is reserved for compile-time constants.
April 14, 2004
In article <e8tp70d62quvt8c4132o0ilcade5hbjo7q@4ax.com>, Ben Hinkle says...
>
>On Wed, 14 Apr 2004 07:31:37 +0000 (UTC), billy_zelsnack
><billy_zelsnack_member@pathlink.com> wrote:
>
>>What is considered the best way to layout and manipulate vectors?
>>
>>(I prefer manipulating with functions rather than operator overloads)
>>
>>The first thing I tried was using a static array, but the compiler won't let me return a static array from a function..
>>
>>float[3] add(float[3] vA,float[3] vB) //nope, can't do this
>>
>>I then tried using a struct like I do in c++.
>>
>>struct float3
>>{
>>float[3] _value;
>>
>>float opIndex(int i)
>>{
>>return _value[i];
>>}
>>
>>int opIndex(int i,float value)
>>{
>>_value[i]=value;
>>return i;
>>}
>>}
>>
>>float3 add(float3 vA,float3 vB) //-- yes, this works
>>
>>The problem is it is really convienient to have a constructor in there and the compiler doesn't like me doing that. A constructor lets you do cool stuff like..
>>
>>float3 value=add(float3(0,0,0),float3(1,1,1));
>>
>>Instead of..
>>
>>float3 posA;
>>posA.set(0,0,0);
>>float3 posB;
>>posB.set(1,1,1);
>>float3 value=add(posA,posB);
>>
>>Is there a way to make a constructor work with a struct?
>
>I can't remember who first discovered it but a static opCall works:
>
>static float3 opCall(float x, float y, float z)
>{
>  float3 v;
>  v.set(x,y,z);
>  return v;
>}
>
>> I guess I could use a helper function like..
>>
>>float3 float3_make(float x,float y,float z) //but it is not as nice
>>
>>Also. Are structs always passed by value to functions? In c++ my vector add function would look something like this..
>>
>>float3 add(const float3& vA,const float3& vB)
>>{
>>return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
>>}
>>
>>or even worse..
>>
>>float3 localToWorld(const float16& mA,const float3& vA);
>>
>>Is there a way to tell the compiler to pass something by reference, but not allow modification of the variable?
>
>nope. 'inout' or 'out' will pass by reference but 'const' is reserved for compile-time constants.


April 14, 2004
billy_zelsnack wrote:

8<-- snip -->8

>Is there a way to tell the compiler to pass something by reference, but not
>allow modification of the variable?
>
>
>
>  
>
You could try using DBC, adding a 'in' block to your function that creates a copy of the argument you want to preserve, and an 'out' block that throws an assert if the value has changed. Some thing like this untested example...

void someFunc(inout int noChange)
in{
 int checkNoChange = noChange;
}
out{
assert(checkNoChange == noChange);
}
body{
...
}

Of course the asserts will be stripped from a release build, but by then the code should have been tested, and you should know that it works as desired...

Alix...

-- 
           Alix Pexton
Webmaster - http://www.theDjournal.com

           Alix@theDjournal.com
April 14, 2004
billy_zelsnack wrote:
> What is considered the best way to layout and manipulate vectors?
> 
> (I prefer manipulating with functions rather than operator overloads)
> 
<snip>

Dig has some nifty vector types (vec2,vec3,vec4).  You might like to look at what it does even though it does implement operator overloads.

Most recent version (unDig):

http://badmama.com.au/~anderson/JA's_D_Page.html

Have a peek in .\dig\net\BurtonRadons\dig\common\math.d

Later,

John
April 15, 2004
In article <c5j16t$t97$1@digitaldaemon.com>, billy_zelsnack says...
>
>In article <e8tp70d62quvt8c4132o0ilcade5hbjo7q@4ax.com>, Ben Hinkle says...
>>
>>On Wed, 14 Apr 2004 07:31:37 +0000 (UTC), billy_zelsnack
>><billy_zelsnack_member@pathlink.com> wrote:
>>
>>>What is considered the best way to layout and manipulate vectors?
>>>
>>>(I prefer manipulating with functions rather than operator overloads)
>>>
>>>The first thing I tried was using a static array, but the compiler won't let me return a static array from a function..
>>>
>>>float[3] add(float[3] vA,float[3] vB) //nope, can't do this
>>>
>>>I then tried using a struct like I do in c++.
>>>
>>>struct float3
>>>{
>>>float[3] _value;
>>>
>>>float opIndex(int i)
>>>{
>>>return _value[i];
>>>}
>>>
>>>int opIndex(int i,float value)
>>>{
>>>_value[i]=value;
>>>return i;
>>>}
>>>}
>>>
>>>float3 add(float3 vA,float3 vB) //-- yes, this works
>>>
>>>The problem is it is really convienient to have a constructor in there and the compiler doesn't like me doing that. A constructor lets you do cool stuff like..
>>>
>>>float3 value=add(float3(0,0,0),float3(1,1,1));
>>>
>>>Instead of..
>>>
>>>float3 posA;
>>>posA.set(0,0,0);
>>>float3 posB;
>>>posB.set(1,1,1);
>>>float3 value=add(posA,posB);
>>>
>>>Is there a way to make a constructor work with a struct?
>>
>>I can't remember who first discovered it but a static opCall works:
>>
>>static float3 opCall(float x, float y, float z)
>>{
>>  float3 v;
>>  v.set(x,y,z);
>>  return v;
>>}
>>
>>> I guess I could use a helper function like..
>>>
>>>float3 float3_make(float x,float y,float z) //but it is not as nice
>>>
>>>Also. Are structs always passed by value to functions? In c++ my vector add function would look something like this..
>>>
>>>float3 add(const float3& vA,const float3& vB)
>>>{
>>>return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
>>>}
>>>
>>>or even worse..
>>>
>>>float3 localToWorld(const float16& mA,const float3& vA);
>>>
>>>Is there a way to tell the compiler to pass something by reference, but not allow modification of the variable?
>>
>>nope. 'inout' or 'out' will pass by reference but 'const' is reserved for compile-time constants.
>
>


April 15, 2004
What the hell. Where did my post go? Ahh. Let's quickly try again.

I tried timing a couple of variants.

//-- 0.675178 seconds
float3 add0(inout float3 vA,inout float3 vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

//-- 0.813258 seconds
float3 add1(inout float3 vA,inout float3 vB)
{
float [] arA=vA.array;
float [] arB=vB.array;
return float3(arA[0]+arB[0],arA[1]+arB[1],arA[2]+arB[2]);
}

//-- 0.413748 seconds
float3 add2(float[] vA,float[] vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

//-- 0.363559 seconds
float3 add3(float* vA,float* vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

//-- 0.233136 seconds
void add4(float[3] vA,float[3] vB,float[3] result)
{
result[0]=vA[0]+vB[0];
result[1]=vA[1]+vB[1];
result[2]=vA[2]+vB[2];
}

//-- 0.193447 seconds
void opAddAssign(float[3] vA)
{
_value[0]+=vA[0];
_value[1]+=vA[1];
_value[2]+=vA[2];
}

//-- 0.191404 seconds (c++)
inline float3 add(const float3& vA,const float3& vB)
{
return float3(vA[0]+vB[0],vA[1]+vB[1],vA[2]+vB[2]);
}

The whole benchmark is at: http://rafb.net/paste/results/Ulj93024.html

I am going to get more familiar with the language and benchmark again later. Speedy vector math is important to my current project as big chunk of it is a realtime physics simulator ( www.shapemaniac.com/bziotd.php ). I guess I could do some parts in C, but I would rather not.