1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU Affero General Public License as
6 // published by the Free Software Foundation, either version 3 of the
7 // License, or (at your option) any later version.
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU Affero General Public License for more details.
14 // You should have received a copy of the GNU Affero General Public License
15 // along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include "nel/misc/aabbox.h"
20 #include "nel/misc/polygon.h"
21 #include "nel/misc/bsphere.h"
22 #include "nel/misc/matrix.h"
31 // ***************************************************************************
32 bool CAABBox::clipFront(const CPlane
&p
) const
36 // The bbox is front of the plane if only one of his vertex is in front.
37 if(p
*(Center
+ HalfSize
) > 0) return true;
38 if(p
*(Center
- HalfSize
) > 0) return true;
39 hswap
.set(-HalfSize
.x
, HalfSize
.y
, HalfSize
.z
);
40 if(p
*(Center
+ hswap
) > 0) return true;
41 if(p
*(Center
- hswap
) > 0) return true;
42 hswap
.set(HalfSize
.x
, -HalfSize
.y
, HalfSize
.z
);
43 if(p
*(Center
+ hswap
) > 0) return true;
44 if(p
*(Center
- hswap
) > 0) return true;
45 hswap
.set(HalfSize
.x
, HalfSize
.y
, -HalfSize
.z
);
46 if(p
*(Center
+ hswap
) > 0) return true;
47 if(p
*(Center
- hswap
) > 0) return true;
51 // ***************************************************************************
52 bool CAABBox::clipBack(const CPlane
&p
) const
56 // The bbox is back of the plane if only one of his vertex is in back.
57 if(p
*(Center
+ HalfSize
) < 0) return true;
58 if(p
*(Center
- HalfSize
) < 0) return true;
59 hswap
.set(-HalfSize
.x
, HalfSize
.y
, HalfSize
.z
);
60 if(p
*(Center
+ hswap
) < 0) return true;
61 if(p
*(Center
- hswap
) < 0) return true;
62 hswap
.set(HalfSize
.x
, -HalfSize
.y
, HalfSize
.z
);
63 if(p
*(Center
+ hswap
) < 0) return true;
64 if(p
*(Center
- hswap
) < 0) return true;
65 hswap
.set(HalfSize
.x
, HalfSize
.y
, -HalfSize
.z
);
66 if(p
*(Center
+ hswap
) < 0) return true;
67 if(p
*(Center
- hswap
) < 0) return true;
73 // ***************************************************************************
74 bool CAABBox::include(const CVector
&a
) const
76 if(Center
.x
+HalfSize
.x
<a
.x
) return false;
77 if(Center
.x
-HalfSize
.x
>a
.x
) return false;
78 if(Center
.y
+HalfSize
.y
<a
.y
) return false;
79 if(Center
.y
-HalfSize
.y
>a
.y
) return false;
80 if(Center
.z
+HalfSize
.z
<a
.z
) return false;
81 if(Center
.z
-HalfSize
.z
>a
.z
) return false;
86 // ***************************************************************************
87 bool CAABBox::include(const CAABBox
&box
) const
89 if(Center
.x
+HalfSize
.x
< box
.Center
.x
+box
.HalfSize
.x
) return false;
90 if(Center
.x
-HalfSize
.x
> box
.Center
.x
-box
.HalfSize
.x
) return false;
91 if(Center
.y
+HalfSize
.y
< box
.Center
.y
+box
.HalfSize
.y
) return false;
92 if(Center
.y
-HalfSize
.y
> box
.Center
.y
-box
.HalfSize
.y
) return false;
93 if(Center
.z
+HalfSize
.z
< box
.Center
.z
+box
.HalfSize
.z
) return false;
94 if(Center
.z
-HalfSize
.z
> box
.Center
.z
-box
.HalfSize
.z
) return false;
99 // ***************************************************************************
100 bool CAABBox::intersect(const CAABBox
&box
) const
102 CVector mina
= getMin(), maxa
= getMax(),
103 minb
= box
.getMin(), maxb
= box
.getMax();
105 return ! ( mina
.x
> maxb
.x
||
113 // ***************************************************************************
114 bool CAABBox::intersect(const CVector
&a
, const CVector
&b
, const CVector
&c
) const
117 if(include(a
) || include(b
) || include(c
))
119 // Else, must test if the polygon intersect the pyamid.
122 CPolygon
poly(a
,b
,c
);
123 poly
.clip(planes
, 6);
124 if(poly
.getNumVertices()==0)
129 // ***************************************************************************
130 bool CAABBox::intersect(const CVector
&a
, const CVector
&b
) const
133 if(include(a
) || include(b
))
135 // Else, must test if the segment intersect the pyamid.
139 // clip the segment against all planes
140 for(uint i
=0;i
<6;i
++)
142 if(!planes
[i
].clipSegmentBack(p0
, p1
))
148 // ***************************************************************************
149 bool CAABBox::clipSegment(CVector
&a
, CVector
&b
) const
151 // Trivial test. If both are in, they are inchanged
152 if(include(a
) && include(b
))
154 // Else, must clip the segment againts the pyamid.
158 // clip the segment against all planes
159 for(uint i
=0;i
<6;i
++)
161 if(!planes
[i
].clipSegmentBack(p0
, p1
))
170 // ***************************************************************************
171 bool CAABBox::intersect(const CBSphere
&s
) const
173 if (Center
.x
+ HalfSize
.x
< s
.Center
.x
- s
.Radius
) return false;
174 if (Center
.y
+ HalfSize
.y
< s
.Center
.y
- s
.Radius
) return false;
175 if (Center
.z
+ HalfSize
.z
< s
.Center
.z
- s
.Radius
) return false;
177 if (Center
.x
- HalfSize
.x
> s
.Center
.x
+ s
.Radius
) return false;
178 if (Center
.y
- HalfSize
.y
> s
.Center
.y
+ s
.Radius
) return false;
179 if (Center
.z
- HalfSize
.z
> s
.Center
.z
+ s
.Radius
) return false;
186 // ***************************************************************************
187 void CAABBox::makePyramid(CPlane planes
[6]) const
189 planes
[0].make(CVector(-1,0,0), Center
-HalfSize
);
190 planes
[1].make(CVector(+1,0,0), Center
+HalfSize
);
191 planes
[2].make(CVector(0,-1,0), Center
-HalfSize
);
192 planes
[3].make(CVector(0,+1,0), Center
+HalfSize
);
193 planes
[4].make(CVector(0,0,-1), Center
-HalfSize
);
194 planes
[5].make(CVector(0,0,+1), Center
+HalfSize
);
198 // ***************************************************************************
199 void CAABBox::serial(NLMISC::IStream
&f
)
201 /* ***********************************************
202 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
203 * It can be loaded/called through CAsyncFileManager for instance
204 * ***********************************************/
205 (void)f
.serialVersion(0);
211 // ***************************************************************************
212 void CAABBox::extend(const CVector
&v
)
214 CVector bmin
= getMin(), bmax
= getMax();
218 setMinMax(bmin
, bmax
);
222 //==========================================================================
224 * Compute the union of 2 aabboxes, that is the aabbox that contains the 2.
225 * Should end up in NLMISC
228 CAABBox
CAABBox::computeAABBoxUnion(const CAABBox
&b1
, const CAABBox
&b2
)
232 CVector min1
= b1
.getMin()
236 max
.maxof(max1
, max2
);
237 min
.minof(min1
, min2
);
238 result
.setMinMax(min
, max
);
243 //==========================================================================
244 void CAABBox::computeIntersection(const CAABBox
&b1
, const CAABBox
&b2
)
246 CVector min1
= b1
.getMin(), max1
= b1
.getMax(),
247 min2
= b2
.getMin(), max2
= b2
.getMax();
250 // don't test if intersect or not.
251 maxr
.minof(max1
, max2
);
252 minr
.maxof(min1
, min2
);
254 setMinMax(minr
, maxr
);
258 //==========================================================================
259 CAABBox
CAABBox::transformAABBox(const CMatrix
&mat
, const CAABBox
&box
)
261 // TODO : optimize this a bit if possible...
264 /* OMG. Old code was false!!
266 then CVector(-ht.x, ht.y, ht.z) != M * CVector(-h.x, h.y, h.z) !!!!
270 CVector min
= box
.getMin();
271 CVector max
= box
.getMax();
272 p
[0].set(min
.x
, min
.y
, min
.z
);
273 p
[1].set(max
.x
, min
.y
, min
.z
);
274 p
[2].set(min
.x
, max
.y
, min
.z
);
275 p
[3].set(max
.x
, max
.y
, min
.z
);
276 p
[4].set(min
.x
, min
.y
, max
.z
);
277 p
[5].set(max
.x
, min
.y
, max
.z
);
278 p
[6].set(min
.x
, max
.y
, max
.z
);
279 p
[7].set(max
.x
, max
.y
, max
.z
);
281 min
= max
= mat
* p
[0];
282 // transform corners.
283 for(uint i
=1;i
<8;i
++)
290 result
.setMinMax(min
, max
);
297 // ***************************************************************************
298 bool CAABBoxExt::clipFront(const CPlane
&p
) const
300 // Assume normalized planes.
302 // if( SpherMax OUT ) return false.
306 // if( SphereMin IN ) return true;
310 // else, standard clip box.
311 return CAABBox::clipFront(p
);
315 // ***************************************************************************
316 bool CAABBoxExt::clipBack(const CPlane
&p
) const
318 // Assume normalized planes.
320 // if( SpherMax OUT ) return false.
324 // if( SphereMin IN ) return true;
328 // else, standard clip box.
329 return CAABBox::clipBack(p
);
333 // ***************************************************************************
334 void CAABBoxExt::serial(NLMISC::IStream
&f
)
336 /* ***********************************************
337 * WARNING: This Class/Method must be thread-safe (ctor/dtor/serial): no static access for instance
338 * It can be loaded/called through CAsyncFileManager for instance
339 * ***********************************************/