1 /**\file dmu_lib.h
2  *\section License
3  * License: GPL
4  * Online License Link: http://www.gnu.org/licenses/gpl.html
5  *
6  *\author Copyright © 2006-2017 Jaakko Keränen <jaakko.keranen@iki.fi>
7  *\author Copyright © 2006-2013 Daniel Swanson <danij@dengine.net>
8  *
9  * This program 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 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program 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 this program; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin St, Fifth Floor,
22  * Boston, MA  02110-1301  USA
23  */
24 
25 /**
26  * Helper routines for accessing the DMU API
27  */
28 
29 #ifndef LIBCOMMON_DMU_LIB_H
30 #define LIBCOMMON_DMU_LIB_H
31 
32 #include "doomsday.h"
33 #include "p_iterlist.h"
34 #include "p_terraintype.h"
35 
36 #define numvertexes             (P_Count(DMU_VERTEX))
37 #define numsectors              (P_Count(DMU_SECTOR))
38 #define numlines                (P_Count(DMU_LINE))
39 #define numsides                (P_Count(DMU_SIDE))
40 #define numpolyobjs             (*(int*) DD_GetVariable(DD_MAP_POLYOBJ_COUNT))
41 
42 // DMU property aliases. For short-hand purposes:
43 #define DMU_FRONT_SECTOR        (DMU_FRONT_OF_LINE | DMU_SECTOR)
44 #define DMU_BACK_SECTOR         (DMU_BACK_OF_LINE | DMU_SECTOR)
45 
46 #define DMU_FRONT_FLAGS         (DMU_FRONT_OF_LINE | DMU_FLAGS)
47 #define DMU_BACK_FLAGS          (DMU_BACK_OF_LINE | DMU_FLAGS)
48 
49 #define DMU_TOP_MATERIAL        (DMU_TOP_OF_SIDE | DMU_MATERIAL)
50 #define DMU_TOP_MATERIAL_OFFSET_X (DMU_TOP_OF_SIDE | DMU_OFFSET_X)
51 #define DMU_TOP_MATERIAL_OFFSET_Y (DMU_TOP_OF_SIDE | DMU_OFFSET_Y)
52 #define DMU_TOP_MATERIAL_OFFSET_XY (DMU_TOP_OF_SIDE | DMU_OFFSET_XY)
53 #define DMU_TOP_FLAGS           (DMU_TOP_OF_SIDE | DMU_FLAGS)
54 #define DMU_TOP_COLOR           (DMU_TOP_OF_SIDE | DMU_COLOR)
55 #define DMU_TOP_COLOR_RED       (DMU_TOP_OF_SIDE | DMU_COLOR_RED)
56 #define DMU_TOP_COLOR_GREEN     (DMU_TOP_OF_SIDE | DMU_COLOR_GREEN)
57 #define DMU_TOP_COLOR_BLUE      (DMU_TOP_OF_SIDE | DMU_COLOR_BLUE)
58 #define DMU_TOP_EMITTER         (DMU_TOP_OF_SIDE | DMU_EMITTER)
59 
60 #define DMU_MIDDLE_MATERIAL     (DMU_MIDDLE_OF_SIDE | DMU_MATERIAL)
61 #define DMU_MIDDLE_MATERIAL_OFFSET_X (DMU_MIDDLE_OF_SIDE | DMU_OFFSET_X)
62 #define DMU_MIDDLE_MATERIAL_OFFSET_Y (DMU_MIDDLE_OF_SIDE | DMU_OFFSET_Y)
63 #define DMU_MIDDLE_MATERIAL_OFFSET_XY (DMU_MIDDLE_OF_SIDE | DMU_OFFSET_XY)
64 #define DMU_MIDDLE_FLAGS        (DMU_MIDDLE_OF_SIDE | DMU_FLAGS)
65 #define DMU_MIDDLE_COLOR        (DMU_MIDDLE_OF_SIDE | DMU_COLOR)
66 #define DMU_MIDDLE_COLOR_RED    (DMU_MIDDLE_OF_SIDE | DMU_COLOR_RED)
67 #define DMU_MIDDLE_COLOR_GREEN  (DMU_MIDDLE_OF_SIDE | DMU_COLOR_GREEN)
68 #define DMU_MIDDLE_COLOR_BLUE   (DMU_MIDDLE_OF_SIDE | DMU_COLOR_BLUE)
69 #define DMU_MIDDLE_ALPHA        (DMU_MIDDLE_OF_SIDE | DMU_ALPHA)
70 #define DMU_MIDDLE_BLENDMODE    (DMU_MIDDLE_OF_SIDE | DMU_BLENDMODE)
71 #define DMU_MIDDLE_EMITTER      (DMU_MIDDLE_OF_SIDE | DMU_EMITTER)
72 
73 #define DMU_BOTTOM_MATERIAL     (DMU_BOTTOM_OF_SIDE | DMU_MATERIAL)
74 #define DMU_BOTTOM_MATERIAL_OFFSET_X (DMU_BOTTOM_OF_SIDE | DMU_OFFSET_X)
75 #define DMU_BOTTOM_MATERIAL_OFFSET_Y (DMU_BOTTOM_OF_SIDE | DMU_OFFSET_Y)
76 #define DMU_BOTTOM_MATERIAL_OFFSET_XY (DMU_BOTTOM_OF_SIDE | DMU_OFFSET_XY)
77 #define DMU_BOTTOM_FLAGS        (DMU_BOTTOM_OF_SIDE | DMU_FLAGS)
78 #define DMU_BOTTOM_COLOR        (DMU_BOTTOM_OF_SIDE | DMU_COLOR)
79 #define DMU_BOTTOM_COLOR_RED    (DMU_BOTTOM_OF_SIDE | DMU_COLOR_RED)
80 #define DMU_BOTTOM_COLOR_GREEN  (DMU_BOTTOM_OF_SIDE | DMU_COLOR_GREEN)
81 #define DMU_BOTTOM_COLOR_BLUE   (DMU_BOTTOM_OF_SIDE | DMU_COLOR_BLUE)
82 #define DMU_BOTTOM_EMITTER      (DMU_BOTTOM_OF_SIDE | DMU_EMITTER)
83 
84 #define DMU_FLOOR_HEIGHT        (DMU_FLOOR_OF_SECTOR | DMU_HEIGHT)
85 #define DMU_FLOOR_TARGET_HEIGHT (DMU_FLOOR_OF_SECTOR | DMU_TARGET_HEIGHT)
86 #define DMU_FLOOR_SPEED         (DMU_FLOOR_OF_SECTOR | DMU_SPEED)
87 #define DMU_FLOOR_MATERIAL      (DMU_FLOOR_OF_SECTOR | DMU_MATERIAL)
88 #define DMU_FLOOR_EMITTER       (DMU_FLOOR_OF_SECTOR | DMU_EMITTER)
89 #define DMU_FLOOR_FLAGS         (DMU_FLOOR_OF_SECTOR | DMU_FLAGS)
90 #define DMU_FLOOR_COLOR         (DMU_FLOOR_OF_SECTOR | DMU_COLOR)
91 #define DMU_FLOOR_COLOR_RED     (DMU_FLOOR_OF_SECTOR | DMU_COLOR_RED)
92 #define DMU_FLOOR_COLOR_GREEN   (DMU_FLOOR_OF_SECTOR | DMU_COLOR_GREEN)
93 #define DMU_FLOOR_COLOR_BLUE    (DMU_FLOOR_OF_SECTOR | DMU_COLOR_BLUE)
94 #define DMU_FLOOR_MATERIAL_OFFSET_X (DMU_FLOOR_OF_SECTOR | DMU_OFFSET_X)
95 #define DMU_FLOOR_MATERIAL_OFFSET_Y (DMU_FLOOR_OF_SECTOR | DMU_OFFSET_Y)
96 #define DMU_FLOOR_MATERIAL_OFFSET_XY (DMU_FLOOR_OF_SECTOR | DMU_OFFSET_XY)
97 #define DMU_FLOOR_TANGENT_X     (DMU_FLOOR_OF_SECTOR | DMU_TANGENT_X)
98 #define DMU_FLOOR_TANGENT_Y     (DMU_FLOOR_OF_SECTOR | DMU_TANGENT_Y)
99 #define DMU_FLOOR_TANGENT_Z     (DMU_FLOOR_OF_SECTOR | DMU_TANGENT_Z)
100 #define DMU_FLOOR_TANGENT_XYZ   (DMU_FLOOR_OF_SECTOR | DMU_TANGENT_XYZ)
101 #define DMU_FLOOR_BITANGENT_X   (DMU_FLOOR_OF_SECTOR | DMU_BITANGENT_X)
102 #define DMU_FLOOR_BITANGENT_Y   (DMU_FLOOR_OF_SECTOR | DMU_BITANGENT_Y)
103 #define DMU_FLOOR_BITANGENT_Z   (DMU_FLOOR_OF_SECTOR | DMU_BITANGENT_Z)
104 #define DMU_FLOOR_BITANGENT_XYZ (DMU_FLOOR_OF_SECTOR | DMU_BITANGENT_XYZ)
105 #define DMU_FLOOR_NORMAL_X      (DMU_FLOOR_OF_SECTOR | DMU_NORMAL_X)
106 #define DMU_FLOOR_NORMAL_Y      (DMU_FLOOR_OF_SECTOR | DMU_NORMAL_Y)
107 #define DMU_FLOOR_NORMAL_Z      (DMU_FLOOR_OF_SECTOR | DMU_NORMAL_Z)
108 #define DMU_FLOOR_NORMAL_XYZ    (DMU_FLOOR_OF_SECTOR | DMU_NORMAL_XYZ)
109 
110 #define DMU_CEILING_HEIGHT      (DMU_CEILING_OF_SECTOR | DMU_HEIGHT)
111 #define DMU_CEILING_TARGET_HEIGHT (DMU_CEILING_OF_SECTOR | DMU_TARGET_HEIGHT)
112 #define DMU_CEILING_SPEED       (DMU_CEILING_OF_SECTOR | DMU_SPEED)
113 #define DMU_CEILING_MATERIAL    (DMU_CEILING_OF_SECTOR | DMU_MATERIAL)
114 #define DMU_CEILING_EMITTER     (DMU_CEILING_OF_SECTOR | DMU_EMITTER)
115 #define DMU_CEILING_FLAGS       (DMU_CEILING_OF_SECTOR | DMU_FLAGS)
116 #define DMU_CEILING_COLOR       (DMU_CEILING_OF_SECTOR | DMU_COLOR)
117 #define DMU_CEILING_COLOR_RED   (DMU_CEILING_OF_SECTOR | DMU_COLOR_RED)
118 #define DMU_CEILING_COLOR_GREEN (DMU_CEILING_OF_SECTOR | DMU_COLOR_GREEN)
119 #define DMU_CEILING_COLOR_BLUE  (DMU_CEILING_OF_SECTOR | DMU_COLOR_BLUE)
120 #define DMU_CEILING_MATERIAL_OFFSET_X (DMU_CEILING_OF_SECTOR | DMU_OFFSET_X)
121 #define DMU_CEILING_MATERIAL_OFFSET_Y (DMU_CEILING_OF_SECTOR | DMU_OFFSET_Y)
122 #define DMU_CEILING_MATERIAL_OFFSET_XY (DMU_CEILING_OF_SECTOR | DMU_OFFSET_XY)
123 #define DMU_CEILING_TANGENT_X   (DMU_CEILING_OF_SECTOR | DMU_TANGENT_X)
124 #define DMU_CEILING_TANGENT_Y   (DMU_CEILING_OF_SECTOR | DMU_TANGENT_Y)
125 #define DMU_CEILING_TANGENT_Z   (DMU_CEILING_OF_SECTOR | DMU_TANGENT_Z)
126 #define DMU_CEILING_TANGENT_XYZ (DMU_CEILING_OF_SECTOR | DMU_TANGENT_XYZ)
127 #define DMU_CEILING_BITANGENT_X (DMU_CEILING_OF_SECTOR | DMU_BITANGENT_X)
128 #define DMU_CEILING_BITANGENT_Y (DMU_CEILING_OF_SECTOR | DMU_BITANGENT_Y)
129 #define DMU_CEILING_BITANGENT_Z (DMU_CEILING_OF_SECTOR | DMU_BITANGENT_Z)
130 #define DMU_CEILING_BITANGENT_XYZ (DMU_CEILING_OF_SECTOR | DMU_BITANGENT_XYZ)
131 #define DMU_CEILING_NORMAL_X    (DMU_CEILING_OF_SECTOR | DMU_NORMAL_X)
132 #define DMU_CEILING_NORMAL_Y    (DMU_CEILING_OF_SECTOR | DMU_NORMAL_Y)
133 #define DMU_CEILING_NORMAL_Z    (DMU_CEILING_OF_SECTOR | DMU_NORMAL_Z)
134 #define DMU_CEILING_NORMAL_XYZ  (DMU_CEILING_OF_SECTOR | DMU_NORMAL_XYZ)
135 
136 /// Side section indices.
137 typedef enum sidesection_e {
138     SS_MIDDLE,
139     SS_BOTTOM,
140     SS_TOP
141 } SideSection;
142 
143 #define VALID_SIDESECTION(v) ((v) >= SS_MIDDLE && (v) <= SS_TOP)
144 
145 /// Helper macro for converting SideSection indices to their associated DMU flag. @ingroup world
146 #define DMU_FLAG_FOR_SIDESECTION(s) (\
147     (s) == SS_MIDDLE? DMU_MIDDLE_OF_SIDE : \
148     (s) == SS_BOTTOM? DMU_BOTTOM_OF_SIDE : DMU_TOP_OF_SIDE)
149 
150 #ifdef __cplusplus
151 extern "C" {
152 #endif
153 
154 /**
155  * Same as P_PathTraverse except 'from' and 'to' arguments are specified
156  * as two sets of separate X and Y map space coordinates.
157  */
158 int P_PathXYTraverse2(coord_t fromX, coord_t fromY, coord_t toX, coord_t toY,
159     int flags, traverser_t callback, void *context);
160 
161 int P_PathXYTraverse(coord_t fromX, coord_t fromY, coord_t toX, coord_t toY,
162     traverser_t callback, void *context);
163 
164 void P_BuildLineTagLists(void);
165 
166 void P_DestroyLineTagLists(void);
167 
168 iterlist_t *P_GetLineIterListForTag(int tag, dd_bool createNewList);
169 
170 void P_BuildSectorTagLists(void);
171 
172 void P_DestroySectorTagLists(void);
173 
174 iterlist_t *P_GetSectorIterListForTag(int tag, dd_bool createNewList);
175 
176 void P_BuildAllTagLists(void);
177 
178 void P_DestroyAllTagLists(void);
179 
180 Line *P_AllocDummyLine(void);
181 
182 void P_FreeDummyLine(Line *line);
183 
184 /**
185  * Get the sector on the other side of the line that is NOT the given sector.
186  *
187  * @param line  Ptr to the line to test.
188  * @param sec  Reference sector to compare against.
189  *
190  * @return  Ptr to the other sector or @c NULL if the specified line is NOT twosided.
191  */
192 Sector *P_GetNextSector(Line *line, Sector *sec);
193 
194 #define FEPHF_MIN           0x1 // Get minium. If not set, get maximum.
195 #define FEPHF_FLOOR         0x2 // Get floors. If not set, get ceilings.
196 
197 typedef struct findextremalplaneheightparams_s {
198     Sector *baseSec;
199     byte flags;
200     coord_t val;
201     Sector *foundSec;
202 } findextremalplaneheightparams_t;
203 
204 /// Find the sector with the lowest floor height in surrounding sectors.
205 Sector *P_FindSectorSurroundingLowestFloor(Sector *sector, coord_t max, coord_t *val);
206 
207 /// Find the sector with the highest floor height in surrounding sectors.
208 Sector *P_FindSectorSurroundingHighestFloor(Sector *sector, coord_t min, coord_t *val);
209 
210 /// Find lowest ceiling in the surrounding sector.
211 Sector *P_FindSectorSurroundingLowestCeiling(Sector *sector, coord_t max, coord_t *val);
212 
213 /// Find highest ceiling in the surrounding sectors.
214 Sector *P_FindSectorSurroundingHighestCeiling(Sector *sector, coord_t min, coord_t *val);
215 
216 #define FNPHF_FLOOR             0x1 // Get floors, if not set get ceilings.
217 #define FNPHF_ABOVE             0x2 // Get next above, if not set get next below.
218 
219 typedef struct findnextplaneheightparams_s {
220     Sector *baseSec;
221     coord_t baseHeight;
222     byte flags;
223     coord_t val;
224     Sector *foundSec;
225 } findnextplaneheightparams_t;
226 
227 /// Find the sector with the next highest floor in surrounding sectors.
228 Sector *P_FindSectorSurroundingNextHighestFloor(Sector *sector, coord_t baseHeight, coord_t *val);
229 
230 /// Find the sector with the next lowest floor in surrounding sectors.
231 Sector *P_FindSectorSurroundingNextLowestFloor(Sector *sector, coord_t baseHeight, coord_t *val);
232 
233 /// Find the sector with the next highest ceiling in surrounding sectors.
234 Sector *P_FindSectorSurroundingNextHighestCeiling(Sector *sector, coord_t baseHeight, coord_t *val);
235 
236 /// Find the sector with the next lowest ceiling in surrounding sectors.
237 Sector *P_FindSectorSurroundingNextLowestCeiling(Sector *sector, coord_t baseHeight, coord_t *val);
238 
239 #define FELLF_MIN               0x1 /// Get minimum. If not set, get maximum.
240 
241 typedef struct findlightlevelparams_s {
242     Sector *baseSec;
243     byte flags;
244     float val;
245     Sector *foundSec;
246 } findlightlevelparams_t;
247 
248 /// Find the sector with the lowest light level in surrounding sectors.
249 Sector *P_FindSectorSurroundingLowestLight(Sector *sector, float *val);
250 
251 /// Find the sector with the highest light level in surrounding sectors.
252 Sector *P_FindSectorSurroundingHighestLight(Sector *sector, float *val);
253 
254 #define FNLLF_ABOVE             0x1 /// Get next above, if not set get next below.
255 
256 typedef struct findnextlightlevelparams_s {
257     Sector *baseSec;
258     float baseLight;
259     byte flags;
260     float val;
261     Sector *foundSec;
262 } findnextlightlevelparams_t;
263 
264 /// Find the sector with the lowest light level in surrounding sectors.
265 Sector *P_FindSectorSurroundingNextLowestLight(Sector *sector, float baseLight, float *val);
266 
267 /// Find the sector with the next highest light level in surrounding sectors.
268 Sector *P_FindSectorSurroundingNextHighestLight(Sector *sector, float baseLight, float *val);
269 
270 /**
271  * Returns the material type of the specified sector, plane.
272  *
273  * @param sec  The sector to check.
274  * @param plane  The plane id to check.
275  */
276 terraintype_t const *P_PlaneMaterialTerrainType(Sector *sec, int plane);
277 
278 /**
279  * Copies all (changeable) properties from one line to another including the
280  * extended properties.
281  */
282 void P_CopyLine(Line *dest, Line *src);
283 
284 /**
285  * Copies all (changeable) properties from one sector to another including
286  * the extended properties.
287  */
288 void P_CopySector(Sector *dest, Sector *src);
289 
290 float P_SectorLight(Sector *sector);
291 void P_SectorSetLight(Sector *sector, float level);
292 void P_SectorModifyLight(Sector *sector, float value);
293 void P_SectorModifyLightx(Sector *sector, fixed_t value);
294 
295 void P_TranslateSideMaterialOrigin(Side *side, SideSection section, float deltaXY[2]);
296 void P_TranslateSideMaterialOriginXY(Side *side, SideSection section, float deltaX, float deltaY);
297 
298 void P_TranslatePlaneMaterialOrigin(Plane *plane, float deltaXY[2]);
299 void P_TranslatePlaneMaterialOriginXY(Plane *plane, float deltaX, float deltaY);
300 
301 #ifdef __cplusplus
302 } // extern "C"
303 #endif
304 
305 #endif /* LIBCOMMON_DMU_LIB_H */
306