Merge branch 'fixes' into main/rendor-staging
[ryzomcore.git] / nel / src / misc / bsphere.cpp
blob1fcf359e79f0e87c35a005ba6e5b20910fba4e55
1 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
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.
8 //
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/>.
17 #include "stdmisc.h"
19 #include "nel/misc/bsphere.h"
21 using namespace NLMISC;
22 using namespace std;
24 #ifdef DEBUG_NEW
25 #define new DEBUG_NEW
26 #endif
28 namespace NLMISC {
31 bool CBSphere::clipFront(const CPlane &p) const
33 // assume normalized planes.
35 // if( SpherMax OUT ) return false.
36 float d= p*Center;
37 if(d<-Radius)
38 return false;
40 return true;
44 bool CBSphere::clipBack(const CPlane &p) const
46 // assume normalized planes.
48 // if( SpherMax OUT ) return false.
49 float d= p*Center;
50 if(d>Radius)
51 return false;
53 return true;
57 bool CBSphere::include(const CVector &p) const
59 float r2= (p-Center).sqrnorm();
60 return (r2<=sqr(Radius));
63 bool CBSphere::include(const CBSphere &s) const
65 // if smaller than s, how could we include it???
66 if(Radius<=s.Radius)
67 return false;
68 float r2= (s.Center-Center).sqrnorm();
69 // Because of prec test, Radius-s.Radius>0.
70 return r2<=sqr(Radius-s.Radius);
73 bool CBSphere::intersect(const CBSphere &s) const
75 float r2= (s.Center-Center).sqrnorm();
77 return r2<=sqr(Radius+s.Radius);
82 void CBSphere::applyTransform(const CMatrix &mat, CBSphere &res)
84 res.Center= mat*Center;
86 if(!mat.hasScalePart())
87 res.Radius= Radius;
88 else
90 if(mat.hasScaleUniform())
91 res.Radius= Radius*mat.getScaleUniform();
92 else
94 // must compute max of 3 axis.
95 float m, mx;
96 CVector i,j,k;
97 i= mat.getI();
98 j= mat.getJ();
99 k= mat.getK();
100 // take the max of the 3 axis.
101 m= i.sqrnorm();
102 mx= m;
103 m= j.sqrnorm();
104 mx= max(m, mx);
105 m= k.sqrnorm();
106 mx= max(m, mx);
108 // result.
109 res.Radius= Radius * (float)sqrt(mx);
115 // ***************************************************************************
116 void CBSphere::setUnion(const CBSphere &sa, const CBSphere &sb)
118 float r2= (sb.Center-sa.Center).norm();
120 // Name Sphere 0 the biggest one, and Sphere 1 the other
121 const CBSphere *s0;
122 const CBSphere *s1;
123 if(sa.Radius>sb.Radius)
125 s0= &sa;
126 s1= &sb;
128 else
130 s0= &sb;
131 s1= &sa;
133 float r0= s0->Radius;
134 float r1= s1->Radius;
136 // If Sphere1 is included into Sphere0, then the union is simply Sphere0
137 if(r2<=(r0-r1))
139 *this= *s0;
141 else
143 /* Compute the Union sphere Diameter. It is D= r0 + r2 + r1
144 do the draw, works for intersect and don't intersect case,
145 acknowledge that Sphere1 not included inton Sphere0
147 float diameter= r0 + r2 + r1;
149 // compute dir from big center to small one.
150 CVector dir= s1->Center - s0->Center;
151 dir.normalize();
153 // Then finally set Radius and center
154 Center= s0->Center + dir * (diameter/2 - r0);
155 Radius= diameter/2;
160 } // NLMISC