-1

I'd like to now if it's possible, and eventually how it's possible, to implement a class in a special way so that you can create a vector of that class and, after having filled it, iterate through the classes attributes without iterating the vector.

This is an example:

class Vertex3f
{
    public:
        union
        {
            float vec[3];
            struct
            {
                float x, y, z;
            };
        };

    public:
        Vertex3f();
        ~Vertex3f();

    ...
}

Then create a std::vector of this class, fill it and access all the class' instances attributes:

Vertex3f v1, v2;
v1.x = 10.0f;
v1.y = 0.0f;
v1.z = 5.0f;
v2.x = 8.0f;
v2.y = -5.0f;
v2.z = 3.0f;

// Create and fill the vector
std::vector<Vertex3f> vec;
vec.push_back(v1);
vec.push_back(v2);

// Get all the vertices data in one go
// This is the tricky part I'm not sure it can be done
size_t size = vec.size() * (sizeof(float) * 3);
float* vertices = new float[size];
memcpy(vertices, &vec[0].x, size);

I now that the Bullet Physics library does something like this for performance reason and I'd like to do the same, but I don't understand how.

zeb
  • 1,105
  • 2
  • 9
  • 32
  • 1
    There is a slight problem with your code: There is no guarantee that `float vec[3]` and your structure will be of the same size. If the compilers native padding for a system is 64-bit then the structure will be double the size of the array. – Some programmer dude May 15 '16 at 16:22
  • 2
    You probably should check out what C++ states about [POD types](http://en.cppreference.com/w/cpp/concept/PODType) and [memory alignment](http://stackoverflow.com/q/5435841/3344612) – Teivaz May 15 '16 at 16:24
  • That's exactly what I was concerned about. `float vec[3]` isn't of the same size of my class because the class will also hold member functions and other attributes – zeb May 15 '16 at 16:28
  • 1
    As well as the links from telvaz, you will need to understand strict aliasing rules. This is all very scary stuff - how badly do you need to do this? – Martin Bonner supports Monica May 15 '16 at 16:31
  • Well, I'd like to use it in the graphic engine I'm writing and I's use it to, for example, copy mesh vertices to OpenGL buffer. As I'm doing now, I create a temporary `float` array where I copy all the vertices data and the use this to pass the data to the OpenGL buffer – zeb May 15 '16 at 16:34

1 Answers1

0

If you just want the functionality I have another implementation that may work for you.

You can create your array of floats and then give your vec3 class a pointer to the x-position of the appropriate point in that vector.

Something like:

class vec3
{
public:
    vec3(float* valN)
    {
        val = valN;
    }

    float x()
    {
        return *val;
    }
private:
    float* val;
};

int size = 3;
float* fArr = (float*)malloc(sizeof(float)*size);

fArr[0] = 8;
fArr[1] = 9;
fArr[2] = 10;

std::vector<vec3> points;
vec3 p(&fArr[0]);

points.push_back(p);

float out = points[0].x();

out should end up as 8.0 here.

Nathan J
  • 195
  • 10
  • Yes, I could do this way but thinking about using a `std::vector` for `fArr` would make this unuseful due to `std::vector` moving thing around in memory when you add/remove elements, and I'd like to keep the possibility to add/remove vertices to my mesh. Also, this way I have to have always `float` array as support, even if I just need a simple `vec3` to make some calculations – zeb May 16 '16 at 06:59
  • If you allocate memory beforehand to the vector with vec.resize() you can avoid the issue with moving memory around. It would also be pretty easy to overload the vec3 constructor to allow it to create its own array. – Nathan J May 16 '16 at 19:29
  • Yes, this seems feasible. I'll give it a try – zeb May 17 '16 at 09:28