void generateMaze(Maze & maze) { initialize(maze); // first line (y==2) for ( int x = 2, y = 2 ; x < maze.GetSizeX() - 2 ; x += 2 ) { int direction; for ( direction = rand() % 4 ; IsWall(maze, x, y, direction) ; direction = rand() % 4 ) { } SetWall(maze, x, y, direction); } // other lines (y!=2) for ( int y = 4 ; y < maze.GetSizeY() - 2; y += 2 ) { for ( int x = 2 ; x < maze.GetSizeX() - 2; x += 2 ) { int direction; for ( direction = rand() % 3 + 1 ; IsWall(maze, x, y, direction) ; direction = rand() % 3 + 1 ) { } SetWall(maze, x, y, direction); } } }
/***************************************************************************** * Function: set_wall * * Description: Will set adjacent cell pointer to null and the adjacent * cell's pointer to null. *****************************************************************************/ void Cell::set_wall( heading_t h ) { if (!IsWall(h)) { adjacent_cells[ h ]->adjacent_cells[ GetReverseHeading( h ) ] = nullptr; adjacent_cells[ h ] = nullptr; } } // set_wall()
uint8 UTerrainManager::GetAreaValue(int32 x, int32 y) { uint8 area = 0; if (IsWall(x - 1, y - 1)) area += 1; if (IsWall(x, y - 1)) area += 2; if (IsWall(x + 1, y - 1)) area += 4; if (IsWall(x - 1, y)) area += 8; if (IsWall(x + 1, y)) area += 16; if (IsWall(x - 1, y + 1)) area += 32; if (IsWall(x, y + 1)) area += 64; if (IsWall(x + 1, y + 1)) area += 128; return area; }
void Terrain::AnalyzeOpennessRearCover( void ) { //Note: You don't need to change this function, but you do need to // write the RearCoverValue function. //Mark every square on the terrain (m_terrainInfluenceMap[r][c]) //with the value returned from RearCoverValue() for( int r=0; r<m_width; r++ ) { for( int c=0; c<m_width; c++ ) { if( !IsWall( r, c ) ) { m_terrainInfluenceMap[r][c] = RearCoverValue( r, c ); } } } }
//! checks if there is collision void Player::CheckCollision(const shoot::Vector3D& vPosition, const shoot::Vector3D& vVelocity, shoot::Vector3D& vNewPosition, shoot::Vector3D& vNewVelocity) { shoot::Vertex3D* pVertices = m_pEnvironment->GetMesh()->GetVertexBuffer()->GetVertices(); shoot::u16* pIndices = m_pEnvironment->GetMesh()->GetIndexBuffer(0)->Indices; shoot::s32 numIndices = m_pEnvironment->GetMesh()->GetIndexBuffer(0)->NumIndices; bool bFound = false; for(shoot::s32 i=0; i<numIndices; i += 3) { shoot::s32 newTriangleIndex = i/3; if(newTriangleIndex != m_iCurrentCollidingTriangle) // don't re-process the current colliding triangle { shoot::Vertex3D v1 = pVertices[pIndices[i + 0]]; shoot::Vertex3D v2 = pVertices[pIndices[i + 1]]; shoot::Vertex3D v3 = pVertices[pIndices[i + 2]]; shoot::Plane plane(v1.Pos, v2.Pos, v3.Pos); // only process front facing planes shoot::Plane::E_Classification eObjectClass = plane.ClassifyPoint(vPosition); if(eObjectClass == shoot::Plane::C_Front) { bool bInTheAir = IsInTheAir(); bool bWall = IsWall(plane); shoot::Vector3D vTestVelocity; shoot::Vector3D vPointToCheck; if(bInTheAir || bWall) { vTestVelocity = vVelocity; vPointToCheck = vPosition - (plane.Normal*m_fRadius); } else { vTestVelocity = shoot::Vector3D(0.0f, -1.0f, 0.0f); vPointToCheck = vPosition + shoot::Vector3D(0.0f, -m_fRadius, 0.0f); } shoot::Vector3D normalizedVelocity = vTestVelocity; normalizedVelocity.Normalize(); shoot::f32 cosAngle = (normalizedVelocity).DotProduct(plane.Normal); if(cosAngle < 0.0f) { shoot::Vector3D vDestPoint = vPointToCheck + vTestVelocity; shoot::Vector3D vIntersection; shoot::Plane::E_Classification eClass; bool bIntersection = plane.IntersectWithRay(vPointToCheck, vTestVelocity, &vIntersection, &eClass); shoot::Triangle triangle(v1.Pos, v2.Pos, v3.Pos); bool bPointInside = bIntersection ? triangle.IsPointInside(vIntersection) : false; if(bIntersection && !bPointInside) { // check if point is on the triangle edges //bPointInside = shoot::Math::IsPointOnLineSegment(vIntersection, triangle.A, triangle.B) // || shoot::Math::IsPointOnLineSegment(vIntersection, triangle.B, triangle.C) // || shoot::Math::IsPointOnLineSegment(vIntersection, triangle.C, triangle.A); } if(bIntersection && bPointInside) { // determine class of dest point shoot::Plane::E_Classification eDestClass = plane.ClassifyPoint(vDestPoint); // if dest point is not front-facing the plane, we have a collision if(eDestClass != shoot::Plane::C_Front) { m_pIntersection1->SetPosition(vIntersection); m_pIntersection1->GetMesh()->GetMaterial(0).SetColor(shoot::Color::Green); shoot::Print("Colliding with triangle '%d' - Normal (%.2f, %.2f, %.2f)\n", i/3, plane.Normal.X, plane.Normal.Y, plane.Normal.Z); if(bWall) { vNewPosition = vIntersection + plane.Normal*m_fRadius; vNewVelocity = shoot::Vector3D(0.0f, 0.0f, 0.0f); } else { vNewPosition = GetNewPosition(vPosition, vIntersection, plane); if(bInTheAir) { vNewVelocity = shoot::Vector3D(0.0f, 0.0f, 0.0f); } m_vSlidingDirection = GetSlidingDirection(plane); m_iCurrentCollidingTriangle = newTriangleIndex; } shoot::Print("bWall = '%d', vNewVelocity(%.2f, %.2f, %.2f)\n", bWall, vNewVelocity.X, vNewVelocity.Y, vNewVelocity.Z); bFound = true; break; } } } } } } if(!bFound) { // quickly check if still in contact with current triangle, if not then we are in the air! if(m_iCurrentCollidingTriangle >= 0) { } } }
Pathfinding::ErrorCodes Pathfinding::CalculatePath() { if (calculated) return AlreadyCalculated; if (mapimg.empty()) return NoMap; if (IsWall(start)) return StartIsWall; if (IsWall(dest)) return DestIsWall; dir = string(); mapimg.copyTo(pathmap); int **closedSet = new int*[mrows]; float **openSet = new float*[mrows]; for (int i = 0; i < mrows; i++) { closedSet[i] = new int[mcols]; openSet[i] = new float[mcols]; for (int j = 0; j < mcols; j++) { closedSet[i][j] = 0; openSet[i][j] = -1.0f; } } priority_queue<Pathfinding::Point2A, vector<Point2A>, CompByFScore> openSetQue[2]; int osq = 0; map<Pathfinding::Point2A, Pathfinding::Point2A, CompByPos> cameFrom; start.fScore = Distance(start, dest); openSetQue[osq].push(start); openSet[start.y][start.x] = 0.0f; while (openSetQue[osq].size() != 0) { Point2A current = openSetQue[osq].top(); if (current == dest) { while (cameFrom.size() != 0) { pathmap.at<Vec3b>(current.y, current.x) = Vec3b(0, 0, 255); dir = to_string(current.dir) + dir; auto it = cameFrom.find(current); Point2A keytmp = current; if (it == cameFrom.end()) { for (int i = 0; i < mrows; i++) { delete openSet[i]; delete closedSet[i]; } delete openSet; delete closedSet; calculated = true; dir = dir.substr(1, dir.length() - 1); return NoError; } current = cameFrom[current]; cameFrom.erase(keytmp); } } openSetQue[osq].pop(); closedSet[current.y][current.x] = 1; int arraySize; Point2A *neighbors = GetNeighbors(current, arraySize); for (int i = 0; i < arraySize; i++) { Point2A neighbor = neighbors[i]; if (closedSet[neighbor.y][neighbor.x] == 1) continue; if (IsWall(neighbor)) { closedSet[neighbor.y][neighbor.x] = 1; continue; } float ngScore = neighbor.level; if (openSet[neighbor.y][neighbor.x] == -1.0f || ngScore < openSet[neighbor.y][neighbor.x]) { cameFrom[neighbor] = current; neighbor.fScore = ngScore + Distance(neighbor, dest) * astar_weight; if (openSet[neighbor.y][neighbor.x] == -1.0f) { openSet[neighbor.y][neighbor.x] = ngScore; openSetQue[osq].push(neighbor); } else { openSet[neighbor.y][neighbor.x] = ngScore; while (!(neighbor == openSetQue[osq].top())) { openSetQue[1 - osq].push(openSetQue[osq].top()); openSetQue[osq].pop(); } openSetQue[osq].pop(); if (openSetQue[osq].size() >= openSetQue[1 - osq].size()) { osq = 1 - osq; } while (!openSetQue[osq].empty()) { openSetQue[1 - osq].push(openSetQue[osq].top()); openSetQue[osq].pop(); } osq = 1 - osq; openSetQue[osq].push(neighbor); } } } delete neighbors; } return NoPath; }