/* * Copyright (c) 2008-2009 Bill Whitacre http://rampancy.g0dsoft.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ #include "contact.h" #include "arbiter.h" rat_contact *rat_contact_create(rat_block_allocator *bal) { rat_contact *mem; if (bal) mem=(rat_contact *)rat_block_alloc(bal,sizeof(rat_contact)); else mem=(rat_contact *)rat_alloc(sizeof(rat_contact)); assert(mem!=NULL); memset(mem,0,sizeof(rat_contact)); mem->bal=bal; return mem; } void rat_contact_destroy(rat_contact *con) { if (con->bal) rat_block_dealloc(con->bal,(void *)con,sizeof(rat_contact)); else rat_dealloc((void *)con); } rat_contact_array *rat_alloc_contact_array(rat_block_allocator *bal,unsigned int numcons) { register unsigned int i; rat_contact_array *conarr; if (bal) conarr=(rat_contact_array *)rat_block_alloc(bal,sizeof(rat_contact_array)); else conarr=(rat_contact_array *)rat_alloc(sizeof(rat_contact_array)); memset(conarr,0,sizeof(rat_contact_array)); conarr->bal=bal; conarr->numcons=numcons; if (!numcons) return conarr; if (bal) conarr->cons=(rat_contact **)rat_block_alloc(bal,numcons*sizeof(rat_contact *)); else conarr->cons=(rat_contact **)rat_alloc(numcons*sizeof(rat_contact *)); for (i=0; icons[i]=rat_contact_create(bal); return conarr; } // note that to use this destructor you MUST have allocated // the (rat_contact_array *) with rat_alloc_contact_array(). void rat_free_contact_array(rat_contact_array *cons) { register unsigned int i; if (cons->numcons>0) { for (i=0; inumcons; i++) rat_contact_destroy(cons->cons[i]); if (cons->bal) rat_block_dealloc(cons->bal,(void *)cons->cons,cons->numcons*sizeof(rat_contact *)); else rat_dealloc((void *)cons->cons); } if (cons->bal) rat_block_dealloc(cons->bal,(void *)cons,sizeof(rat_contact_array)); else rat_dealloc((void *)cons); } rat_contact *rat_add_array_contact(rat_contact_array *cons) { register unsigned int i; if (cons->numcons==0) { if (cons->bal) cons->cons=(rat_contact **)rat_block_alloc(cons->bal,sizeof(rat_contact *)); else cons->cons=(rat_contact **)rat_alloc(sizeof(rat_contact *)); } else { if (cons->bal) cons->cons=(rat_contact **)rat_block_realloc(cons->bal,cons->cons,sizeof(rat_contact *)*cons->numcons,sizeof(rat_contact *)*(cons->numcons+1)); else cons->cons=(rat_contact **)rat_realloc(cons->cons,sizeof(rat_contact *)*(cons->numcons+1)); } cons->cons[cons->numcons]=rat_contact_create(cons->bal); cons->numcons++; return cons->cons[cons->numcons-1]; } int rat_contacts_match(rat_contact *a,rat_contact *b) { if (a->hull_a!=b->hull_a) return 0; if (a->hull_b!=b->hull_b) return 0; if (a->idvala!=b->idvala) return 0; if (a->idvalb!=b->idvalb) return 0; return 1; } void rat_merge_contacts(rat_contact_array **thesecons,rat_contact_array *newcons) { rat_block_allocator *bal=(*thesecons)->bal; rat_contact_array *oldcons=*thesecons; register unsigned int i,j; register unsigned int oldnumcons=oldcons->numcons; register unsigned int newnumcons=newcons->numcons; if (rat_arbiter_global_warm_starting_enabled()) { for (i=0; inorm_acc_j=oldcon->norm_acc_j; newcon->tan_acc_j=oldcon->tan_acc_j; break; } } } } rat_free_contact_array(oldcons); oldcons=rat_alloc_contact_array(bal,newcons->numcons); for (i=0; inumcons; i++) memcpy(oldcons->cons[i],newcons->cons[i],sizeof(rat_contact)-sizeof(rat_block_allocator *)); *thesecons=oldcons; } void rat_invert_contacts(rat_contact_array *cons) { register unsigned int i; register unsigned int numcons=cons->numcons; for (i=0; inormal=vector2_negative(con->normal); } } unsigned int rat_count_array_contacts(rat_contact_array *cons) { return cons->numcons; } rat_contact *rat_indexed_contact(rat_contact_array *cons,unsigned int idx) { return cons->cons[idx]; }