unmath.h
来自「虚幻的再开发程序包源代码」· C头文件 代码 · 共 1,604 行 · 第 1/3 页
H
1,604 行
/*=============================================================================
UnMath.h: Unreal math routines
Copyright 1997-1999 Epic Games, Inc. All Rights Reserved.
Revision history:
* Created by Tim Sweeney
=============================================================================*/
/*-----------------------------------------------------------------------------
Defintions.
-----------------------------------------------------------------------------*/
// Forward declarations.
class FVector;
class FPlane;
class FCoords;
class FRotator;
class FScale;
class FGlobalMath;
// Fixed point conversion.
inline INT Fix (INT A) {return A<<16;};
inline INT Fix (FLOAT A) {return (INT)(A*65536.0);};
inline INT Unfix (INT A) {return A>>16;};
// Constants.
#undef PI
#define PI (3.1415926535897932)
#define SMALL_NUMBER (1.e-8)
#define KINDA_SMALL_NUMBER (1.e-4)
/*-----------------------------------------------------------------------------
Global functions.
-----------------------------------------------------------------------------*/
//
// Snap a value to the nearest grid multiple.
//
inline FLOAT FSnap( FLOAT Location, FLOAT Grid )
{
if( Grid==0.0 ) return Location;
else return appFloor((Location + 0.5*Grid)/Grid)*Grid;
}
//
// Internal sheer adjusting function so it snaps nicely at 0 and 45 degrees.
//
inline FLOAT FSheerSnap (FLOAT Sheer)
{
if (Sheer < -0.65) return Sheer + 0.15;
else if (Sheer > +0.65) return Sheer - 0.15;
else if (Sheer < -0.55) return -0.50;
else if (Sheer > +0.55) return 0.50;
else if (Sheer < -0.05) return Sheer + 0.05;
else if (Sheer > +0.05) return Sheer - 0.05;
else return 0.0;
}
//
// Find the closest power of 2 that is >= N.
//
inline DWORD FNextPowerOfTwo( DWORD N )
{
if (N<=0L ) return 0L;
if (N<=1L ) return 1L;
if (N<=2L ) return 2L;
if (N<=4L ) return 4L;
if (N<=8L ) return 8L;
if (N<=16L ) return 16L;
if (N<=32L ) return 32L;
if (N<=64L ) return 64L;
if (N<=128L ) return 128L;
if (N<=256L ) return 256L;
if (N<=512L ) return 512L;
if (N<=1024L ) return 1024L;
if (N<=2048L ) return 2048L;
if (N<=4096L ) return 4096L;
if (N<=8192L ) return 8192L;
if (N<=16384L ) return 16384L;
if (N<=32768L ) return 32768L;
if (N<=65536L ) return 65536L;
else return 0;
}
//
// Add to a word angle, constraining it within a min (not to cross)
// and a max (not to cross). Accounts for funkyness of word angles.
// Assumes that angle is initially in the desired range.
//
inline _WORD FAddAngleConfined( INT Angle, INT Delta, INT MinThresh, INT MaxThresh )
{
if( Delta < 0 )
{
if ( Delta<=-0x10000L || Delta<=-(INT)((_WORD)(Angle-MinThresh)))
return MinThresh;
}
else if( Delta > 0 )
{
if( Delta>=0x10000L || Delta>=(INT)((_WORD)(MaxThresh-Angle)))
return MaxThresh;
}
return (_WORD)(Angle+Delta);
}
//
// Eliminate all fractional precision from an angle.
//
INT ReduceAngle( INT Angle );
//
// Fast 32-bit float evaluations.
// Warning: likely not portable, and useful on Pentium class processors only.
//
inline UBOOL IsSmallerPositiveFloat(float F1,float F2)
{
return ( (*(DWORD*)&F1) < (*(DWORD*)&F2));
}
inline FLOAT MinPositiveFloat(float F1, float F2)
{
if ( (*(DWORD*)&F1) < (*(DWORD*)&F2)) return F1; else return F2;
}
//
// Warning: 0 and -0 have different binary representations.
//
inline UBOOL EqualPositiveFloat(float F1, float F2)
{
return ( *(DWORD*)&F1 == *(DWORD*)&F2 );
}
inline UBOOL IsNegativeFloat(float F1)
{
return ( (*(DWORD*)&F1) >= (DWORD)0x80000000 ); // Detects sign bit.
}
inline FLOAT MaxPositiveFloat(float F1, float F2)
{
if ( (*(DWORD*)&F1) < (*(DWORD*)&F2)) return F2; else return F1;
}
// Clamp F0 between F1 and F2, all positive assumed.
inline FLOAT ClampPositiveFloat(float F0, float F1, float F2)
{
if ( (*(DWORD*)&F0) < (*(DWORD*)&F1)) return F1;
else if ( (*(DWORD*)&F0) > (*(DWORD*)&F2)) return F2;
else return F0;
}
// Clamp any float F0 between zero and positive float Range
#define ClipFloatFromZero(F0,Range)\
{\
if ( (*(DWORD*)&F0) >= (DWORD)0x80000000) F0 = 0.f;\
else if ( (*(DWORD*)&F0) > (*(DWORD*)&Range)) F0 = Range;\
}
/*-----------------------------------------------------------------------------
FVector.
-----------------------------------------------------------------------------*/
// Information associated with a floating point vector, describing its
// status as a point in a rendering context.
enum EVectorFlags
{
FVF_OutXMin = 0x04, // Outcode rejection, off left hand side of screen.
FVF_OutXMax = 0x08, // Outcode rejection, off right hand side of screen.
FVF_OutYMin = 0x10, // Outcode rejection, off top of screen.
FVF_OutYMax = 0x20, // Outcode rejection, off bottom of screen.
FVF_OutNear = 0x40, // Near clipping plane.
FVF_OutFar = 0x80, // Far clipping plane.
FVF_OutReject = (FVF_OutXMin | FVF_OutXMax | FVF_OutYMin | FVF_OutYMax), // Outcode rejectable.
FVF_OutSkip = (FVF_OutXMin | FVF_OutXMax | FVF_OutYMin | FVF_OutYMax), // Outcode clippable.
};
//
// Floating point vector.
//
class CORE_API FVector
{
public:
// Variables.
FLOAT X,Y,Z;
// Constructors.
FVector()
{}
FVector( FLOAT InX, FLOAT InY, FLOAT InZ )
: X(InX), Y(InY), Z(InZ)
{}
// Binary math operators.
FVector operator^( const FVector& V ) const
{
return FVector
(
Y * V.Z - Z * V.Y,
Z * V.X - X * V.Z,
X * V.Y - Y * V.X
);
}
FLOAT operator|( const FVector& V ) const
{
return X*V.X + Y*V.Y + Z*V.Z;
}
friend FVector operator*( FLOAT Scale, const FVector& V )
{
return FVector( V.X * Scale, V.Y * Scale, V.Z * Scale );
}
FVector operator+( const FVector& V ) const
{
return FVector( X + V.X, Y + V.Y, Z + V.Z );
}
FVector operator-( const FVector& V ) const
{
return FVector( X - V.X, Y - V.Y, Z - V.Z );
}
FVector operator*( FLOAT Scale ) const
{
return FVector( X * Scale, Y * Scale, Z * Scale );
}
FVector operator/( FLOAT Scale ) const
{
FLOAT RScale = 1.0/Scale;
return FVector( X * RScale, Y * RScale, Z * RScale );
}
FVector operator*( const FVector& V ) const
{
return FVector( X * V.X, Y * V.Y, Z * V.Z );
}
// Binary comparison operators.
UBOOL operator==( const FVector& V ) const
{
return X==V.X && Y==V.Y && Z==V.Z;
}
UBOOL operator!=( const FVector& V ) const
{
return X!=V.X || Y!=V.Y || Z!=V.Z;
}
// Unary operators.
FVector operator-() const
{
return FVector( -X, -Y, -Z );
}
// Assignment operators.
FVector operator+=( const FVector& V )
{
X += V.X; Y += V.Y; Z += V.Z;
return *this;
}
FVector operator-=( const FVector& V )
{
X -= V.X; Y -= V.Y; Z -= V.Z;
return *this;
}
FVector operator*=( FLOAT Scale )
{
X *= Scale; Y *= Scale; Z *= Scale;
return *this;
}
FVector operator/=( FLOAT V )
{
FLOAT RV = 1.0/V;
X *= RV; Y *= RV; Z *= RV;
return *this;
}
FVector operator*=( const FVector& V )
{
X *= V.X; Y *= V.Y; Z *= V.Z;
return *this;
}
FVector operator/=( const FVector& V )
{
X /= V.X; Y /= V.Y; Z /= V.Z;
return *this;
}
// Simple functions.
FLOAT Size() const
{
return appSqrt( X*X + Y*Y + Z*Z );
}
FLOAT SizeSquared() const
{
return X*X + Y*Y + Z*Z;
}
FLOAT Size2D() const
{
return appSqrt( X*X + Y*Y );
}
FLOAT SizeSquared2D() const
{
return X*X + Y*Y;
}
int IsNearlyZero() const
{
return
Abs(X)<KINDA_SMALL_NUMBER
&& Abs(Y)<KINDA_SMALL_NUMBER
&& Abs(Z)<KINDA_SMALL_NUMBER;
}
UBOOL IsZero() const
{
return X==0.0 && Y==0.0 && Z==0.0;
}
UBOOL Normalize()
{
FLOAT SquareSum = X*X+Y*Y+Z*Z;
if( SquareSum >= SMALL_NUMBER )
{
FLOAT Scale = 1.0/appSqrt(SquareSum);
X *= Scale; Y *= Scale; Z *= Scale;
return 1;
}
else return 0;
}
FVector Projection() const
{
FLOAT RZ = 1.0/Z;
return FVector( X*RZ, Y*RZ, 1 );
}
FVector UnsafeNormal() const
{
FLOAT Scale = 1.0/appSqrt(X*X+Y*Y+Z*Z);
return FVector( X*Scale, Y*Scale, Z*Scale );
}
FVector GridSnap( const FVector& Grid )
{
return FVector( FSnap(X, Grid.X),FSnap(Y, Grid.Y),FSnap(Z, Grid.Z) );
}
FVector BoundToCube( FLOAT Radius )
{
return FVector
(
Clamp(X,-Radius,Radius),
Clamp(Y,-Radius,Radius),
Clamp(Z,-Radius,Radius)
);
}
void AddBounded( const FVector& V, FLOAT Radius=MAXSWORD )
{
*this = (*this + V).BoundToCube(Radius);
}
FLOAT& Component( INT Index )
{
return (&X)[Index];
}
// Return a boolean that is based on the vector's direction.
// When V==(0.0.0) Booleanize(0)=1.
// Otherwise Booleanize(V) <-> !Booleanize(!B).
UBOOL Booleanize()
{
return
X > 0.0 ? 1 :
X < 0.0 ? 0 :
Y > 0.0 ? 1 :
Y < 0.0 ? 0 :
Z >= 0.0 ? 1 : 0;
}
// Transformation.
FVector TransformVectorBy( const FCoords& Coords ) const;
FVector TransformPointBy( const FCoords& Coords ) const;
FVector MirrorByVector( const FVector& MirrorNormal ) const;
FVector MirrorByPlane( const FPlane& MirrorPlane ) const;
// Complicated functions.
FRotator Rotation();
void FindBestAxisVectors( FVector& Axis1, FVector& Axis2 );
FVector SafeNormal() const; //warning: Not inline because of compiler bug.
// Friends.
friend FLOAT FDist( const FVector& V1, const FVector& V2 );
friend FLOAT FDistSquared( const FVector& V1, const FVector& V2 );
friend UBOOL FPointsAreSame( const FVector& P, const FVector& Q );
friend UBOOL FPointsAreNear( const FVector& Point1, const FVector& Point2, FLOAT Dist);
friend FLOAT FPointPlaneDist( const FVector& Point, const FVector& PlaneBase, const FVector& PlaneNormal );
friend FVector FLinePlaneIntersection( const FVector& Point1, const FVector& Point2, const FVector& PlaneOrigin, const FVector& PlaneNormal );
friend FVector FLinePlaneIntersection( const FVector& Point1, const FVector& Point2, const FPlane& Plane );
friend UBOOL FParallel( const FVector& Normal1, const FVector& Normal2 );
friend UBOOL FCoplanar( const FVector& Base1, const FVector& Normal1, const FVector& Base2, const FVector& Normal2 );
// Serializer.
friend FArchive& operator<<( FArchive& Ar, FVector& V )
{
return Ar << V.X << V.Y << V.Z;
}
};
/*-----------------------------------------------------------------------------
FPlane.
-----------------------------------------------------------------------------*/
class CORE_API FPlane : public FVector
{
public:
// Variables.
FLOAT W;
// Constructors.
FPlane()
{}
FPlane( const FPlane& P )
: FVector(P)
, W(P.W)
{}
FPlane( const FVector& V )
: FVector(V)
, W(0)
{}
FPlane( FLOAT InX, FLOAT InY, FLOAT InZ, FLOAT InW )
: FVector(InX,InY,InZ)
, W(InW)
{}
FPlane( FVector InNormal, FLOAT InW )
: FVector(InNormal), W(InW)
{}
FPlane( FVector InBase, const FVector &InNormal )
: FVector(InNormal)
, W(InBase | InNormal)
{}
FPlane( FVector A, FVector B, FVector C )
: FVector( ((B-A)^(C-A)).SafeNormal() )
, W( A | ((B-A)^(C-A)).SafeNormal() )
{}
// Functions.
FLOAT PlaneDot( const FVector &P ) const
{
return X*P.X + Y*P.Y + Z*P.Z - W;
}
FPlane Flip() const
{
return FPlane(-X,-Y,-Z,-W);
}
FPlane TransformPlaneByOrtho( const FCoords &Coords ) const;
UBOOL operator==( const FPlane& V ) const
{
return X==V.X && Y==V.Y && Z==V.Z && W==V.W;
}
UBOOL operator!=( const FPlane& V ) const
{
return X!=V.X || Y!=V.Y || Z!=V.Z || W!=V.W;
}
// Serializer.
friend FArchive& operator<<( FArchive& Ar, FPlane &P )
{
return Ar << (FVector&)P << P.W;
}
};
/*-----------------------------------------------------------------------------
FSphere.
-----------------------------------------------------------------------------*/
class CORE_API FSphere : public FPlane
{
public:
// Constructors.
FSphere()
{}
FSphere( INT )
: FPlane(0,0,0,0)
{}
FSphere( FVector V, FLOAT W )
: FPlane( V, W )
{}
FSphere( const FVector* Pts, INT Count );
friend FArchive& operator<<( FArchive& Ar, FSphere& S )
{
guardSlow(FSphere<<);
if( Ar.Ver()<=61 )//oldver
Ar << (FVector&)S;
else
Ar << (FPlane&)S;
return Ar;
unguardSlow
}
};
/*-----------------------------------------------------------------------------
FScale.
-----------------------------------------------------------------------------*/
// An axis along which sheering is performed.
enum ESheerAxis
{
SHEER_None = 0,
SHEER_XY = 1,
SHEER_XZ = 2,
SHEER_YX = 3,
SHEER_YZ = 4,
SHEER_ZX = 5,
SHEER_ZY = 6,
};
//
// Scaling and sheering info associated with a brush. This is
// easily-manipulated information which is built into a transformation
// matrix later.
//
class CORE_API FScale
{
public:
// Variables.
FVector Scale;
FLOAT SheerRate;
BYTE SheerAxis; // From ESheerAxis
// Serializer.
friend FArchive& operator<<( FArchive& Ar, FScale &S )
{
return Ar << S.Scale << S.SheerRate << S.SheerAxis;
}
// Constructors.
FScale() {}
FScale( const FVector &InScale, FLOAT InSheerRate, ESheerAxis InSheerAxis )
: Scale(InScale), SheerRate(InSheerRate), SheerAxis(InSheerAxis) {}
// Operators.
UBOOL operator==( const FScale &S ) const
{
return Scale==S.Scale && SheerRate==S.SheerRate && SheerAxis==S.SheerAxis;
}
// Functions.
FLOAT Orientation()
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?