/* * Descent 3 * Copyright (C) 2024 Parallax Software * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . --- HISTORICAL COMMENTS FOLLOW --- * $Logfile: /DescentIII/Main/editor/Erooms.h $ * $Revision: 1.1.1.1 $ * $Date: 2003-08-26 03:57:38 $ * $Author: kevinb $ * * Header for ERooms.cpp * * $Log: not supported by cvs2svn $ * * 50 10/14/99 4:21p Matt * Added code to remove duplicate faces from a room. * * 49 7/14/99 9:07a Gwar * added a parameter to AllocLoadRoom * * 48 7/02/99 2:17p Gwar * added a parameter to AllocLoadRoom to disable centering on origin * * 47 6/17/99 7:34a Gwar * added some function prototypes * * 46 5/05/99 3:02a Gwar * added a parameter to DeleteRoomFace (by permission) * * 45 4/06/99 5:10p Matt * Base room shell on all portals in the room, not just the first one. * * 44 4/01/99 9:42a Matt * Added code to compute room shells, and made verify level do it. * * 43 3/30/99 7:57p Matt * Added prototype and moved a function to be inline in the header. * * 42 3/30/99 7:20p Matt * Deleted PointsAreColinear(), since it was never used and worked the * wrong way. * * 41 2/03/99 1:10p Matt * Changed the paletted room current faces to be stored in a separate * array, instead of in the room structure. * * 40 10/03/98 8:05p Matt * Changed the way CheckIfFaceIsPlanar() works (& renamed it to * FaceIsPlanar()) and added planar check to VerifyMine() & VerifyRoom() * * 39 9/09/98 4:02p Matt * Added default value for parm to CreateNewRoom() * * 38 9/08/98 6:12p Matt * Added code to check for and fix duplicate and unused points. * * 37 9/02/98 4:20p Matt * Cleaned up some linking code now that we don't have multi-face portals. * * 36 9/02/98 2:28p Matt * New function to add a vertex to a face. * * 35 8/31/98 4:37p Matt * Added improved room & mine error checking. * * 34 6/08/98 12:27p Matt * Added function to copy from one face to another the flags that should * be inherited. * * 33 4/27/98 6:43p Matt * Cleaned up epsilons some more, and moved some code here from hroom.cpp. * * 32 4/16/98 10:41a Matt * Added FindSharedEdgeAcrossRooms() * * 31 4/02/98 12:23p Jason * trimmed some fat from our structures * * 30 4/01/98 3:26p Matt * Changed NORMALS_SAME_VALUE to have a more reasonable value (was * 0.99999999, changed to 0.999f) * * 29 2/24/98 2:57p Jason * adjust planar tolerance (again) * * 28 2/24/98 1:54p Jason * added much stricter concavity testing * * 27 1/20/98 4:05p Matt * Move BuildListOfPortalVerts() from roomkeypaddialog.cpp to erooms.cpp * * 26 1/15/98 7:34p Matt * Revamped error checking when computing face normals * * 25 10/13/97 5:08p Matt * Moved ComputeRoomBoundingSphere() & CreateRoomObjects() from editor to * main * * * 24 10/01/97 7:51p Matt * Added code for external rooms * * 23 9/24/97 3:20p Matt * Added ComputeRoomMinMax() * * 22 9/22/97 2:29p Matt * Added comment * * 21 9/19/97 2:52p Jason * changes to fix lightmap seam problem * * 20 9/17/97 11:50a Jason * ripped out segment engine * * 19 9/12/97 1:25p Matt * Added ifdef around body to prevent errors when included twice * * 18 9/02/97 5:17p Jason * changes for dynamic lighting * * 17 9/02/97 2:28p Matt * Changed PointOutsideEdge() to the more generally-useful * CheckPointAgainstEdge() * Made CopyFace() clear the portal number * * 16 8/29/97 5:44p Matt * Moved a couple functions from hroom.cpp, and added a couple more useful * functions. * * 15 8/26/97 10:24a Matt * Removed debugging mprintf() * * 14 8/22/97 1:02p Matt * Got CompressMine() working for rooms * * 13 8/21/97 5:56p Matt * Added a bunch of useful functions, and make CheckFaceConcavity() more * generally useful. * * 12 8/04/97 6:46p Jason * added code for a lightmap system * * 11 8/01/97 6:11p Matt * Added several functions that I needed for attach room code * * 10 8/01/97 12:50p Jason * added code to support scaling of rooms/faces/edges * * 9 7/31/97 3:31p Jason * added functions to rotate portal rooms * * 8 7/29/97 1:55p Matt * Added some generally useful room/face functions * * 7 7/20/97 3:41p Jason * got room/terrain links working (at least in the terrain) * * 6 7/18/97 4:37p Matt * Added function CheckFaceConcavity() * * * * $NoKeywords: $ */ #ifndef _EROOMS_H #define _EROOMS_H #include "room.h" #define DEFAULT_ROOM_SIZE 20.0 // Values to determine if two points are the same, if a point is on a plane, & if a point is on an edge #define POINT_TO_POINT_EPSILON 0.1 #define POINT_TO_PLANE_EPSILON 0.1 #define POINT_TO_EDGE_EPSILON 0.1 // List of current faces for the palette rooms extern int Current_faces[]; // Called at startup to mark all rooms as unused void InitRooms(); // Returns a free room number, & marks it no longer free. Returns -1 if none free. // If palette_room is true, allocate out of the part of the array for the room palette int GetFreeRoom(bool palette_room); // Allocates a room & initializes it. // All fields except the 3d points and the side types are set to default values. // Memory is allocated for faces & verts arrays, but the elements are *not* initialized // If palette_room is true, allocate out of the part of the array for the room palette // Returns: pointer to new room, or NULL if no free rooms room *CreateNewRoom(int nverts, int nfaces, bool palette_room = 0); // Searches thru all rooms for a specific name, returns -1 if not found // or index of room with name int FindRoomName(char *name); // saves a room in our ORF (Outrage room file) format void SaveRoom(int n, char *filename); // Allocates a room and then tries to load it // Returns index into Rooms[] array on success // -1 on fail int AllocLoadRoom(char *filename, bool bCenter = true, bool palette_room = 1); // Gets next room from n that has actually been alloced int GetNextRoom(int n); // Deterimines whether a face is concave or convex // Parameters: num_verts - the number of vertices in the face to be tested // face_verts - list of vertex numbers in this face // normal - the surface normal of this face // verts - array of vertices into which face_verts elements index // Returns: If the face is concave, returns the number of the vertex that makes the concavity. // If the face is convex, returns -1 // NOTE: A face could have multiple concavities, and this will only find the one with the // lowest-numbered vertex int CheckFaceConcavity(int num_verts, int16_t *face_verts, vector *normal, vector *verts); // Goes through each face of the passed room and sets the default uvs void AssignDefaultUVsToRoom(room *rp); // Computes the center point on a face by averaging the points in the face void ComputeCenterPointOnFace(vector *vp, room *rp, int facenum); // Computes the center point on a face by averaging the points in the portal void ComputeCenterPointOnPortal(vector *vp, room *rp, int portalnum); // Recompute the surface normals for all the faces in a room // Parameters: rp - pointer to the room // Returns: true if normals computed ok, false if some normals were bad bool ResetRoomFaceNormals(room *rp); // Copies the contents of one face to another. // Parameters: dfp - pointer to the destination face. This face should be uninitialized. // sfp - pointer to the source face void CopyFace(face *dfp, face *sfp); // Fixes all the concave/nonplanar faces of facelist of room rp void FixConcaveFaces(room *rp, int *facelist, int facecount); void AssignDefaultUVsToRoomFace(room *rp, int facenum); // Changes the number of verts in a face. Frees and reallocates the face_verts & face_uvls arrays. // Leaves all other fields the same void ReInitRoomFace(face *fp, int nverts); // Determines if two points are close enough together to be considered the same // Parameters: v0,v1 - the two points // Returns: true if the points are the same or very close; else false bool PointsAreSame(vector *v0, vector *v1); // Check to see if a point is in, in front of, or behind a plane // Parameters: checkpoint - the point to check // planepoint,normal - the plane we're checking against // Returns: 0 if on the plane, -1 if behind, 1 if in front int CheckPointToPlane(vector *checkpoint, vector *planepoint, vector *normal); // Check to see if all the points on a face are in front of a plane // Parameters: rp,facenum - the face to check // planepoint,normal - define the plane we're checking against // Returns: the number of the first point found on the back of the plane, or -1 of all on front int CheckFaceToPlane(room *rp, int facenum, vector *planepoint, vector *normal); // Check if a point is inside, outside, or on an edge of a polygon // Parameters: checkv - the point to be checked // v1,v0 - the edge to check against. Two sequential verts in a clockwise polygon. // normal - the surface normal of the polygon // Returns: 1 if the point in inside the edge // 0 if the point is on the edge // -1 if the point is outside the edge int CheckPointAgainstEdge(vector *checkv, vector *v0, vector *v1, vector *normal); // Create space for additional vertices in a room. // Allocates a new array of vertices, copies from the old list, and frees the old list // The new vertices are at the end of the list, so none of the old vertices change number // Parameters: rp - the room // n_new_verts - how many vertices are being added to the room // Returns: the number of the first new vertex int RoomAddVertices(room *rp, int num_new_verts); // Create space for additional faces in a room. // Allocates a new faces array, copies from the old list, and frees the old list // The new faces are at the end of the list, so none of the old faces change number // Parameters: rp - the room // num_new_faces - how many faces are being added to the room // Returns: the number of the first new face int RoomAddFaces(room *rp, int num_new_faces); // Structure to hold vector and uvl data for clipping struct vertex { vector vec; roomUVL uvl; }; // Clips on edge of a polygon against another edge // Parameters: normal - defines the plane in which these edgs lie // v0,v1 - the edge to be clipped // v2,v3 - is the edge clipped against // newv - filled in with the intersection point void ClipEdge(vector *normal, vertex *v0, vertex *v1, vector *v2, vector *v3, vertex *newv); // Finds a shared edge, if one exists, between two faces in the same room // Parameters: fp0,fp1 - pointers to the two faces // vn0,vn1 - filled in with the vertex numbers of the edge. These vert numbers are // relative to their own faces. The shared edge is //verts on face 0, and on face 1 Returns: true if a shared edge was found, else // false bool FindSharedEdge(face *fp0, face *fp1, int *vn0, int *vn1); // Finds a shared edge, if one exists, between two faces in different rooms // Parameters: rp0,rp1 - pointers to the two rooms // face0,face1 - the face numbers in rp0 & rp1, respectively // vn0,vn1 - filled in with the vertex numbers of the edge. These vert numbers are // relative to their own faces. The shared edge is //verts on face 0, and on face 1 Returns: true if a shared edge was found, else // false bool FindSharedEdgeAcrossRooms(room *rp0, int face0, room *rp1, int face1, int *vn0, int *vn1); // If two surface normals have a dot product greater than or equal to this value, they are the same #define NORMALS_SAME_VALUE .999f // Determines if two normals are the same (or very very close) // Parameters: n0,n1 - the two normals // Returns: true if they are more-or-less the same, else false inline bool NormalsAreSame(vector *n0, vector *n1) { float d = *n0 * *n1; return (d > NORMALS_SAME_VALUE); } // Delete a face from a room // Parameters: rp - the room the face is in // facenum - the face to be deleted void DeleteRoomFace(room *rp, int facenum, bool delete_unused_verts = true); // Deletes a portal from a room. Does not delete this portal this connects to // Parameters: rp - the room the portal is in // portalnum - the portal to be deleted void DeleteRoomPortal(room *rp, int portalnum); // Remove holes in the room list void CompressRooms(void); // Compress mine by getting rid of holes the the room array void CompressMine(void); // Copies the data from one room into another // Note: Portals are not copied, and the new room will have zero portals // The destination room is assumed to be uninitialized // Parameters: destp - the destination room of the copy // srcp - the source room for the copy void CopyRoom(room *destp, room *srcp); // Links two rooms, creating portals in each room // Parameters: roomlist - pointer to the array of rooms // room0,face0 - the room & face numbers of the first room // room1,face1 - the room & face numbers of the second room void LinkRooms(room *roomlist, int room0, int face0, int room1, int face1); // Back when we had multi-face portals, LinkRoomsSimple() created a pair of 1-face portals #define LinkRoomsSimple LinkRooms // Finds the min and max x,y,z values of the vertices in a room // Parameters: min,max - filled in with the minimum and maximum x,y, & z values, respectively // rp = the room void ComputeRoomMinMax(vector *min, vector *max, room *rp); // Builds a list of all the vertices in a room that are part of a portal // Parameters: rp - the room to check // list - filled in with the list of vert numbers. List should be //MAX_VERTS_PER_ROOM big Returns: the number of verts in the list int BuildListOfPortalVerts(room *rp, int *list); // Copy the flags from one face to another derrived from the first (by clipping or splitting) // Only those flags which are safe to copy are copied // Parameters: dfp - pointer to the destination face // sfp - pointer to the source face void CopyFaceFlags(face *dfp, face *sfp); // Test the mine for validity void VerifyMine(); // Test the given room for validity void VerifyRoom(room *rp); // Inserts a vertex into a face // Parameters: rp - the room for this face // facenum - the face to which to add the vertex // new_v - the number of the vertex to add // after_v - the new vert is added *after* this vert (index into face verts) void AddVertToFace(room *rp, int facenum, int new_v, int after_v); // Removes all the duplicate points in a level void RemoveAllDuplicateAndUnusedPoints(); // Checks to see if a face is planar. // See if all the points are within a certain distance of an average point // Returns 1 if face is planar, 0 if not bool FaceIsPlanar(int nv, int16_t *face_verts, vector *normal, vector *verts); // Checks to see if a face is planar. // See if all the points are within a certain distance of an average point // Returns 1 if face is planar, 0 if not inline bool FaceIsPlanar(room *rp, int facenum) { face *fp = &rp->faces[facenum]; return FaceIsPlanar(fp->num_verts, fp->face_verts, &fp->normal, rp->verts); } // Finds the shell for the specified room. If the shell is found with no errors, sets // the non-shell flag for those faces not in the shell. If there are errors finding the // shell, all faces have the non-shell flag cleared. // Returns the number of shell errors (unconnected edges) in the room. // Writes errors to the error buffer int ComputeRoomShell(room *rp); // Finds shells for all rooms. // Returns the number of rooms with bad shells int ComputeAllRoomShells(); // Log an error in the room check process void CheckError(const char *str, ...); // Checks the normals in a room // Returns the number of bad normals int CheckNormals(room *rp); // Checks for concave faces // Returns the number of concave faces int CheckConcaveFaces(room *rp); int CheckDegenerateFaces(room *rp); // Checks for bad portal connections // Returns the number of bad portals int CheckPortals(room *rp); // Checks for duplicate faces // Returns the number of duplicate faces int CheckDuplicateFaces(room *rp); // Checks for non-planar faces // Returns the number of non-planar faces int CheckNonPlanarFaces(room *rp); // Checks for duplicate points // Returns the number of duplicate points int CheckDuplicatePoints(room *rp); // Find any unused points in a room int CheckUnusedPoints(room *rp); // Checks for duplicate points in faces // Returns the number of duplicate face points int CheckDuplicateFacePoints(room *rp); int CheckRoomPortalFaces(room *rp); // Find t-joints in this room int FindTJoints(room *rp); // Counts the number of unique textures in a level, plus gives names of textures used void CountUniqueTextures(); // Removes all the duplicate faces in a room void RemoveDuplicateFaces(room *rp); #endif // ifndef _EROOMS_H