# Unity Most efficient way of designing a vector class in 3D

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

## Recommended Posts

Recently I started to use unity3d for my hobby game project and I really liked a Vector3 (and similar) classes (in C#). At the moment at work I am implementing a simple (but for large simulations) SPH solver. What I would like to achieve is a similar Vector3 class in C++ in the means of access to elements both by v.x, v.y, v.z and v[0], v[1], v[2]. In general to obtain this is very simple, but none of the solutions that came to my mind is free of flaws.

Solution 1: using references &x, &y, &z, problem: such class has three additional variables which occupy the memory. In the case of large simulation it is problematic:

template <class T>
class Vector3
{
public:
T &x,&y,&z;
T v[3];

Vector3(): x(v[0]), y(v[1]), z(v[2])
{
v[0]=0; v[1]=1;  v[2]=2;
}

T& operator[](int i)
{
return v[i];
}
};

The access is very elegant:

v[i]

as well as

v.x, v.y and v.z

And this is what I woluld like to obtain - this elegant access. However the additional memory overhead is unacceptable.

Solution 2: using class fileds x,y,z and access operator with if statement: problem performance of [] operator

template <class T>
class Vector3
{
public:
T x,y,z;

Vector3(): x(0), y(1), z(2)
{ }

T& operator[](int i)
{
if (i==0) return x;
else if (i==1) return y;
else if (i==2) reurn z;
else
{
//throw access error
}
}
};

This solution is elegant as well, but the operator [] will be very slow.

Solution 3: Using the class functions x(), y(), z()

template <class T>
class Vector3
{
public:
T v[3];

Vector3()
{
v[0]=0; v[1]=1; v[2]=2;
}

T& operator[](int i)
{
return v[i];
}

T& x() { return v[0]; }
T& y() { return v[1]; }
T& z() { return v[2]; }
};

This solution is ideal in means of efficiency and memory overhead, but, does not allow elegant access to members, requires for example v.x() instead of v.x.

The question is: is there a way to obtain this elegant access with no efficiency and memory loss?

##### Share on other sites

Yeah union with anonymous struct has got to be the easiest way to do it,

template <class T>
struct Vector3
{
union
{
T v[3];
struct { T x; T y; T z; };
};
};

Edited by Syntac_

##### Share on other sites

Couldn't you just use the array access? Will you later want to add r, g, b, a and s, t or u, v?

namespace vectors {

enum accessors {
x,
y,
z,
w
};

template <typename T>
struct Vector4
{
T d[4];
T& operator[](size_t index);
const T& operator[](size_t index) const;
};

}



##### Share on other sites

How does that code allow me to write "v.x"?

##### Share on other sites

Sorry I forgot to include the operator to be able access like v[0].

template <class T>
struct Vector3
{
union
{
T v[3];
struct { T x;  T y; T z; };
};

T& operator[](int i)
{
// guard against accessing out-of-bounds
return v[i];
}
};

Vector3<float> v;
v.x = 3.0f;

std::cout << v[0]; // prints 3


##### Share on other sites

How does that code allow me to write "v.x"?

It does not really need to and avoids weird workarounds/UB for a questionable convenience.

But you can easily do:

using namespace vectors;

float bar(const Vector4<float>& v) {
return v[x];
}


Edited by wintertime

##### Share on other sites

Re-iterating what Hodgman wrote, these arrays of floats are functional but not ideal.

If you are looking for performance most systems will use built-in SIMD structures for the data that are specific to the system you are developing for.  That can mean the intrinsic type __m128 variables in the x86 family, or the intrinsic float32x4_t variables in ARM chips.

Transferring to and from these packed, special-purpose registers is not efficient. If possible leave your data packed in the more efficient formats.

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 14
• 30
• 13
• 11
• 11
• ### Forum Statistics

• Total Topics
631781
• Total Posts
3002319
×