void CueTable::addPockets(Polygon2& shape, int numOfHoles){ vector< Edge2 > edges = shape.getEdges(); for(int i = 0; i < numOfHoles; ){ Edge2 edge = edges[rand() % edges.size()]; float alpha = linearRand(0.0f, 1.0f); if(insertPocket(shape, lerp(edge[0],edge[1],alpha))){ i++; } } }
void CueTable::createTableMesh(Polygon2& shape){ tableMesh = new Mesh(); float size = 5.0f; vec3 offset = vec3(0,1,0) * size; for(auto& edge : shape.getEdges()){ vec3 v0 = vec3 (edge[0].x, 0, edge[0].y); vec3 v1 = vec3 (edge[1].x, 0, edge[1].y); vec3 v2 = v0 + offset; vec3 v3 = v1 + offset; tableMesh->beginTriangle(); tableMesh->vertex(v2); tableMesh->vertex(v1); tableMesh->vertex(v0); tableMesh->color(vec3(0.0, 1.0, 0.0)); tableMesh->color(vec3(0.0, 1.0, 0.0)); tableMesh->color(vec3(0.0, 1.0, 0.0)); tableMesh->calculateNormals(); tableMesh->endTriangle(); tableMesh->beginTriangle(); tableMesh->vertex(v2); tableMesh->vertex(v3); tableMesh->vertex(v1); tableMesh->color(vec3(0.0, 1.0, 0.0)); tableMesh->color(vec3(0.0, 1.0, 0.0)); tableMesh->color(vec3(0.0, 1.0, 0.0)); tableMesh->calculateNormals(); tableMesh->endTriangle(); } tableMesh->build(); }
bool CueTable::insertPocket(Polygon2& shape, vec2 holePos){ const Circle circle(holePos, 1.0f); auto edges = &shape.getEdges(); int countEdges = 0; for(uint i = 0; i < edges->size(); i++){ Edge2 edge = edges->at(i); if(circle.inside(edge[0]) ^ circle.inside(edge[1])){ countEdges++; } } if(countEdges > 2){ return false; }else if (countEdges == 1){ return false; } for( auto it = edges->begin(); it != edges->end(); ){ Edge2 edge = (*it); if(circle.inside(edge[0]) && circle.inside(edge[1])){ it = edges->erase( it ); }else{ it++; } } for( auto it = edges->begin(); it != edges->end(); ){ Edge2 edge = (*it); vec2 alpha; IntersectionType intType = circleIntersection(edge, circle, alpha.x, alpha.y); vec2 edge0 = edge[0]; vec2 edge1 = edge[1]; vec2 hit0 = lerp(edge0,edge1,alpha[0]); vec2 hit1 = lerp(edge0,edge1,alpha[1]); switch (intType) { case IMPALE: { it = edges->erase( it ); it = edges->insert(it, Edge2(edge0, hit0)); /*vector<Edge2> pocketEdges = generatePocketEdges(circle, Edge2(edge0, hit0), Edge2(hit1, edge1), 10); for( auto& e : pocketEdges ) it = edges->insert( it + 1, e );*/ it = edges->insert(it + 1, Edge2(hit1, edge1)); it--; break; } case POKE: { it->at(1) = hit0; /*vector<Edge2> pocketEdges = generatePocketEdges(circle, *it, *(it+1), 10); for( auto& e : pocketEdges ) it = edges->insert( it + 1, e );*/ break; } case EXITWOUND: { it->at(0) = hit1; break; } case COMPLETELYINSIDE: case FALLSHORT: case PAST: case NONE: break; case INVALID: default: assert(0); } it++; } return true; }