00001 // Filename: plane_src.I 00002 // Created by: mike (09Jan97) 00003 // 00004 //////////////////////////////////////////////////////////////////// 00005 // 00006 // PANDA 3D SOFTWARE 00007 // Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved 00008 // 00009 // All use of this software is subject to the terms of the Panda 3d 00010 // Software license. You should have received a copy of this license 00011 // along with this source code; you will also find a current copy of 00012 // the license at http://www.panda3d.org/license.txt . 00013 // 00014 // To contact the maintainers of this program write to 00015 // panda3d@yahoogroups.com . 00016 // 00017 //////////////////////////////////////////////////////////////////// 00018 00019 //////////////////////////////////////////////////////////////////// 00020 // Function: Plane::Constructor 00021 // Access: Public 00022 // Description: Creates a default plane. This plane happens to 00023 // intersect the origin, perpendicular to the Z axis. 00024 // It's not clear how useful a default plane is. 00025 //////////////////////////////////////////////////////////////////// 00026 INLINE_MATHUTIL FLOATNAME(Plane):: 00027 FLOATNAME(Plane)(void) { 00028 _a = 0.0f; 00029 _b = 0.0f; 00030 _c = 1.0f; 00031 _d = 0.0f; 00032 } 00033 00034 //////////////////////////////////////////////////////////////////// 00035 // Function: Plane::Copy Constructor 00036 // Access: Public 00037 // Description: 00038 //////////////////////////////////////////////////////////////////// 00039 INLINE_MATHUTIL FLOATNAME(Plane):: 00040 FLOATNAME(Plane)(const FLOATNAME(Plane) ©) : 00041 _a(copy._a), 00042 _b(copy._b), 00043 _c(copy._c), 00044 _d(copy._d) 00045 { 00046 } 00047 00048 //////////////////////////////////////////////////////////////////// 00049 // Function: Plane::Constructor 00050 // Access: Public 00051 // Description: Constructs a plane given three counter-clockwise 00052 // points, as seen from the front of the plane (that is, 00053 // viewed from the end of the normal vector, looking 00054 // down). 00055 //////////////////////////////////////////////////////////////////// 00056 INLINE_MATHUTIL FLOATNAME(Plane):: 00057 FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b, 00058 const FLOATNAME(LPoint3) &c) { 00059 FLOATNAME(LVector3) u = b - a; 00060 FLOATNAME(LVector3) v = c - a; 00061 FLOATNAME(LVector3) p = normalize(cross(u, v)); 00062 00063 _a = p[0]; 00064 _b = p[1]; 00065 _c = p[2]; 00066 _d = -dot(p, a); 00067 } 00068 00069 //////////////////////////////////////////////////////////////////// 00070 // Function: Plane::Constructor 00071 // Access: Public 00072 // Description: Constructs a plane given a surface normal vector and 00073 // a point within the plane. 00074 //////////////////////////////////////////////////////////////////// 00075 INLINE_MATHUTIL FLOATNAME(Plane):: 00076 FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, 00077 const FLOATNAME(LPoint3) &point) { 00078 FLOATNAME(LVector3) p = normalize(normal); 00079 00080 _a = p[0]; 00081 _b = p[1]; 00082 _c = p[2]; 00083 _d = -dot(p, point); 00084 } 00085 00086 //////////////////////////////////////////////////////////////////// 00087 // Function: Plane::Constructor 00088 // Access: Public 00089 // Description: Constructs a plane given the four terms of the plane 00090 // equation. 00091 //////////////////////////////////////////////////////////////////// 00092 INLINE_MATHUTIL FLOATNAME(Plane):: 00093 FLOATNAME(Plane)(FLOATTYPE a, FLOATTYPE b, FLOATTYPE c, FLOATTYPE d) : 00094 _a(a), 00095 _b(b), 00096 _c(c), 00097 _d(d) 00098 { 00099 } 00100 00101 //////////////////////////////////////////////////////////////////// 00102 // Function: Plane::Operator = 00103 // Access: Public 00104 // Description: 00105 //////////////////////////////////////////////////////////////////// 00106 INLINE_MATHUTIL FLOATNAME(Plane)& FLOATNAME(Plane):: 00107 operator = (const FLOATNAME(Plane)& p) { 00108 _a = p._a; 00109 _b = p._b; 00110 _c = p._c; 00111 _d = p._d; 00112 return (*this); 00113 } 00114 00115 //////////////////////////////////////////////////////////////////// 00116 // Function: Plane::Operator * LMatrix3 00117 // Access: Public 00118 // Description: Transforms the plane by the indicated matrix. 00119 //////////////////////////////////////////////////////////////////// 00120 INLINE_MATHUTIL FLOATNAME(Plane) FLOATNAME(Plane):: 00121 operator * (const FLOATNAME(LMatrix3) &mat) const { 00122 FLOATNAME(LVector3) new_normal = get_normal() * mat; 00123 FLOATNAME(LPoint3) new_point = get_point() * mat; 00124 return FLOATNAME(Plane)(new_normal, new_point); 00125 } 00126 00127 //////////////////////////////////////////////////////////////////// 00128 // Function: Plane::Operator * LMatrix4 00129 // Access: Public 00130 // Description: Transforms the plane by the indicated matrix. 00131 //////////////////////////////////////////////////////////////////// 00132 INLINE_MATHUTIL FLOATNAME(Plane) FLOATNAME(Plane):: 00133 operator * (const FLOATNAME(LMatrix4) &mat) const { 00134 FLOATNAME(LVector3) new_normal = get_normal() * mat; 00135 FLOATNAME(LPoint3) new_point = get_point() * mat; 00136 return FLOATNAME(Plane)(new_normal, new_point); 00137 } 00138 00139 //////////////////////////////////////////////////////////////////// 00140 // Function: Plane::get_normal 00141 // Access: Public 00142 // Description: Returns the surface normal of the plane. 00143 //////////////////////////////////////////////////////////////////// 00144 INLINE_MATHUTIL FLOATNAME(LVector3) FLOATNAME(Plane):: 00145 get_normal() const { 00146 return FLOATNAME(LVector3)(_a, _b, _c); 00147 } 00148 00149 //////////////////////////////////////////////////////////////////// 00150 // Function: Plane::dist_to_plane 00151 // Access: Public 00152 // Description: Returns the straight-line shortest distance from the 00153 // point to the plane. The returned value is positive 00154 // if the point is in front of the plane (on the side 00155 // with the normal), or negative in the point is behind 00156 // the plane (on the opposite side from the normal). 00157 // It's zero if the point is exactly in the plane. 00158 //////////////////////////////////////////////////////////////////// 00159 INLINE_MATHUTIL FLOATTYPE FLOATNAME(Plane):: 00160 dist_to_plane(const FLOATNAME(LPoint3) &point) const { 00161 return (_a * point[0] + _b * point[1] + _c * point[2] + _d); 00162 } 00163 00164 //////////////////////////////////////////////////////////////////// 00165 // Function: Plane::intersects_line 00166 // Access: Public 00167 // Description: Returns true if the plane intersects the infinite 00168 // line passing through points p1 and p2, false if the 00169 // line is parallel. The points p1 and p2 are used only 00170 // to define the Euclidean line; they have no other 00171 // bearing on the intersection test. If true, sets 00172 // intersection_point to the point of intersection. 00173 //////////////////////////////////////////////////////////////////// 00174 INLINE_MATHUTIL bool FLOATNAME(Plane):: 00175 intersects_line(FLOATNAME(LPoint3) &intersection_point, 00176 const FLOATNAME(LPoint3) &p1, 00177 const FLOATNAME(LPoint3) &p2) const { 00178 FLOATTYPE t; 00179 if (!intersects_line(t, p1, p2 - p1)) { 00180 return false; 00181 } 00182 intersection_point = p1 + t * (p2 - p1); 00183 return true; 00184 } 00185 00186 //////////////////////////////////////////////////////////////////// 00187 // Function: Plane::intersects_line 00188 // Access: Public 00189 // Description: This flavor of intersects_line() returns a bit more 00190 // information about the nature of the intersecting 00191 // point. The line is defined via the parametric 00192 // equation from + t * delta for all real values of t. 00193 // 00194 // If there is no intersection with the plane, the 00195 // function returns false and leaves t undefined. If 00196 // there is an intersection with the plane, the function 00197 // returns true and sets t to the parametric value that 00198 // defines the point of intersection. That is, t == 0.0f 00199 // implies that the intersection occurred exactly at 00200 // point from, and t == 1.0f implies at point from + 00201 // delta, with other values of t accordingly. 00202 //////////////////////////////////////////////////////////////////// 00203 INLINE_MATHUTIL bool FLOATNAME(Plane):: 00204 intersects_line(FLOATTYPE &t, 00205 const FLOATNAME(LPoint3) &from, 00206 const FLOATNAME(LVector3) &delta) const { 00207 FLOATTYPE denom = dot(get_normal(), delta); 00208 if (IS_NEARLY_ZERO(denom)) { 00209 return false; 00210 } 00211 00212 t = -(dist_to_plane(from) / denom); 00213 return true; 00214 } 00215 00216 //////////////////////////////////////////////////////////////////// 00217 // Function: Plane::get_data 00218 // Access: Public 00219 // Description: Returns the address of the first of the four data 00220 // elements in the plane equation. The remaining 00221 // elements occupy the next positions consecutively in 00222 // memory. 00223 //////////////////////////////////////////////////////////////////// 00224 INLINE_MATHUTIL const FLOATTYPE *FLOATNAME(Plane):: 00225 get_data() const { 00226 return &_a; 00227 } 00228 00229 //////////////////////////////////////////////////////////////////// 00230 // Function: Plane::get_num_components 00231 // Access: Public 00232 // Description: Returns the number of elements in the plane equation, 00233 // four. 00234 //////////////////////////////////////////////////////////////////// 00235 INLINE_MATHUTIL int FLOATNAME(Plane):: 00236 get_num_components() const { 00237 return 4; 00238 } 00239 00240 //////////////////////////////////////////////////////////////////// 00241 // Function: Plane::output 00242 // Access: Public 00243 // Description: 00244 //////////////////////////////////////////////////////////////////// 00245 INLINE_MATHUTIL void FLOATNAME(Plane):: 00246 output(ostream &out) const { 00247 out << "Plane(" << _a << " " << _b << " " << _c << " " << _d << ")"; 00248 } 00249 00250 //////////////////////////////////////////////////////////////////// 00251 // Function: Plane::write 00252 // Access: Public 00253 // Description: 00254 //////////////////////////////////////////////////////////////////// 00255 INLINE_MATHUTIL void FLOATNAME(Plane):: 00256 write(ostream &out, int indent_level) const { 00257 indent(out, indent_level) << *this << "\n"; 00258 } 00259 00260 //////////////////////////////////////////////////////////////////// 00261 // Function: Plane::write_datagram 00262 // Access: Public 00263 // Description: 00264 //////////////////////////////////////////////////////////////////// 00265 INLINE_MATHUTIL void FLOATNAME(Plane):: 00266 write_datagram(Datagram &dest) const { 00267 #if FLOATTOKEN == 'f' 00268 dest.add_float32(_a); 00269 dest.add_float32(_b); 00270 dest.add_float32(_c); 00271 dest.add_float32(_d); 00272 #else 00273 dest.add_float64(_a); 00274 dest.add_float64(_b); 00275 dest.add_float64(_c); 00276 dest.add_float64(_d); 00277 #endif 00278 } 00279 00280 //////////////////////////////////////////////////////////////////// 00281 // Function: Plane::read_datagram 00282 // Access: Public 00283 // Description: 00284 //////////////////////////////////////////////////////////////////// 00285 INLINE_MATHUTIL void FLOATNAME(Plane):: 00286 read_datagram(DatagramIterator &source) { 00287 #if FLOATTOKEN == 'f' 00288 _a = source.get_float32(); 00289 _b = source.get_float32(); 00290 _c = source.get_float32(); 00291 _d = source.get_float32(); 00292 #else 00293 _a = source.get_float64(); 00294 _b = source.get_float64(); 00295 _c = source.get_float64(); 00296 _d = source.get_float64(); 00297 #endif 00298 }