/*
	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License version 2 
	as published by the Free Software Foundation.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA


	Copyright (C) 2006  Thierry Berger-Perrin <tbptbp@gmail.com>
*/
#ifndef KDLIB_CLIPPER_H_
#define KDLIB_CLIPPER_H_

#include "specifics.h"
#include "kdlib.h"
#include "kdlib_internal.h"

namespace kdlib {
	// triangle vs plane/box clipper (Sutherland - Hodgman).
	struct clipper_t {
		// We feed it triangles, so we might end up with n+6 planes = 9 vertices.
		// that will bring like n-2 triangles. ah.
		enum { max_transients = 16 };

		vec_t	clipped[max_transients];	// holds the current clipped triangle (well, poly).
		vec_t	temp[max_transients];		

		int_t	ccount;	// holds the current number of vertices (>= 3)

		// clips vertices against a plane
		template <bool lower_bound> NOINLINE bool_t clip_plane(const aabb_t &box, const uint_t axis);

		// does the per plane clipping for all planes
		//and then updates the bounding box for that triangle
		int clip_triangle(const aabb_t &box, const triangle_t &tri);

		// extract the bounding box back from clipped poly.
		aabb_t extract_aabb() const {
			#ifndef NDEBUG
				//if (ccount < 3
			#endif

			vec_t
				min(clipped[0]),
				max(clipped[0]);
			for (int i=1; i<ccount; ++i) {
				min.x = minf(min.x, clipped[i].x);
				min.y = minf(min.y, clipped[i].y);
				min.z = minf(min.z, clipped[i].z);

				max.x = maxf(max.x, clipped[i].x);
				max.y = maxf(max.y, clipped[i].y);
				max.z = maxf(max.z, clipped[i].z);
			}

			return aabb_t(min,max);
		}
	};
}

#endif
