void PhysicsSystem::CheckCup(const TransformPtr &ball_transform){ using glm::vec2; float radius = 0.05f; BallComponentPtr ball_comp = ball_comp_mapper_(ball_); TileComponentPtr curr_tile = tile_comp_mapper_(ball_comp->current_tile); VolumePtr cup_vol = volume_mapper_(curr_tile->cup); TransformPtr cup_transform = transform_mapper_(curr_tile->cup); // create ball projection vec3 proj = Project(ball_transform->position(), cup_vol->normal, cup_vol->vertices[0]); // project cup vertices to xz plane vector<vec2> projected_vertices; for (int j = 0, sizej = cup_vol->vertices.size(); j < sizej; ++j) { vec3 v = cup_vol->vertices[j]; vec2 p(v.x, v.z); projected_vertices.push_back(p); } // project ball to xz plane vec2 point(proj.x, proj.z); // check to see if ball overlaps hole bool inter = PointInPolygon(point, projected_vertices); // does ball overlap? if (inter) { float dist_from_cup = glm::length(ball_transform->position() - cup_transform->position()); //if ball is close enough to go in hole and moving slow enough, ball went in cup (stop ball) if(dist_from_cup < MADE_CUP_RADIUS && glm::length(ball_comp->velocity) < MAX_CUP_ENTRY_SPEED ) { ball_comp->velocity = vec3(); ball_comp->acceleration = vec3(); ball_comp->in_cup = true; } //if ball is on lip, alter accel to go towards center else if(dist_from_cup > MADE_CUP_RADIUS && dist_from_cup < CUP_LIP_RADIUS) { ball_comp->acceleration += glm::normalize(cup_transform->position() - ball_transform->position()) * LIP_ACCEL; } else{} } }
void PhysicsSystem::UpdateCollision(const TransformPtr &ball_transform) { BallComponentPtr ball_comp = ball_comp_mapper_(ball_); vec3 start = ball_transform->position(); vec3 end = start + ball_comp->velocity * Time::GetDeltaTime(); vec3 normal, penetration; unordered_map<VolumePtr, EntityPtr>::iterator it; for (it = wall_map_.begin(); it != wall_map_.end(); ++it) { if (Intersect(start, end, it->first, normal, penetration)) { ResolveCollision(ball_transform, normal, penetration); } } }
bool PhysicsSystem::UpdateTile(const TransformPtr &ball_transform, const BallComponentPtr &ball_comp, const EntityPtr &tile, const int &depth) { using glm::vec2; TileComponentPtr tile_comp = tile_comp_mapper_(tile); VolumePtr tile_volume = volume_mapper_(tile); if (depth < 0) { return false; } vec3 v; vec2 p; vector<vec2> projected_vertices; for (int j = 0, sizej = tile_volume->vertices.size(); j < sizej; ++j) { v = tile_volume->vertices[j]; p = vec2(v.x, v.z); projected_vertices.push_back(p); } vec2 point(ball_transform->position().x, ball_transform->position().z); MeshPtr mesh = mesh_mapper_(tile); shared_ptr<BasicMaterial> bm = boost::dynamic_pointer_cast<BasicMaterial>(mesh->material); // is ball in this tile? if (PointInPolygon(point, projected_vertices)) { // color tile yellow bm->Ld_ = vec3(1, 1, 0); ProjectToSlope(ball_transform, ball_comp, tile); // set ball's current tile ball_comp->current_tile = tile; return true; } else { bm->Ld_ = vec3(0, 1, 0); vector<EntityPtr>::iterator it, ite; for (it = tile_comp->neighbors.begin(), ite = tile_comp->neighbors.end(); it != ite; ++it) { if (UpdateTile(ball_transform, ball_comp, *it, depth - 1)) { return true; } } /* // This hack is broken ball_comp->velocity = vec3(0); ball_comp->acceleration = vec3(0); VolumePtr volume = volume_mapper_(ball_comp->current_tile); int N = volume->vertices.size(); vec3 position(0); vector<vec3>::iterator jt, jte; for (jt = volume->vertices.begin(), jte = volume->vertices.end(); jt != jte; ++jt) { position += (*jt); } position /= N; ball_transform->set_position(position); ProjectToSlope(ball_transform, ball_comp, ball_comp->current_tile); */ return false; } /* float radius = 0.05f; VolumePtr curr_volume = tile_vols_[0]; // move ball up slopes using projections vec3 proj = Project(ball_transform->position(), curr_volume->normal, curr_volume->vertices[0]); ball_transform->set_position(proj); ball_transform->Translate(curr_volume->normal * radius); // loop through neighbors for (int i = 1, size = tile_vols_.size(); i < size; ++i) { VolumePtr neigh = tile_vols_[i]; // project neighbors vertices to xz plane vector<vec2> projected_vertices; for (int j = 0, sizej = neigh->vertices.size(); j < sizej; ++j) { vec3 v = neigh->vertices[j]; vec2 p(v.x, v.z); projected_vertices.push_back(p); } // project ball to xz plane vec2 point(ball_transform->position().x, ball_transform->position().z); // check to see if ball overlaps neighbor bool inter = PointInPolygon(point, projected_vertices); // does ball overlap? if (inter) { // set current ball to overlapped neighbor MeshPtr mesh = mesh_mapper_(ball_comp->current_tile); shared_ptr<BasicMaterial> bm = boost::dynamic_pointer_cast<BasicMaterial>(mesh->material); bm->Ld_ = vec3(0, 1, 0); //ball_comp->current_tile = curr_tile->neighbors[i - 1]; break; } } */ }