1 /*
2 ===========================================================================
3 
4 Doom 3 GPL Source Code
5 Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
6 
7 This file is part of the Doom 3 GPL Source Code ("Doom 3 Source Code").
8 
9 Doom 3 Source Code is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Doom 3 Source Code is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Doom 3 Source Code.  If not, see <http://www.gnu.org/licenses/>.
21 
22 In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code.  If not, please request a copy in writing from id Software at the address below.
23 
24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
25 
26 ===========================================================================
27 */
28 
29 #ifndef __RENDERWORLDLOCAL_H__
30 #define __RENDERWORLDLOCAL_H__
31 
32 #include "idlib/geometry/Winding.h"
33 #include "renderer/RenderWorld.h"
34 #include "renderer/tr_local.h"
35 
36 class idRenderLightLocal;
37 
38 // assume any lightDef or entityDef index above this is an internal error
39 const int LUDICROUS_INDEX	= 10000;
40 
41 typedef struct portal_s {
42 	int						intoArea;		// area this portal leads to
43 	idWinding *				w;				// winding points have counter clockwise ordering seen this area
44 	idPlane					plane;			// view must be on the positive side of the plane to cross
45 	struct portal_s *		next;			// next portal of the area
46 	struct doublePortal_s *	doublePortal;
47 } portal_t;
48 
49 
50 typedef struct doublePortal_s {
51 	struct portal_s	*		portals[2];
52 	int						blockingBits;	// PS_BLOCK_VIEW, PS_BLOCK_AIR, etc, set by doors that shut them off
53 
54 	// A portal will be considered closed if it is past the
55 	// fog-out point in a fog volume.  We only support a single
56 	// fog volume over each portal.
57 	idRenderLightLocal *		fogLight;
58 	struct doublePortal_s *	nextFoggedPortal;
59 } doublePortal_t;
60 
61 
62 typedef struct portalArea_s {
63 	int				areaNum;
64 	int				connectedAreaNum[NUM_PORTAL_ATTRIBUTES];	// if two areas have matching connectedAreaNum, they are
65 									// not separated by a portal with the apropriate PS_BLOCK_* blockingBits
66 	int				viewCount;		// set by R_FindViewLightsAndEntities
67 	portal_t *		portals;		// never changes after load
68 	areaReference_t	entityRefs;		// head/tail of doubly linked list, may change
69 	areaReference_t	lightRefs;		// head/tail of doubly linked list, may change
70 } portalArea_t;
71 
72 
73 static const int	CHILDREN_HAVE_MULTIPLE_AREAS = -2;
74 static const int	AREANUM_SOLID = -1;
75 typedef struct {
76 	idPlane			plane;
77 	int				children[2];		// negative numbers are (-1 - areaNumber), 0 = solid
78 	int				commonChildrenArea;	// if all children are either solid or a single area,
79 										// this is the area number, else CHILDREN_HAVE_MULTIPLE_AREAS
80 } areaNode_t;
81 
82 
83 class idRenderWorldLocal : public idRenderWorld {
84 public:
85 							idRenderWorldLocal();
86 	virtual					~idRenderWorldLocal();
87 
88 	virtual	qhandle_t		AddEntityDef( const renderEntity_t *re );
89 	virtual	void			UpdateEntityDef( qhandle_t entityHandle, const renderEntity_t *re );
90 	virtual	void			FreeEntityDef( qhandle_t entityHandle );
91 	virtual const renderEntity_t *GetRenderEntity( qhandle_t entityHandle ) const;
92 
93 	virtual	qhandle_t		AddLightDef( const renderLight_t *rlight );
94 	virtual	void			UpdateLightDef( qhandle_t lightHandle, const renderLight_t *rlight );
95 	virtual	void			FreeLightDef( qhandle_t lightHandle );
96 	virtual const renderLight_t *GetRenderLight( qhandle_t lightHandle ) const;
97 
98 	virtual bool			CheckAreaForPortalSky( int areaNum );
99 
100 	virtual	void			GenerateAllInteractions();
101 	virtual void			RegenerateWorld();
102 
103 	virtual void			ProjectDecalOntoWorld( const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime );
104 	virtual void			ProjectDecal( qhandle_t entityHandle, const idFixedWinding &winding, const idVec3 &projectionOrigin, const bool parallel, const float fadeDepth, const idMaterial *material, const int startTime );
105 	virtual void			ProjectOverlay( qhandle_t entityHandle, const idPlane localTextureAxis[2], const idMaterial *material );
106 	virtual void			RemoveDecals( qhandle_t entityHandle );
107 
108 	virtual void			SetRenderView( const renderView_t *renderView );
109 	virtual	void			RenderScene( const renderView_t *renderView );
110 
111 	virtual	int				NumAreas( void ) const;
112 	virtual int				PointInArea( const idVec3 &point ) const;
113 	virtual int				BoundsInAreas( const idBounds &bounds, int *areas, int maxAreas ) const;
114 	virtual	int				NumPortalsInArea( int areaNum );
115 	virtual exitPortal_t	GetPortal( int areaNum, int portalNum );
116 
117 	virtual	guiPoint_t		GuiTrace( qhandle_t entityHandle, const idVec3 start, const idVec3 end ) const;
118 	virtual bool			ModelTrace( modelTrace_t &trace, qhandle_t entityHandle, const idVec3 &start, const idVec3 &end, const float radius ) const;
119 	virtual bool			Trace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end, const float radius, bool skipDynamic = true, bool skipPlayer = false ) const;
120 	virtual bool			FastWorldTrace( modelTrace_t &trace, const idVec3 &start, const idVec3 &end ) const;
121 
122 	virtual void			DebugClearLines( int time );
123 	virtual void			DebugLine( const idVec4 &color, const idVec3 &start, const idVec3 &end, const int lifetime = 0, const bool depthTest = false );
124 	virtual void			DebugArrow( const idVec4 &color, const idVec3 &start, const idVec3 &end, int size, const int lifetime = 0 );
125 	virtual void			DebugWinding( const idVec4 &color, const idWinding &w, const idVec3 &origin, const idMat3 &axis, const int lifetime = 0, const bool depthTest = false );
126 	virtual void			DebugCircle( const idVec4 &color, const idVec3 &origin, const idVec3 &dir, const float radius, const int numSteps, const int lifetime = 0, const bool depthTest = false );
127 	virtual void			DebugSphere( const idVec4 &color, const idSphere &sphere, const int lifetime = 0, bool depthTest = false );
128 	virtual void			DebugBounds( const idVec4 &color, const idBounds &bounds, const idVec3 &org = vec3_origin, const int lifetime = 0 );
129 	virtual void			DebugBox( const idVec4 &color, const idBox &box, const int lifetime = 0 );
130 	virtual void			DebugFrustum( const idVec4 &color, const idFrustum &frustum, const bool showFromOrigin = false, const int lifetime = 0 );
131 	virtual void			DebugCone( const idVec4 &color, const idVec3 &apex, const idVec3 &dir, float radius1, float radius2, const int lifetime = 0 );
132 	virtual void			DebugScreenRect( const idVec4 &color, const idScreenRect &rect, const viewDef_t *viewDef, const int lifetime = 0 );
133 	virtual void			DebugAxis( const idVec3 &origin, const idMat3 &axis );
134 
135 	virtual void			DebugClearPolygons( int time );
136 	virtual void			DebugPolygon( const idVec4 &color, const idWinding &winding, const int lifeTime = 0, const bool depthTest = false );
137 
138 	virtual void			DrawText( const char *text, const idVec3 &origin, float scale, const idVec4 &color, const idMat3 &viewAxis, const int align = 1, const int lifetime = 0, bool depthTest = false );
139 
140 	//-----------------------
141 
142 	idStr					mapName;				// ie: maps/tim_dm2.proc, written to demoFile
143 	ID_TIME_T					mapTimeStamp;			// for fast reloads of the same level
144 
145 	areaNode_t *			areaNodes;
146 	int						numAreaNodes;
147 
148 	portalArea_t *			portalAreas;
149 	int						numPortalAreas;
150 	int						connectedAreaNum;		// incremented every time a door portal state changes
151 
152 	idScreenRect *			areaScreenRect;
153 
154 	doublePortal_t *		doublePortals;
155 	int						numInterAreaPortals;
156 
157 	idList<idRenderModel *>	localModels;
158 
159 	idList<idRenderEntityLocal*>	entityDefs;
160 	idList<idRenderLightLocal*>		lightDefs;
161 
162 	idBlockAlloc<areaReference_t, 1024> areaReferenceAllocator;
163 	idBlockAlloc<idInteraction, 256>	interactionAllocator;
164 	idBlockAlloc<areaNumRef_t, 1024>	areaNumRefAllocator;
165 
166 	// all light / entity interactions are referenced here for fast lookup without
167 	// having to crawl the doubly linked lists.  EnntityDefs are sequential for better
168 	// cache access, because the table is accessed by light in idRenderWorldLocal::CreateLightDefInteractions()
169 	// Growing this table is time consuming, so we add a pad value to the number
170 	// of entityDefs and lightDefs
171 	idInteraction **		interactionTable;
172 	int						interactionTableWidth;		// entityDefs
173 	int						interactionTableHeight;		// lightDefs
174 
175 
176 	bool					generateAllInteractionsCalled;
177 
178 	//-----------------------
179 	// RenderWorld_load.cpp
180 
181 	idRenderModel *			ParseModel( idLexer *src );
182 	idRenderModel *			ParseShadowModel( idLexer *src );
183 	void					SetupAreaRefs();
184 	void					ParseInterAreaPortals( idLexer *src );
185 	void					ParseNodes( idLexer *src );
186 	int						CommonChildrenArea_r( areaNode_t *node );
187 	void					FreeWorld();
188 	void					ClearWorld();
189 	void					FreeDefs();
190 	void					TouchWorldModels( void );
191 	void					AddWorldModelEntities();
192 	void					ClearPortalStates();
193 	virtual	bool			InitFromMap( const char *mapName );
194 
195 	//--------------------------
196 	// RenderWorld_portals.cpp
197 
198 	idScreenRect			ScreenRectFromWinding( const idWinding *w, viewEntity_t *space );
199 	bool					PortalIsFoggedOut( const portal_t *p );
200 	void					FloodViewThroughArea_r( const idVec3 origin, int areaNum, const struct portalStack_s *ps );
201 	void					FlowViewThroughPortals( const idVec3 origin, int numPlanes, const idPlane *planes );
202 	void					FloodLightThroughArea_r( idRenderLightLocal *light, int areaNum, const struct portalStack_s *ps );
203 	void					FlowLightThroughPortals( idRenderLightLocal *light );
204 	areaNumRef_t *			FloodFrustumAreas_r( const idFrustum &frustum, const int areaNum, const idBounds &bounds, areaNumRef_t *areas );
205 	areaNumRef_t *			FloodFrustumAreas( const idFrustum &frustum, areaNumRef_t *areas );
206 	bool					CullEntityByPortals( const idRenderEntityLocal *entity, const struct portalStack_s *ps );
207 	void					AddAreaEntityRefs( int areaNum, const struct portalStack_s *ps );
208 	bool					CullLightByPortals( const idRenderLightLocal *light, const struct portalStack_s *ps );
209 	void					AddAreaLightRefs( int areaNum, const struct portalStack_s *ps );
210 	void					AddAreaRefs( int areaNum, const struct portalStack_s *ps );
211 	void					BuildConnectedAreas_r( int areaNum );
212 	void					BuildConnectedAreas( void );
213 	void					FindViewLightsAndEntities( void );
214 
215 	int						NumPortals( void ) const;
216 	qhandle_t				FindPortal( const idBounds &b ) const;
217 	void					SetPortalState( qhandle_t portal, int blockingBits );
218 	int						GetPortalState( qhandle_t portal );
219 	bool					AreasAreConnected( int areaNum1, int areaNum2, portalConnection_t connection );
220 	void					FloodConnectedAreas( portalArea_t *area, int portalAttributeIndex );
GetAreaScreenRect(int areaNum)221 	idScreenRect &			GetAreaScreenRect( int areaNum ) const { return areaScreenRect[areaNum]; }
222 	void					ShowPortals();
223 
224 	//--------------------------
225 	// RenderWorld_demo.cpp
226 
227 	void					StartWritingDemo( idDemoFile *demo );
228 	void					StopWritingDemo();
229 	bool					ProcessDemoCommand( idDemoFile *readDemo, renderView_t *demoRenderView, int *demoTimeOffset );
230 
231 	void					WriteLoadMap();
232 	void					WriteRenderView( const renderView_t *renderView );
233 	void					WriteVisibleDefs( const viewDef_t *viewDef );
234 	void					WriteFreeLight( qhandle_t handle );
235 	void					WriteFreeEntity( qhandle_t handle );
236 	void					WriteRenderLight( qhandle_t handle, const renderLight_t *light );
237 	void					WriteRenderEntity( qhandle_t handle, const renderEntity_t *ent );
238 	void					ReadRenderEntity();
239 	void					ReadRenderLight();
240 
241 
242 	//--------------------------
243 	// RenderWorld.cpp
244 
245 	void					ResizeInteractionTable();
246 
247 	void					AddEntityRefToArea( idRenderEntityLocal *def, portalArea_t *area );
248 	void					AddLightRefToArea( idRenderLightLocal *light, portalArea_t *area );
249 
250 	void					RecurseProcBSP_r( modelTrace_t *results, int parentNodeNum, int nodeNum, float p1f, float p2f, const idVec3 &p1, const idVec3 &p2 ) const;
251 
252 	void					BoundsInAreas_r( int nodeNum, const idBounds &bounds, int *areas, int *numAreas, int maxAreas ) const;
253 
254 	float					DrawTextLength( const char *text, float scale, int len = 0 );
255 
256 	void					FreeInteractions();
257 
258 	void					PushVolumeIntoTree_r( idRenderEntityLocal *def, idRenderLightLocal *light, const idSphere *sphere, int numPoints, const idVec3 (*points), int nodeNum );
259 
260 	void					PushVolumeIntoTree( idRenderEntityLocal *def, idRenderLightLocal *light, int numPoints, const idVec3 (*points) );
261 
262 	//-------------------------------
263 	// tr_light.c
264 	void					CreateLightDefInteractions( idRenderLightLocal *ldef );
265 };
266 
267 #endif /* !__RENDERWORLDLOCAL_H__ */
268