/*
								+----------------------------------+
								|                                  |
								|  ***  Texcoords generators  ***  |
								|                                  |
								|   Copyright © -tHE SWINe- 2007   |
								|                                  |
								|           TexCoords.h            |
								|                                  |
								+----------------------------------+
*/

#pragma once
#ifndef __TEXCOORDS_GENERATOR_INCLUDED
#define __TEXCOORDS_GENERATOR_INCLUDED

/**
 *	@file dev/TexCoords.h
 *	@date 2007
 *	@author -tHE SWINe-
 *	@brief Texcoords generators
 *
 *	@date 2008-06-24
 *
 *	renamed CPolygon2::r_t_Vertex() and CPolyMesh::r_t_Vertex() to
 *	CPolygon2::r_Vertex() and CPolyMesh::r_Vertex() respectively
 *
 *	@date 2008-08-21
 *
 *	unified gizmo semantics, unit gizmo matrix should transform mesh bounding
 *	box to axis-aligned unit cube with one of corners at O and some other one at (1, 1, 1)
 *
 *	removed map_Cylinder_Caps cap texcoord scaling
 *
 *	added CTexCoordGen::t_Gizmo() for calculating unit gizmo matrix
 *
 *	@date 2009-05-23
 *
 *	removed all instances of std::vector::reserve and replaced them by stl_ut::Reserve_*
 *
 *	@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.
 *
 */

class CTexCoordGen {
public:
	enum {
		map_Plane,
		map_Box,
		map_Sphere,
		map_Cylinder,
		map_Cylinder_Caps
	};

	/*
	 *	static Matrix4f CTexCoordGen::t_Gizmo(CPolyMesh &r_t_mesh)
	 *		- creates (unit) textcoord mapping gizmo for mesh r_t_mesh
	 *		- returns matrix for transforming vertex positions to positions inside mapping gizmo
	 */
	static Matrix4f t_Gizmo(CPolyMesh &r_t_mesh);

	/*
	 *	static Matrix4f CTexCoordGen::t_Gizmo(Vector3f v_min, Vector3f v_max)
	 *		- creates (unit) textcoord mapping gizmo for mesh with bounding
	 *		  box given by it's two corners (v_min, v_max)
	 *		- returns matrix for transforming vertex positions to positions inside mapping gizmo
	 */
	static Matrix4f t_Gizmo(Vector3f v_min, Vector3f v_max);

	/*
	 *	static bool CTexCoordGen::CalcTexcoords(CPolyMesh &r_t_mesh, Matrix4f t_gizmo_transform,
	 *		int n_map_type, int n_channel, int n_coord_s = 0, int n_coord_t = 1)
	 *		- calculates 2D texcoords for mesh r_t_mesh
	 *		- t_gizmo_transform is matrix for transforming vertex positions to positions
	 *		  inside mapping gizmo (such transformation that vertex coordinates are transformed
	 *		  to unit cube with center at (.5, .5, .5))
	 *		- n_map_type is one of map_Plane, map_Box, map_Sphere,
	 *		  map_Cylinder or map_Cylinder_Caps (note all but map_Plane explodes vertices)
	 *		- note map_Box and map_Cylinder_Caps require correct polygon normals
	 *		- n_channel is output texture channel (currently 0 - 3)
	 *		- n_coord_s is index of vector component where s coordinate is to be stored (0 - 3)
	 *		- n_coord_t is index of vector component where t coordinate is to be stored (0 - 3)
	 *		- returns true on success, false on failure (needs to create some tables)
	 */
	static bool CalcTexcoords(CPolyMesh &r_t_mesh, Matrix4f t_gizmo_transform,
		int n_map_type, int n_channel, int n_coord_s = 0, int n_coord_t = 1);

	/*
	 *	static void CTexCoordGen::CalcTangents(CPolyMesh &r_t_mesh,
	 *		int n_channel_in, int n_channel_out)
	 *		- calculates tangents of texture, mapped to coordinates n_coord_s and
	 *		  n_coord_t of channel n_channel_in
	 *		- writes binormal direction and texture polarity to n_channel_out
	 *		  (takes up the whole channel)
	 *		- note texture polarity is either 1 or -1, face and vertex normals are
	 *		  required to calculate it
	 *		- f_angle_thresh is maximal angle between tangents of faces for their vertices to break
	 *		- returns true on success, false on failure (needs to create some tables)
	 */
	static bool CalcTangents(CPolyMesh &r_t_mesh, int n_channel_in,
		int n_coord_s, int n_coord_t, int n_channel_out, float f_angle_thresh = f_pi * .125f,
		uint32_t n_face_flags_mask = -1, int n_face_material_mask = -1);

protected:
	template <class CCoordSelector>
	static void CalcAzimuth(const std::vector<Vector3f> &r_pos_list,
		std::vector<float> &r_azimuth_list, CCoordSelector selector);
};

#endif // __TEXCOORDS_GENERATOR_INCLUDED
