CSC3223_Graphics_For_Games_Software_Rasteriser / SoftwareRasteriser / Mesh.cpp
Mesh.cpp
Raw
#include "Mesh.h"
#include <vector>

Mesh::Mesh(void) {
  type = PRIMITIVE_POINTS;

  numVertices = 0;

  vertices = NULL;
  colours = NULL;
  textureCoords = NULL;
}

Mesh::~Mesh(void) {
  delete[] vertices;
  delete[] colours;
  delete[] textureCoords;
}

Mesh *Mesh::GenerateLine(const Vector3 &from, const Vector3 &to) {
	Mesh *m = new Mesh();

	m->numVertices = 2;
	m->vertices = new Vector4[m->numVertices];
	m->colours = new Colour[m->numVertices];
	m->textureCoords = new Vector2[m->numVertices];

	m->vertices[0] = Vector4(from.x, from.y, from.z, 1.0f);
	m->vertices[1] = Vector4(to.x, to.y, to.z, 1.0f);

	m->colours[0] = Colour(255, 0, 0, 255);
	m->colours[1] = Colour(0, 0, 255, 255);

	m->textureCoords[0] = Vector2(0.0f, 0.0f);
	m->textureCoords[1] = Vector2(1.0f, 1.0f);

	m->type = PRIMITIVE_LINES;

	return m;
}

Mesh *Mesh::GeneratePoints(const Vector3 &from, const Colour &col) {
	Mesh *m = new Mesh();
	
	m->numVertices = 1;
	m->vertices = new Vector4[m->numVertices];
	m->colours = new Colour[m->numVertices];
	m->textureCoords = new Vector2[m->numVertices];

	m->vertices[0] = Vector4(from.x, from.y, from.z, 1.0f);
	m->colours[0] = Colour(col.r, col.g, col.b, col.a);
	m->textureCoords[0] = Vector2(0.0f, 0.0f);

	m->type = PRIMITIVE_POINTS;
	return m;
}

Mesh *Mesh::GenerateTriangle() {
	Mesh *m = new Mesh();

	m->numVertices = 3;
	m->vertices = new Vector4[m->numVertices];
	m->colours = new Colour[m->numVertices];
	m->textureCoords = new Vector2[m->numVertices];

	m->vertices[0] = Vector4(0.5f, -0.5f, 0.0f, 1.0f);
	m->vertices[1] = Vector4(0.0f, 0.5f, 0.0f, 1.0f);
	m->vertices[2] = Vector4(-0.5f, -0.5f, 0.0f, 1.0f);

	m->colours[0] = Colour(255, 0, 0, 127);
	m->colours[1] = Colour(0, 255, 0, 127);
	m->colours[2] = Colour(0, 0, 255, 127);

	m->textureCoords[0] = Vector2(0.0f, 0.0f);
	m->textureCoords[1] = Vector2(0.5f, 1.0f);
	m->textureCoords[2] = Vector2(1.0f, 0.0f);

	m->type = PRIMITIVE_TRIANGLES;
	return m;
}

Mesh *Mesh::LoadMeshFile(const string &filename) {
  ifstream f(filename);

  if (!f)
    return NULL;

  Mesh *m = new Mesh();
  m->type = PRIMITIVE_TRIANGLES;
  f >> m->numVertices;

  int hasTex = 0;
  f >> hasTex;

  int hasColour = 0;
  f >> hasColour;

  m->vertices = new Vector4[m->numVertices];
  m->textureCoords = new Vector2[m->numVertices];
  m->colours = new Colour[m->numVertices];

  for (unsigned int i = 0; i < m->numVertices; ++i)   {
    f >> m->vertices[i].x;
    f >> m->vertices[i].y;
    f >> m->vertices[i].z;

	m->type = PRIMITIVE_TRIANGLES;
  }
  if (hasColour)
  {
    for (unsigned int i = 0; i < m->numVertices; ++i)     {
      f >> m->colours[i].r;
      f >> m->colours[i].g;
      f >> m->colours[i].b;
      f >> m->colours[i].a;
    }
  }
  if (hasTex)   {
    for (unsigned int i = 0; i < m->numVertices; ++i)     {
      f >> m->textureCoords[i].x;
      f >> m->textureCoords[i].y;
    }
  }
  return m;
}

/*Triangle Strip Primitives*/
Mesh *Mesh::GenerateTriangleStripPrimitives() {
  Mesh *m = new Mesh();

  m->numVertices = 5;
  m->vertices = new Vector4[m->numVertices];
  m->colours = new Colour[m->numVertices];
  m->textureCoords = new Vector2[m->numVertices];

  m->vertices[0] = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
  m->vertices[1] = Vector4(0.25f, 0.5f, 0.0f, 1.0f);
  m->vertices[2] = Vector4(0.5f, 0.0f, 0.0f, 1.0f);
  m->vertices[3] = Vector4(0.75f, 0.5f, 0.0f, 1.0f);
  m->vertices[4] = Vector4(1.0f, 0.0f, 0.0f, 1.0f);

  m->colours[0] = Colour(255, 0, 0, 127);
  m->colours[1] = Colour(0, 255, 0, 127);
  m->colours[2] = Colour(0, 0, 255, 127);
  m->colours[3] = Colour(255, 0, 0, 255);
  m->colours[4] = Colour(0, 255, 0, 255);

  m->textureCoords[0] = Vector2(0.0f, 0.0f);
  m->textureCoords[1] = Vector2(0.5f, 1.0f);
  m->textureCoords[2] = Vector2(1.0f, 0.0f);
  m->textureCoords[3] = Vector2(1.0f, 0.5f);
  m->textureCoords[4] = Vector2(0.5f, 0.5f);

  m->type = PRIMITIVE_TRIANGLES_STRIP;

  return m;
}

/*Triangle Fan Primitives*/
Mesh *Mesh::GenerateTriangleFanPrimitives() {
  Mesh *m = new Mesh();

  m->numVertices = 5;
  m->vertices = new Vector4[m->numVertices];
  m->colours = new Colour[m->numVertices];
  m->textureCoords = new Vector2[m->numVertices];

  m->vertices[0] = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
  m->vertices[1] = Vector4(0.5f, 0.5f, 0.0f, 1.0f);
  m->vertices[2] = Vector4(0.5f, -0.5f, 0.0f, 1.0f);
  m->vertices[3] = Vector4(-0.5f, -0.5f, 0.0f, 1.0f);
  m->vertices[4] = Vector4(-0.5f, 0.5f, 0.0f, 1.0f);

  m->colours[0] = Colour(0, 0, 0, 127);
  m->colours[1] = Colour(255, 0, 0, 127);
  m->colours[2] = Colour(0, 255, 0, 127);
  m->colours[3] = Colour(0, 0, 255, 127);
  m->colours[4] = Colour(255, 255, 255, 127);

  m->textureCoords[0] = Vector2(0.0f, 0.0f);
  m->textureCoords[1] = Vector2(0.5f, 1.0f);
  m->textureCoords[2] = Vector2(1.0f, 0.0f);
  m->textureCoords[3] = Vector2(1.0f, 0.0f);
  m->textureCoords[4] = Vector2(1.0f, 0.0f);

  m->type = PRIMITIVE_TRIANGLES_FAN;

  return m;
}

/*Asteroid*/
Mesh* Mesh::GenerateNSidedShape(const int size) {
	Mesh* m = new Mesh();
	const int two = 2;

	m->numVertices = size * two;
	m->vertices = new Vector4[m->numVertices];
	m->colours = new Colour[m->numVertices];
	m->textureCoords = new Vector2[m->numVertices];

	const float point = 2 * PI / size;
	for (int i = 0; i < m->numVertices; i = i + two) {
		const float pointX1 = cos(point * i);
		const float pointY1 = sin(point * i);

		m->vertices[i] = Vector4(pointX1, pointY1, 0.0, 1.0f);
		m->colours[i] = Colour(255, 255, 255, 255);
		m->textureCoords[i] = Vector2(pointX1, pointY1);

		const float pointX2 = cos(point * (i + 1));
		const float pointY2 = sin(point * (i + 1));

		m->vertices[i + 1] = Vector4(pointX2, pointY2, 0.0, 1.0f);
		m->colours[i + 1] = Colour(255, 255, 255, 255);
		m->textureCoords[i + 1] = Vector2(pointX2, pointY2);
	}

	m->type = PRIMITIVE_LINES;
	return m;
}

/*This creates Planet*/
Mesh *Mesh::GeneratePlanetCircle(const float radius, const int size) {
	Mesh *m = new Mesh();

	m->numVertices = size + 2;
	m->vertices = new Vector4[m->numVertices];
	m->colours = new Colour[m->numVertices];
	m->textureCoords = new Vector2[m->numVertices];

	const float difference = ((PI * 2) / size);

	m->vertices[0] = Vector4(0.0f, 0.0f, 0.0f, 1.0f);
	m->colours[0] = Colour::White;
	m->textureCoords[0] = Vector2(0.5f, 0.5f);

	for (int i = 1; i < size + 2; ++i) {
		const float value = i * difference;

		m->vertices[i] = Vector4(cos(value) * radius, sin(value) * radius, 0.0f, 1.0f);
		m->colours[i] = Colour::White;
		Vector2 result = Vector2(abs(cos(value)), abs(sin(value)));
		m->textureCoords[i] = result;
	}

	m->type = PRIMITIVE_TRIANGLES_FAN;

	return m;
}

/*This creates Asteroid Ring*/
Mesh *Mesh::GenerateSpaceDebrish(const float radiusOut, const float radiusIn, const int size) {
	Mesh *m = new Mesh();
	const int two = 2;
	m->numVertices = (size + two) * two;
	m->vertices = new Vector4[m->numVertices];
	m->colours = new Colour[m->numVertices];
	m->textureCoords = new Vector2[m->numVertices];

	const float difference = ((PI * two) / size);

	int index = 0;
	for (int i = 0; i < size + two; i++) {
		const float value = i * difference;

		m->vertices[index] = Vector4(cos(value) * radiusOut, sin(value) * radiusOut, 0.0f, 1.0f);
		m->colours[index] = Colour::White;
		m->textureCoords[index] = Vector2(abs(cos(value)), abs(sin(value)));
		index++;

		m->vertices[index] = Vector4(cos(value) * radiusIn, sin(value) * radiusIn, 0.0f, 1.0f);
		m->colours[index] = Colour::White;
		m->textureCoords[index] = Vector2(abs(cos(value)), abs(sin(value)));
		index++;
	}

	m->type = PRIMITIVE_TRIANGLES_STRIP;

	return m;
}

/*This creates Moon*/
Mesh *Mesh::GenerateMoonSphere(const float radius, const int size, const Colour &colour) {
  Mesh *m = new Mesh();
  const int two = 2;

  m->numVertices = size * size * two;
  m->vertices = new Vector4[m->numVertices];
  m->colours = new Colour[m->numVertices];
  m->textureCoords = new Vector2[m->numVertices];

  const float deltaT = (PI / size);
  const float deltaP = ((PI * two) / size);

  const float normalization = 1.0f / size;

  int index = 0;
  for (int i = 0; i < size; i++) {
    const float calc1 = i * deltaT;
    const float calc2 = (i + 1) * deltaT;

    const float value1 = i * normalization;
    const float value2 = (i + 1) * normalization;

    for (int j = 0; j < size; j++) {
      const float dPhi = j * deltaP;
      const float result = j * normalization;

      m->vertices[index] = Vector4(cos(calc1) * sin(dPhi) * radius, sin(calc1) * sin(dPhi) * radius, cos(dPhi) * radius, 1.0f);
      m->colours[index] = colour;
      m->textureCoords[index] = Vector2(value1, result);
	  index++;

      m->vertices[index] = Vector4(cos(calc2) * sin(dPhi) * radius, sin(calc2) * sin(dPhi) * radius, cos(dPhi) * radius, 1.0f);
      m->colours[index] = colour;
      m->textureCoords[index] = Vector2(value2, result);
	  index++;
    }
  }

  m->type = PRIMITIVE_TRIANGLES_STRIP;

  return m;
}