Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
opbox.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 1998,1999,2000 by Jorrit Tyberghein
3  Largely rewritten by Ivan Avramovic <ivan@avramovic.com>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public
16  License along with this library; if not, write to the Free
17  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 
20 #ifndef __CS_BOX_H__
21 #define __CS_BOX_H__
22 
23 
24 #include "opvector3.h"
25 
26 
27 class csPlane3;
28 
33 #define CS_BOUNDINGBOX_MAXVALUE 1000000000.
34 
35 
40 #define BOX_CORNER_xyz 0
41 #define BOX_CORNER_xyZ 1
42 #define BOX_CORNER_xYz 2
43 #define BOX_CORNER_xYZ 3
44 #define BOX_CORNER_Xyz 4
45 #define BOX_CORNER_XyZ 5
46 #define BOX_CORNER_XYz 6
47 #define BOX_CORNER_XYZ 7
48 
53 #define BOX_SIDE_x 0
54 #define BOX_SIDE_X 1
55 #define BOX_SIDE_y 2
56 #define BOX_SIDE_Y 3
57 #define BOX_SIDE_z 4
58 #define BOX_SIDE_Z 5
59 #define BOX_INSIDE 6
60 
65 #define BOX_EDGE_Xyz_xyz 0
66 #define BOX_EDGE_xyz_Xyz 1
67 #define BOX_EDGE_xyz_xYz 2
68 #define BOX_EDGE_xYz_xyz 3
69 #define BOX_EDGE_xYz_XYz 4
70 #define BOX_EDGE_XYz_xYz 5
71 #define BOX_EDGE_XYz_Xyz 6
72 #define BOX_EDGE_Xyz_XYz 7
73 #define BOX_EDGE_Xyz_XyZ 8
74 #define BOX_EDGE_XyZ_Xyz 9
75 #define BOX_EDGE_XyZ_XYZ 10
76 #define BOX_EDGE_XYZ_XyZ 11
77 #define BOX_EDGE_XYZ_XYz 12
78 #define BOX_EDGE_XYz_XYZ 13
79 #define BOX_EDGE_XYZ_xYZ 14
80 #define BOX_EDGE_xYZ_XYZ 15
81 #define BOX_EDGE_xYZ_xYz 16
82 #define BOX_EDGE_xYz_xYZ 17
83 #define BOX_EDGE_xYZ_xyZ 18
84 #define BOX_EDGE_xyZ_xYZ 19
85 #define BOX_EDGE_xyZ_xyz 20
86 #define BOX_EDGE_xyz_xyZ 21
87 #define BOX_EDGE_xyZ_XyZ 22
88 #define BOX_EDGE_XyZ_xyZ 23
89 
97 class csBox3
98 {
99 protected:
104 
105  struct bEdge
106  {
107  uint8 v1, v2; // Indices of vertex in bounding box (BOX_CORNER_...)
108  uint8 fl, fr; // Indices of left/right faces sharing edge (BOX_SIDE_...)
109  };
110  typedef uint8 bFace[4]; // Indices of four clock-wise edges (0..23)
111  // Index by edge number. Edge e and e+1 with e even are opposite edges.
112  // (BOX_EDGE_...)
113  static bEdge edges[24];
114  // Index by BOX_SIDE_? number.
115  static bFace faces[6];
116 public:
118  float MinX () const { return minbox.x; }
120  float MinY () const { return minbox.y; }
122  float MinZ () const { return minbox.z; }
124  float MaxX () const { return maxbox.x; }
126  float MaxY () const { return maxbox.y; }
128  float MaxZ () const { return maxbox.z; }
130  float Min (int idx) const
131  { return idx == 1 ? minbox.y : idx == 0 ? minbox.x : minbox.z; }
133  float Max (int idx) const
134  { return idx == 1 ? maxbox.y : idx == 0 ? maxbox.x : maxbox.z; }
136  const csVector3& Min () const { return minbox; }
138  const csVector3& Max () const { return maxbox; }
139 
148  csVector3 GetCorner (int corner) const;
149 
154  void GetEdgeInfo (int edge, int& v1, int& v2, int& fleft, int& fright) const
155  {
156  v1 = edges[edge].v1;
157  v2 = edges[edge].v2;
158  fleft = edges[edge].fl;
159  fright = edges[edge].fr;
160  }
161 
166  uint8* GetFaceEdges (int face) const
167  {
168  return faces[face];
169  }
170 
174  csVector3 GetCenter () const { return csVector3((minbox.x+maxbox.x)/2, (minbox.y+maxbox.y)/2, (minbox.z+maxbox.z)/2); }
175 
180  void SetCenter (const csVector3& c);
181 
185  void SetSize (const csVector3& s);
186 
199  int GetVisibleSides (const csVector3& pos, int* visible_sides) const;
200 
205  static int OtherSide (int side)
206  {
207  return side ^ 1;
208  }
209 
231  bool In (float x, float y, float z) const
233  {
234  if (x < minbox.x || x > maxbox.x) return false;
235  if (y < minbox.y || y > maxbox.y) return false;
236  if (z < minbox.z || z > maxbox.z) return false;
237  return true;
238  }
239 
241  bool In (const csVector3& v) const
242  {
243  return In (v.x, v.y, v.z);
244  }
245 
247  bool Overlap (const csBox3& box) const
248  {
249  if (maxbox.x < box.minbox.x || minbox.x > box.maxbox.x) return false;
250  if (maxbox.y < box.minbox.y || minbox.y > box.maxbox.y) return false;
251  if (maxbox.z < box.minbox.z || minbox.z > box.maxbox.z) return false;
252  return true;
253  }
254 
256  bool Contains (const csBox3& box) const
257  {
258  return (box.minbox.x >= minbox.x && box.maxbox.x <= maxbox.x) &&
259  (box.minbox.y >= minbox.y && box.maxbox.y <= maxbox.y) &&
260  (box.minbox.z >= minbox.z && box.maxbox.z <= maxbox.z);
261  }
262 
264  bool Empty () const
265  {
266  if (minbox.x > maxbox.x) return true;
267  if (minbox.y > maxbox.y) return true;
268  if (minbox.z > maxbox.z) return true;
269  return false;
270  }
271 
274  {
281  }
282 
285  {
286  minbox = v; maxbox = v;
287  }
288 
290  void AddBoundingVertex (float x, float y, float z)
291  {
292  if (x < minbox.x) minbox.x = x; if (x > maxbox.x) maxbox.x = x;
293  if (y < minbox.y) minbox.y = y; if (y > maxbox.y) maxbox.y = y;
294  if (z < minbox.z) minbox.z = z; if (z > maxbox.z) maxbox.z = z;
295  }
296 
299  {
300  AddBoundingVertex (v.x, v.y, v.z);
301  }
302 
308  void AddBoundingVertexSmart (float x, float y, float z)
309  {
310  if (x < minbox.x) minbox.x = x; else if (x > maxbox.x) maxbox.x = x;
311  if (y < minbox.y) minbox.y = y; else if (y > maxbox.y) maxbox.y = y;
312  if (z < minbox.z) minbox.z = z; else if (z > maxbox.z) maxbox.z = z;
313  }
314 
321  {
322  AddBoundingVertexSmart (v.x, v.y, v.z);
323  }
324 
325  //-----
326  // Maintenance Note: The csBox3 constructors and Set() appear at this point
327  // in the file, rather than earlier, in order to appease the OpenStep 4.2
328  // compiler. Specifically, the problem is that the compiler botches code
329  // generation if an unseen method (which is later declared inline) is
330  // called from within another inline method. For instance, if the
331  // constructors were listed at the top of the file, rather than here, the
332  // compiler would see calls to Empty() and StartBoundingBox() before seeing
333  // declarations for them. In such a situation, the buggy compiler
334  // generated a broken object file. The simple work-around of textually
335  // reorganizing the file ensures that the declarations for Empty() and
336  // StartBoundingBox() are seen before they are called.
337  //-----
338 
340  csBox3 () :
347 
349  csBox3 (const csVector3& v) : minbox (v), maxbox (v) { }
350 
352  csBox3 (const csVector3& v1, const csVector3& v2) :
353  minbox (v1), maxbox (v2)
354  { if (Empty ()) StartBoundingBox (); }
355 
357  csBox3 (float x1, float y1, float z1, float x2, float y2, float z2) :
358  minbox (x1, y1, z1), maxbox (x2, y2, z2)
359  { if (Empty ()) StartBoundingBox (); }
360 
362  void Set (const csVector3& bmin, const csVector3& bmax)
363  {
364  minbox = bmin;
365  maxbox = bmax;
366  }
367 
369  void Set (float x1, float y1, float z1, float x2, float y2, float z2)
370  {
371  if (x1>x2 || y1>y2 || z1>z2) StartBoundingBox();
372  else
373  {
374  minbox.x = x1; minbox.y = y1; minbox.z = z1;
375  maxbox.x = x2; maxbox.y = y2; maxbox.z = z2;
376  }
377  }
378 
382  bool AdjacentX (const csBox3& other) const;
383 
387  bool AdjacentY (const csBox3& other) const;
388 
392  bool AdjacentZ (const csBox3& other) const;
393 
400  int Adjacent (const csBox3& other) const;
401 
410  void GetConvexOutline (const csVector3& pos,
411  csVector3* array, int& num_array, bool bVisible=false) const;
412 
416  bool Between (const csBox3& box1, const csBox3& box2) const;
417 
422  void ManhattanDistance (const csBox3& other, csVector3& dist) const;
423 
428  float SquaredOriginDist () const;
429 
435  float SquaredOriginMaxDist () const;
436 
438  csBox3& operator+= (const csBox3& box);
440  csBox3& operator+= (const csVector3& point);
442  csBox3& operator*= (const csBox3& box);
443 
445  friend csBox3 operator+ (const csBox3& box1, const csBox3& box2);
447  friend csBox3 operator+ (const csBox3& box, const csVector3& point);
449  friend csBox3 operator* (const csBox3& box1, const csBox3& box2);
450 
452  friend bool operator== (const csBox3& box1, const csBox3& box2);
454  friend bool operator!= (const csBox3& box1, const csBox3& box2);
456  friend bool operator< (const csBox3& box1, const csBox3& box2);
458  friend bool operator> (const csBox3& box1, const csBox3& box2);
460  friend bool operator< (const csVector3& point, const csBox3& box);
461 };
462 
463 #endif // __CS_BOX_H__