Hosting by Solid Eight Studios ,PhotoTangler Collage Maker

This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 3D Platonic Primitive Generators   Submitted by

This is a minimal C++ primitive polygon loader. I use it (and maintain it) for my 3d engine "DexVT", which can be found on my site.

If you like clean, minimal OOP code like I do, then this loader is for you. it manages to stay out of your code as much as possible.

PS. The Vector, Matrix, Transform utility classes are included as a bonus :)

Jerry Chen (Dextre)
http://onlyuser.cjb.net

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Vector.cpp] - (4,856 bytes)

 ```#include "Vector.h"Vector::Vector() {} Vector::~Vector() {}//============================================================================= Vector::Vector(float x, float y, float z) {this->x = x; this->y = y; this->z = z;} Vector::Vector(Vector &v) {*this = v;} Vector::Vector(float s) {x = s; y = s; z = s;} Vector::Vector(float *v) {memcpy(this->v, v, sizeof(float) * 3);}//============================================================================= void Vector::toArray(float *v) { memcpy(v, this->v, sizeof(float) * 3); }//============================================================================= Vector &Vector::operator=(Vector &v) {x = v.x; y = v.y; z = v.z; return *this;}Vector &Vector::operator+=(Vector &v) {x += v.x; y += v.y; z += v.z; return *this;} Vector &Vector::operator-=(Vector &v) {x -= v.x; y -= v.y; z -= v.z; return *this;} Vector &Vector::operator&=(Vector &v) {x *= v.x; y *= v.y; z *= v.z; return *this;} Vector &Vector::operator*=(float s) {x *= s; y *= s; z *= s; return *this;} Vector &Vector::operator/=(float s) { float r = 1 / s; x *= r; y *= r; z *= r; return *this; } Vector &Vector::operator*=(Vector &v) { return *this = Vector( y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x ); } Vector &Vector::operator*=(Matrix &m) { return *this = Vector( x * m[0][0] + y * m[1][0] + z * m[2][0] + m[3][0], x * m[0][1] + y * m[1][1] + z * m[2][1] + m[3][1], x * m[0][2] + y * m[1][2] + z * m[2][2] + m[3][2] ); }Vector Vector::operator+(Vector &v) {return Vector(*this) += v;} Vector Vector::operator-(Vector &v) {return Vector(*this) -= v;} Vector Vector::operator&(Vector &v) {return Vector(*this) &= v;} Vector Vector::operator*(float s) {return Vector(*this) *= s;} Vector Vector::operator/(float s) {return Vector(*this) /= s;} Vector Vector::operator*(Vector &v) {return Vector(*this) *= v;} Vector Vector::operator*(Matrix &m) {return Vector(*this) *= m;}float &Vector::operator[](AXIS::AXIS axis) {return v[axis];} float Vector::operator|(Vector &v) {return x * v.x + y * v.y + z * v.z;} Vector Vector::operator-() {return *this * -1;}; bool Vector::operator==(Vector &v) {return x == v.x && y == v.y && z == v.z;} bool Vector::operator!=(Vector &v) {return x != v.x || y != v.y || z != v.z;}//============================================================================= Vector &Vector::mask(Vector &m, Vector &v) { x = m.x ? v.x : x; y = m.y ? v.y : y; z = m.z ? v.z : z; return *this; }Vector Vector::vec_interp(Vector &v, float s) { return interp(*this, v, s); }float Vector::mod() { return (float) pow(*this | *this, 0.5f); }float Vector::dist(Vector &v) { return (*this - v).mod(); }Vector &Vector::normalize() { float t = this->mod(); return *this = (t != 0) ? *this / t : NULL_VECTOR; }Vector Vector::normal() { return Vector(*this).normalize(); }Vector Vector::normTri(Vector &v1, Vector &v2) { return ((v1 - *this) * (v2 - *this)).normalize(); }float Vector::angle(Vector &v) { return this->normal() | v.normal(); }int Vector::compare(Vector &v1, Vector &v2) { return sgn((*this | v1) - (*this | v2)); }float Vector::sectPlane(Vector &p, Vector &v, Vector &n) { float t = n | *this; return (t != 0) ? (n | (v - p)) / t : BIG_NUMBER; }Vector Vector::project(Vector &v) { Vector t = v.normal(); return t * (*this | t); }Vector Vector::ortho(Vector &v) { return *this - this->project(v); }Vector Vector::reflect(Vector &n) { if (this->angle(n) < 0) return *this + this->project(n) * -2; return *this; }Vector &Vector::fromAngle(Vector &v) { return *this = FWD_VECTOR * RotateTrans(AXIS::X, v.pitch) * RotateTrans(AXIS::Y, v.yaw); }Vector Vector::toAngle() { Vector t(x, 0, z); Vector r( 0, acosEx(t.angle(*this)), acosEx(t.angle(FWD_VECTOR)) ); if (x < 0) r.yaw *= -1; if (y > 0) r.pitch *= -1; return r; }//============================================================================= Vector &Vector::vec_wrap(Vector &pMin, Vector &pMax) { x = wrap(x, pMin.x, pMax.x); y = wrap(y, pMin.y, pMax.y); z = wrap(z, pMin.z, pMax.z); return *this; }Vector &Vector::vec_limit(Vector &pMin, Vector &pMax) { x = limit(x, pMin.x, pMax.x); y = limit(y, pMin.y, pMax.y); z = limit(z, pMin.z, pMax.z); return *this; }void Vector::multEx(float *r, Matrix &m) { r[0] = x * m[0][0] + y * m[1][0] + z * m[2][0] + m[3][0]; r[1] = x * m[0][1] + y * m[1][1] + z * m[2][1] + m[3][1]; r[2] = x * m[0][2] + y * m[1][2] + z * m[2][2] + m[3][2]; r[3] = x * m[0][3] + y * m[1][3] + z * m[2][3] + m[3][3]; } ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Transform.cpp] - (2,224 bytes)

 ```#include "Transform.h"ScaleTrans::ScaleTrans(Vector &v) { *((Matrix *) this) = IDENT_MATRIX; (*this)[0][0] = v.x; (*this)[1][1] = v.y; (*this)[2][2] = v.z; }TranslateTrans::TranslateTrans(Vector &v) { *((Matrix *) this) = IDENT_MATRIX; (*this)[3][0] = v.x; (*this)[3][1] = v.y; (*this)[3][2] = v.z; }RotateTrans::RotateTrans(AXIS::AXIS axis, float angle) { *((Matrix *) this) = IDENT_MATRIX; float pSin = (float) sin(angle); float pCos = (float) cos(angle); switch (axis) { case AXIS::X: (*this)[1][1] = pCos; (*this)[1][2] = pSin; (*this)[2][1] = -pSin; (*this)[2][2] = pCos; break; case AXIS::Y: (*this)[0][0] = pCos; (*this)[0][2] = -pSin; (*this)[2][0] = pSin; (*this)[2][2] = pCos; break; case AXIS::Z: (*this)[0][0] = pCos; (*this)[0][1] = pSin; (*this)[1][0] = -pSin; (*this)[1][1] = pCos; } }ComboTrans::ComboTrans(Vector &origin, Vector &angle, Vector &scale) { *((Matrix *) this) = IDENT_MATRIX; (*this) *= ScaleTrans((Vector &) scale); (*this) *= RotateTrans(AXIS::Y, angle.roll); (*this) *= RotateTrans(AXIS::X, angle.pitch); (*this) *= RotateTrans(AXIS::Y, angle.yaw); (*this) *= TranslateTrans((Vector &) origin); }ProjectTrans::ProjectTrans(float sw, float sh, float n, float f) { if (n <= 0 || n > f) throw Exception("invalid clipping planes"); *((Matrix *) this) = ZERO_MATRIX; cx = sw / 2; cy = sh / 2; }ProjectPerspectTrans::ProjectPerspectTrans(float sw, float sh, float aspect, float n, float f, float halfTan) : ProjectTrans(sw, sh, n, f) { float h = halfTan * n; float tempA = -h / n; float tempB = -f / (n - f); (*this)[0][0] = cx / aspect; (*this)[1][1] = -cy; (*this)[2][0] = cx * tempA; (*this)[2][1] = cy * tempA; (*this)[2][2] = tempA * tempB; (*this)[2][3] = tempA; (*this)[3][2] = h * tempB; }ProjectOrthoTrans::ProjectOrthoTrans(float sw, float sh, float aspect, float n, float f, float zoom) : ProjectTrans(sw, sh, n, f) { float tempA = 1 / (n - f); (*this)[0][0] = zoom / aspect; (*this)[1][1] = -zoom; (*this)[2][2] = -tempA; (*this)[3][0] = cx; (*this)[3][1] = cy; (*this)[3][2] = n * tempA; (*this)[3][3] = 1; } ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [IMesh.h] - (555 bytes)

 ```#ifndef H_IMESH #define H_IMESH#include "Vector.h"class IMesh { protected: int mVertCnt; int mFaceCnt; public: IMesh(int vertCnt, int faceCnt); ~IMesh(); int getVertCnt(); int getFaceCnt(); virtual void resize(int vertCnt, int faceCnt); virtual Vector *getVertices() = 0; virtual void setVertex(int index, float x, float y, float z) = 0; virtual void setFace(int index, int a, int b, int c) = 0; virtual void setAnchor(int index, float x, float y) = 0; virtual void getDim(Vector &pMin, Vector &pMax) = 0; };#endif ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Matrix.cpp] - (4,216 bytes)

 ```#include "Matrix.h"Matrix::Matrix() {} Matrix::~Matrix() {}//============================================================================= Matrix::Matrix(Matrix &m) {*this = m;} Matrix::Matrix(float s) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) mItem[i][j] = (i == j) ? s : 0; } Matrix::Matrix(float **m) {this->set(m);}//============================================================================= inline void Matrix::get(float **m) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) m[i][j] = mItem[i][j]; }inline Matrix &Matrix::set(float **m) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) mItem[i][j] = m[i][j]; return *this; }//============================================================================= void Matrix::toArray(float *m) { for (int i = 0; i < 4; i++) memcpy(&m[i * 4], mItem[i], sizeof(float) * 4); }//============================================================================= inline Matrix &Matrix::mult(Matrix &m) { Matrix t; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) t[i][j] = mItem[i][0] * m[0][j] + mItem[i][1] * m[1][j] + mItem[i][2] * m[2][j] + mItem[i][3] * m[3][j]; return *this = t; }inline Matrix &Matrix::scale(float s) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) mItem[i][j] *= s; return *this; }//============================================================================= inline Matrix Matrix::mult(Matrix &m1, Matrix &m2) { Matrix r; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) r[i][j] = m1[i][0] * m2[0][j] + m1[i][1] * m2[1][j] + m1[i][2] * m2[2][j] + m1[i][3] * m2[3][j]; return r; }inline Matrix Matrix::scale(Matrix &m, float s) { Matrix r; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) r[i][j] = m[i][j] * s; return r; }//============================================================================= Matrix &Matrix::operator=(Matrix &m) { for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) mItem[i][j] = m[i][j]; return *this; } Matrix Matrix::operator~() { Matrix r; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) r[i][j] = mItem[j][i]; return r; }Matrix &Matrix::operator*=(Matrix &m) {return this->mult(m);} Matrix &Matrix::operator*=(float s) {return this->scale(s);} Matrix &Matrix::operator/=(float s) {return this->scale(1 / s);}Matrix Matrix::operator*(Matrix &m) {return this->mult(*this, m);} Matrix Matrix::operator*(float s) {return this->scale(*this, s);} Matrix Matrix::operator/(float s) {return this->scale(*this, 1 / s);}float *Matrix::operator[](int row) {return mItem[row];} Matrix Matrix::operator!() {return this->inverse();}//============================================================================= inline void Matrix::minor(float **r, float **m, int rowCnt, int colCnt, int row, int col) { int row2 = 0; for (int i = 0; i < rowCnt; i++) if (i != row) { int col2 = 0; for (int j = 0; j < colCnt; j++) if (j != col) { r[row2][col2] = m[i][j]; col2++; } row2++; } }inline float Matrix::cofact(float **t, float **m, int size, int row, int col) { minor(t, m, size, size, row, col); return (float) pow(-1, row + col) * det(t, size - 1); }inline float Matrix::det(float **m, int size) { float result = 0; if (size == 1) result = m[0][0]; else { float **t = buildArray(size - 1, size - 1); for (int i = 0; i < size; i++) result += m[0][i] * cofact(t, m, size, 0, i); killArray(t, size - 1); } return result; }Matrix &Matrix::invert() { float **m = buildArray(4, 4); float **t = buildArray(3, 3); float **r = buildArray(4, 4); this->get(m); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) r[i][j] = cofact(t, m, 4, i, j); float d = det(r, 4); this->set(r); killArray(m, 4); killArray(t, 3); killArray(r, 4); return *this = (d != 0) ? ~(*this) / d : ZERO_MATRIX; }Matrix Matrix::inverse() { return Matrix(*this).invert(); } ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [IMesh.cpp] - (327 bytes)

 ```#include "IMesh.h"IMesh::IMesh(int vertCnt, int faceCnt) { this->resize(vertCnt, faceCnt); }IMesh::~IMesh() { }void IMesh::resize(int vertCnt, int faceCnt) { mVertCnt = vertCnt; mFaceCnt = faceCnt; }int IMesh::getVertCnt() { return mVertCnt; }int IMesh::getFaceCnt() { return mFaceCnt; } ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Vector.h] - (2,905 bytes)

 ```#ifndef H_VECTOR #define H_VECTOR#include // memcpy() #include // pow() #include "Matrix.h" #include "Util.h" // BIG_NUMBER #define UNIT_VECTOR UnitVector #define NULL_VECTOR NullVector #define FWD_VECTOR FwdVector #define LEFT_VECTOR LeftVector #define UP_VECTOR UpVector #define RAND_VECTOR Vector(rand(), rand(), rand())namespace AXIS { enum AXIS {X, Y, Z, S}; };class Vector { public: union { float v[3]; struct { union {float x; float roll;}; union {float y; float pitch;}; union {float z; float yaw;}; }; }; Vector(); ~Vector(); //============================================================================= Vector(float x, float y, float z); Vector(Vector &v); Vector(float s); Vector(float *v); //============================================================================= void toArray(float *v); //============================================================================= Vector &operator=(Vector &v); //============================================================================= Vector &operator+=(Vector &v); Vector &operator-=(Vector &v); Vector &operator&=(Vector &v); Vector &operator*=(float s); Vector &operator/=(float s); Vector &operator*=(Vector &v); Vector &operator*=(Matrix &m); //============================================================================= Vector operator+(Vector &v); Vector operator-(Vector &v); Vector operator&(Vector &v); Vector operator*(float s); Vector operator/(float s); Vector operator*(Vector &v); Vector operator*(Matrix &m); //============================================================================= float &operator[](AXIS::AXIS axis); float operator|(Vector &v); Vector operator-(); bool operator==(Vector &v); bool operator!=(Vector &v); //============================================================================= Vector &mask(Vector &m, Vector &v); Vector vec_interp(Vector &v, float s); float mod(); float dist(Vector &v); Vector &normalize(); Vector normal(); Vector normTri(Vector &v1, Vector &v2); float angle(Vector &v); int compare(Vector &v1, Vector &v2); float sectPlane(Vector &p, Vector &v, Vector &n); Vector project(Vector &v); Vector ortho(Vector &v); Vector reflect(Vector &n); Vector &fromAngle(Vector &v); Vector toAngle(); //============================================================================= Vector &vec_wrap(Vector &pMin, Vector &pMax); Vector &vec_limit(Vector &pMin, Vector &pMax); void multEx(float *r, Matrix &m); //============================================================================= };static Vector UnitVector(1.0); static Vector NullVector(0.0); static Vector FwdVector(0, 0, 1); static Vector LeftVector(1, 0, 0); static Vector UpVector(0, 1, 0);#include "Transform.h"#endif ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Transform.h] - (1,004 bytes)

 ```#ifndef H_TRANSFORM #define H_TRANSFORM#include // sin(), cos() #include "Vector.h" #include "Matrix.h" #include "Exception.h"class ScaleTrans : public Matrix {public: ScaleTrans(Vector &v);}; class TranslateTrans : public Matrix {public: TranslateTrans(Vector &v);}; class RotateTrans : public Matrix {public: RotateTrans(AXIS::AXIS axis, float angle);};class ComboTrans : public Matrix { public: ComboTrans( Vector &origin, Vector &angle, Vector &scale ); };class ProjectTrans : public Matrix { protected: float cx; float cy; public: ProjectTrans( float sw, float sh, float n, float f ); };class ProjectPerspectTrans : public ProjectTrans { public: ProjectPerspectTrans( float sw, float sh, float aspect, float n, float f, float halfTan ); };class ProjectOrthoTrans : public ProjectTrans { public: ProjectOrthoTrans( float sw, float sh, float aspect, float n, float f, float zoom ); };#endif ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Polygon.h] - (598 bytes)

 ```#ifndef H_POLYGON #define H_POLYGON#include "IMesh.h"class Polygon { public: static void makeBox(IMesh *mesh); static void makeGrid(IMesh *mesh, int gridX, int gridZ); static void makeCylinder(IMesh *mesh, int step); static void makeCone(IMesh *mesh, int step); static void makeSphere(IMesh *mesh, int stepLng, int stepLat); static void makeHemis(IMesh *mesh, int stepLng, int stepLat); static void makeTorus(IMesh *mesh, float radMajor, float radMinor, int stepMajor, int stepMinor); static void makeOcta(IMesh *mesh); static void makeTetra(IMesh *mesh); };#endif ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Matrix.h] - (2,546 bytes)

 ```#ifndef H_MATRIX #define H_MATRIX#include // memcpy() #include // pow() #define IDENT_MATRIX IdentMatrix #define ZERO_MATRIX ZeroMatrixinline float **buildArray(int rowCnt, int colCnt) { float **r = new float *[rowCnt]; for (int i = 0; i < rowCnt; i++) r[i] = new float[colCnt]; return r; }inline void killArray(float **m, int rowCnt) { for (int i = 0; i < rowCnt; i++) delete []m[i]; delete []m; }class Matrix { private: float mItem[4][4]; //============================================================================= inline void get(float **m); inline Matrix &set(float **m); //============================================================================= inline Matrix &mult(Matrix &m); inline Matrix &scale(float s); //============================================================================= inline Matrix mult(Matrix &m1, Matrix &m2); inline Matrix scale(Matrix &m, float s); //============================================================================= static inline void minor(float **r, float **m, int rowCnt, int colCnt, int row, int col); static inline float cofact(float **t, float **m, int size, int row, int col); static inline float det(float **m, int size); //============================================================================= public: Matrix(); ~Matrix(); //============================================================================= Matrix(Matrix &m); Matrix(float **m); Matrix(float s); //============================================================================= void toArray(float *m); //============================================================================= Matrix &operator=(Matrix &m); Matrix operator~(); //============================================================================= Matrix &operator*=(Matrix &m); Matrix &operator*=(float s); Matrix &operator/=(float s); //============================================================================= Matrix operator*(Matrix &m); Matrix operator*(float s); Matrix operator/(float s); //============================================================================= float *operator[](int row); Matrix operator!(); //============================================================================= Matrix &invert(); Matrix inverse(); //============================================================================= };static Matrix IdentMatrix(1.0); static Matrix ZeroMatrix(0.0);#endif ```

Currently browsing [3DPlatonicPrimitives.zip] (7,232 bytes) - [Polygon.cpp] - (4,489 bytes)

 ```#include "Polygon.h"void Polygon::makeBox(IMesh *mesh) { mesh->resize(8, 12); mesh->setVertex(0, 0, 0, 0); mesh->setVertex(1, 1, 0, 0); mesh->setVertex(2, 1, 0, 1); mesh->setVertex(3, 0, 0, 1); mesh->setVertex(4, 0, 1, 0); mesh->setVertex(5, 1, 1, 0); mesh->setVertex(6, 1, 1, 1); mesh->setVertex(7, 0, 1, 1); mesh->setFace(0, 0, 4, 5); mesh->setFace(1, 5, 1, 0); mesh->setFace(2, 1, 5, 6); mesh->setFace(3, 6, 2, 1); mesh->setFace(4, 2, 6, 7); mesh->setFace(5, 7, 3, 2); mesh->setFace(6, 3, 7, 4); mesh->setFace(7, 4, 0, 3); mesh->setFace(8, 0, 1, 2); mesh->setFace(9, 2, 3, 0); mesh->setFace(10, 5, 4, 7); mesh->setFace(11, 7, 6, 5); }void Polygon::makeGrid(IMesh *mesh, int gridX, int gridZ) { mesh->resize(gridX * gridZ, (gridX - 1) * (gridZ - 1) * 2); int vertCnt = 0; int faceCnt = 0; for (int x = 0; x < gridX; x++) for (int z = 0; z < gridZ; z++) { mesh->setVertex( vertCnt, 1 - (float) x / (gridX - 1), 0, 1 - (float) z / (gridZ - 1) ); if (x < gridX - 1 && z < gridZ - 1) { mesh->setFace( faceCnt++, vertCnt + 0, vertCnt + 1, vertCnt + 1 + gridZ ); mesh->setFace( faceCnt++, vertCnt + 1 + gridZ, vertCnt + gridZ, vertCnt + 0 ); } vertCnt++; } }void Polygon::makeCylinder(IMesh *mesh, int step) { makeGrid(mesh, step + 1, 4); float unit = 2 * PI / step; int vertCnt = 0; for (int i = 0; i < step + 1; i++) { mesh->setVertex(vertCnt++, 0, 1, 0); Vector v = Vector(0, 0, 1) * RotateTrans(AXIS::Y, i * unit); mesh->setVertex(vertCnt++, v.x, v.y + 1, v.z); mesh->setVertex(vertCnt++, v.x, v.y, v.z); mesh->setVertex(vertCnt++, 0, 0, 0); } }void Polygon::makeCone(IMesh *mesh, int step) { makeGrid(mesh, step + 1, 3); float unit = 2 * PI / step; int vertCnt = 0; for (int i = 0; i < step + 1; i++) { mesh->setVertex(vertCnt++, 0, 1, 0); Vector v = Vector(0, 0, 1) * RotateTrans(AXIS::Y, i * unit); mesh->setVertex(vertCnt++, v.x, v.y, v.z); mesh->setVertex(vertCnt++, 0, 0, 0); } }void Polygon::makeSphere(IMesh *mesh, int stepLng, int stepLat) { makeGrid(mesh, stepLng + 1, (stepLat / 2) + 1); float unitLng = 2 * PI / stepLng; float unitLat = PI / (stepLat / 2); int vertCnt = 0; for (int i = 0; i < stepLng + 1; i++) for (int j = 0; j < (stepLat / 2) + 1; j++) { Vector v = Vector(0, 1, 0) * RotateTrans(AXIS::X, j * unitLat) * RotateTrans(AXIS::Y, i * unitLng); mesh->setVertex(vertCnt++, v.x, v.y, v.z); } }void Polygon::makeHemis(IMesh *mesh, int stepLng, int stepLat) { makeGrid(mesh, stepLng + 1, (stepLat / 4) + 2); float unitLng = 2 * PI / stepLng; float unitLat = PI / (stepLat / 2); int vertCnt = 0; for (int i = 0; i < stepLng + 1; i++) { for (int j = 0; j < (stepLat / 4) + 1; j++) { Vector v = Vector(0, 1, 0) * RotateTrans(AXIS::X, j * unitLat) * RotateTrans(AXIS::Y, i * unitLng); mesh->setVertex(vertCnt++, v.x, v.y, v.z); } mesh->setVertex(vertCnt++, 0, 0, 0); } }void Polygon::makeTorus( IMesh *mesh, float radMajor, float radMinor, int stepMajor, int stepMinor ) { makeGrid(mesh, stepMajor + 1, stepMinor + 1); float unitMajor = 2 * PI / stepMajor; float unitMinor = 2 * PI / stepMinor; int vertCnt = 0; for (int i = 0; i < stepMajor + 1; i++) for (int j = 0; j < stepMinor + 1; j++) { Vector v = Vector(0, radMinor, 0) * RotateTrans(AXIS::X, j * unitMinor) * TranslateTrans(Vector(0, 0, radMajor)) * RotateTrans(AXIS::Y, i * unitMajor); mesh->setVertex(vertCnt++, v.x, v.y, v.z); } }void Polygon::makeOcta(IMesh *mesh) { mesh->resize(6, 8); mesh->setVertex(0, 0, 0, 0); mesh->setVertex(1, 1, 0, 0); mesh->setVertex(2, 1, 0, 1); mesh->setVertex(3, 0, 0, 1); mesh->setVertex(4, 0.5f, -1, 0.5f); mesh->setVertex(5, 0.5f, 1, 0.5f); mesh->setFace(0, 0, 1, 4); mesh->setFace(1, 1, 2, 4); mesh->setFace(2, 2, 3, 4); mesh->setFace(3, 3, 0, 4); mesh->setFace(4, 0, 5, 1); mesh->setFace(5, 1, 5, 2); mesh->setFace(6, 2, 5, 3); mesh->setFace(7, 3, 5, 0); }void Polygon::makeTetra(IMesh *mesh) { mesh->resize(4, 4); mesh->setVertex(0, 0, 0, 0); mesh->setVertex(1, 1, 1, 0); mesh->setVertex(2, 0, 1, 1); mesh->setVertex(3, 1, 0, 1); mesh->setFace(0, 0, 1, 3); mesh->setFace(1, 0, 2, 1); mesh->setFace(2, 0, 3, 2); mesh->setFace(3, 1, 2, 3); } ```

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.