bool CollisionSolverSW::solve_static(const ShapeSW *p_shape_A, const Transform &p_transform_A, const ShapeSW *p_shape_B, const Transform &p_transform_B, CallbackResult p_result_callback, void *p_userdata, Vector3 *r_sep_axis, real_t p_margin_A, real_t p_margin_B) { PhysicsServer::ShapeType type_A = p_shape_A->get_type(); PhysicsServer::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); bool concave_B = p_shape_B->is_concave(); bool swap = false; if (type_A > type_B) { SWAP(type_A, type_B); SWAP(concave_A, concave_B); swap = true; } if (type_A == PhysicsServer::SHAPE_PLANE) { if (type_B == PhysicsServer::SHAPE_PLANE) return false; if (type_B == PhysicsServer::SHAPE_RAY) { return false; } if (swap) { return solve_static_plane(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); } else { return solve_static_plane(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); } } else if (type_A == PhysicsServer::SHAPE_RAY) { if (type_B == PhysicsServer::SHAPE_RAY) return false; if (swap) { return solve_ray(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); } else { return solve_ray(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); } } else if (concave_B) { if (concave_A) return false; if (!swap) return solve_concave(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, p_margin_A, p_margin_B); else return solve_concave(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, p_margin_A, p_margin_B); } else { return collision_solver(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, r_sep_axis, p_margin_A, p_margin_B); } return false; }
void CollisionSolverSW::concave_callback(void *p_userdata, ShapeSW *p_convex) { _ConcaveCollisionInfo &cinfo = *(_ConcaveCollisionInfo *)(p_userdata); cinfo.aabb_tests++; bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, p_convex, *cinfo.transform_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, NULL, cinfo.margin_A, cinfo.margin_B); if (!collided) return; cinfo.collided = true; cinfo.collisions++; }
void CollisionSolver2DSW::concave_callback(void *p_userdata, Shape2DSW *p_convex) { _ConcaveCollisionInfo2D &cinfo = *(_ConcaveCollisionInfo2D *)(p_userdata); cinfo.aabb_tests++; if (!cinfo.result_callback && cinfo.collided) return; //already collided and no contacts requested, don't test anymore bool collided = collision_solver(cinfo.shape_A, *cinfo.transform_A, cinfo.motion_A, p_convex, *cinfo.transform_B, cinfo.motion_B, cinfo.result_callback, cinfo.userdata, cinfo.swap_result, cinfo.sep_axis, cinfo.margin_A, cinfo.margin_B); if (!collided) return; cinfo.collided = true; cinfo.collisions++; }
bool CollisionSolver2DSW::solve(const Shape2DSW *p_shape_A, const Transform2D &p_transform_A, const Vector2 &p_motion_A, const Shape2DSW *p_shape_B, const Transform2D &p_transform_B, const Vector2 &p_motion_B, CallbackResult p_result_callback, void *p_userdata, Vector2 *sep_axis, real_t p_margin_A, real_t p_margin_B) { Physics2DServer::ShapeType type_A = p_shape_A->get_type(); Physics2DServer::ShapeType type_B = p_shape_B->get_type(); bool concave_A = p_shape_A->is_concave(); bool concave_B = p_shape_B->is_concave(); real_t margin_A = p_margin_A, margin_B = p_margin_B; bool swap = false; if (type_A > type_B) { SWAP(type_A, type_B); SWAP(concave_A, concave_B); SWAP(margin_A, margin_B); swap = true; } if (type_A == Physics2DServer::SHAPE_LINE) { if (type_B == Physics2DServer::SHAPE_LINE || type_B == Physics2DServer::SHAPE_RAY) { return false; } /* if (type_B==Physics2DServer::SHAPE_RAY) { return false; */ if (swap) { return solve_static_line(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true); } else { return solve_static_line(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false); } /*} else if (type_A==Physics2DServer::SHAPE_RAY) { if (type_B==Physics2DServer::SHAPE_RAY) return false; if (swap) { return solve_ray(p_shape_B,p_transform_B,p_shape_A,p_transform_A,p_inverse_A,p_result_callback,p_userdata,true); } else { return solve_ray(p_shape_A,p_transform_A,p_shape_B,p_transform_B,p_inverse_B,p_result_callback,p_userdata,false); } */ } else if (type_A == Physics2DServer::SHAPE_RAY) { if (type_B == Physics2DServer::SHAPE_RAY) { return false; //no ray-ray } if (swap) { return solve_raycast(p_shape_B, p_transform_B, p_shape_A, p_transform_A, p_result_callback, p_userdata, true, sep_axis); } else { return solve_raycast(p_shape_A, p_transform_A, p_shape_B, p_transform_B, p_result_callback, p_userdata, false, sep_axis); } } else if (concave_B) { if (concave_A) return false; if (!swap) return solve_concave(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B); else return solve_concave(p_shape_B, p_transform_B, p_motion_B, p_shape_A, p_transform_A, p_motion_A, p_result_callback, p_userdata, true, sep_axis, margin_A, margin_B); } else { return collision_solver(p_shape_A, p_transform_A, p_motion_A, p_shape_B, p_transform_B, p_motion_B, p_result_callback, p_userdata, false, sep_axis, margin_A, margin_B); } return false; }