/* vis.h PVS/PHS generation tool Copyright (C) 1996-1997 Id Software, Inc. Copyright (C) 2002 Colin Thompson 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 2 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, write to: Free Software Foundation, Inc. 59 Temple Place - Suite 330 Boston, MA 02111-1307, USA */ #ifndef __vis_h #define __vis_h #ifdef HAVE_CONFIG_H # include "config.h" #endif #if defined (HAVE_PTHREAD_H) && defined (HAVE_PTHREAD) #define USE_PTHREADS #endif #ifdef USE_PTHREADS #include extern pthread_rwlock_t *global_lock; extern pthread_rwlock_t *portal_locks; extern pthread_rwlock_t *stats_lock; #define WRLOCK(l) \ do { \ if (options.threads > 1) \ pthread_rwlock_wrlock (l); \ } while (0) #define RDLOCK(l) \ do { \ if (options.threads > 1) \ pthread_rwlock_rdlock (l); \ } while (0) #define UNLOCK(l) \ do { \ if (options.threads > 1) \ pthread_rwlock_unlock (l); \ } while (0) #define WRLOCK_PORTAL(p) WRLOCK (&portal_locks[p - portals]) #define RDLOCK_PORTAL(p) RDLOCK (&portal_locks[p - portals]) #define UNLOCK_PORTAL(p) UNLOCK (&portal_locks[p - portals]) #else #define LOCK(l) #define UNLOCK(l) #define WRLOCK_PORTAL(p) #define RDLOCK_PORTAL(p) #define UNLOCK_PORTAL(p) #endif #include "QF/cmem.h" #include "QF/dstring.h" #include "QF/set.h" #include "QF/zone.h" #include "QF/simd/vec4f.h" #define PORTALFILE "PRT1" #define PORTALFILE_AM "PRT1-AM" #define PORTALFILE2 "PRT2" #define ON_EPSILON 0.1 typedef struct winding_s { struct winding_s *next; qboolean original; // don't free, it's part of the portal unsigned numpoints; int id; int thread; vec4f_t points[1]; // variable sized } winding_t; typedef enum { stat_none, stat_selected, stat_working, stat_done } vstatus_t; typedef struct { vec4f_t plane; // normal pointing into neighbor vspheref_t sphere; // bounding sphere int cluster; // neighbor winding_t *winding; vstatus_t status; set_t *visbits; set_t *mightsee; int nummightsee; int numcansee; } portal_t; typedef struct seperating_plane_s { vec4f_t plane; // from portal is on positive side struct seperating_plane_s *next; } sep_t; typedef struct passage_s { struct passage_s *next; int from, to; // cluster numbers sep_t *planes; } passage_t; typedef struct cluster_s { int numportals; int visofs; vspheref_t sphere; passage_t *passages; portal_t *portals; } cluster_t; typedef struct pstack_s { struct pstack_s *next; ///< linked list of active stack objects cluster_t *cluster; ///< the cluster being sub-vised winding_t *source_winding; ///< clipped source portal winding portal_t *pass_portal; ///< the portal exiting from the cluster vec4f_t pass_plane; ///< plane of the pass portal winding_t *pass_winding; ///< clipped pass portal winding set_t *mightsee; sep_t *separators[2]; } pstack_t; typedef struct { unsigned long portaltest; ///< number of portals tested via separators unsigned long portalpass; ///< number of portals through which vis passes unsigned long portalcheck; ///< number of portal checks unsigned long targettested; ///< number of times target portal tested unsigned long targettrimmed;///< number of times target portal trimmed unsigned long targetclipped;///< number of times target portal clipped away unsigned long sourcetested; ///< number of times source portal tested unsigned long sourcetrimmed;///< number of times source portal trimmed unsigned long sourceclipped;///< number of times source portal clipped away unsigned long chains; ///< number of visits to clusters unsigned long mighttest; ///< amount mightsee is used for masked tests unsigned long vistest; ///< amount visbits is used for masked tests unsigned long mightseeupdate;///< amount of updates to waiting portals unsigned sep_alloc; ///< how many separators were allocated unsigned sep_free; ///< how many separators were freed unsigned sep_highwater; ///< most separators in flight unsigned sep_maxbulk; ///< most separators freed at once size_t winding_mark; ///< most memory allocated to windings unsigned stack_alloc; ///< how many stack blocks were allocated unsigned stack_free; ///< how many stack blocks were freed } visstat_t; typedef struct threaddata_s { visstat_t stats; ///< per-thread statistics merged on completion set_t *clustervis; ///< clusters base portal can see portal_t *base; ///< portal for which this thread is being run pstack_t pstack_head; sep_t *sep_freelist; ///< per-thread list of free separators memsuper_t *memsuper; ///< per-thread memory pool memhunk_t *hunk; dstring_t *str; set_pool_t set_pool; int id; int winding_id; } threaddata_t; typedef struct { set_t *portalsee; unsigned long selfcull; ///< number of protals culled by self unsigned long clustercull; ///< number of portals culled by cluster sphere unsigned long clustertest; ///< number of portals tested by cluster unsigned long spheretest; ///< number of portal sphere tests done unsigned long spherecull; ///< number of portals culled by sphere tests unsigned long spherepass; ///< number of portals passed by sphere tests unsigned long windingtest; ///< number of portal pairs tested by winding unsigned long windingcull; ///< number of portals culled by winding tests unsigned long windingpass; ///< number of portals passed by winding tests unsigned long clustersee; int id; } basethread_t; extern unsigned numportals; extern unsigned portalclusters; extern unsigned numrealleafs; extern int bitbytes; extern int bitbytes_l; extern int bitlongs; extern struct bsp_s *bsp; extern portal_t *portals; extern cluster_t *clusters; extern uint32_t *leafcluster; extern byte *uncompressed; winding_t *NewWinding (threaddata_t *thread, int points); winding_t *ClipWinding (threaddata_t *thread, winding_t *in, vec4f_t split, qboolean keepon); winding_t *CopyWinding (threaddata_t *thread, const winding_t *w); void ClusterFlow (int clusternum); void PortalBase (basethread_t *thread, portal_t *portal); void PortalFlow (threaddata_t *data, portal_t *portal); void CalcAmbientSounds (void); struct sizebuf_s; int CompressRow (struct sizebuf_s *dest, const byte *vis, unsigned num_leafs, int utf8); void CalcFatPVS (void); void RunThreads (const char *heading, void *(*thread_func) (void *), int (*calc_progress)(void)); extern const char spinner[]; extern const char progress[]; extern int *working; extern int progress_tick; #endif// __vis_h