mirror of
https://foundry.openuru.org/gitblit/r/CWE-ou-minkata.git
synced 2025-07-14 02:27:40 -04:00
CWE Directory Reorganization
Rearrange directory structure of CWE to be loosely equivalent to the H'uru Plasma repository. Part 1: Movement of directories and files.
This commit is contained in:
4
Sources/Plasma/PubUtilLib/plIntersect/notes.txt
Normal file
4
Sources/Plasma/PubUtilLib/plIntersect/notes.txt
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
Collection of geometry intersection routines between various primitives, e.g. TriList/Box, Box/Box, Box/Sphere, etc.
|
||||
|
||||
Mesh types will often convert themselves to appropriate type, and call from this lib when queried for intersection.
|
701
Sources/Plasma/PubUtilLib/plIntersect/plClosest.cpp
Normal file
701
Sources/Plasma/PubUtilLib/plIntersect/plClosest.cpp
Normal file
@ -0,0 +1,701 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "plClosest.h"
|
||||
#include "hsFastMath.h"
|
||||
|
||||
|
||||
static const hsScalar kRealSmall = 1.e-5f;
|
||||
|
||||
// Find the closest point on a line (or segment) to a point.
|
||||
UInt32 plClosest::PointOnLine(const hsPoint3& p0,
|
||||
const hsPoint3& p1, const hsVector3& v1,
|
||||
hsPoint3& cp,
|
||||
UInt32 clamp)
|
||||
{
|
||||
hsScalar invV1Sq = v1.MagnitudeSquared();
|
||||
// v1 is also zero length. The two input points are the only options for output.
|
||||
if( invV1Sq < kRealSmall )
|
||||
{
|
||||
cp = p1;
|
||||
return kClamp;
|
||||
}
|
||||
hsScalar t = v1.InnerProduct(p0 - p1) / invV1Sq;
|
||||
cp = p1;
|
||||
// clamp to the ends of segment v1.
|
||||
if( (clamp & kClampLower1) && (t < 0) )
|
||||
{
|
||||
return kClampLower1;
|
||||
}
|
||||
if( (clamp & kClampUpper1) && (t > 1.f) )
|
||||
{
|
||||
cp += v1;
|
||||
return kClampUpper1;
|
||||
}
|
||||
|
||||
cp += v1 * t;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find closest points to each other from two lines (or segments).
|
||||
UInt32 plClosest::PointsOnLines(const hsPoint3& p0, const hsVector3& v0,
|
||||
const hsPoint3& p1, const hsVector3& v1,
|
||||
hsPoint3& cp0, hsPoint3& cp1,
|
||||
UInt32 clamp)
|
||||
{
|
||||
hsScalar invV0Sq = v0.MagnitudeSquared();
|
||||
// First handle degenerate cases.
|
||||
// v0 is zero length. Resolves to finding closest point on p1+v1 to p0
|
||||
if( invV0Sq < kRealSmall )
|
||||
{
|
||||
cp0 = p0;
|
||||
return kClamp0 | PointOnLine(p0, p1, v1, cp1, clamp);
|
||||
}
|
||||
invV0Sq = 1.f / invV0Sq;
|
||||
|
||||
// The real thing here, two non-zero length segments. (v1 can
|
||||
// be zero length, it doesn't affect the math like |v0|=0 does,
|
||||
// so we don't even bother to check. Only means maybe doing extra
|
||||
// work, since we're using segment-segment math when all we really
|
||||
// need is point-segment.)
|
||||
|
||||
// The parameterized points for along each of the segments are
|
||||
// P(t0) = p0 + v0*t0
|
||||
// P(t1) = p1 + v1*t1
|
||||
//
|
||||
// The closest point on p0+v0 to P(t1) is:
|
||||
// cp0 = p0 + ((P(t1) - p0) dot v0) * v0 / ||v0|| ||x|| is mag squared here
|
||||
// cp0 = p0 + v0*t0 => t0 = ((P(t1) - p0) dot v0 ) / ||v0||
|
||||
// t0 = ((p1 + v1*t1 - p0) dot v0) / ||v0||
|
||||
//
|
||||
// The distance squared from P(t1) to cp0 is:
|
||||
// (cp0 - P(t1)) dot (cp0 - P(t1))
|
||||
//
|
||||
// This expands out to:
|
||||
//
|
||||
// CV0 dot CV0 + 2 CV0 dot DV0 * t1 + (DV0 dot DV0) * t1^2
|
||||
//
|
||||
// where
|
||||
//
|
||||
// CV0 = p0 - p1 + ((p1 - p0) dot v0) / ||v0||) * v0 == vector from p1 to closest point on p0+v0
|
||||
// and
|
||||
// DV0 = ((v1 dot v0) / ||v0||) * v0 - v1 == ortho divergence vector of v1 from v0 negated.
|
||||
//
|
||||
// Taking the first derivative to find the local minimum of the function gives
|
||||
//
|
||||
// t1 = - (CV0 dot DV0) / (DV0 dot DV0)
|
||||
// and
|
||||
// t0 = ((p1 - v1 * t1 - p0) dot v0) / ||v0||
|
||||
//
|
||||
// which seems kind of obvious in retrospect.
|
||||
|
||||
hsVector3 p0subp1(&p0, &p1);
|
||||
|
||||
hsVector3 CV0 = p0subp1;
|
||||
CV0 += v0 * p0subp1.InnerProduct(v0) * -invV0Sq;
|
||||
|
||||
hsVector3 DV0 = v0 * (v1.InnerProduct(v0) * invV0Sq) - v1;
|
||||
|
||||
// Check for the vectors v0 and v1 being parallel, in which case
|
||||
// following the lines won't get us to any closer point.
|
||||
hsScalar DV0dotDV0 = DV0.InnerProduct(DV0);
|
||||
if( DV0dotDV0 < kRealSmall )
|
||||
{
|
||||
// If neither is clamped, return any two corresponding points.
|
||||
// If one is clamped, return closest points in its clamp range.
|
||||
// If both are clamped, well, both are clamped. The distance between
|
||||
// points will no longer be the distance between lines.
|
||||
// In any case, the distance between the points should be correct.
|
||||
UInt32 clamp1 = PointOnLine(p0, p1, v1, cp1, clamp);
|
||||
UInt32 clamp0 = PointOnLine(cp1, p0, v0, cp0, clamp >> 1);
|
||||
return clamp1 | (clamp0 << 1);
|
||||
}
|
||||
|
||||
UInt32 retVal = 0;
|
||||
|
||||
hsScalar t1 = - (CV0.InnerProduct(DV0)) / DV0dotDV0;
|
||||
if( (clamp & kClampLower1) && (t1 <= 0) )
|
||||
{
|
||||
t1 = 0;
|
||||
retVal |= kClampLower1;
|
||||
}
|
||||
else if( (clamp & kClampUpper1) && (t1 >= 1.f) )
|
||||
{
|
||||
t1 = 1.f;
|
||||
retVal |= kClampUpper1;
|
||||
}
|
||||
|
||||
hsScalar t0 = v0.InnerProduct(p0subp1 - v1 * t1) * -invV0Sq;
|
||||
cp0 = p0;
|
||||
if( (clamp & kClampUpper0) && (t0 >= 1.f) )
|
||||
{
|
||||
cp0 += v0;
|
||||
retVal |= kClampUpper0;
|
||||
}
|
||||
else if( !(clamp & kClampLower0) || (t0 > 0) )
|
||||
{
|
||||
cp0 += v0 * t0;
|
||||
}
|
||||
else
|
||||
{
|
||||
retVal |= kClampLower0;
|
||||
}
|
||||
|
||||
// If we clamped t0, we need to recalc t1 because the original
|
||||
// calculation of t1 was based on an infinite p0+v0.
|
||||
if( retVal & kClamp0 )
|
||||
{
|
||||
t1 = v1.InnerProduct(cp0 - p1) / v1.MagnitudeSquared();
|
||||
retVal &= ~kClamp1;
|
||||
if( (clamp & kClampLower1) && (t1 <= 0) )
|
||||
{
|
||||
t1 = 0;
|
||||
retVal |= kClampLower1;
|
||||
}
|
||||
else if( (clamp & kClampUpper1) && (t1 >= 1.f) )
|
||||
{
|
||||
t1 = 1.f;
|
||||
retVal |= kClampUpper1;
|
||||
}
|
||||
}
|
||||
|
||||
cp1 = p1;
|
||||
cp1 += v1 * t1;
|
||||
|
||||
return retVal;;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointOnSphere(const hsPoint3& p0,
|
||||
const hsPoint3& center, hsScalar rad,
|
||||
hsPoint3& cp)
|
||||
{
|
||||
hsVector3 del(&p0, ¢er);
|
||||
hsScalar dist = hsFastMath::InvSqrtAppr(del.MagnitudeSquared());
|
||||
dist *= rad;
|
||||
del *= dist;
|
||||
cp = center;
|
||||
cp += del;
|
||||
return dist <= 1.f;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointOnBox(const hsPoint3& p0,
|
||||
const hsPoint3& corner,
|
||||
const hsVector3& axis0,
|
||||
const hsVector3& axis1,
|
||||
const hsVector3& axis2,
|
||||
hsPoint3& cp)
|
||||
{
|
||||
UInt32 clamps = 0;
|
||||
hsPoint3 currPt = corner;
|
||||
clamps |= PointOnLine(p0, currPt, axis0, cp, kClamp);
|
||||
currPt = cp;
|
||||
clamps |= PointOnLine(p0, currPt, axis1, cp, kClamp);
|
||||
currPt = cp;
|
||||
clamps |= PointOnLine(p0, currPt, axis2, cp, kClamp);
|
||||
|
||||
return !clamps;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointOnSphere(const hsPoint3& p0, const hsVector3& v0,
|
||||
const hsPoint3& center, hsScalar rad,
|
||||
hsPoint3& cp,
|
||||
UInt32 clamp)
|
||||
{
|
||||
// Does the line hit the sphere? If it does, we return the entry point in cp,
|
||||
// otherwise we find the closest point on the sphere to the line.
|
||||
/*
|
||||
((p0 + v0*t) - center)^2 = rad
|
||||
v0*v0 * t*t + 2 * v0*t * (p0-c) + (p0-c)^2 - rad = 0
|
||||
|
||||
t = (-2 * v0*(p0-c) +- sqrt(4 * (v0*(p0-c))^2 - 4 * v0*v0 * ((p0-c)^2 - rad) / 2 * v0 * v0
|
||||
|
||||
t = (-v0*(p0-c) +- sqrt((v0*(p0-c))^2 - v0*v0 * ((p0-c)^2 - rad) / v0 * v0
|
||||
|
||||
So, line hits the sphere if
|
||||
(v0*(p0-c))^2 > v0*v0 * ((p0-c)^2 - rad)
|
||||
|
||||
If clamped, need additional checks on t before returning true
|
||||
|
||||
If line doesn't hit the sphere, we find the closest point on the line
|
||||
to the center of the sphere, and return the intersection of the segment
|
||||
connecting that point and the center with the sphere.
|
||||
*/
|
||||
hsScalar termA = v0.InnerProduct(v0);
|
||||
if( termA < kRealSmall )
|
||||
{
|
||||
return PointOnSphere(p0, center, rad, cp);
|
||||
}
|
||||
hsVector3 p0Subc(&p0, ¢er);
|
||||
hsScalar termB = v0.InnerProduct(p0Subc);
|
||||
hsScalar termC = p0Subc.InnerProduct(p0Subc) - rad;
|
||||
hsScalar disc = termB * termB - 4 * termA * termC;
|
||||
if( disc >= 0 )
|
||||
{
|
||||
disc = hsSquareRoot(disc);
|
||||
hsScalar t = (-termB - disc) / (2.f * termA);
|
||||
if( (t < 0) && (clamp & kClampLower0) )
|
||||
{
|
||||
hsScalar tOut = (-termB + disc) / (2.f * termA);
|
||||
if( tOut < 0 )
|
||||
{
|
||||
// Both isects are before beginning of clamped line.
|
||||
cp = p0;
|
||||
cp += v0 * tOut;
|
||||
return false;
|
||||
}
|
||||
if( (tOut > 1.f) && (clamp & kClampUpper0) )
|
||||
{
|
||||
// The segment is entirely within the sphere. Take the closer end.
|
||||
if( -t < tOut - 1.f )
|
||||
{
|
||||
cp = p0;
|
||||
cp += v0 * t;
|
||||
}
|
||||
else
|
||||
{
|
||||
cp = p0;
|
||||
cp += v0 * tOut;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
// We pierce the sphere from inside.
|
||||
cp = p0;
|
||||
cp += v0 * tOut;
|
||||
return true;
|
||||
}
|
||||
cp = p0;
|
||||
cp += v0 * t;
|
||||
if( (t > 1.f) && (clamp & kClampUpper0) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Okay, missed the sphere, find closest point.
|
||||
hsPoint3 lp;
|
||||
PointOnLine(center, p0, v0, lp, clamp);
|
||||
PointOnSphere(lp, center, rad, cp);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointOnBox(const hsPoint3& p0, const hsVector3& v0,
|
||||
const hsPoint3& corner,
|
||||
const hsVector3& axis0,
|
||||
const hsVector3& axis1,
|
||||
const hsVector3& axis2,
|
||||
hsPoint3& cp,
|
||||
UInt32 clamp)
|
||||
{
|
||||
UInt32 clampRes = 0;
|
||||
|
||||
hsPoint3 cp0, cp1;
|
||||
hsPoint3 currPt = corner;
|
||||
|
||||
clampRes |= PointsOnLines(p0, v0, currPt, axis0, cp0, cp1, clamp);
|
||||
currPt = cp1;
|
||||
|
||||
clampRes |= PointsOnLines(p0, v0, currPt, axis1, cp0, cp1, clamp);
|
||||
currPt = cp1;
|
||||
|
||||
clampRes |= PointsOnLines(p0, v0, currPt, axis2, cp0, cp1, clamp);
|
||||
currPt = cp1;
|
||||
|
||||
return !clampRes;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointOnPlane(const hsPoint3& p0,
|
||||
const hsPoint3& pPln, const hsVector3& n,
|
||||
hsPoint3& cp)
|
||||
{
|
||||
/*
|
||||
p' = p - ((p-pPln)*n)/|n| * n/|n|
|
||||
p' = p + ((pPln-p)*n) * n / |n|^2
|
||||
*/
|
||||
hsScalar invNLen = hsFastMath::InvSqrt(n.MagnitudeSquared());
|
||||
|
||||
hsScalar nDotp = n.InnerProduct(pPln - p0);
|
||||
cp = p0 + n * (nDotp * invNLen);
|
||||
|
||||
return nDotp >= 0;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointOnPlane(const hsPoint3& p0, const hsVector3& v0,
|
||||
const hsPoint3& pPln, const hsVector3& n,
|
||||
hsPoint3& cp,
|
||||
UInt32 clamp)
|
||||
{
|
||||
/*
|
||||
p0 + v0*t is on plane, i.e.
|
||||
(p0 + v0*t) * n = pPln * n
|
||||
|
||||
p0 * n + v0 * n * t = pPln * n
|
||||
v0 * n * t = (pPln - p0) * n
|
||||
t = (pPln - p0) * n / (v0 * n)
|
||||
|
||||
Then clamp appropriately, garnish, and serve with wild rice.
|
||||
*/
|
||||
hsBool retVal = true;
|
||||
hsScalar pDotn = n.InnerProduct(pPln - p0);
|
||||
hsScalar v0Dotn = n.InnerProduct(v0);
|
||||
if( (v0Dotn < -kRealSmall) || (v0Dotn > kRealSmall) )
|
||||
{
|
||||
hsScalar t = pDotn / v0Dotn;
|
||||
|
||||
if( (clamp & kClampLower) && (t < 0) )
|
||||
{
|
||||
t = 0;
|
||||
retVal = false;
|
||||
}
|
||||
else if( (clamp & kClampUpper) && (t > 1.f) )
|
||||
{
|
||||
t = 1.f;
|
||||
retVal = false;
|
||||
}
|
||||
cp = p0;
|
||||
cp += v0 * t;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
cp = p0 + v0 * 0.5f;
|
||||
retVal = (pDotn > -kRealSmall) && (pDotn < kRealSmall);
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
hsBool plClosest::PointBetweenBoxes(const hsPoint3& aCorner,
|
||||
const hsVector3& aAxis0,
|
||||
const hsVector3& aAxis1,
|
||||
const hsVector3& aAxis2,
|
||||
const hsPoint3& bCorner,
|
||||
const hsVector3& bAxis0,
|
||||
const hsVector3& bAxis1,
|
||||
const hsVector3& bAxis2,
|
||||
hsPoint3& cp0, hsPoint3& cp1)
|
||||
{
|
||||
const hsVector3* aAxes[3] = { &aAxis0, &aAxis1, &aAxis2 };
|
||||
const hsVector3* bAxes[3] = { &bAxis0, &bAxis1, &bAxis2 };
|
||||
|
||||
return PointBetweenBoxes(aCorner, aAxes, bCorner, bAxes, cp0, cp1);
|
||||
}
|
||||
|
||||
#if 0 // TRASH THIS
|
||||
hsBool plClosest::PointBetweenBoxes(const hsPoint3& aCorner,
|
||||
const hsVector3* aAxes[3],
|
||||
const hsPoint3& bCorner,
|
||||
const hsVector3* bAxes[3],
|
||||
hsPoint3& cp0, hsPoint3& cp1)
|
||||
{
|
||||
hsPoint3 aCurrPt = aCorner;
|
||||
hsPoint3 bCurrPt = bCorner;
|
||||
|
||||
hsPoint3 bStartPt[3];
|
||||
bStartPt[0] = bStartPt[1] = bStartPt[2] = bCorner;
|
||||
|
||||
hsBool retVal = true;
|
||||
int i, j;
|
||||
for( i = 0; i < 3; i++ )
|
||||
{
|
||||
hsPoint3 aBestPt;
|
||||
hsPoint3 bBestPt;
|
||||
|
||||
hsScalar minDistSq = 1.e33f;
|
||||
for( j = 0; j < 3; j++ )
|
||||
{
|
||||
hsPoint3 aNextPt, bNextPt;
|
||||
PointsOnLines(aCurrPt, *aAxes[i],
|
||||
bStartPt[j], *bAxes[j],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
hsScalar distSq = hsVector3(&aNextPt, &bNextPt).MagnitudeSquared();
|
||||
if( distSq < minDistSq )
|
||||
{
|
||||
aBestPt = aNextPt;
|
||||
bBestPt = bNextPt;
|
||||
|
||||
if( distSq < kRealSmall )
|
||||
retVal = true;
|
||||
|
||||
minDistSq = distSq;
|
||||
}
|
||||
hsVector3 bMove(&bNextPt, &bStartPt[j]);
|
||||
int k;
|
||||
for( k = 0; k < 3; k++ )
|
||||
{
|
||||
if( k != j )
|
||||
bStartPt[k] += bMove;
|
||||
}
|
||||
}
|
||||
aCurrPt = aBestPt;
|
||||
bCurrPt = bBestPt;
|
||||
}
|
||||
cp0 = aCurrPt;
|
||||
cp1 = bCurrPt;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
#elif 0 // TRASH THIS
|
||||
|
||||
hsBool plClosest::PointBetweenBoxes(const hsPoint3& aCorner,
|
||||
const hsVector3* aAxes[3],
|
||||
const hsPoint3& bCorner,
|
||||
const hsVector3* bAxes[3],
|
||||
hsPoint3& cp0, hsPoint3& cp1)
|
||||
{
|
||||
/*
|
||||
Six combinations to try to go through every possible
|
||||
combination of axes from A and B
|
||||
|
||||
00 00 01 01 02 02
|
||||
11 12 12 10 10 11
|
||||
22 21 20 22 21 20
|
||||
*/
|
||||
|
||||
int bIdx0 = 0;
|
||||
int bIdx1 = 1;
|
||||
int bIdx2 = 2;
|
||||
|
||||
hsPoint3 aBestPt, bBestPt;
|
||||
hsScalar minDistSq = 1.e33f;
|
||||
|
||||
hsBool retVal = false;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 6; i++ )
|
||||
{
|
||||
hsPoint3 aCurrPt = aCorner;
|
||||
hsPoint3 bCurrPt = bCorner;
|
||||
|
||||
hsPoint3 aNextPt, bNextPt;
|
||||
PointsOnLines(aCurrPt, *aAxes[0],
|
||||
bCurrPt, *bAxes[bIdx0],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
aCurrPt = aNextPt;
|
||||
bCurrPt = bNextPt;
|
||||
|
||||
PointsOnLines(aCurrPt, *aAxes[1],
|
||||
bCurrPt, *bAxes[bIdx1],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
aCurrPt = aNextPt;
|
||||
bCurrPt = bNextPt;
|
||||
|
||||
PointsOnLines(aCurrPt, *aAxes[2],
|
||||
bCurrPt, *bAxes[bIdx2],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
|
||||
hsScalar distSq = hsVector3(&aNextPt, &bNextPt).MagnitudeSquared();
|
||||
if( distSq < minDistSq )
|
||||
{
|
||||
aBestPt = aNextPt;
|
||||
bBestPt = bNextPt;
|
||||
|
||||
if( distSq < kRealSmall )
|
||||
retVal = true;
|
||||
|
||||
minDistSq = distSq;
|
||||
}
|
||||
|
||||
if( i & 0x1 )
|
||||
{
|
||||
bIdx0++;
|
||||
bIdx1 = bIdx0 < 2 ? bIdx0+1 : 0;
|
||||
bIdx2 = bIdx1 < 2 ? bIdx1+1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int t = bIdx1;
|
||||
bIdx1 = bIdx2;
|
||||
bIdx2 = t;
|
||||
}
|
||||
}
|
||||
cp0 = aBestPt;
|
||||
cp1 = bBestPt;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
#else // TRASH THIS
|
||||
|
||||
hsBool plClosest::PointBetweenBoxes(const hsPoint3& aCorner,
|
||||
const hsVector3* aAxes[3],
|
||||
const hsPoint3& bCorner,
|
||||
const hsVector3* bAxes[3],
|
||||
hsPoint3& cp0, hsPoint3& cp1)
|
||||
{
|
||||
/*
|
||||
Six combinations to try to go through every possible
|
||||
combination of axes from A and B
|
||||
|
||||
00 00 01 01 02 02
|
||||
11 12 12 10 10 11
|
||||
22 21 20 22 21 20
|
||||
*/
|
||||
|
||||
struct trial {
|
||||
int aIdx[3];
|
||||
int bIdx[3];
|
||||
} trials[36];
|
||||
|
||||
|
||||
int tNext = 0;
|
||||
int k,l;
|
||||
for( k = 0; k < 3; k++ )
|
||||
{
|
||||
for( l = 0; l < 3; l++ )
|
||||
{
|
||||
int kPlus = k < 2 ? k+1 : 0;
|
||||
int kPlusPlus = kPlus < 2 ? kPlus+1 : 0;
|
||||
|
||||
int lPlus = l < 2 ? l+1 : 0;
|
||||
int lPlusPlus = lPlus < 2 ? lPlus+1 : 0;
|
||||
|
||||
trials[tNext].aIdx[0] = k;
|
||||
trials[tNext].bIdx[0] = l;
|
||||
|
||||
trials[tNext].aIdx[1] = kPlus;
|
||||
trials[tNext].bIdx[1] = lPlus;
|
||||
|
||||
trials[tNext].aIdx[2] = kPlusPlus;
|
||||
trials[tNext].bIdx[2] = lPlusPlus;
|
||||
|
||||
tNext++;
|
||||
|
||||
trials[tNext].aIdx[0] = k;
|
||||
trials[tNext].bIdx[0] = l;
|
||||
|
||||
trials[tNext].aIdx[1] = kPlusPlus;
|
||||
trials[tNext].bIdx[1] = lPlusPlus;
|
||||
|
||||
trials[tNext].aIdx[2] = kPlus;
|
||||
trials[tNext].bIdx[2] = lPlus;
|
||||
|
||||
tNext++;
|
||||
|
||||
trials[tNext].aIdx[0] = k;
|
||||
trials[tNext].bIdx[0] = l;
|
||||
|
||||
trials[tNext].aIdx[1] = kPlus;
|
||||
trials[tNext].bIdx[1] = lPlusPlus;
|
||||
|
||||
trials[tNext].aIdx[2] = kPlusPlus;
|
||||
trials[tNext].bIdx[2] = lPlus;
|
||||
|
||||
tNext++;
|
||||
|
||||
trials[tNext].aIdx[0] = k;
|
||||
trials[tNext].bIdx[0] = l;
|
||||
|
||||
trials[tNext].aIdx[1] = kPlusPlus;
|
||||
trials[tNext].bIdx[1] = lPlus;
|
||||
|
||||
trials[tNext].aIdx[2] = kPlus;
|
||||
trials[tNext].bIdx[2] = lPlusPlus;
|
||||
|
||||
tNext++;
|
||||
}
|
||||
}
|
||||
|
||||
hsPoint3 aBestPt, bBestPt;
|
||||
hsScalar minDistSq = 1.e33f;
|
||||
|
||||
hsBool retVal = false;
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 36; i++ )
|
||||
{
|
||||
hsPoint3 aCurrPt = aCorner;
|
||||
hsPoint3 bCurrPt = bCorner;
|
||||
|
||||
hsPoint3 aNextPt, bNextPt;
|
||||
PointsOnLines(aCurrPt, *aAxes[trials[i].aIdx[0]],
|
||||
bCurrPt, *bAxes[trials[i].bIdx[0]],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
aCurrPt = aNextPt;
|
||||
bCurrPt = bNextPt;
|
||||
|
||||
PointsOnLines(aCurrPt, *aAxes[trials[i].aIdx[1]],
|
||||
bCurrPt, *bAxes[trials[i].bIdx[1]],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
aCurrPt = aNextPt;
|
||||
bCurrPt = bNextPt;
|
||||
|
||||
PointsOnLines(aCurrPt, *aAxes[trials[i].aIdx[2]],
|
||||
bCurrPt, *bAxes[trials[i].bIdx[2]],
|
||||
aNextPt, bNextPt,
|
||||
plClosest::kClamp);
|
||||
|
||||
|
||||
hsScalar distSq = hsVector3(&aNextPt, &bNextPt).MagnitudeSquared();
|
||||
if( distSq < minDistSq )
|
||||
{
|
||||
aBestPt = aNextPt;
|
||||
bBestPt = bNextPt;
|
||||
|
||||
if( distSq < kRealSmall )
|
||||
retVal = true;
|
||||
|
||||
minDistSq = distSq;
|
||||
}
|
||||
|
||||
}
|
||||
cp0 = aBestPt;
|
||||
cp1 = bBestPt;
|
||||
|
||||
return retVal;
|
||||
}
|
||||
#endif // TRASH THIS
|
138
Sources/Plasma/PubUtilLib/plIntersect/plClosest.h
Normal file
138
Sources/Plasma/PubUtilLib/plIntersect/plClosest.h
Normal file
@ -0,0 +1,138 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plIsect_inc
|
||||
#define plIsect_inc
|
||||
|
||||
struct hsPoint3;
|
||||
struct hsVector3;
|
||||
|
||||
|
||||
class plClosest
|
||||
{
|
||||
public:
|
||||
enum plClosestClampFlags
|
||||
{
|
||||
kClampLower0 = 0x1,
|
||||
kClampUpper0 = 0x2,
|
||||
kClamp0 = kClampLower0 | kClampUpper0,
|
||||
kClampLower1 = 0x4,
|
||||
kClampLower = kClampLower0 | kClampLower1,
|
||||
kClampUpper1 = 0x8,
|
||||
kClampUpper = kClampUpper0 | kClampUpper1,
|
||||
kClamp1 = kClampLower1 | kClampUpper1,
|
||||
kClamp = kClamp0 | kClamp1
|
||||
};
|
||||
|
||||
|
||||
// Return clamp flags for where clamped
|
||||
static UInt32 PointOnLine(const hsPoint3& p0, // Point
|
||||
const hsPoint3& p1, const hsVector3& v1, // Line
|
||||
hsPoint3& cp, // Output closest point on line to p0
|
||||
UInt32 clamp); // Clamp on ends of segment (use Lower1/Upper1)
|
||||
|
||||
// Return clamp flags for where clamped
|
||||
static UInt32 PointsOnLines(const hsPoint3& p0, const hsVector3& v0,// First line
|
||||
const hsPoint3& p1, const hsVector3& v1, // Second line
|
||||
hsPoint3& cp0, // Output closest on line0 to line1
|
||||
hsPoint3& cp1, // Output closest on line1 to line0
|
||||
UInt32 clamp); // Clamp on ends
|
||||
|
||||
// Return true if p0 is inside or on sphere.
|
||||
static hsBool PointOnSphere(const hsPoint3& p0, // Point
|
||||
const hsPoint3& center, hsScalar rad, // Sphere
|
||||
hsPoint3& cp); // Output closest on sphere to p0
|
||||
|
||||
// Return true if p0 is inside box.
|
||||
static hsBool PointOnBox(const hsPoint3& p0, // Point
|
||||
const hsPoint3& corner, // Box defined by corner point and 3 (presumably but
|
||||
const hsVector3& axis0, // not required) ortho axes.
|
||||
const hsVector3& axis1,
|
||||
const hsVector3& axis2,
|
||||
hsPoint3& cp);
|
||||
|
||||
// Return true if line intersects or is inside sphere.
|
||||
static hsBool PointOnSphere(const hsPoint3& p0, const hsVector3& v0, // Line
|
||||
const hsPoint3& center, hsScalar rad, // Sphere
|
||||
hsPoint3& cp, // Output closest on sphere to p0, or entry point if line hits sphere
|
||||
UInt32 clamp);
|
||||
|
||||
// Return true if line intersects or is inside box.
|
||||
static hsBool PointOnBox(const hsPoint3& p0, const hsVector3& v0, // Line
|
||||
const hsPoint3& corner, // Box defined by corner point and 3 (presumably but
|
||||
const hsVector3& axis0, // not required) ortho axes.
|
||||
const hsVector3& axis1,
|
||||
const hsVector3& axis2,
|
||||
hsPoint3& cp,
|
||||
UInt32 clamp);
|
||||
|
||||
// Return true if point inside (negative side) of plane
|
||||
static hsBool PointOnPlane(const hsPoint3& p0,
|
||||
const hsPoint3& pPln, const hsVector3& n,
|
||||
hsPoint3& cp);
|
||||
|
||||
// Return true if line passes through plane.
|
||||
static hsBool PointOnPlane(const hsPoint3& p0, const hsVector3& v0,
|
||||
const hsPoint3& pPln, const hsVector3& n,
|
||||
hsPoint3& cp,
|
||||
UInt32 clamp);
|
||||
|
||||
// Two identical functions, just different wrapping. First version repacks
|
||||
// parameters and calls second.
|
||||
static hsBool PointBetweenBoxes(const hsPoint3& aCorner,
|
||||
const hsVector3& aAxis0,
|
||||
const hsVector3& aAxis1,
|
||||
const hsVector3& aAxis2,
|
||||
const hsPoint3& bCorner,
|
||||
const hsVector3& bAxis0,
|
||||
const hsVector3& bAxis1,
|
||||
const hsVector3& bAxis2,
|
||||
hsPoint3& cp0, hsPoint3& cp1);
|
||||
|
||||
static hsBool PointBetweenBoxes(const hsPoint3& aCorner,
|
||||
const hsVector3* aAxes[3],
|
||||
const hsPoint3& bCorner,
|
||||
const hsVector3* bAxes[3],
|
||||
hsPoint3& cp0, hsPoint3& cp1);
|
||||
};
|
||||
|
||||
#endif // plVolume_inc
|
112
Sources/Plasma/PubUtilLib/plIntersect/plHardRegion.cpp
Normal file
112
Sources/Plasma/PubUtilLib/plIntersect/plHardRegion.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
#include "plHardRegion.h"
|
||||
|
||||
#include "plgDispatch.h"
|
||||
#include "../plMessage/plRenderMsg.h"
|
||||
#include "plPipeline.h"
|
||||
|
||||
plHardRegion::plHardRegion()
|
||||
: fState(kDirty)
|
||||
{
|
||||
}
|
||||
|
||||
plHardRegion::~plHardRegion()
|
||||
{
|
||||
}
|
||||
|
||||
void plHardRegion::SetKey(plKey k)
|
||||
{
|
||||
plRegionBase::SetKey(k);
|
||||
|
||||
#if 0 // The caching of this probably isn't worth it.
|
||||
// We'll try evaluation every time first, and try
|
||||
// this later as an optimization.
|
||||
if( k )
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plRenderMsg::Index(), GetKey());
|
||||
}
|
||||
#endif // Caching
|
||||
}
|
||||
|
||||
void plHardRegion::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plRegionBase::Read(s, mgr);
|
||||
|
||||
fState = kDirty;
|
||||
}
|
||||
|
||||
void plHardRegion::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plRegionBase::Write(s, mgr);
|
||||
}
|
||||
|
||||
hsBool plHardRegion::CameraInside() const
|
||||
{
|
||||
if( fState & kDirty )
|
||||
{
|
||||
if( ICameraInside() )
|
||||
fState |= kCamInside;
|
||||
else
|
||||
fState &= ~kCamInside;
|
||||
fState &= ~kDirty;
|
||||
}
|
||||
return 0 != (fState & kCamInside);
|
||||
}
|
||||
|
||||
hsBool plHardRegion::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plRenderMsg* rend = plRenderMsg::ConvertNoRef(msg);
|
||||
if( rend )
|
||||
{
|
||||
fState |= kDirty;
|
||||
fCamPos = rend->Pipeline()->GetViewPositionWorld();
|
||||
return true;
|
||||
}
|
||||
|
||||
return plRegionBase::MsgReceive(msg);
|
||||
}
|
||||
|
96
Sources/Plasma/PubUtilLib/plIntersect/plHardRegion.h
Normal file
96
Sources/Plasma/PubUtilLib/plIntersect/plHardRegion.h
Normal file
@ -0,0 +1,96 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plHardRegion_inc
|
||||
#define plHardRegion_inc
|
||||
|
||||
#include "plRegionBase.h"
|
||||
#include "hsGeometry3.h"
|
||||
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
class plMessage;
|
||||
|
||||
class plHardRegion : public plRegionBase
|
||||
{
|
||||
public:
|
||||
enum RefTypes {
|
||||
kSubRegion
|
||||
};
|
||||
|
||||
protected:
|
||||
enum
|
||||
{
|
||||
kDirty,
|
||||
kCamInside
|
||||
};
|
||||
|
||||
mutable UInt32 fState;
|
||||
hsPoint3 fCamPos;
|
||||
|
||||
virtual void SetKey(plKey k);
|
||||
|
||||
public:
|
||||
plHardRegion();
|
||||
virtual ~plHardRegion();
|
||||
|
||||
CLASSNAME_REGISTER( plHardRegion );
|
||||
GETINTERFACE_ANY( plHardRegion, plRegionBase );
|
||||
|
||||
virtual hsBool IsInside(const hsPoint3& pos) const { return IIsInside(pos); }
|
||||
virtual hsBool CameraInside() const;
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) = 0;
|
||||
|
||||
virtual Int32 GetNumProperties() const { return 1; } // This is stupid.
|
||||
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
virtual hsBool IIsInside(const hsPoint3& pos) const = 0;
|
||||
virtual hsBool ICameraInside() const = 0;
|
||||
};
|
||||
|
||||
#endif // plHardRegion_inc
|
168
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionPlanes.cpp
Normal file
168
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionPlanes.cpp
Normal file
@ -0,0 +1,168 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "plHardRegionPlanes.h"
|
||||
|
||||
#include "hsStream.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsFastMath.h"
|
||||
#include "hsMatrix44.h"
|
||||
|
||||
|
||||
plHardRegionPlanes::plHardRegionPlanes()
|
||||
{
|
||||
}
|
||||
|
||||
plHardRegionPlanes::~plHardRegionPlanes()
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plHardRegionPlanes::IIsInside(const hsPoint3& pos) const
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fPlanes.GetCount(); i++ )
|
||||
{
|
||||
if( fPlanes[i].fWorldNorm.InnerProduct(pos) > fPlanes[i].fWorldDist )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plHardRegionPlanes::ICameraInside() const
|
||||
{
|
||||
return IIsInside(fCamPos);
|
||||
}
|
||||
|
||||
void plHardRegionPlanes::SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l)
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fPlanes.GetCount(); i++ )
|
||||
{
|
||||
fPlanes[i].fWorldPos = l2w * fPlanes[i].fPos;
|
||||
|
||||
// Normal gets transpose of inverse.
|
||||
fPlanes[i].fWorldNorm.fX = w2l.fMap[0][0] * fPlanes[i].fNorm.fX
|
||||
+ w2l.fMap[1][0] * fPlanes[i].fNorm.fY
|
||||
+ w2l.fMap[2][0] * fPlanes[i].fNorm.fZ;
|
||||
|
||||
fPlanes[i].fWorldNorm.fY = w2l.fMap[0][1] * fPlanes[i].fNorm.fX
|
||||
+ w2l.fMap[1][1] * fPlanes[i].fNorm.fY
|
||||
+ w2l.fMap[2][1] * fPlanes[i].fNorm.fZ;
|
||||
|
||||
fPlanes[i].fWorldNorm.fZ = w2l.fMap[0][2] * fPlanes[i].fNorm.fX
|
||||
+ w2l.fMap[1][2] * fPlanes[i].fNorm.fY
|
||||
+ w2l.fMap[2][2] * fPlanes[i].fNorm.fZ;
|
||||
|
||||
hsFastMath::NormalizeAppr(fPlanes[i].fWorldNorm);
|
||||
|
||||
fPlanes[i].fWorldDist = fPlanes[i].fWorldNorm.InnerProduct(fPlanes[i].fWorldPos);
|
||||
}
|
||||
}
|
||||
|
||||
void plHardRegionPlanes::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plHardRegion::Read(s, mgr);
|
||||
|
||||
int n = s->ReadSwap32();
|
||||
fPlanes.SetCount(n);
|
||||
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
{
|
||||
fPlanes[i].fNorm.Read(s);
|
||||
fPlanes[i].fPos.Read(s);
|
||||
|
||||
fPlanes[i].fWorldNorm.Read(s);
|
||||
fPlanes[i].fWorldPos.Read(s);
|
||||
|
||||
fPlanes[i].fWorldDist = fPlanes[i].fWorldNorm.InnerProduct(fPlanes[i].fWorldPos);
|
||||
}
|
||||
}
|
||||
|
||||
void plHardRegionPlanes::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plHardRegion::Write(s, mgr);
|
||||
|
||||
s->WriteSwap32(fPlanes.GetCount());
|
||||
|
||||
int i;
|
||||
for( i = 0; i < fPlanes.GetCount(); i++ )
|
||||
{
|
||||
fPlanes[i].fNorm.Write(s);
|
||||
fPlanes[i].fPos.Write(s);
|
||||
|
||||
fPlanes[i].fWorldNorm.Write(s);
|
||||
fPlanes[i].fWorldPos.Write(s);
|
||||
}
|
||||
}
|
||||
|
||||
void plHardRegionPlanes::AddPlane(const hsVector3& n, const hsPoint3& p)
|
||||
{
|
||||
hsVector3 nNorm = n;
|
||||
hsFastMath::Normalize(nNorm);
|
||||
|
||||
// First, make sure some idiot isn't adding the same plane in twice.
|
||||
// Also, look for the degenerate case of two parallel planes. In that
|
||||
// case, take the outer.
|
||||
int i;
|
||||
for( i = 0; i < fPlanes.GetCount(); i++ )
|
||||
{
|
||||
const hsScalar kCloseToOne = 1.f - 1.e-4f;
|
||||
if( fPlanes[i].fNorm.InnerProduct(nNorm) >= kCloseToOne )
|
||||
{
|
||||
hsScalar newDist = nNorm.InnerProduct(p);
|
||||
hsScalar oldDist = fPlanes[i].fNorm.InnerProduct(fPlanes[i].fPos);
|
||||
if( newDist > oldDist )
|
||||
{
|
||||
fPlanes[i].fPos = p;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
HardPlane plane;
|
||||
plane.fWorldNorm = plane.fNorm = nNorm;
|
||||
plane.fWorldPos = plane.fPos = p;
|
||||
plane.fWorldDist = plane.fWorldNorm.InnerProduct(plane.fWorldPos);
|
||||
|
||||
fPlanes.Append(plane);
|
||||
}
|
90
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionPlanes.h
Normal file
90
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionPlanes.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plHardRegionPlanes_inc
|
||||
#define plHardRegionPlanes_inc
|
||||
|
||||
#include "plHardRegion.h"
|
||||
|
||||
class plHardRegionPlanes : public plHardRegion
|
||||
{
|
||||
protected:
|
||||
class HardPlane
|
||||
{
|
||||
public:
|
||||
hsVector3 fNorm;
|
||||
hsPoint3 fPos;
|
||||
|
||||
hsVector3 fWorldNorm;
|
||||
hsPoint3 fWorldPos;
|
||||
hsScalar fWorldDist;
|
||||
};
|
||||
hsTArray<HardPlane> fPlanes;
|
||||
|
||||
protected:
|
||||
public:
|
||||
plHardRegionPlanes();
|
||||
virtual ~plHardRegionPlanes();
|
||||
|
||||
CLASSNAME_REGISTER( plHardRegionPlanes );
|
||||
GETINTERFACE_ANY( plHardRegionPlanes, plHardRegion );
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
// Now Planes specifics
|
||||
void AddPlane(const hsVector3& n, const hsPoint3& p);
|
||||
UInt32 GetNumPlanes() const { return fPlanes.GetCount(); }
|
||||
void GetPlane(int i, hsVector3& n, hsPoint3& p) const { n = fPlanes[i].fNorm; p = fPlanes[i].fPos; }
|
||||
void GetWorldPlane(int i, hsVector3& n, hsPoint3& p) const { n = fPlanes[i].fWorldNorm; p = fPlanes[i].fWorldPos; }
|
||||
|
||||
virtual hsBool IIsInside(const hsPoint3& pos) const;
|
||||
virtual hsBool ICameraInside() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // plHardRegionPlanes_inc
|
||||
|
212
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionTypes.cpp
Normal file
212
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionTypes.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
|
||||
#include "plHardRegionTypes.h"
|
||||
#include "hsStream.h"
|
||||
#include "hsResMgr.h"
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Base hard and complex
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
plHardRegionComplex::plHardRegionComplex()
|
||||
{
|
||||
}
|
||||
|
||||
plHardRegionComplex::~plHardRegionComplex()
|
||||
{
|
||||
}
|
||||
|
||||
void plHardRegionComplex::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plHardRegion::Read(s, mgr);
|
||||
|
||||
int n = s->ReadSwap32();
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kSubRegion), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
void plHardRegionComplex::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plHardRegion::Write(s, mgr);
|
||||
|
||||
s->WriteSwap32(fSubRegions.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < fSubRegions.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fSubRegions[i]);
|
||||
}
|
||||
|
||||
hsBool plHardRegionComplex::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest) )
|
||||
{
|
||||
plHardRegion* sub = plHardRegion::ConvertNoRef(refMsg->GetRef());
|
||||
hsAssert(fSubRegions.kMissingIndex == fSubRegions.Find(sub), "Adding subRegion I already have");
|
||||
fSubRegions.Append(sub);
|
||||
}
|
||||
else if( refMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
|
||||
{
|
||||
plHardRegion* sub = (plHardRegion*)refMsg->GetRef();
|
||||
int idx = fSubRegions.Find(sub);
|
||||
if( idx != fSubRegions.kMissingIndex )
|
||||
fSubRegions.Remove(idx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plHardRegion::MsgReceive(msg);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Booleans follow
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Union
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plHardRegionUnion::plHardRegionUnion()
|
||||
{
|
||||
}
|
||||
|
||||
plHardRegionUnion::~plHardRegionUnion()
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plHardRegionUnion::IIsInside(const hsPoint3& pos) const
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fSubRegions.GetCount(); i++ )
|
||||
{
|
||||
if( fSubRegions[i]->IIsInside(pos) )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
hsBool plHardRegionUnion::ICameraInside() const
|
||||
{
|
||||
if( fState & kDirty )
|
||||
{
|
||||
fState &= ~(kCamInside | kDirty);
|
||||
int i;
|
||||
for( i = 0; i < fSubRegions.GetCount(); i++ )
|
||||
{
|
||||
if( fSubRegions[i]->ICameraInside() )
|
||||
{
|
||||
fState |= kCamInside;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Intersection
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
plHardRegionIntersect::plHardRegionIntersect()
|
||||
{
|
||||
}
|
||||
|
||||
plHardRegionIntersect::~plHardRegionIntersect()
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plHardRegionIntersect::IIsInside(const hsPoint3& pos) const
|
||||
{
|
||||
int i;
|
||||
for( i = 0; i < fSubRegions.GetCount(); i++ )
|
||||
{
|
||||
if( !fSubRegions[i]->IIsInside(pos) )
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
hsBool plHardRegionIntersect::ICameraInside() const
|
||||
{
|
||||
if( fState & kDirty )
|
||||
{
|
||||
fState &= ~kDirty;
|
||||
fState |= kCamInside;
|
||||
int i;
|
||||
for( i = 0; i < fSubRegions.GetCount(); i++ )
|
||||
{
|
||||
if( !fSubRegions[i]->ICameraInside() )
|
||||
{
|
||||
fState &= ~kCamInside;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Invert
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plHardRegionInvert::plHardRegionInvert()
|
||||
{
|
||||
}
|
||||
|
||||
plHardRegionInvert::~plHardRegionInvert()
|
||||
{
|
||||
}
|
||||
|
||||
hsBool plHardRegionInvert::IIsInside(const hsPoint3& pos) const
|
||||
{
|
||||
hsAssert(fSubRegions.GetCount() <= 1, "Too many subRegions on inverter");
|
||||
return !fSubRegions[0]->IIsInside(pos);
|
||||
}
|
||||
|
||||
hsBool plHardRegionInvert::ICameraInside() const
|
||||
{
|
||||
hsAssert(fSubRegions.GetCount() <= 1, "Too many subRegions on inverter");
|
||||
return !fSubRegions[0]->ICameraInside();
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
120
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionTypes.h
Normal file
120
Sources/Plasma/PubUtilLib/plIntersect/plHardRegionTypes.h
Normal file
@ -0,0 +1,120 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plHardRegionTypes_inc
|
||||
#define plHardRegionTypes_inc
|
||||
|
||||
#include "plHardRegion.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
class plHardRegionComplex : public plHardRegion
|
||||
{
|
||||
protected:
|
||||
hsTArray<plHardRegion*> fSubRegions;
|
||||
|
||||
public:
|
||||
plHardRegionComplex();
|
||||
virtual ~plHardRegionComplex();
|
||||
|
||||
CLASSNAME_REGISTER( plHardRegionComplex );
|
||||
GETINTERFACE_ANY( plHardRegionComplex, plHardRegion );
|
||||
|
||||
// Don't propagate the settransform to our children, they move independently
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) {}
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
// Now Complex specifics
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
UInt16 GetNumSubs() const { return fSubRegions.GetCount(); }
|
||||
const plHardRegion* GetSub(int i) const { return fSubRegions[i]; }
|
||||
};
|
||||
|
||||
class plHardRegionUnion : public plHardRegionComplex
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
plHardRegionUnion();
|
||||
virtual ~plHardRegionUnion();
|
||||
|
||||
CLASSNAME_REGISTER( plHardRegionUnion );
|
||||
GETINTERFACE_ANY( plHardRegionUnion, plHardRegionComplex );
|
||||
|
||||
virtual hsBool IIsInside(const hsPoint3& pos) const;
|
||||
virtual hsBool ICameraInside() const;
|
||||
|
||||
};
|
||||
|
||||
class plHardRegionIntersect : public plHardRegionComplex
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
plHardRegionIntersect();
|
||||
virtual ~plHardRegionIntersect();
|
||||
|
||||
CLASSNAME_REGISTER( plHardRegionIntersect );
|
||||
GETINTERFACE_ANY( plHardRegionIntersect, plHardRegionComplex );
|
||||
|
||||
virtual hsBool IIsInside(const hsPoint3& pos) const;
|
||||
virtual hsBool ICameraInside() const;
|
||||
|
||||
};
|
||||
|
||||
class plHardRegionInvert : public plHardRegionComplex
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
plHardRegionInvert();
|
||||
virtual ~plHardRegionInvert();
|
||||
|
||||
CLASSNAME_REGISTER( plHardRegionInvert );
|
||||
GETINTERFACE_ANY( plHardRegionInvert, plHardRegionComplex );
|
||||
|
||||
virtual hsBool IIsInside(const hsPoint3& pos) const;
|
||||
virtual hsBool ICameraInside() const;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // plHardRegionTypes_inc
|
99
Sources/Plasma/PubUtilLib/plIntersect/plIntersectCreatable.h
Normal file
99
Sources/Plasma/PubUtilLib/plIntersect/plIntersectCreatable.h
Normal file
@ -0,0 +1,99 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plIntersectCreatable_inc
|
||||
#define plIntersectCreatable_inc
|
||||
|
||||
#include "../pnFactory/plCreator.h"
|
||||
|
||||
#include "plVolumeIsect.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plVolumeIsect );
|
||||
|
||||
REGISTER_CREATABLE( plSphereIsect );
|
||||
REGISTER_CREATABLE( plConeIsect );
|
||||
REGISTER_CREATABLE( plCylinderIsect );
|
||||
REGISTER_CREATABLE( plParallelIsect );
|
||||
REGISTER_CREATABLE( plConvexIsect );
|
||||
|
||||
REGISTER_CREATABLE( plBoundsIsect );
|
||||
|
||||
REGISTER_NONCREATABLE( plComplexIsect );
|
||||
|
||||
REGISTER_CREATABLE( plUnionIsect );
|
||||
REGISTER_CREATABLE( plIntersectionIsect );
|
||||
|
||||
#include "plRegionBase.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plRegionBase );
|
||||
|
||||
#include "plSoftVolume.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plSoftVolume );
|
||||
|
||||
#include "plSoftVolumeTypes.h"
|
||||
|
||||
REGISTER_CREATABLE( plSoftVolumeSimple );
|
||||
|
||||
REGISTER_NONCREATABLE( plSoftVolumeComplex );
|
||||
|
||||
REGISTER_CREATABLE( plSoftVolumeUnion );
|
||||
REGISTER_CREATABLE( plSoftVolumeIntersect );
|
||||
REGISTER_CREATABLE( plSoftVolumeInvert );
|
||||
|
||||
#include "plHardRegion.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plHardRegion );
|
||||
|
||||
#include "plHardRegionPlanes.h"
|
||||
|
||||
REGISTER_CREATABLE( plHardRegionPlanes );
|
||||
|
||||
#include "plHardRegionTypes.h"
|
||||
|
||||
REGISTER_NONCREATABLE( plHardRegionComplex );
|
||||
|
||||
REGISTER_CREATABLE( plHardRegionUnion );
|
||||
REGISTER_CREATABLE( plHardRegionIntersect );
|
||||
REGISTER_CREATABLE( plHardRegionInvert );
|
||||
|
||||
#endif // plIntersectCreatable_inc
|
62
Sources/Plasma/PubUtilLib/plIntersect/plRegionBase.h
Normal file
62
Sources/Plasma/PubUtilLib/plIntersect/plRegionBase.h
Normal file
@ -0,0 +1,62 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plRegionBase_inc
|
||||
#define plRegionBase_inc
|
||||
|
||||
#include "../pnSceneObject/plObjInterface.h"
|
||||
|
||||
struct hsPoint3;
|
||||
|
||||
class plRegionBase : public plObjInterface
|
||||
{
|
||||
public:
|
||||
plRegionBase() {}
|
||||
virtual ~plRegionBase() {}
|
||||
|
||||
CLASSNAME_REGISTER( plRegionBase );
|
||||
GETINTERFACE_ANY( plRegionBase, plObjInterface );
|
||||
|
||||
virtual hsBool IsInside(const hsPoint3& pos) const = 0;
|
||||
};
|
||||
|
||||
#endif // plRegionBase_inc
|
159
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolume.cpp
Normal file
159
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolume.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
#include "plSoftVolume.h"
|
||||
|
||||
#include "plgDispatch.h"
|
||||
#include "../plMessage/plListenerMsg.h"
|
||||
|
||||
plSoftVolume::plSoftVolume()
|
||||
: fListenState(0),
|
||||
fListenStrength(0),
|
||||
fInsideStrength(1.f),
|
||||
fOutsideStrength(0)
|
||||
{
|
||||
fListenPos.Set(0,0,0);
|
||||
}
|
||||
|
||||
plSoftVolume::~plSoftVolume()
|
||||
{
|
||||
}
|
||||
|
||||
void plSoftVolume::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plRegionBase::Read(s, mgr);
|
||||
|
||||
fListenState = s->ReadSwap32();
|
||||
|
||||
SetCheckListener(0 != (fListenState & kListenCheck));
|
||||
|
||||
fInsideStrength = s->ReadSwapScalar();
|
||||
fOutsideStrength = s->ReadSwapScalar();
|
||||
}
|
||||
|
||||
void plSoftVolume::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plRegionBase::Write(s, mgr);
|
||||
|
||||
s->WriteSwap32(fListenState);
|
||||
|
||||
s->WriteSwapScalar(fInsideStrength);
|
||||
s->WriteSwapScalar(fOutsideStrength);
|
||||
}
|
||||
|
||||
hsScalar plSoftVolume::GetStrength(const hsPoint3& pos) const
|
||||
{
|
||||
return IRemapStrength(IGetStrength(pos));
|
||||
}
|
||||
|
||||
hsScalar plSoftVolume::GetListenerStrength() const
|
||||
{
|
||||
if( !(fListenState & kListenPosSet) )
|
||||
{
|
||||
// Some screw-up, haven't received a pos yet. Turn it off till we do.
|
||||
return fListenStrength = IRemapStrength(0);
|
||||
}
|
||||
if( fListenState & kListenDirty )
|
||||
{
|
||||
fListenStrength = IUpdateListenerStrength();
|
||||
fListenState &= ~kListenDirty;
|
||||
}
|
||||
return fListenStrength;
|
||||
}
|
||||
|
||||
void plSoftVolume::UpdateListenerPosition(const hsPoint3& pos)
|
||||
{
|
||||
fListenPos = pos;
|
||||
fListenState |= kListenDirty | kListenPosSet;
|
||||
}
|
||||
|
||||
void plSoftVolume::SetCheckListener(hsBool on)
|
||||
{
|
||||
if( on )
|
||||
{
|
||||
plgDispatch::Dispatch()->RegisterForExactType(plListenerMsg::Index(), GetKey());
|
||||
fListenState |= kListenCheck | kListenDirty | kListenRegistered;
|
||||
}
|
||||
else
|
||||
{
|
||||
plgDispatch::Dispatch()->UnRegisterForExactType(plListenerMsg::Index(), GetKey());
|
||||
fListenState &= ~(kListenCheck | kListenDirty | kListenRegistered);
|
||||
}
|
||||
}
|
||||
|
||||
hsBool plSoftVolume::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plListenerMsg* list = plListenerMsg::ConvertNoRef(msg);
|
||||
if( list )
|
||||
{
|
||||
UpdateListenerPosition(list->GetPosition());
|
||||
return true;
|
||||
}
|
||||
|
||||
return plRegionBase::MsgReceive(msg);
|
||||
}
|
||||
|
||||
hsScalar plSoftVolume::IUpdateListenerStrength() const
|
||||
{
|
||||
return fListenStrength = GetStrength(fListenPos);
|
||||
}
|
||||
|
||||
void plSoftVolume::SetInsideStrength(hsScalar s)
|
||||
{
|
||||
if( s < 0 )
|
||||
s = 0;
|
||||
else if( s > 1.f )
|
||||
s = 1.f;
|
||||
fInsideStrength = s;
|
||||
}
|
||||
|
||||
void plSoftVolume::SetOutsideStrength(hsScalar s)
|
||||
{
|
||||
if( s < 0 )
|
||||
s = 0;
|
||||
else if( s > 1.f )
|
||||
s = 1.f;
|
||||
fOutsideStrength = s;
|
||||
}
|
116
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolume.h
Normal file
116
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolume.h
Normal file
@ -0,0 +1,116 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plSoftVolume_inc
|
||||
#define plSoftVolume_inc
|
||||
|
||||
#include "plRegionBase.h"
|
||||
#include "hsGeometry3.h"
|
||||
|
||||
class hsStream;
|
||||
class hsResMgr;
|
||||
class plMessage;
|
||||
|
||||
class plSoftVolume : public plRegionBase
|
||||
{
|
||||
public:
|
||||
enum RefTypes {
|
||||
kSubVolume
|
||||
};
|
||||
|
||||
protected:
|
||||
enum {
|
||||
kListenNone = 0x0,
|
||||
kListenCheck = 0x1,
|
||||
kListenPosSet = 0x2,
|
||||
kListenDirty = 0x4,
|
||||
kListenRegistered = 0x8
|
||||
};
|
||||
|
||||
hsPoint3 fListenPos;
|
||||
mutable hsScalar fListenStrength;
|
||||
mutable UInt32 fListenState;
|
||||
|
||||
hsScalar fInsideStrength;
|
||||
hsScalar fOutsideStrength;
|
||||
|
||||
virtual hsScalar IUpdateListenerStrength() const;
|
||||
|
||||
hsScalar IRemapStrength(hsScalar s) const { return fOutsideStrength + s * (fInsideStrength - fOutsideStrength); }
|
||||
|
||||
private:
|
||||
// Don't call this, use public GetStrength().
|
||||
virtual hsScalar IGetStrength(const hsPoint3& pos) const = 0;
|
||||
|
||||
public:
|
||||
plSoftVolume();
|
||||
virtual ~plSoftVolume();
|
||||
|
||||
CLASSNAME_REGISTER( plSoftVolume );
|
||||
GETINTERFACE_ANY( plSoftVolume, plRegionBase );
|
||||
|
||||
virtual hsScalar GetStrength(const hsPoint3& pos) const;
|
||||
virtual hsBool IsInside(const hsPoint3& pos) const { return GetStrength(pos) >= 1.f; }
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) = 0;
|
||||
|
||||
virtual Int32 GetNumProperties() const { return 1; } // This is stupid.
|
||||
|
||||
virtual hsScalar GetListenerStrength() const;
|
||||
virtual void UpdateListenerPosition(const hsPoint3& p);
|
||||
virtual void SetCheckListener(hsBool on=true);
|
||||
virtual hsBool GetCheckListener() const { return 0 != (fListenState & kListenCheck); }
|
||||
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
void SetInsideStrength(hsScalar s);
|
||||
void SetOutsideStrength(hsScalar s);
|
||||
|
||||
hsScalar GetInsideStrength() const { return fInsideStrength; }
|
||||
hsScalar GetOutsideStrength() const { return fOutsideStrength; }
|
||||
};
|
||||
|
||||
#endif // plSoftVolume_inc
|
||||
|
295
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolumeTypes.cpp
Normal file
295
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolumeTypes.cpp
Normal file
@ -0,0 +1,295 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#include "hsTypes.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsResMgr.h"
|
||||
#include "hsStream.h"
|
||||
|
||||
#include "plVolumeIsect.h"
|
||||
#include "plSoftVolumeTypes.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plSoftVolumeSimple::plSoftVolumeSimple()
|
||||
: fVolume(nil),
|
||||
fSoftDist(0)
|
||||
{
|
||||
}
|
||||
|
||||
plSoftVolumeSimple::~plSoftVolumeSimple()
|
||||
{
|
||||
delete fVolume;
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeSimple::IGetStrength(const hsPoint3& pos) const
|
||||
{
|
||||
if( !fVolume || GetProperty(kDisable) )
|
||||
return 0;
|
||||
|
||||
hsScalar dist = fVolume->Test(pos);
|
||||
|
||||
if( dist <= 0 )
|
||||
return 1.f;
|
||||
|
||||
if( dist >= fSoftDist )
|
||||
return 0;
|
||||
|
||||
dist /= fSoftDist;
|
||||
|
||||
return 1.f - dist;
|
||||
}
|
||||
|
||||
void plSoftVolumeSimple::SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l)
|
||||
{
|
||||
if( fVolume )
|
||||
fVolume->SetTransform(l2w, w2l);
|
||||
}
|
||||
|
||||
void plSoftVolumeSimple::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plSoftVolume::Read(s, mgr);
|
||||
|
||||
fSoftDist = s->ReadSwapScalar();
|
||||
|
||||
fVolume = plVolumeIsect::ConvertNoRef(mgr->ReadCreatable(s));
|
||||
}
|
||||
|
||||
void plSoftVolumeSimple::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plSoftVolume::Write(s, mgr);
|
||||
|
||||
s->WriteSwapScalar(fSoftDist);
|
||||
|
||||
mgr->WriteCreatable(s, fVolume);
|
||||
}
|
||||
|
||||
void plSoftVolumeSimple::SetVolume(plVolumeIsect* v)
|
||||
{
|
||||
delete fVolume;
|
||||
fVolume = v;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plSoftVolumeComplex::plSoftVolumeComplex()
|
||||
{
|
||||
}
|
||||
|
||||
plSoftVolumeComplex::~plSoftVolumeComplex()
|
||||
{
|
||||
}
|
||||
|
||||
void plSoftVolumeComplex::Read(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plSoftVolume::Read(s, mgr);
|
||||
|
||||
int n = s->ReadSwap32();
|
||||
int i;
|
||||
for( i = 0; i < n; i++ )
|
||||
mgr->ReadKeyNotifyMe(s, TRACKED_NEW plGenRefMsg(GetKey(), plRefMsg::kOnCreate, 0, kSubVolume), plRefFlags::kActiveRef);
|
||||
}
|
||||
|
||||
void plSoftVolumeComplex::Write(hsStream* s, hsResMgr* mgr)
|
||||
{
|
||||
plSoftVolume::Write(s, mgr);
|
||||
|
||||
s->WriteSwap32(fSubVolumes.GetCount());
|
||||
int i;
|
||||
for( i = 0; i < fSubVolumes.GetCount(); i++ )
|
||||
mgr->WriteKey(s, fSubVolumes[i]);
|
||||
}
|
||||
|
||||
hsBool plSoftVolumeComplex::MsgReceive(plMessage* msg)
|
||||
{
|
||||
plGenRefMsg* refMsg = plGenRefMsg::ConvertNoRef(msg);
|
||||
if( refMsg )
|
||||
{
|
||||
if( refMsg->GetContext() & (plRefMsg::kOnCreate|plRefMsg::kOnRequest) )
|
||||
{
|
||||
plSoftVolume* sub = plSoftVolume::ConvertNoRef(refMsg->GetRef());
|
||||
hsAssert(fSubVolumes.kMissingIndex == fSubVolumes.Find(sub), "Adding subvolume I already have");
|
||||
fSubVolumes.Append(sub);
|
||||
}
|
||||
else if( refMsg->GetContext() & (plRefMsg::kOnDestroy|plRefMsg::kOnRemove) )
|
||||
{
|
||||
plSoftVolume* sub = (plSoftVolume*)refMsg->GetRef();
|
||||
int idx = fSubVolumes.Find(sub);
|
||||
if( idx != fSubVolumes.kMissingIndex )
|
||||
fSubVolumes.Remove(idx);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return plSoftVolume::MsgReceive(msg);
|
||||
}
|
||||
|
||||
void plSoftVolumeComplex::UpdateListenerPosition(const hsPoint3& pos)
|
||||
{
|
||||
plSoftVolume::UpdateListenerPosition(pos);
|
||||
int i;
|
||||
for( i = 0; i < fSubVolumes.GetCount(); i++ )
|
||||
fSubVolumes[i]->UpdateListenerPosition(pos);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plSoftVolumeUnion::plSoftVolumeUnion()
|
||||
{
|
||||
}
|
||||
|
||||
plSoftVolumeUnion::~plSoftVolumeUnion()
|
||||
{
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeUnion::IGetStrength(const hsPoint3& pos) const
|
||||
{
|
||||
hsScalar retVal = 0;
|
||||
int i;
|
||||
for( i = 0; i < fSubVolumes.GetCount(); i++ )
|
||||
{
|
||||
hsScalar subRet = fSubVolumes[i]->GetStrength(pos);
|
||||
if( subRet >= 1.f )
|
||||
return 1.f;
|
||||
if( subRet > retVal )
|
||||
retVal = subRet;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeUnion::IUpdateListenerStrength() const
|
||||
{
|
||||
hsScalar retVal = 0;
|
||||
int i;
|
||||
for( i = 0; i < fSubVolumes.GetCount(); i++ )
|
||||
{
|
||||
hsScalar subRet = fSubVolumes[i]->GetListenerStrength();
|
||||
if( subRet >= 1.f )
|
||||
{
|
||||
retVal = 1.f;
|
||||
break;
|
||||
}
|
||||
if( subRet > retVal )
|
||||
retVal = subRet;
|
||||
}
|
||||
return fListenStrength = IRemapStrength(retVal);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plSoftVolumeIntersect::plSoftVolumeIntersect()
|
||||
{
|
||||
}
|
||||
|
||||
plSoftVolumeIntersect::~plSoftVolumeIntersect()
|
||||
{
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeIntersect::IGetStrength(const hsPoint3& pos) const
|
||||
{
|
||||
hsScalar retVal = 1.f;
|
||||
int i;
|
||||
for( i = 0; i < fSubVolumes.GetCount(); i++ )
|
||||
{
|
||||
hsScalar subRet = fSubVolumes[i]->GetStrength(pos);
|
||||
if( subRet <= 0 )
|
||||
return 0;
|
||||
if( subRet < retVal )
|
||||
retVal = subRet;
|
||||
}
|
||||
return retVal;
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeIntersect::IUpdateListenerStrength() const
|
||||
{
|
||||
hsScalar retVal = 1.f;
|
||||
int i;
|
||||
for( i = 0; i < fSubVolumes.GetCount(); i++ )
|
||||
{
|
||||
hsScalar subRet = fSubVolumes[i]->GetListenerStrength();
|
||||
if( subRet <= 0 )
|
||||
{
|
||||
retVal = 0.f;
|
||||
break;
|
||||
}
|
||||
if( subRet < retVal )
|
||||
retVal = subRet;
|
||||
}
|
||||
return fListenStrength = IRemapStrength(retVal);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
plSoftVolumeInvert::plSoftVolumeInvert()
|
||||
{
|
||||
}
|
||||
|
||||
plSoftVolumeInvert::~plSoftVolumeInvert()
|
||||
{
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeInvert::IGetStrength(const hsPoint3& pos) const
|
||||
{
|
||||
hsAssert(fSubVolumes.GetCount() <= 1, "Too many subvolumes on inverter");
|
||||
if( fSubVolumes.GetCount() )
|
||||
return 1.f - fSubVolumes[0]->GetStrength(pos);
|
||||
|
||||
return 1.f;
|
||||
}
|
||||
|
||||
hsScalar plSoftVolumeInvert::IUpdateListenerStrength() const
|
||||
{
|
||||
hsAssert(fSubVolumes.GetCount() <= 1, "Too many subvolumes on inverter");
|
||||
hsScalar retVal = 1.f;
|
||||
if( fSubVolumes.GetCount() )
|
||||
retVal = (1.f - fSubVolumes[0]->GetListenerStrength());
|
||||
|
||||
return fListenStrength = IRemapStrength(retVal);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////
|
160
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolumeTypes.h
Normal file
160
Sources/Plasma/PubUtilLib/plIntersect/plSoftVolumeTypes.h
Normal file
@ -0,0 +1,160 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plSoftVolumeTypes_inc
|
||||
#define plSoftVolumeTypes_inc
|
||||
|
||||
#include "plSoftVolume.h"
|
||||
#include "hsTemplates.h"
|
||||
|
||||
class plVolumeIsect;
|
||||
|
||||
class plSoftVolumeSimple : public plSoftVolume
|
||||
{
|
||||
protected:
|
||||
plVolumeIsect* fVolume;
|
||||
hsScalar fSoftDist;
|
||||
|
||||
private:
|
||||
virtual hsScalar IGetStrength(const hsPoint3& pos) const;
|
||||
|
||||
public:
|
||||
plSoftVolumeSimple();
|
||||
virtual ~plSoftVolumeSimple();
|
||||
|
||||
CLASSNAME_REGISTER( plSoftVolumeSimple );
|
||||
GETINTERFACE_ANY( plSoftVolumeSimple, plSoftVolume );
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
// Now Simple specifics
|
||||
plVolumeIsect* GetVolume() const { return fVolume; }
|
||||
void SetVolume(plVolumeIsect* v); // Takes ownership, don't delete after giving to SoftVolume
|
||||
|
||||
hsScalar GetDistance() const { return fSoftDist; }
|
||||
void SetDistance(hsScalar d) { fSoftDist = d; }
|
||||
|
||||
};
|
||||
|
||||
class plSoftVolumeComplex : public plSoftVolume
|
||||
{
|
||||
protected:
|
||||
hsTArray<plSoftVolume*> fSubVolumes;
|
||||
|
||||
public:
|
||||
plSoftVolumeComplex();
|
||||
virtual ~plSoftVolumeComplex();
|
||||
|
||||
CLASSNAME_REGISTER( plSoftVolumeComplex );
|
||||
GETINTERFACE_ANY( plSoftVolumeComplex, plSoftVolume );
|
||||
|
||||
// Don't propagate the settransform to our children, they move independently
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) {}
|
||||
|
||||
virtual void Read(hsStream* stream, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* stream, hsResMgr* mgr);
|
||||
|
||||
virtual void UpdateListenerPosition(const hsPoint3& p);
|
||||
|
||||
// Now Complex specifics
|
||||
virtual hsBool MsgReceive(plMessage* msg);
|
||||
|
||||
UInt16 GetNumSubs() const { return fSubVolumes.GetCount(); }
|
||||
const plSoftVolume* GetSub(int i) const { return fSubVolumes[i]; }
|
||||
};
|
||||
|
||||
class plSoftVolumeUnion : public plSoftVolumeComplex
|
||||
{
|
||||
protected:
|
||||
virtual hsScalar IUpdateListenerStrength() const;
|
||||
|
||||
private:
|
||||
virtual hsScalar IGetStrength(const hsPoint3& pos) const;
|
||||
|
||||
public:
|
||||
plSoftVolumeUnion();
|
||||
virtual ~plSoftVolumeUnion();
|
||||
|
||||
CLASSNAME_REGISTER( plSoftVolumeUnion );
|
||||
GETINTERFACE_ANY( plSoftVolumeUnion, plSoftVolumeComplex );
|
||||
|
||||
};
|
||||
|
||||
class plSoftVolumeIntersect : public plSoftVolumeComplex
|
||||
{
|
||||
protected:
|
||||
virtual hsScalar IUpdateListenerStrength() const;
|
||||
|
||||
private:
|
||||
virtual hsScalar IGetStrength(const hsPoint3& pos) const;
|
||||
|
||||
public:
|
||||
plSoftVolumeIntersect();
|
||||
virtual ~plSoftVolumeIntersect();
|
||||
|
||||
CLASSNAME_REGISTER( plSoftVolumeIntersect );
|
||||
GETINTERFACE_ANY( plSoftVolumeIntersect, plSoftVolumeComplex );
|
||||
|
||||
};
|
||||
|
||||
class plSoftVolumeInvert : public plSoftVolumeComplex
|
||||
{
|
||||
protected:
|
||||
virtual hsScalar IUpdateListenerStrength() const;
|
||||
|
||||
private:
|
||||
virtual hsScalar IGetStrength(const hsPoint3& pos) const;
|
||||
|
||||
public:
|
||||
plSoftVolumeInvert();
|
||||
virtual ~plSoftVolumeInvert();
|
||||
|
||||
CLASSNAME_REGISTER( plSoftVolumeInvert );
|
||||
GETINTERFACE_ANY( plSoftVolumeInvert, plSoftVolumeComplex );
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // plSoftVolumeTypes_inc
|
1005
Sources/Plasma/PubUtilLib/plIntersect/plVolumeIsect.cpp
Normal file
1005
Sources/Plasma/PubUtilLib/plIntersect/plVolumeIsect.cpp
Normal file
File diff suppressed because it is too large
Load Diff
324
Sources/Plasma/PubUtilLib/plIntersect/plVolumeIsect.h
Normal file
324
Sources/Plasma/PubUtilLib/plIntersect/plVolumeIsect.h
Normal file
@ -0,0 +1,324 @@
|
||||
/*==LICENSE==*
|
||||
|
||||
CyanWorlds.com Engine - MMOG client, server and tools
|
||||
Copyright (C) 2011 Cyan Worlds, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Additional permissions under GNU GPL version 3 section 7
|
||||
|
||||
If you modify this Program, or any covered work, by linking or
|
||||
combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK,
|
||||
NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent
|
||||
JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK
|
||||
(or a modified version of those libraries),
|
||||
containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA,
|
||||
PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG
|
||||
JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the
|
||||
licensors of this Program grant you additional
|
||||
permission to convey the resulting work. Corresponding Source for a
|
||||
non-source form of such a combination shall include the source code for
|
||||
the parts of OpenSSL and IJG JPEG Library used as well as that of the covered
|
||||
work.
|
||||
|
||||
You can contact Cyan Worlds, Inc. by email legal@cyan.com
|
||||
or by snail mail at:
|
||||
Cyan Worlds, Inc.
|
||||
14617 N Newport Hwy
|
||||
Mead, WA 99021
|
||||
|
||||
*==LICENSE==*/
|
||||
|
||||
#ifndef plVolumeIsect_inc
|
||||
#define plVolumeIsect_inc
|
||||
|
||||
#include "hsGeometry3.h"
|
||||
#include "hsMatrix44.h"
|
||||
#include "hsTemplates.h"
|
||||
#include "hsBounds.h"
|
||||
|
||||
#include "../pnFactory/plCreatable.h"
|
||||
|
||||
class hsBounds3Ext;
|
||||
|
||||
enum plVolumeCullResult
|
||||
{
|
||||
kVolumeClear = 0x0,
|
||||
kVolumeCulled = 0x1,
|
||||
kVolumeSplit = 0x2
|
||||
};
|
||||
|
||||
|
||||
class plVolumeIsect : public plCreatable
|
||||
{
|
||||
public:
|
||||
CLASSNAME_REGISTER( plVolumeIsect );
|
||||
GETINTERFACE_ANY( plVolumeIsect, plCreatable );
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l) = 0;
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const = 0;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const = 0;
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr) = 0;
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr) = 0;
|
||||
};
|
||||
|
||||
class plSphereIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
hsPoint3 fCenter;
|
||||
hsPoint3 fWorldCenter;
|
||||
hsScalar fRadius;
|
||||
hsPoint3 fMins;
|
||||
hsPoint3 fMaxs;
|
||||
public:
|
||||
plSphereIsect();
|
||||
virtual ~plSphereIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plSphereIsect );
|
||||
GETINTERFACE_ANY( plSphereIsect, plVolumeIsect );
|
||||
|
||||
void SetCenter(const hsPoint3& c);
|
||||
void SetRadius(hsScalar r);
|
||||
|
||||
hsScalar GetRadius() const { return fRadius; }
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const; // return 0 if point inside, else "distance" from pos to volume
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plConeIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
hsBool fCapped;
|
||||
|
||||
hsScalar fRadAngle;
|
||||
hsScalar fLength;
|
||||
|
||||
hsPoint3 fWorldTip;
|
||||
hsVector3 fWorldNorm;
|
||||
|
||||
hsMatrix44 fWorldToNDC;
|
||||
hsMatrix44 fLightToNDC;
|
||||
|
||||
hsVector3 fNorms[5];
|
||||
hsScalar fDists[5];
|
||||
|
||||
void ISetup();
|
||||
public:
|
||||
|
||||
plConeIsect();
|
||||
virtual ~plConeIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plConeIsect );
|
||||
GETINTERFACE_ANY( plConeIsect, plVolumeIsect );
|
||||
|
||||
void SetAngle(hsScalar rads);
|
||||
void SetLength(hsScalar d);
|
||||
|
||||
hsScalar GetLength() const { return fCapped ? fLength : 0; }
|
||||
hsScalar GetAngle() const { return fRadAngle; }
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plCylinderIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
hsPoint3 fTop;
|
||||
hsPoint3 fBot;
|
||||
hsScalar fRadius;
|
||||
|
||||
hsPoint3 fWorldBot;
|
||||
hsVector3 fWorldNorm;
|
||||
hsScalar fLength;
|
||||
hsScalar fMin;
|
||||
hsScalar fMax;
|
||||
|
||||
void ISetupCyl(const hsPoint3& wTop, const hsPoint3& wBot, hsScalar radius);
|
||||
|
||||
public:
|
||||
plCylinderIsect();
|
||||
virtual ~plCylinderIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plCylinderIsect );
|
||||
GETINTERFACE_ANY( plCylinderIsect, plVolumeIsect );
|
||||
|
||||
void SetCylinder(const hsPoint3& lTop, const hsPoint3& lBot, hsScalar radius);
|
||||
void SetCylinder(const hsPoint3& lBot, const hsVector3& axis, hsScalar radius);
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plParallelIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
class ParPlane
|
||||
{
|
||||
public:
|
||||
hsVector3 fNorm;
|
||||
hsScalar fMin;
|
||||
hsScalar fMax;
|
||||
|
||||
hsPoint3 fPosOne;
|
||||
hsPoint3 fPosTwo;
|
||||
};
|
||||
hsTArray<ParPlane> fPlanes;
|
||||
|
||||
public:
|
||||
plParallelIsect();
|
||||
virtual ~plParallelIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plParallelIsect );
|
||||
GETINTERFACE_ANY( plParallelIsect, plVolumeIsect );
|
||||
|
||||
void SetNumPlanes(int n); // each plane is really two parallel planes
|
||||
UInt16 GetNumPlanes() const { return fPlanes.GetCount(); }
|
||||
|
||||
void SetPlane(int which, const hsPoint3& locPosOne, const hsPoint3& locPosTwo);
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plConvexIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
class SinglePlane
|
||||
{
|
||||
public:
|
||||
hsVector3 fNorm;
|
||||
hsScalar fDist;
|
||||
hsPoint3 fPos;
|
||||
|
||||
hsVector3 fWorldNorm;
|
||||
hsScalar fWorldDist;
|
||||
};
|
||||
|
||||
hsTArray<SinglePlane> fPlanes;
|
||||
|
||||
public:
|
||||
plConvexIsect();
|
||||
virtual ~plConvexIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plConvexIsect );
|
||||
GETINTERFACE_ANY( plConvexIsect, plVolumeIsect );
|
||||
|
||||
void ClearPlanes() { fPlanes.SetCount(0); }
|
||||
void AddPlaneUnchecked(const hsVector3& n, hsScalar dist); // no validation here
|
||||
void AddPlane(const hsVector3& n, const hsPoint3& p);
|
||||
UInt16 GetNumPlanes() const { return fPlanes.GetCount(); }
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plBoundsIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
hsBounds3Ext fLocalBounds;
|
||||
hsBounds3Ext fWorldBounds;
|
||||
public:
|
||||
plBoundsIsect();
|
||||
virtual ~plBoundsIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plBoundsIsect );
|
||||
GETINTERFACE_ANY( plBoundsIsect, plVolumeIsect );
|
||||
|
||||
void SetBounds(const hsBounds3Ext& bnd);
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plComplexIsect : public plVolumeIsect
|
||||
{
|
||||
protected:
|
||||
hsTArray<plVolumeIsect*> fVolumes;
|
||||
|
||||
public:
|
||||
plComplexIsect();
|
||||
virtual ~plComplexIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plComplexIsect );
|
||||
GETINTERFACE_ANY( plComplexIsect, plVolumeIsect );
|
||||
|
||||
void AddVolume(plVolumeIsect* v); // Will capture pointer
|
||||
UInt16 GetNumVolumes() const { return fVolumes.GetCount(); }
|
||||
|
||||
virtual void SetTransform(const hsMatrix44& l2w, const hsMatrix44& w2l);
|
||||
|
||||
virtual void Read(hsStream* s, hsResMgr* mgr);
|
||||
virtual void Write(hsStream* s, hsResMgr* mgr);
|
||||
};
|
||||
|
||||
class plUnionIsect : public plComplexIsect
|
||||
{
|
||||
public:
|
||||
plUnionIsect();
|
||||
~plUnionIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plUnionIsect );
|
||||
GETINTERFACE_ANY( plUnionIsect, plComplexIsect );
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
};
|
||||
|
||||
class plIntersectionIsect : public plComplexIsect
|
||||
{
|
||||
public:
|
||||
plIntersectionIsect();
|
||||
~plIntersectionIsect();
|
||||
|
||||
CLASSNAME_REGISTER( plIntersectionIsect );
|
||||
GETINTERFACE_ANY( plIntersectionIsect, plComplexIsect );
|
||||
|
||||
virtual plVolumeCullResult Test(const hsBounds3Ext& bnd) const;
|
||||
virtual hsScalar Test(const hsPoint3& pos) const;
|
||||
};
|
||||
|
||||
#endif // plVolumeIsect_inc
|
Reference in New Issue
Block a user