977 lines
15 KiB
C
977 lines
15 KiB
C
#if !defined(HANDMADE_MATH_H)
|
|
/* ========================================================================
|
|
$File: $
|
|
$Date: $
|
|
$Revision: $
|
|
$Creator: Casey Muratori $
|
|
$Notice: (C) Copyright 2014 by Molly Rocket, Inc. All Rights Reserved. $
|
|
======================================================================== */
|
|
|
|
inline v2
|
|
V2i(int32 X, int32 Y)
|
|
{
|
|
v2 Result = {(real32)X, (real32)Y};
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
V2i(uint32 X, uint32 Y)
|
|
{
|
|
v2 Result = {(real32)X, (real32)Y};
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
V2(real32 X, real32 Y)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = X;
|
|
Result.y = Y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
V3(real32 X, real32 Y, real32 Z)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = X;
|
|
Result.y = Y;
|
|
Result.z = Z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
V3(v2 XY, real32 Z)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = XY.x;
|
|
Result.y = XY.y;
|
|
Result.z = Z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
V4(real32 X, real32 Y, real32 Z, real32 W)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.x = X;
|
|
Result.y = Y;
|
|
Result.z = Z;
|
|
Result.w = W;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
V4(v3 XYZ, real32 W)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.xyz = XYZ;
|
|
Result.w = W;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// NOTE(casey): Scalar operations
|
|
//
|
|
|
|
inline real32
|
|
Square(real32 A)
|
|
{
|
|
real32 Result = A*A;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Lerp(real32 A, real32 t, real32 B)
|
|
{
|
|
real32 Result = (1.0f - t)*A + t*B;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Clamp(real32 Min, real32 Value, real32 Max)
|
|
{
|
|
real32 Result = Value;
|
|
|
|
if(Result < Min)
|
|
{
|
|
Result = Min;
|
|
}
|
|
else if(Result > Max)
|
|
{
|
|
Result = Max;
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Clamp01(real32 Value)
|
|
{
|
|
real32 Result = Clamp(0.0f, Value, 1.0f);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Clamp01MapToRange(real32 Min, real32 t, real32 Max)
|
|
{
|
|
real32 Result = 0.0f;
|
|
|
|
real32 Range = Max - Min;
|
|
if(Range != 0.0f)
|
|
{
|
|
Result = Clamp01((t - Min) / Range);
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
SafeRatioN(real32 Numerator, real32 Divisor, real32 N)
|
|
{
|
|
real32 Result = N;
|
|
|
|
if(Divisor != 0.0f)
|
|
{
|
|
Result = Numerator / Divisor;
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
SafeRatio0(real32 Numerator, real32 Divisor)
|
|
{
|
|
real32 Result = SafeRatioN(Numerator, Divisor, 0.0f);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
SafeRatio1(real32 Numerator, real32 Divisor)
|
|
{
|
|
real32 Result = SafeRatioN(Numerator, Divisor, 1.0f);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// NOTE(casey): v2 operations
|
|
//
|
|
|
|
inline v2
|
|
Perp(v2 A)
|
|
{
|
|
v2 Result = {-A.y, A.x};
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
operator*(real32 A, v2 B)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = A*B.x;
|
|
Result.y = A*B.y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
operator*(v2 B, real32 A)
|
|
{
|
|
v2 Result = A*B;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2 &
|
|
operator*=(v2 &B, real32 A)
|
|
{
|
|
B = A * B;
|
|
|
|
return(B);
|
|
}
|
|
|
|
inline v2
|
|
operator-(v2 A)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = -A.x;
|
|
Result.y = -A.y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
operator+(v2 A, v2 B)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = A.x + B.x;
|
|
Result.y = A.y + B.y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2 &
|
|
operator+=(v2 &A, v2 B)
|
|
{
|
|
A = A + B;
|
|
|
|
return(A);
|
|
}
|
|
|
|
inline v2
|
|
operator-(v2 A, v2 B)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = A.x - B.x;
|
|
Result.y = A.y - B.y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2 &
|
|
operator-=(v2 &A, v2 B)
|
|
{
|
|
A = A - B;
|
|
|
|
return(A);
|
|
}
|
|
|
|
inline v2
|
|
Hadamard(v2 A, v2 B)
|
|
{
|
|
v2 Result = {A.x*B.x, A.y*B.y};
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Inner(v2 A, v2 B)
|
|
{
|
|
real32 Result = A.x*B.x + A.y*B.y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
LengthSq(v2 A)
|
|
{
|
|
real32 Result = Inner(A, A);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Length(v2 A)
|
|
{
|
|
real32 Result = SquareRoot(LengthSq(A));
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
Clamp01(v2 Value)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = Clamp01(Value.x);
|
|
Result.y = Clamp01(Value.y);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
Arm2(r32 Angle)
|
|
{
|
|
v2 Result = {Cos(Angle), Sin(Angle)};
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// NOTE(casey): v3 operations
|
|
//
|
|
|
|
inline v3
|
|
operator*(real32 A, v3 B)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = A*B.x;
|
|
Result.y = A*B.y;
|
|
Result.z = A*B.z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
operator*(v3 B, real32 A)
|
|
{
|
|
v3 Result = A*B;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3 &
|
|
operator*=(v3 &B, real32 A)
|
|
{
|
|
B = A * B;
|
|
|
|
return(B);
|
|
}
|
|
|
|
inline v3
|
|
operator-(v3 A)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = -A.x;
|
|
Result.y = -A.y;
|
|
Result.z = -A.z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
operator+(v3 A, v3 B)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = A.x + B.x;
|
|
Result.y = A.y + B.y;
|
|
Result.z = A.z + B.z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3 &
|
|
operator+=(v3 &A, v3 B)
|
|
{
|
|
A = A + B;
|
|
|
|
return(A);
|
|
}
|
|
|
|
inline v3
|
|
operator-(v3 A, v3 B)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = A.x - B.x;
|
|
Result.y = A.y - B.y;
|
|
Result.z = A.z - B.z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3 &
|
|
operator-=(v3 &A, v3 B)
|
|
{
|
|
A = A - B;
|
|
|
|
return(A);
|
|
}
|
|
|
|
inline v3
|
|
Hadamard(v3 A, v3 B)
|
|
{
|
|
v3 Result = {A.x*B.x, A.y*B.y, A.z*B.z};
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Inner(v3 A, v3 B)
|
|
{
|
|
real32 Result = A.x*B.x + A.y*B.y + A.z*B.z;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
LengthSq(v3 A)
|
|
{
|
|
real32 Result = Inner(A, A);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Length(v3 A)
|
|
{
|
|
real32 Result = SquareRoot(LengthSq(A));
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
Normalize(v3 A)
|
|
{
|
|
v3 Result = A * (1.0f / Length(A));
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
Clamp01(v3 Value)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = Clamp01(Value.x);
|
|
Result.y = Clamp01(Value.y);
|
|
Result.z = Clamp01(Value.z);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
Lerp(v3 A, real32 t, v3 B)
|
|
{
|
|
v3 Result = (1.0f - t)*A + t*B;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// NOTE(casey): v4 operations
|
|
//
|
|
|
|
inline v4
|
|
operator*(real32 A, v4 B)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.x = A*B.x;
|
|
Result.y = A*B.y;
|
|
Result.z = A*B.z;
|
|
Result.w = A*B.w;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
operator*(v4 B, real32 A)
|
|
{
|
|
v4 Result = A*B;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4 &
|
|
operator*=(v4 &B, real32 A)
|
|
{
|
|
B = A * B;
|
|
|
|
return(B);
|
|
}
|
|
|
|
inline v4
|
|
operator-(v4 A)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.x = -A.x;
|
|
Result.y = -A.y;
|
|
Result.z = -A.z;
|
|
Result.w = -A.w;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
operator+(v4 A, v4 B)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.x = A.x + B.x;
|
|
Result.y = A.y + B.y;
|
|
Result.z = A.z + B.z;
|
|
Result.w = A.w + B.w;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4 &
|
|
operator+=(v4 &A, v4 B)
|
|
{
|
|
A = A + B;
|
|
|
|
return(A);
|
|
}
|
|
|
|
inline v4
|
|
operator-(v4 A, v4 B)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.x = A.x - B.x;
|
|
Result.y = A.y - B.y;
|
|
Result.z = A.z - B.z;
|
|
Result.w = A.w - B.w;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4 &
|
|
operator-=(v4 &A, v4 B)
|
|
{
|
|
A = A - B;
|
|
|
|
return(A);
|
|
}
|
|
|
|
inline v4
|
|
Hadamard(v4 A, v4 B)
|
|
{
|
|
v4 Result = {A.x*B.x, A.y*B.y, A.z*B.z, A.w*B.w};
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Inner(v4 A, v4 B)
|
|
{
|
|
real32 Result = A.x*B.x + A.y*B.y + A.z*B.z + A.w*B.w;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
LengthSq(v4 A)
|
|
{
|
|
real32 Result = Inner(A, A);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline real32
|
|
Length(v4 A)
|
|
{
|
|
real32 Result = SquareRoot(LengthSq(A));
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
Clamp01(v4 Value)
|
|
{
|
|
v4 Result;
|
|
|
|
Result.x = Clamp01(Value.x);
|
|
Result.y = Clamp01(Value.y);
|
|
Result.z = Clamp01(Value.z);
|
|
Result.w = Clamp01(Value.w);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
Lerp(v4 A, real32 t, v4 B)
|
|
{
|
|
v4 Result = (1.0f - t)*A + t*B;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// NOTE(casey): Rectangle2
|
|
//
|
|
|
|
inline rectangle2
|
|
InvertedInfinityRectangle2(void)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min.x = Result.Min.y = Real32Maximum;
|
|
Result.Max.x = Result.Max.y = -Real32Maximum;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
Union(rectangle2 A, rectangle2 B)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min.x = (A.Min.x < B.Min.x) ? A.Min.x : B.Min.x;
|
|
Result.Min.y = (A.Min.y < B.Min.y) ? A.Min.y : B.Min.y;
|
|
Result.Max.x = (A.Max.x > B.Max.x) ? A.Max.x : B.Max.x;
|
|
Result.Max.y = (A.Max.y > B.Max.y) ? A.Max.y : B.Max.y;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
GetMinCorner(rectangle2 Rect)
|
|
{
|
|
v2 Result = Rect.Min;
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
GetMaxCorner(rectangle2 Rect)
|
|
{
|
|
v2 Result = Rect.Max;
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
GetDim(rectangle2 Rect)
|
|
{
|
|
v2 Result = Rect.Max - Rect.Min;
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
GetCenter(rectangle2 Rect)
|
|
{
|
|
v2 Result = 0.5f*(Rect.Min + Rect.Max);
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
RectMinMax(v2 Min, v2 Max)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min = Min;
|
|
Result.Max = Max;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
RectMinDim(v2 Min, v2 Dim)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min = Min;
|
|
Result.Max = Min + Dim;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
RectCenterHalfDim(v2 Center, v2 HalfDim)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min = Center - HalfDim;
|
|
Result.Max = Center + HalfDim;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
AddRadiusTo(rectangle2 A, v2 Radius)
|
|
{
|
|
rectangle2 Result;
|
|
Result.Min = A.Min - Radius;
|
|
Result.Max = A.Max + Radius;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
Offset(rectangle2 A, v2 Offset)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min = A.Min + Offset;
|
|
Result.Max = A.Max + Offset;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
RectCenterDim(v2 Center, v2 Dim)
|
|
{
|
|
rectangle2 Result = RectCenterHalfDim(Center, 0.5f*Dim);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline bool32
|
|
IsInRectangle(rectangle2 Rectangle, v2 Test)
|
|
{
|
|
bool32 Result = ((Test.x >= Rectangle.Min.x) &&
|
|
(Test.y >= Rectangle.Min.y) &&
|
|
(Test.x < Rectangle.Max.x) &&
|
|
(Test.y < Rectangle.Max.y));
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v2
|
|
GetBarycentric(rectangle2 A, v2 P)
|
|
{
|
|
v2 Result;
|
|
|
|
Result.x = SafeRatio0(P.x - A.Min.x, A.Max.x - A.Min.x);
|
|
Result.y = SafeRatio0(P.y - A.Min.y, A.Max.y - A.Min.y);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
// NOTE(casey): Rectangle3
|
|
//
|
|
|
|
inline v3
|
|
GetMinCorner(rectangle3 Rect)
|
|
{
|
|
v3 Result = Rect.Min;
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
GetMaxCorner(rectangle3 Rect)
|
|
{
|
|
v3 Result = Rect.Max;
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
GetDim(rectangle3 Rect)
|
|
{
|
|
v3 Result = Rect.Max - Rect.Min;
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
GetCenter(rectangle3 Rect)
|
|
{
|
|
v3 Result = 0.5f*(Rect.Min + Rect.Max);
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle3
|
|
RectMinMax(v3 Min, v3 Max)
|
|
{
|
|
rectangle3 Result;
|
|
|
|
Result.Min = Min;
|
|
Result.Max = Max;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle3
|
|
RectMinDim(v3 Min, v3 Dim)
|
|
{
|
|
rectangle3 Result;
|
|
|
|
Result.Min = Min;
|
|
Result.Max = Min + Dim;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle3
|
|
RectCenterHalfDim(v3 Center, v3 HalfDim)
|
|
{
|
|
rectangle3 Result;
|
|
|
|
Result.Min = Center - HalfDim;
|
|
Result.Max = Center + HalfDim;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle3
|
|
AddRadiusTo(rectangle3 A, v3 Radius)
|
|
{
|
|
rectangle3 Result;
|
|
|
|
Result.Min = A.Min - Radius;
|
|
Result.Max = A.Max + Radius;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle3
|
|
Offset(rectangle3 A, v3 Offset)
|
|
{
|
|
rectangle3 Result;
|
|
|
|
Result.Min = A.Min + Offset;
|
|
Result.Max = A.Max + Offset;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle3
|
|
RectCenterDim(v3 Center, v3 Dim)
|
|
{
|
|
rectangle3 Result = RectCenterHalfDim(Center, 0.5f*Dim);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline bool32
|
|
IsInRectangle(rectangle3 Rectangle, v3 Test)
|
|
{
|
|
bool32 Result = ((Test.x >= Rectangle.Min.x) &&
|
|
(Test.y >= Rectangle.Min.y) &&
|
|
(Test.z >= Rectangle.Min.z) &&
|
|
(Test.x < Rectangle.Max.x) &&
|
|
(Test.y < Rectangle.Max.y) &&
|
|
(Test.z < Rectangle.Max.z));
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline bool32
|
|
RectanglesIntersect(rectangle3 A, rectangle3 B)
|
|
{
|
|
bool32 Result = !((B.Max.x <= A.Min.x) ||
|
|
(B.Min.x >= A.Max.x) ||
|
|
(B.Max.y <= A.Min.y) ||
|
|
(B.Min.y >= A.Max.y) ||
|
|
(B.Max.z <= A.Min.z) ||
|
|
(B.Min.z >= A.Max.z));
|
|
return(Result);
|
|
}
|
|
|
|
inline v3
|
|
GetBarycentric(rectangle3 A, v3 P)
|
|
{
|
|
v3 Result;
|
|
|
|
Result.x = SafeRatio0(P.x - A.Min.x, A.Max.x - A.Min.x);
|
|
Result.y = SafeRatio0(P.y - A.Min.y, A.Max.y - A.Min.y);
|
|
Result.z = SafeRatio0(P.z - A.Min.z, A.Max.z - A.Min.z);
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2
|
|
ToRectangleXY(rectangle3 A)
|
|
{
|
|
rectangle2 Result;
|
|
|
|
Result.Min = A.Min.xy;
|
|
Result.Max = A.Max.xy;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
//
|
|
//
|
|
//
|
|
|
|
struct rectangle2i
|
|
{
|
|
int32 MinX, MinY;
|
|
int32 MaxX, MaxY;
|
|
};
|
|
|
|
inline rectangle2i
|
|
Intersect(rectangle2i A, rectangle2i B)
|
|
{
|
|
rectangle2i Result;
|
|
|
|
Result.MinX = (A.MinX < B.MinX) ? B.MinX : A.MinX;
|
|
Result.MinY = (A.MinY < B.MinY) ? B.MinY : A.MinY;
|
|
Result.MaxX = (A.MaxX > B.MaxX) ? B.MaxX : A.MaxX;
|
|
Result.MaxY = (A.MaxY > B.MaxY) ? B.MaxY : A.MaxY;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2i
|
|
Union(rectangle2i A, rectangle2i B)
|
|
{
|
|
rectangle2i Result;
|
|
|
|
Result.MinX = (A.MinX < B.MinX) ? A.MinX : B.MinX;
|
|
Result.MinY = (A.MinY < B.MinY) ? A.MinY : B.MinY;
|
|
Result.MaxX = (A.MaxX > B.MaxX) ? A.MaxX : B.MaxX;
|
|
Result.MaxY = (A.MaxY > B.MaxY) ? A.MaxY : B.MaxY;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline int32
|
|
GetClampedRectArea(rectangle2i A)
|
|
{
|
|
int32 Width = (A.MaxX - A.MinX);
|
|
int32 Height = (A.MaxY - A.MinY);
|
|
int32 Result = 0;
|
|
if((Width > 0) && (Height > 0))
|
|
{
|
|
Result = Width*Height;
|
|
}
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline bool32
|
|
HasArea(rectangle2i A)
|
|
{
|
|
bool32 Result = ((A.MinX < A.MaxX) && (A.MinY < A.MaxY));
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline rectangle2i
|
|
InvertedInfinityRectangle2i(void)
|
|
{
|
|
rectangle2i Result;
|
|
|
|
Result.MinX = Result.MinY = INT_MAX;
|
|
Result.MaxX = Result.MaxY = -INT_MAX;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
SRGB255ToLinear1(v4 C)
|
|
{
|
|
v4 Result;
|
|
|
|
real32 Inv255 = 1.0f / 255.0f;
|
|
|
|
Result.r = Square(Inv255*C.r);
|
|
Result.g = Square(Inv255*C.g);
|
|
Result.b = Square(Inv255*C.b);
|
|
Result.a = Inv255*C.a;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
inline v4
|
|
Linear1ToSRGB255(v4 C)
|
|
{
|
|
v4 Result;
|
|
|
|
real32 One255 = 255.0f;
|
|
|
|
Result.r = One255*SquareRoot(C.r);
|
|
Result.g = One255*SquareRoot(C.g);
|
|
Result.b = One255*SquareRoot(C.b);
|
|
Result.a = One255*C.a;
|
|
|
|
return(Result);
|
|
}
|
|
|
|
#define HANDMADE_MATH_H
|
|
#endif
|