2
3
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:
rarified
2021-05-15 12:49:46 -06:00
parent c3f4a640a3
commit 96903e8dca
4002 changed files with 159 additions and 644 deletions

View 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.

View 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, &center);
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, &center);
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

View 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

View 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);
}

View 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

View 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);
}

View 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

View 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();
}
///////////////////////////////////////////////////////////////////////////////

View 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

View 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

View 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

View 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;
}

View 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

View 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);
}
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

View 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

File diff suppressed because it is too large Load Diff

View 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