/******************************************************************/
/* This file is part of the homework assignments for CSCI-427/527 */
/* at The College of William & Mary and authored by Pieter Peers. */
/* No part of this file, whether altered or in original form, can */
/* be distributed or used outside the context of CSCI-427/527 */
/* without consent of either the College of William & Mary or */
/* Pieter Peers. */
/******************************************************************/
#ifndef _TRIANGLE_H_
#define _TRIANGLE_H_
#include <array>
#include <vector>
#include <memory>
#include <ostream>
#include "ray.h"
#include "vec2d.h"
#include "vec3d.h"
#include "boundingBox.h"
class triangle {
public:
//////////////////
// Constructors //
//////////////////
triangle(void);
triangle(const triangle& t);
triangle(triangle&& t);
triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3);
triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list);
triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3,
const vec3d& n1, const vec3d& n2, const vec3d& n3);
triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list,
size_t n1_idx, size_t n2_idx, size_t n3_idx, const std::shared_ptr<const std::vector<vec3d>>& normal_list);
triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3,
const vec2d& t1, const vec2d& t2, const vec2d& t3);
triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list,
size_t t1_idx, size_t t2_idx, size_t t3_idx, const std::shared_ptr<const std::vector<vec2d>>& texcoord_list);
triangle(const vec3d& v1, const vec3d& v2, const vec3d& v3,
const vec3d& n1, const vec3d& n2, const vec3d& n3,
const vec2d& t1, const vec2d& t2, const vec2d& t3);
triangle(size_t v1_idx, size_t v2_idx, size_t v3_idx, const std::shared_ptr<const std::vector<vec3d>>& vertex_list,
size_t n1_idx, size_t n2_idx, size_t n3_idx, const std::shared_ptr<const std::vector<vec3d>>& normal_list,
size_t t1_idx, size_t t2_idx, size_t t3_idx, const std::shared_ptr<const std::vector<vec2d>>& texcoord_list);
////////////////
// Inspectors //
////////////////
const vec3d& vertex(size_t index) const;
const vec3d& normal(size_t index) const;
const vec2d& textureCoordinate(size_t index) const;
bool hasPerVertexNormals(void) const;
bool hasPerVertexTextureCoordinates(void) const;
///////////////
// Operators //
///////////////
triangle& operator=(const triangle& t);
triangle& operator=(triangle&& t);
/////////////
// Methods //
/////////////
bool intersect(const ray& r, vec3d& barycentricCoord, float& t) const;
boundingBox boundingbox(void) const;
vec3d vertex(const vec3d& barycentricCoord) const;
vec3d normal(void) const;
vec3d shadingAxis(void) const;
vec3d normal(const vec3d& barycentricCoord) const;
vec2d textureCoordinate(const vec3d& barycentricCoord) const;
vec3d sample(float r1, float r2, vec3d& barycentricCoord, float& pdf) const;
float area(void) const;
/////////////
// Friends //
/////////////
friend void swap(triangle& a, triangle& b) { a._swap(b); }
friend std::ostream& operator<<(std::ostream& s, const triangle& t)
{
s << "Triangle: v=(" << t.vertex(0) << "," << t.vertex(1) << "," << t.vertex(2) << ")";
if(t._normal_list)
s << ", n=(" << t.normal(0) << "," << t.normal(1) << "," << t.normal(2) << ")";
if(t._textureCoord_list)
s << ", t=(" << t.textureCoordinate(0) << "," << t.textureCoordinate(1) << "," << t.textureCoordinate(2) << ")";
return s;
}
private:
/////////////////////
// Private Methods //
/////////////////////
void _assign(const triangle& t);
void _swap(triangle& t);
//////////////////
// Data Members //
//////////////////
std::array<size_t, 3> _vertex_idx;
std::array<size_t, 3> _normal_idx;
std::array<size_t,3 > _textureCoord_idx;
std::shared_ptr<const std::vector<vec3d>> _vertex_list;
std::shared_ptr<const std::vector<vec3d>> _normal_list;
std::shared_ptr<const std::vector<vec2d>> _textureCoord_list;
};
#endif /* _TRIANGLE_H_ */