
/*
-----------------------------------------------------------------------------
This source file is part of GIMPACT Library.

For the latest info, see http://gimpact.sourceforge.net/

Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371.
email: projectileman@yahoo.com

 This library is free software; you can redistribute it and/or
 modify it under the terms of EITHER:
   (1) The GNU Lesser General Public License as published by the Free
       Software Foundation; either version 2.1 of the License, or (at
       your option) any later version. The text of the GNU Lesser
       General Public License is included with this library in the
       file GIMPACT-LICENSE-LGPL.TXT.
   (2) The BSD-style license that is included with this library in
       the file GIMPACT-LICENSE-BSD.TXT.
   (3) The zlib/libpng license that is included with this library in
       the file GIMPACT-LICENSE-ZLIB.TXT.

 This library 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 files
 GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details.

-----------------------------------------------------------------------------
*/

#include "BulletCollision/Gimpact/gim_contact.h"

#define MAX_COINCIDENT 8

void gim_contact_array::merge_contacts(
	const gim_contact_array & contacts, bool normal_contact_average)
{
	clear();

	if(contacts.size()==1)
	{
		push_back(contacts.back());
		return;
	}

	gim_array<GIM_RSORT_TOKEN> keycontacts(contacts.size());
	keycontacts.resize(contacts.size(),false);

	//fill key contacts

	GUINT i;

	for (i = 0;i<contacts.size() ;i++ )
	{
		keycontacts[i].m_key = contacts[i].calc_key_contact();
		keycontacts[i].m_value = i;
	}

	//sort keys
	gim_heap_sort(keycontacts.pointer(),keycontacts.size(),GIM_RSORT_TOKEN_COMPARATOR());

	// Merge contacts

	GUINT coincident_count=0;
	btVector3 coincident_normals[MAX_COINCIDENT];

	GUINT last_key = keycontacts[0].m_key;
	GUINT key = 0;

	push_back(contacts[keycontacts[0].m_value]);
	GIM_CONTACT * pcontact = &back();



	for( i=1;i<keycontacts.size();i++)
	{
	    key = keycontacts[i].m_key;
		const GIM_CONTACT * scontact = &contacts[keycontacts[i].m_value];

		if(last_key ==  key)//same points
		{
			//merge contact
			if(pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//)
			{
				*pcontact = *scontact;
                coincident_count = 0;
			}
			else if(normal_contact_average)
			{
				if(btFabs(pcontact->m_depth - scontact->m_depth)<CONTACT_DIFF_EPSILON)
                {
                    if(coincident_count<MAX_COINCIDENT)
                    {
                    	coincident_normals[coincident_count] = scontact->m_normal;
                        coincident_count++;
                    }
                }
			}
		}
		else
		{//add new contact

		    if(normal_contact_average && coincident_count>0)
		    {
		    	pcontact->interpolate_normals(coincident_normals,coincident_count);
		        coincident_count = 0;
		    }

		    push_back(*scontact);
		    pcontact = &back();
        }
		last_key = key;
	}
}

void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts)
{
	clear();

	if(contacts.size()==1)
	{
		push_back(contacts.back());
		return;
	}

	GIM_CONTACT average_contact = contacts.back();

	for (GUINT i=1;i<contacts.size() ;i++ )
	{
		average_contact.m_point += contacts[i].m_point;
		average_contact.m_normal += contacts[i].m_normal * contacts[i].m_depth;
	}

	//divide
	GREAL divide_average = 1.0f/((GREAL)contacts.size());

	average_contact.m_point *= divide_average;

	average_contact.m_normal *= divide_average;

	average_contact.m_depth = average_contact.m_normal.length();

	average_contact.m_normal /= average_contact.m_depth;

}

