diff --git a/Common/VertexArray.cpp b/Common/VertexArray.cpp index 4666c18339dde99c85482d42097f4616480546ad..ee86f6e1620f93282b3fc9f5a3e5e4309bcc88c3 100644 --- a/Common/VertexArray.cpp +++ b/Common/VertexArray.cpp @@ -22,14 +22,14 @@ VertexArray::VertexArray(int numVerticesPerElement, int numElements) _colors.reserve(nb * 4); } -void VertexArray::addVertex(float x, float y, float z) +void VertexArray::_addVertex(float x, float y, float z) { _vertices.push_back(x); _vertices.push_back(y); _vertices.push_back(z); } -void VertexArray::addNormal(float nx, float ny, float nz) +void VertexArray::_addNormal(float nx, float ny, float nz) { // storing the normals as bytes hurts rendering performance, but it // significantly reduces the memory footprint @@ -41,30 +41,46 @@ void VertexArray::addNormal(float nx, float ny, float nz) _normals.push_back(cz); } -void VertexArray::addColor(unsigned int col) +void VertexArray::_addColor(unsigned char r, unsigned char g, unsigned char b, + unsigned char a) { - unsigned char r = CTX.UNPACK_RED(col); - unsigned char g = CTX.UNPACK_GREEN(col); - unsigned char b = CTX.UNPACK_BLUE(col); - unsigned char a = CTX.UNPACK_ALPHA(col); _colors.push_back(r); _colors.push_back(g); _colors.push_back(b); _colors.push_back(a); } -void VertexArray::addElement(MElement *ele) +void VertexArray::_addElement(MElement *ele) { if(ele && CTX.pick_elements) _elements.push_back(ele); } void VertexArray::add(double *x, double *y, double *z, SVector3 *n, unsigned int *col, MElement *ele, bool unique, bool boundary) +{ + if(col){ + unsigned char r[100], g[100], b[100], a[100]; + int npe = getNumVerticesPerElement(); + for(int i = 0; i < npe; i++){ + r[i] = CTX.UNPACK_RED(col[i]); + g[i] = CTX.UNPACK_GREEN(col[i]); + b[i] = CTX.UNPACK_BLUE(col[i]); + a[i] = CTX.UNPACK_ALPHA(col[i]); + } + add(x, y, z, n, r, g, b, a, ele, unique, boundary); + } + else + add(x, y, z, n, 0, 0, 0, 0, ele, unique, boundary); +} + +void VertexArray::add(double *x, double *y, double *z, SVector3 *n, unsigned char *r, + unsigned char *g, unsigned char *b, unsigned char *a, + MElement *ele, bool unique, bool boundary) { int npe = getNumVerticesPerElement(); if(boundary && npe == 3){ - ElementData<3> e(x, y, z, n, col, ele); + ElementData<3> e(x, y, z, n, r, g, b, a, ele); ElementDataLessThan<3>::tolerance = CTX.lc * 1.e-12; std::set<ElementData<3>, ElementDataLessThan<3> >::iterator it = _data3.find(e); if(it == _data3.end()) @@ -85,10 +101,10 @@ void VertexArray::add(double *x, double *y, double *z, SVector3 *n, } for(int i = 0; i < npe; i++){ - addVertex(x[i], y[i], z[i]); - if(n) addNormal(n[i].x(), n[i].y(), n[i].z()); - if(col) addColor(col[i]); - addElement(ele); + _addVertex(x[i], y[i], z[i]); + if(n) _addNormal(n[i].x(), n[i].y(), n[i].z()); + if(r && g && b && a) _addColor(r[i], g[i], b[i], a[i]); + _addElement(ele); } } @@ -98,10 +114,10 @@ void VertexArray::finalize() std::set<ElementData<3>, ElementDataLessThan<3> >::iterator it = _data3.begin(); for(; it != _data3.end(); it++){ for(int i = 0; i < 3; i++){ - addVertex(it->x(i), it->y(i), it->z(i)); - addNormal(it->nx(i), it->ny(i), it->nz(i)); - addColor(it->col(i)); - addElement(it->ele()); + _addVertex(it->x(i), it->y(i), it->z(i)); + _addNormal(it->nx(i), it->ny(i), it->nz(i)); + _addColor(it->r(i), it->g(i), it->b(i), it->a(i)); + _addElement(it->ele()); } } _data3.clear(); @@ -160,17 +176,12 @@ void VertexArray::sort(double x, double y, double z) std::vector<AlphaElement> elements; elements.reserve(n); - if(_normals.size()) - for(int i = 0; i < n; i++) - elements.push_back(AlphaElement(&_vertices[3 * npe * i], - &_normals[3 * npe * i], - &_colors[4 * npe * i])); - else - for(int i = 0; i < n; i++) - elements.push_back(AlphaElement(&_vertices[3 * npe * i], - 0, - &_colors[4 * npe * i])); - + for(int i = 0; i < n; i++){ + float *vp = &_vertices[3 * npe * i]; + char *np = _normals.empty() ? 0 : &_normals[3 * npe * i]; + unsigned char *cp = _colors.empty() ? 0 : &_colors[4 * npe * i]; + elements.push_back(AlphaElement(vp, np, cp)); + } std::sort(elements.begin(), elements.end(), AlphaElementLessThan()); std::vector<float> sortedVertices; @@ -182,17 +193,17 @@ void VertexArray::sort(double x, double y, double z) for(int i = 0; i < n; i++){ for(int j = 0; j < npe; j++){ - for(int k = 0; k < 3; k++){ + for(int k = 0; k < 3; k++) sortedVertices.push_back(elements[i].v[3 * j + k]); - if(elements[i].v) + if(elements[i].n) + for(int k = 0; k < 3; k++) sortedNormals.push_back(elements[i].n[3 * j + k]); - } - for(int k = 0; k < 4; k++){ - sortedColors.push_back(elements[i].c[4 * j + k]); - } + if(elements[i].c) + for(int k = 0; k < 4; k++) + sortedColors.push_back(elements[i].c[4 * j + k]); } } - + _vertices = sortedVertices; _normals = sortedNormals; _colors = sortedColors; diff --git a/Common/VertexArray.h b/Common/VertexArray.h index 834ad053fefd6cfca5b40175305ebadf0950c1a8..d294e372bbc19a448e6355ad4ed3ec4b6836adfe 100644 --- a/Common/VertexArray.h +++ b/Common/VertexArray.h @@ -16,11 +16,11 @@ template<int N> class ElementData { private: float _x[N], _y[N], _z[N], _nx[N], _ny[N], _nz[N]; - unsigned int _col[N]; + unsigned char _r[N], _g[N], _b[N], _a[N]; MElement *_ele; public: - ElementData(double *x, double *y, double *z, SVector3 *n, unsigned int *col, - MElement *ele) + ElementData(double *x, double *y, double *z, SVector3 *n, unsigned char *r, + unsigned char *g, unsigned char *b, unsigned char *a, MElement *ele) { for(int i = 0; i < N; i++){ _x[i] = x[i]; @@ -33,21 +33,28 @@ class ElementData { } else _nx[i] = _ny[i] = _nz[i] = 0.; - if(col) - _col[i] = col[i]; + if(r && g && b && a){ + _r[i] = r[i]; + _g[i] = g[i]; + _b[i] = b[i]; + _a[i] = a[i]; + } else - _col[i] = 0; + _r[i] = _g[i] = _b[i] = _a[i] = 0; } _ele = ele; } - float x(int i) const { return _x[i]; } - float y(int i) const { return _y[i]; } - float z(int i) const { return _z[i]; } - float nx(int i) const { return _nx[i]; } - float ny(int i) const { return _ny[i]; } - float nz(int i) const { return _nz[i]; } - unsigned int col(int i) const { return _col[i]; } - MElement *ele() const { return _ele; } + inline float x(int i) const { return _x[i]; } + inline float y(int i) const { return _y[i]; } + inline float z(int i) const { return _z[i]; } + inline float nx(int i) const { return _nx[i]; } + inline float ny(int i) const { return _ny[i]; } + inline float nz(int i) const { return _nz[i]; } + inline unsigned char r(int i) const { return _r[i]; } + inline unsigned char g(int i) const { return _g[i]; } + inline unsigned char b(int i) const { return _b[i]; } + inline unsigned char a(int i) const { return _a[i]; } + inline MElement *ele() const { return _ele; } SPoint3 barycenter() const { SPoint3 p(0., 0., 0.); @@ -85,9 +92,9 @@ class Barycenter { float _x, _y, _z; public: Barycenter(double x, double y, double z) : _x(x), _y(y), _z(z){} - float x() const { return _x; } - float y() const { return _y; } - float z() const { return _z; } + inline float x() const { return _x; } + inline float y() const { return _y; } + inline float z() const { return _z; } void operator+=(const Barycenter &p){ _x += p.x(); _y += p.y(); _z += p.z(); } }; @@ -114,36 +121,40 @@ class VertexArray{ std::vector<MElement*> _elements; std::set<ElementData<3>, ElementDataLessThan<3> > _data3; std::set<Barycenter, BarycenterLessThan> _barycenters; + // add stuff in the arrays + void _addVertex(float x, float y, float z); + void _addNormal(float nx, float ny, float nz); + void _addColor(unsigned char r, unsigned char g, unsigned char b, + unsigned char a); + void _addElement(MElement *ele); public: VertexArray(int numVerticesPerElement, int numElements); ~VertexArray(){} - // returns the number of vertices in the array + // return the number of vertices in the array int getNumVertices() { return _vertices.size() / 3; } - // returns the number of vertices per element + // return the number of vertices per element int getNumVerticesPerElement() { return _numVerticesPerElement; } - // returns the number of element pointers + // return the number of element pointers int getNumElementPointers() { return _elements.size(); } - // returns a pointer to the raw vertex array + // return a pointer to the raw vertex array float *getVertexArray(int i=0){ return &_vertices[i]; } - // returns a pointer to the raw normal array + // return a pointer to the raw normal array char *getNormalArray(int i=0){ return &_normals[i]; } - // returns a pointer to the raw color array + // return a pointer to the raw color array unsigned char *getColorArray(int i=0){ return &_colors[i]; } - // returns a pointer to the raw element array + // return a pointer to the raw element array MElement **getElementPointerArray(int i=0){ return &_elements[i]; } - // adds stuff in the arrays - void addVertex(float x, float y, float z); - void addNormal(float nx, float ny, float nz); - void addColor(unsigned int col); - void addElement(MElement *ele); // add element data in the arrays (if unique is set, only add the // element if another one with the same barycenter is not already // present) - void add(double *x, double *y, double *z, SVector3 *n, unsigned int *col, + void add(double *x, double *y, double *z, SVector3 *n, unsigned int *col, + MElement *ele=0, bool unique=true, bool boundary=false); + void add(double *x, double *y, double *z, SVector3 *n, unsigned char *r=0, + unsigned char *g=0, unsigned char *b=0, unsigned char *a=0, MElement *ele=0, bool unique=true, bool boundary=false); // finalize the arrays void finalize(); - // sorts the arrays with elements back to front wrt the eye position + // sort the arrays with elements back to front wrt the eye position void sort(double x, double y, double z); };