/*
								+----------------------------------+
								|                                  |
								|  ***  Platonic primitives  ***   |
								|                                  |
								|   Copyright © -tHE SWINe- 2007   |
								|                                  |
								|            PlatPrim.h            |
								|                                  |
								+----------------------------------+
*/

#pragma once
#ifndef __PLATONIC_PRIMITIVE_GENERATOR_INCLUDED
#define __PLATONIC_PRIMITIVE_GENERATOR_INCLUDED

/**
 *	@file dev/PlatPrim.h
 *	@date 2007
 *	@author -tHE SWINe-
 *	@brief platonic primitives
 *
 *	@date 2008-06-24
 *
 *	renamed CPolygon2::r_t_Vertex() and CPolyMesh::r_t_Vertex() to
 *	CPolygon2::r_Vertex() and CPolyMesh::r_Vertex() respectively
 *
 *	@date 2009-10-20
 *
 *	fixed some warnings when compiling under VC 2005, implemented "Security
 *	Enhancements in the CRT" for VC 2008. compare against MyProjects_2009-10-19_
 *
 *	@date 2012-06-19
 *
 *	Moved multiple inclusion guard before file documentation comment.
 *
 */

#include "PolyMesh.h"

#define PLATONIC_PRIMITIVES_GENERATE_TEXCOORDS
// if defined, 2D texture coordinates are automatically generated in channel 0
// when creating mesh, unless specified otherwise

/*
 *	class CPlatonicPrimitives
 *		- platonic primitive mesh generator
 */
class CPlatonicPrimitives {
public:
	/*
	 *	static bool CPlatonicPrimitives::MakeSphere(CPolyMesh &r_t_mesh,
	 *		int n_tess_axis, int n_tess_radius)
	 *		- makes unit sphere mesh (sphere has center at O and radius 1)
	 *		- mesh is tesselated to n_tess_axis segments along y-axis and
	 *		  to n_tess_radius arround y-axis
	 *		- returns true on success, false on failure
	 */
	static bool MakeSphere(CPolyMesh &r_t_mesh, int n_tess_axis, int n_tess_radius);

	/*
	 *	static bool CPlatonicPrimitives::MakeCube(CPolyMesh &r_t_mesh,
	 *		int n_tess_x, int n_tess_y, int n_tess_z)
	 *		- makes unit cube mesh (axis-aligned cube with min vertex
	 *		  at (-1, -1, -1) and max vertex at (1, 1, 1))
	 *		- mesh is tesselated to n_tess_x segments along x-axis,
	 *		  n_tess_y along y-axis and n_tess_z along z-axis
	 *		- returns true on success, false on failure
	 */
	static bool MakeCube(CPolyMesh &r_t_mesh, int n_tess_x, int n_tess_y, int n_tess_z);

	/*
	 *	static bool CPlatonicPrimitives::MakePlane(CPolyMesh &r_t_mesh,
	 *		int n_tess_x, int n_tess_y)
	 *		- makes unit plane mesh (x-z plane with min vertex
	 *		  at (-1, 0, -1) and max vertex at (1, 0, 1))
	 *		- mesh is tesselated to n_tess_x segments along x-axis and
	 *		  n_tess_y segments along y-axis
	 *		- returns true on success, false on failure
	 */
	static bool MakePlane(CPolyMesh &r_t_mesh, int n_tess_x, int n_tess_y);

	/*
	 *	static bool CPlatonicPrimitives::MakeCylinder(CPolyMesh &r_t_mesh, int n_tess_axis,
	 *		int n_tess_radius, int n_cap_tess)
	 *		- creates cylinder mesh (cylinder axis is identical to y-axis, radius is 1,
	 *		  bottom cap is at y = -1, top cap is at y = 1)
	 *		- mesh is tesselated to n_tess_axis segments along cylinder axis and
	 *		  to n_tess_radius arround cylinder axis
	 *		- in case n_cap_tess is greater than zero, cap faces are generated
	 *		- returns true on success, false on failure
	 */
	static bool MakeCylinder(CPolyMesh &r_t_mesh, int n_tess_axis, int n_tess_radius, int n_cap_tess);

	/*
	 *	static bool CPlatonicPrimitives::MakeCone(CPolyMesh &r_t_mesh, int n_tess_axis,
	 *		int n_tess_radius, int n_cap_tess)
	 *		- creates cone mesh (cone axis is identical to y-axis, base radius is 1,
	 *		  base lies at y = -1, top vertex is at y = 1)
	 *		- mesh is tesselated to n_tess_axis segments along cylinder axis and
	 *		  to n_tess_radius arround cylinder axis
	 *		- in case n_cap_tess is greater than zero, cap faces are generated
	 *		- returns true on success, false on failure
	 */
	static bool MakeCone(CPolyMesh &r_t_mesh, int n_tess_axis, int n_tess_radius, int n_cap_tess);

	/*
	 *	static bool CPlatonicPrimitives::MakeTube(CPolyMesh &r_t_mesh, int n_tess_axis,
	 *		int n_tess_radius, float f_inner_radius)
	 *		- creates tube mesh (tube axis is identical to y-axis, radius is 1,
	 *		  inner radius is f_inner_radius, bottom cap is at y = -1, top cap is at y = 1)
	 *		- mesh is tesselated to n_tess_axis segments along cylinder axis and
	 *		  to n_tess_radius arround cylinder axis
	 *		- in case n_cap_tess is greater than zero, cap faces are generated
	 *		- returns true on success, false on failure
	 */
	static bool MakeTube(CPolyMesh &r_t_mesh, int n_tess_axis,
		int n_tess_radius, float f_inner_radius);

	/*
	 *	static bool CPlatonicPrimitives::MakeTorus(CPolyMesh &r_t_mesh, int n_tess_major,
	 *		int n_tess_minor, float f_minor_radius)
	 *		- creates torus (annuloid); center is at O, major radius is 1 and lies on x-z plane
	 *		- minor radius is f_minor_radius
	 *		- torus is tesselated to n_tess_major segments arround major radius and
	 *		  to n_tess_minor segments arround minor radius
	 *		- returns true on success, false on failure
	 */
	static bool MakeTorus(CPolyMesh &r_t_mesh, int n_tess_major,
		int n_tess_minor, float f_minor_radius);

	/*
	 *	static bool CPlatonicPrimitives::WindGrid(CPolyMesh &r_t_mesh, int n_face, int n_vertex,
	 *		int n_size_x, int n_size_y, bool b_flip = false)
	 *		- creates winding of grid of n_size_x * n_size_y quads (requires
	 *		  (n_size_x + 1) * (n_size_y + 1) vertices and n_size_x * n_size_y * quads)
	 *		- r_t_mesh is mesh where grid should be generated
	 *		- n_face is the first face of grid
	 *		- n_vertex is the first vertex of grid
	 *		- n_size_x and n_size_y are grid dimensions
	 *		- in case b_flip is true, faces are wound with reversed vertex order
	 */
	static bool WindGrid(CPolyMesh &r_t_mesh, int n_face, int n_vertex,
		int n_size_x, int n_size_y, bool b_flip = false);

	/*
	 *	static bool CPlatonicPrimitives::WindFan(CPolyMesh &r_t_mesh, int n_face,
	 *		int n_center_vertex, int n_fan_vertex, int n_fan_length,
	 *		bool b_loop = true, bool b_flip = false);
	 *		- creates winding of triangle fan
	 *		- n_face points to first face of triangle fan
	 *		- n_center_vertex points to shared vertex of triangle fan
	 *		- n_fan_vertex points to satellite vertices of triangle fan
	 *		- n_fan_length is number of satellite vertices forming fan
	 *		- in case b_loop is true, face between first and last fan vertex is created
	 *		  (n_fan_length faces is created; otherwise n_fan_length - 1)
	 *		- in case b_flip is true, faces are wound with reversed vertex order
	 */
	static bool WindFan(CPolyMesh &r_t_mesh, int n_face, int n_center_vertex, int n_fan_vertex,
		int n_fan_length, bool b_loop = true, bool b_flip = false);

	/*
	 *	static bool CPlatonicPrimitives::WindSection(CPolyMesh &r_t_mesh, int n_face,
	 *		int n_left_vertex, int n_right_vertex, int n_section_length,
	 *		bool b_loop = true, bool b_flip = false)
	 *		- wind quadriliteral section between left and right vertices
	 *		- n_face points to first face of section
	 *		- n_left_vertex points to left vertices of section
	 *		- n_right_vertex points to right vertices of section
	 *		- n_section_length is number of section vertices (there's
	 *		  n_section_length vertices in both left and right array)
	 *		- in case b_loop is true, quad between first and last section vertices is created
	 *		  (n_section_length quads is created; otherwise n_section_length - 1)
	 *		- in case b_flip is true, faces are wound with reversed vertex order
	 */
	static bool WindSection(CPolyMesh &r_t_mesh, int n_face, int n_left_vertex,
		int n_right_vertex, int n_section_length, bool b_loop, bool b_flip);
};

#endif // __PLATONIC_PRIMITIVE_GENERATOR_INCLUDED
