#include "StdAfx.h"

#include "CrossSectionUnit.h"

#include "Algorithm/Geom3d.h"
#include "Algorithm/ConvexHullGen.h"



namespace lib_geo
{


void CrossSectionUnit::UpdateParams(const Plane& cut_plane)
{
	UpdateLengthRangeCenter();

	UpdateConvexVerts(cut_plane);

	UpdateConvexLength();
}

void CrossSectionUnit::UpdateLengthRangeCenter(void)
{
	m_Center.set_zero();
	m_Length = 0.0f;
	m_Range.clear();

	for (SectionSegment& ss : m_Segments)
	{
		const lm::vec3f& v0 = ss.p0;
		const lm::vec3f& v1 = ss.p1;

		float l = (v0 - v1).length();
		m_Length += l;
		m_Center += (v0 + v1) * 0.5f * l;

		m_Range.expand( v0 );
		m_Range.expand( v1 );
	}

	m_Center /= m_Length;
}

void CrossSectionUnit::UpdateConvexVerts(const Plane& cut_plane)
{
	std::vector<lm::vec3f> points( m_Segments.size() * 2 );
	for( size_t i = 0 ; i < m_Segments.size() ; ++i )
	{
		points[ i * 2 + 0 ] = m_Segments[i].p0;
		points[ i * 2 + 1 ] = m_Segments[i].p1;
	}

	lm::vec3f cut_n = cut_plane.normal;
	float nx = fabs(cut_n.x);
	float ny = fabs(cut_n.y);
	float nz = fabs(cut_n.z);

	lm::vec3f cut_binormal;
	if(nx <= ny && nx <= nz)
		cut_binormal.set(1.0f, 0.0f, 0.0f);
	else if(ny <= nz && ny <= nx)
		cut_binormal.set(0.0f, 1.0f, 0.0f);
	else
		cut_binormal.set(0.0f, 0.0f, 1.0f);

	lm::vec3f cut_up = cross(cut_n, cut_binormal).get_normalize();

	m_ConvexVerts.clear();
	ConvexHullGen2d gen;
	gen.Generate(points, cut_n, cut_up, m_ConvexVerts);
}

void CrossSectionUnit::UpdateConvexLength(void)
{
	m_ConvexLength = 0.0f;
	for( size_t i = 0 ; i < m_ConvexVerts.size() ; ++i )
	{
		const lm::vec3f& v0 = m_ConvexVerts[i];
		const lm::vec3f& v1 = m_ConvexVerts[(i+1)%m_ConvexVerts.size()];

		m_ConvexLength += (v0 - v1).length();
	}
}


}

