/* * 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 "hull_polygon.h" static rat_hull *polygon_create(vector2 pos,unsigned int numverts,vector2 *verts) { register unsigned int i; rat_hull_polygon *hull=rat_alloc(sizeof(rat_hull_polygon)); memset(hull,0,sizeof(rat_hull_polygon)); rat_init_hull_classes(); hull->type=rat_hull_type_polygon; hull->clas=&rat_polygon_class; hull->userdata=NULL; hull->numverts=numverts; hull->pos=pos; hull->angle=0; hull->verts=(vector2 *)rat_alloc(sizeof(vector2)*numverts); hull->world_verts=(vector2 *)rat_alloc(sizeof(vector2)*numverts); hull->axes=(rat_polygon_axis *)rat_alloc(sizeof(rat_polygon_axis)*numverts); hull->world_axes=(rat_polygon_axis *)rat_alloc(sizeof(rat_polygon_axis)*numverts); memcpy(hull->verts,verts,sizeof(vector2)*numverts); for (i=0; iaxes[i].normal=vector2_getnormalized(vector2_perp_left( vector2_sub(hull->verts[(i+1)%numverts],hull->verts[i]))); hull->axes[i].dist=vector2_dot(hull->axes[i].normal,hull->verts[i]); } rat_hull_polygon_update_cache((rat_hull *)hull,0); return (rat_hull *)hull; } rat_hull *rat_hull_polygon_create(vector2 pos,unsigned int numverts,vector2 *verts) { return polygon_create(pos,numverts,verts); } rat_hull *rat_hull_polygon_create_box(vector2 pos,vector2 extent) { rat_hull_polygon *box; vector2 boxverts[4]; boxverts[0]=vector2_negative(extent); boxverts[1].x=-extent.x; boxverts[1].y=extent.y; boxverts[2]=extent; boxverts[3].x=extent.x; boxverts[3].y=-extent.y; box=(rat_hull_polygon *)polygon_create(pos,4,boxverts); return (rat_hull *)box; } void rat_hull_polygon_destroy(rat_hull *hull) { rat_dealloc((void *)((rat_hull_polygon *)hull)->verts); rat_dealloc((void *)((rat_hull_polygon *)hull)->axes); rat_dealloc((void *)((rat_hull_polygon *)hull)->world_verts); rat_dealloc((void *)((rat_hull_polygon *)hull)->world_axes); } void rat_hull_polygon_update_cache(rat_hull *hull,int is_static) { if (!is_static) { register unsigned int i; aabb temp_bb; rat_hull_polygon *polygon=(rat_hull_polygon *)hull; rat_real pos_buf[2]={polygon->pos.x,polygon->pos.y}; rat_real *temp_buf=(rat_real *)rat_alloc(sizeof(vector2)*polygon->numverts); register rat_real cosine=cos(polygon->angle); register rat_real sine=sin(polygon->angle); rotate_points_with_precalc_sine2(cosine,sine,(rat_real *)polygon->verts,temp_buf,polygon->numverts); translate_points2(pos_buf,temp_buf,(rat_real *)polygon->world_verts,polygon->numverts); rat_dealloc((void *)temp_buf); for (i=0; inumverts; i++) { polygon->world_axes[i].normal.x= polygon->axes[i].normal.x*cosine- polygon->axes[i].normal.y*sine; polygon->world_axes[i].normal.y= polygon->axes[i].normal.y*cosine+ polygon->axes[i].normal.x*sine; polygon->world_axes[i].dist=vector2_dot(polygon->world_axes[i].normal,polygon->world_verts[i]); } rat_points_bounding_box(polygon->world_verts,polygon->numverts,&(polygon->cached_bb)); } } int rat_hull_polygon_get_verts(rat_hull *hull,vector2 **verts) { *verts=((rat_hull_polygon *)hull)->verts; return ((rat_hull_polygon *)hull)->numverts; } rat_real rat_hull_polygon_get_angle(rat_hull *hull) {return ((rat_hull_polygon *)hull)->angle;} vector2 rat_hull_polygon_get_pos(rat_hull *hull) {return ((rat_hull_polygon *)hull)->pos;} void rat_hull_polygon_set_angle(rat_hull *hull,rat_real angle) { ((rat_hull_polygon *)hull)->angle=angle; } void rat_hull_polygon_set_pos(rat_hull *hull,vector2 pos) { ((rat_hull_polygon *)hull)->pos=pos; } rat_real rat_polygon_point_dist(vector2 *verts,rat_polygon_axis *axes,unsigned int numverts,vector2 point) { register unsigned int i; register rat_real dist,min_dist; min_dist=vector2_dot(axes[0].normal,point)-axes[0].dist; for (i=1; i0.0) return 0; min_dist=dist>min_dist?dist:min_dist; } return min_dist; } int rat_polygon_point_manifold_depth(vector2 *verts,rat_polygon_axis *axes,unsigned int numverts,vector2 point,rat_real *min_dist) { register unsigned int i; register rat_real dist; register int min_i=-1; *min_dist=0; dist=vector2_dot(axes[0].normal,point)-axes[0].dist; if (dist>0.0) return -1; if (dist<*min_dist) { *min_dist=dist; min_i=0; } for (i=1; i0.0) return -1; if (dist<*min_dist) { *min_dist=dist; min_i=i; } } return min_i; } int rat_hull_polygon_point_query(rat_hull *hull,vector2 point) { return rat_polygon_point_dist( ((rat_hull_polygon *)hull)->world_verts, ((rat_hull_polygon *)hull)->world_axes, ((rat_hull_polygon *)hull)->numverts, point)<0.0; } rat_real rat_polygon_axis_value(vector2 *verts,unsigned int numverts,rat_polygon_axis axis) { register unsigned int i; rat_real min=vector2_dot(axis.normal,verts[0]); for (i=1; i