247 lines
9.0 KiB
Plaintext
247 lines
9.0 KiB
Plaintext
// Filename: plane_src.I
|
|
// Created by: mike (09Jan97)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// PANDA 3D SOFTWARE
|
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
|
//
|
|
// All use of this software is subject to the terms of the Panda 3d
|
|
// Software license. You should have received a copy of this license
|
|
// along with this source code; you will also find a current copy of
|
|
// the license at http://www.panda3d.org/license.txt .
|
|
//
|
|
// To contact the maintainers of this program write to
|
|
// panda3d@yahoogroups.com .
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Constructor
|
|
// Access: Public
|
|
// Description: Creates a default plane. This plane happens to
|
|
// intersect the origin, perpendicular to the Z axis.
|
|
// It's not clear how useful a default plane is.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane)::
|
|
FLOATNAME(Plane)(void) {
|
|
_a = 0.0f;
|
|
_b = 0.0f;
|
|
_c = 1.0f;
|
|
_d = 0.0f;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Copy Constructor
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane)::
|
|
FLOATNAME(Plane)(const FLOATNAME(Plane) ©) :
|
|
_a(copy._a),
|
|
_b(copy._b),
|
|
_c(copy._c),
|
|
_d(copy._d)
|
|
{
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Constructor
|
|
// Access: Public
|
|
// Description: Constructs a plane given three counter-clockwise
|
|
// points, as seen from the front of the plane (that is,
|
|
// viewed from the end of the normal vector, looking
|
|
// down).
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane)::
|
|
FLOATNAME(Plane)(const FLOATNAME(LPoint3) &a, const FLOATNAME(LPoint3) &b,
|
|
const FLOATNAME(LPoint3) &c) {
|
|
FLOATNAME(LVector3) u = b - a;
|
|
FLOATNAME(LVector3) v = c - a;
|
|
FLOATNAME(LVector3) p = normalize(cross(u, v));
|
|
|
|
_a = p[0];
|
|
_b = p[1];
|
|
_c = p[2];
|
|
_d = -dot(p, a);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Constructor
|
|
// Access: Public
|
|
// Description: Constructs a plane given a surface normal vector and
|
|
// a point within the plane.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane)::
|
|
FLOATNAME(Plane)(const FLOATNAME(LVector3) &normal, const FLOATNAME(LPoint3) &point) {
|
|
FLOATNAME(LVector3) p = normalize(normal);
|
|
|
|
_a = p[0];
|
|
_b = p[1];
|
|
_c = p[2];
|
|
_d = -dot(p, point);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Operator =
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane)& FLOATNAME(Plane)::
|
|
operator = (const FLOATNAME(Plane)& p) {
|
|
_a = p._a;
|
|
_b = p._b;
|
|
_c = p._c;
|
|
_d = p._d;
|
|
return (*this);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Operator * LMatrix3
|
|
// Access: Public
|
|
// Description: Transforms the plane by the indicated matrix.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane) FLOATNAME(Plane)::
|
|
operator * (const FLOATNAME(LMatrix3) &mat) const {
|
|
FLOATNAME(LVector3) new_normal = get_normal() * mat;
|
|
FLOATNAME(LPoint3) new_point = get_point() * mat;
|
|
return FLOATNAME(Plane)(new_normal, new_point);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::Operator * LMatrix4
|
|
// Access: Public
|
|
// Description: Transforms the plane by the indicated matrix.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(Plane) FLOATNAME(Plane)::
|
|
operator * (const FLOATNAME(LMatrix4) &mat) const {
|
|
FLOATNAME(LVector3) new_normal = get_normal() * mat;
|
|
FLOATNAME(LPoint3) new_point = get_point() * mat;
|
|
return FLOATNAME(Plane)(new_normal, new_point);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::get_normal
|
|
// Access: Public
|
|
// Description: Returns the surface normal of the plane.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATNAME(LVector3) FLOATNAME(Plane)::
|
|
get_normal() const {
|
|
return FLOATNAME(LVector3)(_a, _b, _c);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::dist_to_plane
|
|
// Access: Public
|
|
// Description: Returns the straight-line shortest distance from the
|
|
// point to the plane. The returned value is positive
|
|
// if the point is in front of the plane (on the side
|
|
// with the normal), or negative in the point is behind
|
|
// the plane (on the opposite side from the normal).
|
|
// It's zero if the point is exactly in the plane.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL FLOATTYPE FLOATNAME(Plane)::
|
|
dist_to_plane(const FLOATNAME(LPoint3) &point) const {
|
|
return (_a * point[0] + _b * point[1] + _c * point[2] + _d);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::intersects_line
|
|
// Access: Public
|
|
// Description: Returns true if the plane intersects the infinite
|
|
// line passing through points p1 and p2, false if the
|
|
// line is parallel. The points p1 and p2 are used only
|
|
// to define the Euclidean line; they have no other
|
|
// bearing on the intersection test. If true, sets
|
|
// intersection_point to the point of intersection.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL bool FLOATNAME(Plane)::
|
|
intersects_line(FLOATNAME(LPoint3) &intersection_point,
|
|
const FLOATNAME(LPoint3) &p1,
|
|
const FLOATNAME(LPoint3) &p2) const {
|
|
FLOATTYPE t;
|
|
if (!intersects_line(t, p1, p2 - p1)) {
|
|
return false;
|
|
}
|
|
intersection_point = p1 + t * (p2 - p1);
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::intersects_line
|
|
// Access: Public
|
|
// Description: This flavor of intersects_line() returns a bit more
|
|
// information about the nature of the intersecting
|
|
// point. The line is defined via the parametric
|
|
// equation from + t * delta for all real values of t.
|
|
//
|
|
// If there is no intersection with the plane, the
|
|
// function returns false and leaves t undefined. If
|
|
// there is an intersection with the plane, the function
|
|
// returns true and sets t to the parametric value that
|
|
// defines the point of intersection. That is, t == 0.0f
|
|
// implies that the intersection occurred exactly at
|
|
// point from, and t == 1.0f implies at point from +
|
|
// delta, with other values of t accordingly.
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL bool FLOATNAME(Plane)::
|
|
intersects_line(FLOATTYPE &t,
|
|
const FLOATNAME(LPoint3) &from,
|
|
const FLOATNAME(LVector3) &delta) const {
|
|
FLOATTYPE denom = dot(get_normal(), delta);
|
|
if (IS_NEARLY_ZERO(denom)) {
|
|
return false;
|
|
}
|
|
|
|
t = -(dist_to_plane(from) / denom);
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::output
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL void FLOATNAME(Plane)::
|
|
output(ostream &out) const {
|
|
out << "Plane(" << _a << " " << _b << " " << _c << " " << _d << ")";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::write
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL void FLOATNAME(Plane)::
|
|
write(ostream &out, int indent_level) const {
|
|
indent(out, indent_level) << *this << "\n";
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::write_datagram
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL void FLOATNAME(Plane)::
|
|
write_datagram(Datagram &dest)
|
|
{
|
|
dest.add_float32(_a);
|
|
dest.add_float32(_b);
|
|
dest.add_float32(_c);
|
|
dest.add_float32(_d);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: Plane::read_datagram
|
|
// Access: Public
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
INLINE_MATHUTIL void FLOATNAME(Plane)::
|
|
read_datagram(DatagramIterator &source)
|
|
{
|
|
_a = source.get_float32();
|
|
_b = source.get_float32();
|
|
_c = source.get_float32();
|
|
_d = source.get_float32();
|
|
}
|