/* =========================================================================== Copyright (C) 1999-2005 Id Software, Inc. This file is part of Quake III Arena source code. Quake III Arena source code 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. Quake III Arena source code 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 Quake III Arena source code; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #include "q_shared.h" #include "qcommon.h" #include "cm_polylib.h" #include "cm_terrain.h" #ifdef __cplusplus extern "C" { #endif #define MAX_SUBMODELS 1024 #define BOX_MODEL_HANDLE (MAX_SUBMODELS-1) #define CAPSULE_MODEL_HANDLE 510 #define MAX_OBFUSCATIONS 1024 typedef struct { cplane_t *plane; int children[2]; // negative numbers are leafs } cNode_t; typedef struct { int cluster; int area; intptr_t firstLeafBrush; int numLeafBrushes; intptr_t firstLeafSurface; int numLeafSurfaces; //added for mohaa int firstLeafTerrain; int numLeafTerrains; } cLeaf_t; typedef struct cfencemask_s { char name[ 64 ]; int iWidth; int iHeight; byte *pData; struct cfencemask_s *pNext; } cfencemask_t; typedef struct { char shader[ 64 ]; int surfaceFlags; int contentFlags; cfencemask_t *mask; float obfuscationWidthDensity; float obfuscationHeightDensity; } cshader_t; typedef struct cmodel_s { vec3_t mins, maxs; cLeaf_t leaf; // submodels don't reference the main tree } cmodel_t; typedef struct { cplane_t *plane; int surfaceFlags; int shaderNum; dsideequation_t *pEq; } cbrushside_t; typedef struct { int shaderNum; // the shader that determined the contents int contents; vec3_t bounds[2]; int numsides; cbrushside_t *sides; int checkcount; // to avoid repeated testings } cbrush_t; typedef struct { int checkcount; // to avoid repeated testings int surfaceFlags; int contents; int shaderNum; int subdivisions; struct patchCollide_s *pc; } cPatch_t; typedef struct { int checkcount; int surfaceFlags; int contents; int shaderNum; terrainCollide_t tc; } cTerrain_t; typedef struct { int floodnum; int floodvalid; } cArea_t; // IneQuation typedef struct { int checkcount; // to avoid repeated testings struct terPatchCollide_s *tc; } cterPatch_t; typedef struct { char name[ MAX_QPATH ]; int numShaders; cfencemask_t *fencemasks; cshader_t *shaders; int numSideEquations; dsideequation_t *sideequations; int numBrushSides; cbrushside_t *brushsides; int numPlanes; cplane_t *planes; int numNodes; cNode_t *nodes; int numLeafs; cLeaf_t *leafs; int numLeafBrushes; int *leafbrushes; int numLeafSurfaces; int *leafsurfaces; int numLeafTerrains; cTerrain_t **leafterrains; int numSubModels; cmodel_t *cmodels; int numBrushes; cbrush_t *brushes; int numClusters; int clusterBytes; byte *visibility; qboolean vised; // if false, visibility is just a single cluster of ffs int numEntityChars; char *entityString; int numAreas; cArea_t *areas; int *areaPortals; // [ numAreas*numAreas ] reference counts int numSurfaces; cPatch_t **surfaces; // non-patches will be NULL // IneQuation int numTerrain; cTerrain_t *terrain; int floodvalid; int checkcount; // incremented on each trace } clipMap_t; // keep 1/8 unit away to keep the position valid before network snapping // and to avoid various numeric issues #define SURFACE_CLIP_EPSILON (0.125) // cm_test.c // Used for oriented capsule collision detection typedef struct { qboolean use; float radius; vec3_t offset; } sphere_t; typedef struct { vec3_t start; vec3_t end; vec3_t size[2]; // size of the box being swept through the model vec3_t offsets[8]; // [signbits][x] = either size[0][x] or size[1][x] float maxOffset; // longest corner length from origin vec3_t extents; // greatest of abs(size[0]) and abs(size[1]) vec3_t bounds[2]; // enclosing box of start and end surrounding by size float height; float radius; int contents; // ored contents of the model tracing through qboolean isPoint; // optimized case trace_t trace; // returned from trace call } traceWork_t; typedef struct leafList_s { int count; int maxcount; qboolean overflowed; int *list; vec3_t bounds[2]; int lastLeaf; // for overflows where each leaf can't be stored individually void (*storeLeafs)( struct leafList_s *ll, int nodenum ); } leafList_t; typedef struct { char name[MAX_QPATH]; float widthDensity; float heightDensity; } obfuscation_t; extern clipMap_t cm; extern int c_pointcontents; extern int c_traces, c_brush_traces, c_patch_traces, c_terrain_patch_traces; extern cvar_t *cm_noAreas; extern cvar_t *cm_noCurves; extern cvar_t *cm_playerCurveClip; extern cvar_t *cm_FCMcacheall; extern cvar_t *cm_FCMdebug; extern cvar_t *cm_ter_usesphere; extern sphere_t sphere; int CM_BoxBrushes( const vec3_t mins, const vec3_t maxs, cbrush_t **list, int listsize ); void CM_StoreLeafs( leafList_t *ll, int nodenum ); void CM_StoreBrushes( leafList_t *ll, int nodenum ); void CM_BoxLeafnums_r( leafList_t *ll, int nodenum ); cmodel_t *CM_ClipHandleToModel( clipHandle_t handle ); qboolean CM_BoundsIntersect( const vec3_t mins, const vec3_t maxs, const vec3_t mins2, const vec3_t maxs2 ); qboolean CM_BoundsIntersectPoint( const vec3_t mins, const vec3_t maxs, const vec3_t point ); // cm_patch.c qboolean CM_PlaneFromPoints( vec4_t plane, vec3_t a, vec3_t b, vec3_t c ); struct patchCollide_s *CM_GeneratePatchCollide( int width, int height, vec3_t *points, float subdivisions ); void CM_TraceThroughPatchCollide( traceWork_t *tw, const struct patchCollide_s *pc ); qboolean CM_PositionTestInPatchCollide( traceWork_t *tw, const struct patchCollide_s *pc ); void CM_ClearLevelPatches( void ); // cm_terrain.c struct terPatchCollide_s *CM_GenerateTerPatchCollide(vec3_t origin, byte heightmap[9][9], baseshader_t *shader); void CM_TraceThroughTerrainCollide(traceWork_t *tw, terrainCollide_t *tc); qboolean CM_PositionTestInTerrainCollide( traceWork_t *tw, terrainCollide_t *tc ); qboolean CM_SightTracePointThroughTerrainCollide( void ); qboolean CM_SightTraceThroughTerrainCollide( traceWork_t *tw, terrainCollide_t *tc ); // cm_fencemask.c cfencemask_t *CM_GetFenceMask( const char *szMaskName ); qboolean CM_TraceThroughFence( traceWork_t *tw, cbrush_t *brush, cbrushside_t *side, float fTraceFraction ); // cm_trace_obfuscation.cpp obfuscation_t* CM_SetupObfuscationMapping(); void CM_ReleaseObfuscationMapping(obfuscation_t* obfuscation); void CM_ObfuscationForShader(obfuscation_t* list, const char* shaderName, float* widthDensity, float* heightDensity); #ifdef __cplusplus } #endif