/*
* 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