=================== CM_GeneratePatchCollide Creates an internal structure that will be used to perform collision detection with a patch mesh. Points is packed as concatenated rows. =================== */
| 1213 | =================== |
| 1214 | */ |
| 1215 | struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, vec3_t *points ) { |
| 1216 | patchCollide_t *pf; |
| 1217 | cGrid_t grid; |
| 1218 | int i, j; |
| 1219 | |
| 1220 | if ( width <= 2 || height <= 2 || !points ) { |
| 1221 | Com_Error( ERR_DROP, "CM_GeneratePatchFacets: bad parameters: (%i, %i, %p)", |
| 1222 | width, height, points ); |
| 1223 | } |
| 1224 | |
| 1225 | if ( !(width & 1) || !(height & 1) ) { |
| 1226 | Com_Error( ERR_DROP, "CM_GeneratePatchFacets: even sizes are invalid for quadratic meshes" ); |
| 1227 | } |
| 1228 | |
| 1229 | if ( width > CM_MAX_GRID_SIZE || height > CM_MAX_GRID_SIZE ) { |
| 1230 | Com_Error( ERR_DROP, "CM_GeneratePatchFacets: source is > CM_MAX_GRID_SIZE" ); |
| 1231 | } |
| 1232 | |
| 1233 | // build a grid |
| 1234 | grid.width = width; |
| 1235 | grid.height = height; |
| 1236 | grid.wrapWidth = qfalse; |
| 1237 | grid.wrapHeight = qfalse; |
| 1238 | for ( i = 0 ; i < width ; i++ ) { |
| 1239 | for ( j = 0 ; j < height ; j++ ) { |
| 1240 | VectorCopy( points[j*width + i], grid.points[i][j] ); |
| 1241 | } |
| 1242 | } |
| 1243 | |
| 1244 | // subdivide the grid |
| 1245 | CM_SetGridWrapWidth( &grid ); |
| 1246 | CM_SubdivideGridColumns( &grid ); |
| 1247 | CM_RemoveDegenerateColumns( &grid ); |
| 1248 | |
| 1249 | CM_TransposeGrid( &grid ); |
| 1250 | |
| 1251 | CM_SetGridWrapWidth( &grid ); |
| 1252 | CM_SubdivideGridColumns( &grid ); |
| 1253 | CM_RemoveDegenerateColumns( &grid ); |
| 1254 | |
| 1255 | // we now have a grid of points exactly on the curve |
| 1256 | // the aproximate surface defined by these points will be |
| 1257 | // collided against |
| 1258 | pf = (patchCollide_t *) Z_Malloc( sizeof( *pf ), TAG_BSP, qfalse ); |
| 1259 | ClearBounds( pf->bounds[0], pf->bounds[1] ); |
| 1260 | for ( i = 0 ; i < grid.width ; i++ ) { |
| 1261 | for ( j = 0 ; j < grid.height ; j++ ) { |
| 1262 | AddPointToBounds( grid.points[i][j], pf->bounds[0], pf->bounds[1] ); |
| 1263 | } |
| 1264 | } |
| 1265 | |
| 1266 | c_totalPatchBlocks += ( grid.width - 1 ) * ( grid.height - 1 ); |
| 1267 | |
| 1268 | // generate a bsp tree for the surface |
| 1269 | CM_PatchCollideFromGrid( &grid, pf ); |
| 1270 | |
| 1271 | // expand by one unit for epsilon purposes |
| 1272 | pf->bounds[0][0] -= 1; |
no test coverage detected