#pragma once #include #include #include #include #include "../../../engine/resources.h" const float GR_OBJ_SCALE{0.5f}; /// Object scale reduction from blender 1x1 const float GR_WALL_OFFSET{0.425f}; /// Wall offset to line up no edge of floor const float GR_CORNER_OFFSET{0.5f}; /// Corner offset for floor from walls #define GR_ENTITY_FLOOR "EntityF_" #define GR_ENTITY_WALL "EntityW_" #define GR_FLOOR "Floor_" #define GR_DOOR "Door_" #define GR_WALL "Wall_" #define GR_ROTATION "Rotation_" /** * @class gameRoom * @brief A class to create a room according to a size, location, and models. * * @author Chase Percy * */ class gameRoom { public: struct RoomModels { std::vector> floors; std::vector> walls; std::shared_ptr debugCube{nullptr}; std::shared_ptr debugSphere{nullptr}; }; /** * Generates a room given a x,z, an origin (bottom left), and a set of * models * @param x the size of the room on the x axis * @param z the size of the room on the z axis * @param wallFillPercent The percent of the walls to fill with decorations * @param floors the floors for the room, the first element is the default * floor * @param floorFillPercent The percent of the floor to fill with decoration. * @param xOrigin the x origin of the room * @param zOrigin the z origin of the room * @param roomModels the models for the room * @param seed the seed for room generation * */ gameRoom(int x, int z, int wallFillPercent, int floorFillPercent, int xOrigin, int zOrigin, const RoomModels& roomModels, int seed, const std::vector>& doors); ~gameRoom(); gameRoom() = delete; gameRoom(const gameRoom& other); gameRoom& operator=(const gameRoom&); /** * Returns all the wall points for the room * @return wall points */ const std::vector>& getWallPoints() const; /** * Returns all bounding spheres for entities in the room * @return bounding spheres */ const std::vector>& getBoundingSpheres() const; glm::vec3 getMin() const; glm::vec3 getMax() const; /** * Draw all objects that represent a room. */ void draw(); /** * Draw all debug data for wall points and bounding spheres. */ void drawDebug(); /** * Returns the coordinates at the centre of the room (used for draw * distance) * @return the coords at centre of room */ glm::vec3 getLocation() const; private: struct Dimension { int xMax{0}; int zMax{0}; int max{0}; }; struct Normals { glm::vec3 negX{-1, 0, 0}; glm::vec3 posX{1, 0, 0}; glm::vec3 negZ{0, 0, -1}; glm::vec3 posZ{0, 0, 1}; }; struct Offset { int xMin{0}; int zMin{0}; int xMax{0}; int zMax{0}; int xCent{0}; int zCent{0}; }; enum accessTypes { wall, floor, empty, floorEntity, wallEntity, door }; enum direction { NaD = -1, negZ, negX, posZ, posX }; /// NaD is used to represent an invalid direction accessTypes* m_accessible{ nullptr}; /// Array of accessible cells in the room std::vector> m_wallPoints{}; /// the wall points for the room std::vector> m_entityBoundingSpheres{}; /// The bounding spheres of the room's /// entities Dimension m_floor; /// the dimensions of the floor Dimension m_wall; /// the dimensions of the floor + walls Dimension m_dimensions; /// The dimensions of the room Offset m_offset; /// The offsets for the room Normals m_normals; /// A predefined set of normals to copy RoomModels m_models; /// the models for the room to use std::map m_objects{}; /// The objects for this room bool m_debugData{ false}; /// Tracks if debug data has been generated or not. std::vector m_debugObjects{}; /// The debug objects fro this room int m_seed; /// The seed for the room int m_randomRotationOffset{0}; /// Offset for random rotations std::map m_rotationAngles; std::vector> m_doors; /** * Creates a room as specified by the x & z values in the constructor. */ void createRoom(); /** * Creates a wall at a given location * @param row the row to create the wall * @param col the col to create the wall * @param model the model to create the wall as */ void createWallType(int row, int col, std::shared_ptr& model, accessTypes accessType); /** * Creates a floor type at a given location * @param row the row to create the floor * @param col the col to create the floor * @param model the model to create the floor as * @param accessType the type of floor (entity or standard) being created */ void createFloorType(int row, int col, std::shared_ptr& model, accessTypes accessType); /** * Checks if a element at row,col is a wall. * @param row the row to check * @param col the col to check * @return true if a wall, else false */ bool isWall(int row, int col) const; /** * Checks if a element is a corner * @param row the row to check * @param col the col to check * @return true if a corner, else false */ bool isCorner(int row, int col) const; /** * Adds decoration to the room up to the fillPercent's * @param floorPercent the amount of the floors to fill * @param wallPercent the amount of the walls to fill */ void addDecoration(float floorPercent, float wallPercent); /** * Returns a 0, 90, 180, 270 angle randomly * @return an angle */ float randomRotation(); /** * returns an integer representing an enum in direction based on the walls * position. * @param row the row to check * @param col the col to check * @return the walls direction enum */ direction wallPosition(int row, int col) const; /** * Update a wall points location so that it aligns properly with the offset * @param location the wall location to update * @param wallPos the current wall direction enum */ void updateWallPointLocation(glm::vec3& location, direction wallPos) const; /** * Gets a normal for a wall based on its current wall direction enum * @param wallPos the wall direction enum * @return the normal for the wall */ glm::vec3 getNormal(direction wallPos) const; /** * Gets the index based on row and col for the accessible array * @param row the row to find * @param col the col to find * @return the index */ std::size_t getIndex(int row, int col) const; /** * Generates the wall points for the room */ void generateWallPoints(); /** * Inserts the wall points into the wall vector based on their direction and * position. * @param row the row to check for a wall * @param col the col to check for a wall * @param wall the wall vector * @param pOneInserted if the first point has been inserted * @param wallCount the number of wall accessTypes connected to the wall * @param dir the location of the wall */ void insertWallPoints(int row, int col, std::vector& wall, bool& pOneInserted, int& wallCount, direction dir); /** * Creates the bounding sphere objects for the entities in the scene */ void generateEntityBoundingSpheres(); /** * Create all debug objects. */ void generateDebugData(); /** * Set the door locations for the room */ void setDoors(); /** * Make sure that doors arent blocked and that there is a way to get to each * wall. * @param start the starting location to walk from. * @param doorAxis the axis the door is aligned with */ void walkRoom(std::pair start, direction doorAxis); /** * Checks if a position in m_accessible is a floor type * @param row the row to check * @param col the col to check * @return true if floor type, else false. */ bool isFloor(int row, int col) const; /** * Checks if a position in m_accessible is a floor entity type * @param row the row to check * @param col the col to check * @return true if floor entity type, else false. */ bool isFloorEntity(int row, int col) const; /** * Removes a floor entity at row & col and replaces it with a floor type. * @param row the row to remove it from * @param col the col to remove it from */ void removeFloorEntity(int row, int col); /** * Updates the walking position for the walkRoom function based on the * direction the door started at. * @param walking the walking variable to update * @param dir the direction the door started at */ void updateWalking(int& walking, direction dir); /** * Sets the strafe start and end variable in the walkRoom function. * @param strafe The strafe variable to set * @param strafeEnd The strafe end variable to set * @param dir The direction of the door * @param row The current row * @param col The current col */ void setStrafe(int& strafe, int& strafeEnd, direction dir, int row, int col) const; /** * Checks if the strafe position is colliding with any entities at its * current position or current position + 1 in the walking direction. * @param strafe The current strafe position * @param dir The direction of the door * @param row The current row * @param col The current col * @return {true, true} if next position is valid. {true, false} if strafe * position is valid but walk position is not. {false, false} is strafe * position isn't valid. */ std::pair checkStrafeCollision(int strafe, direction dir, int& row, int& col) const; /** * Moves the row and col values forward based on the door location. * @param row the row to increase/decrease. * @param col the col to increase/decrease. * @param dir The direction of the door. */ void walkForward(int& row, int& col, direction dir); /** * Set the starting & ending points for the walking variables based on the * doors direction. * @param start The starting spot for walking * @param end The ending spot for walking * @param dir The direction of the door */ void setWalkingStart(int& start, int& end, direction dir); };