//-----------------------------------------------------------------------
// Triangulation by insertion
void Triangulator::delaunay(PointList& pointList, DelaunayTriangleBuffer& tbuffer)
{
	// Compute super triangle
	float maxTriangleSize = 0.f;
	for (PointList::iterator it = pointList.begin(); it!=pointList.end();it++)
	{
		maxTriangleSize = std::max<float>(maxTriangleSize,fabs(it->x));
		maxTriangleSize = std::max<float>(maxTriangleSize,fabs(it->y));
	}
	int maxTriangleIndex=pointList.size();
	pointList.push_back(Ogre::Vector2(-3*maxTriangleSize,-3*maxTriangleSize));
	pointList.push_back(Ogre::Vector2(3*maxTriangleSize,-3*maxTriangleSize));
	pointList.push_back(Ogre::Vector2(0.,3*maxTriangleSize));
	Triangle superTriangle(&pointList, tbuffer.end());
	superTriangle.i[0]= maxTriangleIndex;
	superTriangle.i[1]= maxTriangleIndex+1;
	superTriangle.i[2]= maxTriangleIndex+2;
	tbuffer.push_back(superTriangle);

	// Point insertion loop
	for (int i=0;i<pointList.size()-3;i++)
	{
		// Insert 1 point, find triangle containing it
		Vector2& p = pointList[i];
		DelaunayTriangleBuffer::iterator triangle;
		for (DelaunayTriangleBuffer::iterator it = tbuffer.begin();it!=tbuffer.end();it++)
		{
			if (it->isPointInside(p))
				triangle = it;
		}
		// Build 3 triangles and suppress old triangle
		//Triangle* subTri[3];
		DelaunayTriangleBuffer::iterator subTri[3];
		tbuffer.push_back(Triangle(&pointList, tbuffer.end()));
		subTri[0] = --tbuffer.end();
		tbuffer.push_back(Triangle(&pointList, tbuffer.end()));
		subTri[1] = --tbuffer.end();
		tbuffer.push_back(Triangle(&pointList, tbuffer.end()));
		subTri[2] = --tbuffer.end();

		subTri[0]->setVertices(triangle->i[0],triangle->i[1],i);
		subTri[1]->setVertices(triangle->i[1],triangle->i[2],i);
		subTri[2]->setVertices(triangle->i[2],triangle->i[0],i);
		subTri[0]->setAdj(subTri[1],subTri[2],triangle->adj[2], subTri[0]);
		subTri[1]->setAdj(subTri[2],subTri[0],triangle->adj[0], subTri[1]);
		subTri[2]->setAdj(subTri[0],subTri[1],triangle->adj[1], subTri[2]);
		triangle = tbuffer.erase(triangle);

		for (int k=0;k<3;k++)
		{
			DelaunayTriangleBuffer::iterator tri0 = subTri[k];
			//Check if new triangle is Delaunay
			Circle c(tri0->p(0), tri0->p(1), tri0->p(2));
			bool isDelaunay = true;
			for (int j = 0;j<i+1;j++)
			{
				if (j!=tri0->i[0] && j!=tri0->i[1] && j!=tri0->i[2])
				if (c.isPointInside(pointList[j]))
				{
					isDelaunay = false;
					break;
				}
			}
			// Flip edges where needed
			if (!isDelaunay && tri0->adj[2]!=tbuffer.end())
			{
				DelaunayTriangleBuffer::iterator tri1 = tri0->adj[2];
				tbuffer.push_back(Triangle(&pointList, tbuffer.end()));
				DelaunayTriangleBuffer::iterator newt0 = --tbuffer.end();
				tbuffer.push_back(Triangle(&pointList, tbuffer.end()));
				DelaunayTriangleBuffer::iterator newt1 = --tbuffer.end();
				int x = tri1->findSegNumber(tri0->i[0],tri0->i[1]);//opposite of common side for t1
				newt0->setVertices(tri0->i[2],tri1->i[x],tri0->i[1]);
				newt1->setVertices(tri0->i[2],tri0->i[0],tri1->i[x]);
				newt0->setAdj(tri1->adj[(x+2)%3], tri0->adj[0], newt1, newt0);
				newt1->setAdj(tri1->adj[(x+1)%3], newt0,tri0->adj[1],newt1);
				tbuffer.erase(tri0);
				tbuffer.erase(tri1);
			}
		}
	}

	//Remove super triangle
	TouchSuperTriangle touchSuperTriangle(maxTriangleIndex, maxTriangleIndex+1,maxTriangleIndex+2);
	tbuffer.remove_if(touchSuperTriangle);
	pointList.pop_back();
	pointList.pop_back();
	pointList.pop_back();
}