charcoal/CharcoalBuiltin/MeshGenerator.h

821 lines
26 KiB
C
Raw Normal View History

#pragma once
#include <type_traits>
#include <glm/glm.hpp>
#include <charcoal/MeshFactory.h>
#include <charcoal/Mesh.h>
#include "BuiltinTypes.h"
// TODO: Consider a mesh generator for every render type (i.e. basic::meshgenerator, lit::meshgenerator, etc.)
namespace charcoal
{
using namespace glm;
namespace builtin
{
// Uses MeshFactory to generate meshes for the builtin vertex types.
namespace meshgenerator
{
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* set_material(Mesh<VertexType, IndexType>* mesh, const PhongMaterial& material)
{
for (unsigned int i = 0; i < mesh->vertex_count; ++i)
{
mesh->vertices[i].set_material(material);
}
return mesh;
}
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* gen_plane_pn(const DrawMode& draw_mode, float width, float depth)
{
Mesh<VertexType, IndexType>* mesh;
float x = width / 2.0f;
float z = depth / 2.0f;
Position pos0(-x, 0.0f, z);
Position pos1(-x, 0.0f, -z);
Position pos2(x, 0.0f, z);
Position pos3(x, 0.0f, -z);
Normal normal(0.0f, 1.0f, 0.0f);
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 2;
mesh->indices[3] = 3;
break;
case DrawMode::DRAW_LINE_STRIP:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 5);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 3;
mesh->indices[3] = 2;
mesh->indices[4] = 0;
break;
case DrawMode::DRAW_LINE_LOOP:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 3;
mesh->indices[3] = 2;
break;
case DrawMode::DRAW_LINES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 8);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 1;
mesh->indices[3] = 3;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
mesh->indices[6] = 2;
mesh->indices[7] = 0;
break;
case DrawMode::DRAW_TRIANGLE_STRIP:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 2;
break;
case DrawMode::DRAW_TRIANGLE_FAN:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 3;
mesh->indices[3] = 2;
break;
case DrawMode::DRAW_TRIANGLES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 6);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[0].set_normal(normal);
mesh->vertices[1].set_normal(normal);
mesh->vertices[2].set_normal(normal);
mesh->vertices[3].set_normal(normal);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 0;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
break;
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw EXCEPTION("Unable to gen_plane_p for current draw mode: " + std::to_string(draw_mode));
}
return mesh;
}
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* gen_cube_p(const DrawMode& draw_mode, float width, float height, float depth)
{
//static_assert(std::is_base_of<Positioned, VertexType>::value, "VertexType must be Positioned");
Mesh<VertexType, IndexType>* mesh;
float x = width / 2.0f;
float y = height / 2.0f;
float z = depth / 2.0f;
Position pos0(-x, y, -z); // Front Left Top
Position pos1(-x, -y, -z); // Front Left Bottom
Position pos2(x, y, -z); // Front Right Top
Position pos3(x, -y, -z); // Front Right Bottom
Position pos4(-x, y, z); // Back Left Top
Position pos5(-x, -y, z); // Back Left Bottom
Position pos6(x, y, z); // Back Right Top
Position pos7(x, -y, z); // Back Right Bottom
switch (draw_mode)
{
case DrawMode::DRAW_POINTS:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(8, 8);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[4].set_position(pos4);
mesh->vertices[5].set_position(pos5);
mesh->vertices[6].set_position(pos6);
mesh->vertices[7].set_position(pos7);
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 3;
mesh->indices[3] = 3;
mesh->indices[4] = 4;
mesh->indices[5] = 5;
mesh->indices[6] = 6;
mesh->indices[7] = 7;
return mesh;
case DrawMode::DRAW_LINES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(8, 24);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[4].set_position(pos4);
mesh->vertices[5].set_position(pos5);
mesh->vertices[6].set_position(pos6);
mesh->vertices[7].set_position(pos7);
// Front
mesh->indices[0] = 0;
mesh->indices[1] = 1;
mesh->indices[2] = 1;
mesh->indices[3] = 2;
mesh->indices[4] = 2;
mesh->indices[5] = 3;
mesh->indices[6] = 3;
mesh->indices[7] = 0;
// Back
mesh->indices[8] = 4;
mesh->indices[9] = 5;
mesh->indices[10] = 5;
mesh->indices[11] = 6;
mesh->indices[12] = 6;
mesh->indices[13] = 7;
mesh->indices[14] = 7;
mesh->indices[15] = 4;
// Connecting
mesh->indices[16] = 0;
mesh->indices[17] = 4;
mesh->indices[18] = 1;
mesh->indices[19] = 5;
mesh->indices[20] = 2;
mesh->indices[21] = 6;
mesh->indices[22] = 3;
mesh->indices[23] = 7;
return mesh;
case DrawMode::DRAW_TRIANGLES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(8, 36);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[4].set_position(pos4);
mesh->vertices[5].set_position(pos5);
mesh->vertices[6].set_position(pos6);
mesh->vertices[7].set_position(pos7);
// Counter Clockwise
// Front
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 0;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
// Right
mesh->indices[6] = 3;
mesh->indices[7] = 7;
mesh->indices[8] = 2;
mesh->indices[9] = 2;
mesh->indices[10] = 7;
mesh->indices[11] = 6;
// Back
mesh->indices[12] = 7;
mesh->indices[13] = 5;
mesh->indices[14] = 6;
mesh->indices[15] = 6;
mesh->indices[16] = 5;
mesh->indices[17] = 4;
// Left
mesh->indices[18] = 5;
mesh->indices[19] = 1;
mesh->indices[20] = 4;
mesh->indices[21] = 4;
mesh->indices[22] = 1;
mesh->indices[23] = 0;
// Top
mesh->indices[24] = 0;
mesh->indices[25] = 2;
mesh->indices[26] = 4;
mesh->indices[27] = 4;
mesh->indices[28] = 2;
mesh->indices[29] = 6;
// Bottom
mesh->indices[30] = 5;
mesh->indices[31] = 7;
mesh->indices[32] = 1;
mesh->indices[33] = 1;
mesh->indices[34] = 7;
mesh->indices[35] = 3;
return mesh;
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw EXCEPTION("Unable to gen_cube for current draw mode: " + std::to_string(draw_mode));
}
}
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* gen_cube_pt(const DrawMode& draw_mode, float width, float height, float depth)
{
Mesh<VertexType, IndexType>* mesh;
float x = width / 2.0f;
float y = height / 2.0f;
float z = depth / 2.0f;
Position pos0(-x, y, -z); // Front Left Top
Position pos1(-x, -y, -z); // Front Left Bottom
Position pos2(x, y, -z); // Front Right Top
Position pos3(x, -y, -z); // Front Right Bottom
Position pos4(-x, y, z); // Back Left Top
Position pos5(-x, -y, z); // Back Left Bottom
Position pos6(x, y, z); // Back Right Top
Position pos7(x, -y, z); // Back Right Bottom
Normal front(0.0f, 0.0f, -1.0f);
Normal right(1.0f, 0.0f, 0.0f);
Normal back(0.0f, 0.0f, 1.0f);
Normal left(-1.0f, 0.0f, 0.0f);
Normal top(0.0f, 1.0f, 0.0f);
Normal bottom(0.0f, -1.0f, 0.0f);
UV front_tr(0.0000000f, 1.0f);
UV front_br(0.0000000f, 0.0f);
UV front_tl(0.1666666f, 1.0f);
UV front_bl(0.1666666f, 0.0f);
UV right_tr(0.1666666f, 1.0f);
UV right_br(0.1666666f, 0.0f);
UV right_tl(0.3333333f, 1.0f);
UV right_bl(0.3333333f, 0.0f);
UV back_tr(0.3333333f, 1.0f);
UV back_br(0.3333333f, 0.0f);
UV back_tl(0.5000000f, 1.0f);
UV back_bl(0.5000000f, 0.0f);
UV left_tr(0.5000000f, 1.0f);
UV left_br(0.5000000f, 0.0f);
UV left_tl(0.6666666f, 1.0f);
UV left_bl(0.6666666f, 0.0f);
UV top_tr(0.6666666f, 1.0f);
UV top_br(0.6666666f, 0.0f);
UV top_tl(0.8333333f, 1.0f);
UV top_bl(0.8333333f, 0.0f);
UV bottom_tr(0.8333333f, 1.0f);
UV bottom_br(0.8333333f, 0.0f);
UV bottom_tl(1.0000000f, 1.0f);
UV bottom_bl(1.0000000f, 0.0f);
switch (draw_mode)
{
case DrawMode::DRAW_TRIANGLES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(24, 36);
mesh->vertices[0].set_uv(front_tr);
mesh->vertices[1].set_uv(front_br);
mesh->vertices[2].set_uv(front_tl);
mesh->vertices[3].set_uv(front_bl);
mesh->vertices[4].set_uv(right_tr);
mesh->vertices[5].set_uv(right_br);
mesh->vertices[6].set_uv(right_tl);
mesh->vertices[7].set_uv(right_bl);
mesh->vertices[8].set_uv(back_tr);
mesh->vertices[9].set_uv(back_br);
mesh->vertices[10].set_uv(back_tl);
mesh->vertices[11].set_uv(back_bl);
mesh->vertices[12].set_uv(left_tr);
mesh->vertices[13].set_uv(left_br);
mesh->vertices[14].set_uv(left_tl);
mesh->vertices[15].set_uv(left_bl);
mesh->vertices[16].set_uv(top_tr);
mesh->vertices[17].set_uv(top_br);
mesh->vertices[18].set_uv(top_tl);
mesh->vertices[19].set_uv(top_bl);
mesh->vertices[20].set_uv(bottom_tr);
mesh->vertices[21].set_uv(bottom_br);
mesh->vertices[22].set_uv(bottom_tl);
mesh->vertices[23].set_uv(bottom_bl);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[4].set_position(pos2);
mesh->vertices[5].set_position(pos3);
mesh->vertices[6].set_position(pos6);
mesh->vertices[7].set_position(pos7);
mesh->vertices[8].set_position(pos6);
mesh->vertices[9].set_position(pos7);
mesh->vertices[10].set_position(pos4);
mesh->vertices[11].set_position(pos5);
mesh->vertices[12].set_position(pos4);
mesh->vertices[13].set_position(pos5);
mesh->vertices[14].set_position(pos0);
mesh->vertices[15].set_position(pos1);
mesh->vertices[16].set_position(pos4);
mesh->vertices[17].set_position(pos0);
mesh->vertices[18].set_position(pos6);
mesh->vertices[19].set_position(pos2);
mesh->vertices[20].set_position(pos1);
mesh->vertices[21].set_position(pos5);
mesh->vertices[22].set_position(pos3);
mesh->vertices[23].set_position(pos7);
// Counter Clockwise
// Front
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 0;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
// Right
mesh->indices[6] = 5;
mesh->indices[7] = 7;
mesh->indices[8] = 4;
mesh->indices[9] = 4;
mesh->indices[10] = 7;
mesh->indices[11] = 6;
// Back
mesh->indices[12] = 9;
mesh->indices[13] = 11;
mesh->indices[14] = 8;
mesh->indices[15] = 8;
mesh->indices[16] = 11;
mesh->indices[17] = 10;
// Left
mesh->indices[18] = 13;
mesh->indices[19] = 15;
mesh->indices[20] = 12;
mesh->indices[21] = 12;
mesh->indices[22] = 15;
mesh->indices[23] = 14;
// Top
mesh->indices[24] = 17;
mesh->indices[25] = 19;
mesh->indices[26] = 16;
mesh->indices[27] = 16;
mesh->indices[28] = 19;
mesh->indices[29] = 18;
// Bottom
mesh->indices[30] = 21;
mesh->indices[31] = 23;
mesh->indices[32] = 20;
mesh->indices[33] = 20;
mesh->indices[34] = 23;
mesh->indices[35] = 22;
return mesh;
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw EXCEPTION("Unable to gen_cube for current draw mode: " + std::to_string(draw_mode));
}
}
// Creates a cube centered at the origin with specified width, height, and depth
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* gen_cube_pn(const DrawMode& draw_mode, float width, float height, float depth)
{
//static_assert(std::is_base_of<Positioned, VertexType>::value, "VertexType must be Positioned");
//static_assert(std::is_base_of<Normaled, VertexType>::value, "VertexType must be Normaled");
Mesh<VertexType, IndexType>* mesh;
float x = width / 2.0f;
float y = height / 2.0f;
float z = depth / 2.0f;
Position pos0(-x, y, -z); // Front Left Top
Position pos1(-x, -y, -z); // Front Left Bottom
Position pos2(x, y, -z); // Front Right Top
Position pos3(x, -y, -z); // Front Right Bottom
Position pos4(-x, y, z); // Back Left Top
Position pos5(-x, -y, z); // Back Left Bottom
Position pos6(x, y, z); // Back Right Top
Position pos7(x, -y, z); // Back Right Bottom
Normal front(0.0f, 0.0f, -1.0f);
Normal right(1.0f, 0.0f, 0.0f);
Normal back(0.0f, 0.0f, 1.0f);
Normal left(-1.0f, 0.0f, 0.0f);
Normal top(0.0f, 1.0f, 0.0f);
Normal bottom(0.0f, -1.0f, 0.0f);
switch (draw_mode)
{
case DrawMode::DRAW_TRIANGLES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(24, 36);
mesh->vertices[0].set_normal(front);
mesh->vertices[1].set_normal(front);
mesh->vertices[2].set_normal(front);
mesh->vertices[3].set_normal(front);
mesh->vertices[4].set_normal(right);
mesh->vertices[5].set_normal(right);
mesh->vertices[6].set_normal(right);
mesh->vertices[7].set_normal(right);
mesh->vertices[8].set_normal(back);
mesh->vertices[9].set_normal(back);
mesh->vertices[10].set_normal(back);
mesh->vertices[11].set_normal(back);
mesh->vertices[12].set_normal(left);
mesh->vertices[13].set_normal(left);
mesh->vertices[14].set_normal(left);
mesh->vertices[15].set_normal(left);
mesh->vertices[16].set_normal(top);
mesh->vertices[17].set_normal(top);
mesh->vertices[18].set_normal(top);
mesh->vertices[19].set_normal(top);
mesh->vertices[20].set_normal(bottom);
mesh->vertices[21].set_normal(bottom);
mesh->vertices[22].set_normal(bottom);
mesh->vertices[23].set_normal(bottom);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->vertices[4].set_position(pos2);
mesh->vertices[5].set_position(pos3);
mesh->vertices[6].set_position(pos6);
mesh->vertices[7].set_position(pos7);
mesh->vertices[8].set_position(pos6);
mesh->vertices[9].set_position(pos7);
mesh->vertices[10].set_position(pos4);
mesh->vertices[11].set_position(pos5);
mesh->vertices[12].set_position(pos4);
mesh->vertices[13].set_position(pos5);
mesh->vertices[14].set_position(pos0);
mesh->vertices[15].set_position(pos1);
mesh->vertices[16].set_position(pos4);
mesh->vertices[17].set_position(pos0);
mesh->vertices[18].set_position(pos6);
mesh->vertices[19].set_position(pos2);
mesh->vertices[20].set_position(pos1);
mesh->vertices[21].set_position(pos5);
mesh->vertices[22].set_position(pos3);
mesh->vertices[23].set_position(pos7);
// Counter Clockwise
// Front
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 0;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
// Right
mesh->indices[6] = 5;
mesh->indices[7] = 7;
mesh->indices[8] = 4;
mesh->indices[9] = 4;
mesh->indices[10] = 7;
mesh->indices[11] = 6;
// Back
mesh->indices[12] = 9;
mesh->indices[13] = 11;
mesh->indices[14] = 8;
mesh->indices[15] = 8;
mesh->indices[16] = 11;
mesh->indices[17] = 10;
// Left
mesh->indices[18] = 13;
mesh->indices[19] = 15;
mesh->indices[20] = 12;
mesh->indices[21] = 12;
mesh->indices[22] = 15;
mesh->indices[23] = 14;
// Top
mesh->indices[24] = 17;
mesh->indices[25] = 19;
mesh->indices[26] = 16;
mesh->indices[27] = 16;
mesh->indices[28] = 19;
mesh->indices[29] = 18;
// Bottom
mesh->indices[30] = 21;
mesh->indices[31] = 23;
mesh->indices[32] = 20;
mesh->indices[33] = 20;
mesh->indices[34] = 23;
mesh->indices[35] = 22;
return mesh;
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_TRIANGLE_STRIP:
case DrawMode::DRAW_TRIANGLE_FAN:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw EXCEPTION("Unable to gen_cube for current draw mode: " + std::to_string(draw_mode));
}
}
// TODO: Mesh<PNTVertex, Index>* gen_cube(const DrawMode& draw_mode, float width, float height, float depth);
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* gen_rect_p(const DrawMode& draw_mode, float width, float height, float offset_x = 0.0f, float offset_y = 0.0f)
{
float half_width = width / 2.0f;
float half_height = height / 2.0f;
Mesh<VertexType, IndexType>* mesh;
Position pos0(offset_x - half_width, offset_y - half_height, 0.0f);
Position pos1(offset_x - half_width, offset_y + half_height, 0.0f);
Position pos2(offset_x + half_width, offset_y - half_height, 0.0f);
Position pos3(offset_x + half_width, offset_y + half_height, 0.0f);
switch (draw_mode)
{
case DrawMode::DRAW_TRIANGLES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 6);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 0;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
return mesh;
case DrawMode::DRAW_TRIANGLE_STRIP:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 2;
return mesh;
case DrawMode::DRAW_TRIANGLE_FAN:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 2;
mesh->indices[3] = 0;
return mesh;
case DrawMode::DRAW_POINTS: // TODO: Point, lines, line_strip, line_loop
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw EXCEPTION("Unable to gen_rect_pt for current draw mode: " + std::to_string(draw_mode));
}
}
template <typename VertexType, typename IndexType>
Mesh<VertexType, IndexType>* gen_rect_pt(const DrawMode& draw_mode, float width, float height, float offset_x = 0.0f, float offset_y = 0.0f)
{
float half_width = width / 2.0f;
float half_height = height / 2.0f;
Mesh<VertexType, IndexType>* mesh;
Position pos0(offset_x - half_width, offset_y - half_width, 0.0f);
Position pos1(offset_x - half_width, offset_y + half_width, 0.0f);
Position pos2(offset_x + half_width, offset_y - half_width, 0.0f);
Position pos3(offset_x + half_width, offset_y + half_width, 0.0f);
UV uv0(0.0f, 1.0f);
UV uv1(0.0f, 0.0f);
UV uv2(1.0f, 1.0f);
UV uv3(1.0f, 0.0f);
switch (draw_mode)
{
case DrawMode::DRAW_TRIANGLES:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 6);
mesh->vertices[0].set_uv(uv0);
mesh->vertices[1].set_uv(uv1);
mesh->vertices[2].set_uv(uv2);
mesh->vertices[3].set_uv(uv3);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 0;
mesh->indices[4] = 3;
mesh->indices[5] = 2;
return mesh;
case DrawMode::DRAW_TRIANGLE_STRIP:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_uv(uv0);
mesh->vertices[1].set_uv(uv1);
mesh->vertices[2].set_uv(uv2);
mesh->vertices[3].set_uv(uv3);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 0;
mesh->indices[3] = 2;
return mesh;
case DrawMode::DRAW_TRIANGLE_FAN:
mesh = MeshFactory<VertexType, IndexType>::create_mesh(4, 4);
mesh->vertices[0].set_uv(uv0);
mesh->vertices[1].set_uv(uv1);
mesh->vertices[2].set_uv(uv2);
mesh->vertices[3].set_uv(uv3);
mesh->vertices[0].set_position(pos0);
mesh->vertices[1].set_position(pos1);
mesh->vertices[2].set_position(pos2);
mesh->vertices[3].set_position(pos3);
mesh->indices[0] = 1;
mesh->indices[1] = 3;
mesh->indices[2] = 2;
mesh->indices[3] = 0;
return mesh;
case DrawMode::DRAW_POINTS:
case DrawMode::DRAW_LINES:
case DrawMode::DRAW_LINE_STRIP:
case DrawMode::DRAW_LINE_LOOP:
case DrawMode::DRAW_LINE_STRIP_ADJACENCY:
case DrawMode::DRAW_LINES_ADJACENCY:
case DrawMode::DRAW_TRIANGLE_STRIP_ADJACENCY:
case DrawMode::DRAW_TRIANGLES_ADJACENCY:
case DrawMode::DRAW_PATCHES:
default:
throw EXCEPTION("Unable to gen_rect_pt for current draw mode: " + std::to_string(draw_mode));
}
}
}
}
}