Skip to content
Open
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ endif()

include(cmake/config.cmake)
include(cmake/gamespy.cmake)
if (NOT IS_VS6_BUILD)
Comment thread
Okladnoj marked this conversation as resolved.
include(cmake/gamemath.cmake)
endif()
include(cmake/lzhl.cmake)

if (IS_VS6_BUILD)
Expand Down
4 changes: 4 additions & 0 deletions Core/GameEngine/Include/Common/Diagnostic/SimulationMathCrc.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@

#pragma once

// Flags for diagnostic math benchmarks
#define RUN_MATH_BENCHMARK_REPLAY400_FLAG (0)

class SimulationMathCrc
{
public:
static UnsignedInt calculate();
static void runBenchmark(int iterations = 10000);
};
103 changes: 89 additions & 14 deletions Core/GameEngine/Source/Common/Diagnostic/SimulationMathCrc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,10 @@
#include "GameLogic/FPUControl.h"

#include <math.h>
#include <stdio.h>
#include <time.h>

static void appendSimulationMathCrc(XferCRC &xfer)
static void appendSimulationMathCrc_Deterministic(XferCRC &xfer)
{
Matrix3D matrix;
Matrix3D factorsMatrix;
Expand All @@ -37,18 +39,48 @@ static void appendSimulationMathCrc(XferCRC &xfer)
0.9f, 1.0f, 2.1f, 1.2f);

factorsMatrix.Set(
WWMath::Sin(0.7f) * log10f(2.3f),
WWMath::Cos(1.1f) * powf(1.1f, 2.0f),
tanf(0.3f),
asinf(0.967302263f),
acosf(0.967302263f),
atanf(0.967302263f) * powf(1.1f, 2.0f),
atan2f(0.4f, 1.3f),
sinhf(0.2f),
coshf(0.4f) * tanhf(0.5f),
sqrtf(55788.84375f),
expf(0.1f) * log10f(2.3f),
logf(1.4f));
WWMath::Sin(0.7f) * WWMath::Log10f_Origin(2.3f),
WWMath::Cos(1.1f) * WWMath::Powf_Origin(1.1f, 2.0f),
WWMath::Tanf_Origin(0.3f),
WWMath::ASinf_Origin(0.967302263f),
WWMath::ACosf_Origin(0.967302263f),
WWMath::Atanf_Origin(0.967302263f) * WWMath::Powf_Origin(1.1f, 2.0f),
WWMath::Atan2f_Origin(0.4f, 1.3f),
WWMath::Sinhf_Origin(0.2f),
WWMath::Coshf_Origin(0.4f) * WWMath::Tanhf_Origin(0.5f),
WWMath::Sqrtf_Origin(55788.84375f),
WWMath::Expf_Origin(0.1f) * WWMath::Log10f_Origin(2.3f),
WWMath::Logf_Origin(1.4f));

Matrix3D::Multiply(matrix, factorsMatrix, &matrix);
matrix.Get_Inverse(matrix);

xfer.xferMatrix3D(&matrix);
}

static void appendSimulationMathCrc_Native(XferCRC &xfer)
{
Matrix3D matrix;
Matrix3D factorsMatrix;

matrix.Set(
4.1f, 1.2f, 0.3f, 0.4f,
0.5f, 3.6f, 0.7f, 0.8f,
0.9f, 1.0f, 2.1f, 1.2f);

factorsMatrix.Set(
(float)(::sin(0.7) * ::log10(2.3)),
(float)(::cos(1.1) * ::pow(1.1, 2.0)),
(float)::tan(0.3),
(float)::asin(0.967302263),
(float)::acos(0.967302263),
(float)(::atan(0.967302263) * ::pow(1.1, 2.0)),
(float)::atan2(0.4, 1.3),
(float)::sinh(0.2),
(float)(::cosh(0.4) * ::tanh(0.5)),
(float)::sqrt(55788.84375),
(float)(::exp(0.1) * ::log10(2.3)),
(float)::log(1.4));

Matrix3D::Multiply(matrix, factorsMatrix, &matrix);
matrix.Get_Inverse(matrix);
Expand All @@ -63,11 +95,54 @@ UnsignedInt SimulationMathCrc::calculate()

setFPMode();

appendSimulationMathCrc(xfer);
appendSimulationMathCrc_Deterministic(xfer);

_fpreset();

xfer.close();

return xfer.getCRC();
}

void SimulationMathCrc::runBenchmark(int iterations)
{
int i;
clock_t startDet = clock();
UnsignedInt crcDet = 0;

setFPMode();

for (i = 0; i < iterations; ++i)
{
XferCRC xfer;
xfer.open("SimMathDet");
appendSimulationMathCrc_Deterministic(xfer);
xfer.close();
if (i == 0) crcDet = xfer.getCRC();
Comment thread
Okladnoj marked this conversation as resolved.
}
_fpreset();
clock_t endDet = clock();
double timeDetMs = (double)(endDet - startDet) / CLOCKS_PER_SEC * 1000.0;

clock_t startNat = clock();
UnsignedInt crcNat = 0;

setFPMode();

for (i = 0; i < iterations; ++i)
{
XferCRC xfer;
xfer.open("SimMathNat");
appendSimulationMathCrc_Native(xfer);
xfer.close();
if (i == 0) crcNat = xfer.getCRC();
Comment thread
Okladnoj marked this conversation as resolved.
}
_fpreset();
clock_t endNat = clock();
double timeNatMs = (double)(endNat - startNat) / CLOCKS_PER_SEC * 1000.0;

printf("\n================ MATH BENCHMARK (%d iterations) ================\n", iterations);
printf("Deterministic (WWMath): CRC = %08X, Time = %.2f ms\n", crcDet, timeDetMs);
printf("Native (system math): CRC = %08X, Time = %.2f ms\n", crcNat, timeNatMs);
printf("===========================================================\n\n");
}
4 changes: 2 additions & 2 deletions Core/GameEngine/Source/Common/INI/INI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1789,15 +1789,15 @@ void INI::parseDurationReal( INI *ini, void * /*instance*/, void *store, const v
void INI::parseDurationUnsignedInt( INI *ini, void * /*instance*/, void *store, const void* /*userData*/ )
{
UnsignedInt val = scanUnsignedInt(ini->getNextToken());
*(UnsignedInt *)store = (UnsignedInt)ceilf(ConvertDurationFromMsecsToFrames((Real)val));
*(UnsignedInt *)store = (UnsignedInt)WWMath::Ceilf_Origin(ConvertDurationFromMsecsToFrames((Real)val));
}

// ------------------------------------------------------------------------------------------------
// parse a duration in msec and convert to duration in integral number of frames, (unsignedshort) rounding UP
void INI::parseDurationUnsignedShort( INI *ini, void * /*instance*/, void *store, const void* /*userData*/ )
{
UnsignedInt val = scanUnsignedInt(ini->getNextToken());
*(UnsignedShort *)store = (UnsignedShort)ceilf(ConvertDurationFromMsecsToFrames((Real)val));
*(UnsignedShort *)store = (UnsignedShort)WWMath::Ceilf_Origin(ConvertDurationFromMsecsToFrames((Real)val));
}

//-------------------------------------------------------------------------------------------------
Expand Down
32 changes: 16 additions & 16 deletions Core/GameEngine/Source/GameLogic/AI/AIPathfind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -727,9 +727,9 @@ inline Bool isReallyClose(const Coord3D& a, const Coord3D& b)
{
const Real CLOSE_ENOUGH = 0.1f;
return
fabs(a.x-b.x) <= CLOSE_ENOUGH &&
fabs(a.y-b.y) <= CLOSE_ENOUGH &&
fabs(a.z-b.z) <= CLOSE_ENOUGH;
WWMath::FAbs_Origin(a.x-b.x) <= CLOSE_ENOUGH &&
WWMath::FAbs_Origin(a.y-b.y) <= CLOSE_ENOUGH &&
WWMath::FAbs_Origin(a.z-b.z) <= CLOSE_ENOUGH;
}

/**
Expand Down Expand Up @@ -921,7 +921,7 @@ void Path::computePointOnPath(
// compute distance of point from this path segment
Real toDistSqr = sqr(toPos.x) + sqr(toPos.y);
Real offsetDistSq = toDistSqr - sqr(alongPathDist);
Real offsetDist = (offsetDistSq <= 0.0) ? 0.0 : sqrt(offsetDistSq);
Real offsetDist = (offsetDistSq <= 0.0) ? 0.0 : WWMath::Sqrt_Origin(offsetDistSq);

// If we are basically on the path, return the next path node as the movement goal.
// However, the farther off the path we get, the movement goal becomes closer to our
Expand Down Expand Up @@ -1011,8 +1011,8 @@ void Path::computePointOnPath(
out.posOnPath.x = closeNodePos->x + alongPathDist * segmentDirNorm.x;
out.posOnPath.y = closeNodePos->y + alongPathDist * segmentDirNorm.y;
out.posOnPath.z = closeNodePos->z;
Real dx = fabs(pos.x - out.posOnPath.x);
Real dy = fabs(pos.y - out.posOnPath.y);
Real dx = WWMath::FAbs_Origin(pos.x - out.posOnPath.x);
Real dy = WWMath::FAbs_Origin(pos.y - out.posOnPath.y);
if (dx<1 && dy<1 && closeNode->getNextOptimized() && closeNode->getNextOptimized()->getNextOptimized()) {
out.posOnPath = *closeNode->getNextOptimized()->getNextOptimized()->getPosition();
}
Expand Down Expand Up @@ -2070,7 +2070,7 @@ UnsignedInt PathfindCell::costToGoal( PathfindCell *goal )
Int dy = m_info->m_pos.y - goal->getYIndex();
#define NO_REAL_DIST
#ifdef REAL_DIST
Int cost = COST_ORTHOGONAL*sqrt(dx*dx + dy*dy);
Int cost = COST_ORTHOGONAL*WWMath::Sqrt_Origin(dx*dx + dy*dy);
#else
if (dx<0) dx = -dx;
if (dy<0) dy = -dy;
Expand All @@ -2096,7 +2096,7 @@ UnsignedInt PathfindCell::costToHierGoal( PathfindCell *goal )
}
Int dx = m_info->m_pos.x - goal->getXIndex();
Int dy = m_info->m_pos.y - goal->getYIndex();
Int cost = REAL_TO_INT_FLOOR(COST_ORTHOGONAL*sqrt(dx*dx + dy*dy) + 0.5f);
Int cost = REAL_TO_INT_FLOOR(COST_ORTHOGONAL*WWMath::Sqrt_Origin(dx*dx + dy*dy) + 0.5f);
return cost;
}

Expand Down Expand Up @@ -3963,8 +3963,8 @@ Bool PathfindLayer::isPointOnWall(ObjectID *wallPieces, Int numPieces, const Coo
Real pty = pt->y - obj->getPosition()->y;

// inverse-rotate it to the right coord system
Real ptx_new = (Real)fabs(ptx*c - pty*s);
Real pty_new = (Real)fabs(ptx*s + pty*c);
Real ptx_new = (Real)WWMath::FAbs_Origin(ptx*c - pty*s);
Real pty_new = (Real)WWMath::FAbs_Origin(ptx*s + pty*c);

if (ptx_new <= major && pty_new <= minor)
{
Expand Down Expand Up @@ -6415,7 +6415,7 @@ Int Pathfinder::examineNeighboringCells(PathfindCell *parentCell, PathfindCell *
toPos.y = newCellCoord.y * PATHFIND_CELL_SIZE_F ;
toPos.z = TheTerrainLogic->getGroundHeight(toPos.x , toPos.y);

if ( fabs(fromPos.z - toPos.z)<PATHFIND_CELL_SIZE_F) {
if ( WWMath::FAbs_Origin(fromPos.z - toPos.z)<PATHFIND_CELL_SIZE_F) {
newCostSoFar += 7*COST_DIAGONAL;
}
} else if (newCell->getPinched()) {
Expand All @@ -6440,7 +6440,7 @@ Int Pathfinder::examineNeighboringCells(PathfindCell *parentCell, PathfindCell *
} else {
dx = newCellCoord.x - goalCell->getXIndex();
dy = newCellCoord.y - goalCell->getYIndex();
costRemaining = COST_ORTHOGONAL*sqrt(dx*dx + dy*dy);
costRemaining = COST_ORTHOGONAL*WWMath::Sqrt_Origin(dx*dx + dy*dy);
costRemaining -= attackDistance/2;
if (costRemaining<0)
costRemaining=0;
Expand Down Expand Up @@ -6764,7 +6764,7 @@ Path *Pathfinder::internalFindPath( Object *obj, const LocomotorSet& locomotorSe
dx = from->x - to->x;
dy = from->y - to->y;

Int count = sqrt(dx*dx+dy*dy)/(PATHFIND_CELL_SIZE_F/2);
Int count = WWMath::Sqrt_Origin(dx*dx+dy*dy)/(PATHFIND_CELL_SIZE_F/2);
if (count<2) count = 2;
Int i;
color.green = 0;
Expand Down Expand Up @@ -7455,7 +7455,7 @@ Path *Pathfinder::findGroundPath( const Coord3D *from,
dx = from->x - to->x;
dy = from->y - to->y;

Int count = sqrt(dx*dx+dy*dy)/(PATHFIND_CELL_SIZE_F/2);
Int count = WWMath::Sqrt_Origin(dx*dx+dy*dy)/(PATHFIND_CELL_SIZE_F/2);
if (count<2) count = 2;
Int i;
color.green = 0;
Expand Down Expand Up @@ -8159,7 +8159,7 @@ Path *Pathfinder::internal_findHierarchicalPath( Bool isHuman, const LocomotorSu
dx = from->x - to->x;
dy = from->y - to->y;

Int count = sqrt(dx*dx+dy*dy)/(PATHFIND_CELL_SIZE_F/2);
Int count = WWMath::Sqrt_Origin(dx*dx+dy*dy)/(PATHFIND_CELL_SIZE_F/2);
if (count<2) count = 2;
Int i;
color.green = 0;
Expand Down Expand Up @@ -11216,7 +11216,7 @@ Path *Pathfinder::findSafePath( const Object *obj, const LocomotorSet& locomotor
farthestDistanceSqr = distSqr;
if (cellCount > MAX_CELLS) {
#ifdef INTENSE_DEBUG
DEBUG_LOG(("Took intermediate path, dist %f, goal dist %f", sqrt(farthestDistanceSqr), repulsorRadius));
DEBUG_LOG(("Took intermediate path, dist %f, goal dist %f", WWMath::Sqrt_Origin(farthestDistanceSqr), repulsorRadius));
#endif
ok = true; // Already a big search, just take this one.
}
Expand Down
10 changes: 5 additions & 5 deletions Core/Libraries/Include/Lib/BaseType.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ struct Coord2D
return x == value && y == value;
}

Real length() const { return (Real)sqrt( x*x + y*y ); }
Real length() const { return (Real)Sqrt( x*x + y*y ); }
Real lengthSqr() const { return x*x + y*y; }

void normalize()
Expand All @@ -273,7 +273,7 @@ inline Real Coord2D::toAngle() const
vector.x = x;
vector.y = y;

Real dist = (Real)sqrt(vector.x * vector.x + vector.y * vector.y);
Real dist = (Real)Sqrt(vector.x * vector.x + vector.y * vector.y);

// normalize
if (dist == 0.0f)
Expand Down Expand Up @@ -340,7 +340,7 @@ struct ICoord2D
return x == value && y == value;
}

Int length() const { return (Int)sqrt( (double)(x*x + y*y) ); }
Int length() const { return (Int)Sqrt( (double)(x*x + y*y) ); }
};

struct Region2D
Expand Down Expand Up @@ -388,7 +388,7 @@ struct Coord3D
{
Real x, y, z;

Real length() const { return (Real)sqrt( x*x + y*y + z*z ); }
Real length() const { return (Real)Sqrt( x*x + y*y + z*z ); }
Comment thread
Okladnoj marked this conversation as resolved.
Real lengthSqr() const { return ( x*x + y*y + z*z ); }

void normalize()
Expand Down Expand Up @@ -476,7 +476,7 @@ struct ICoord3D
{
Int x, y, z;

Int length() const { return (Int)sqrt( (double)(x*x + y*y + z*z) ); }
Int length() const { return (Int)Sqrt( (double)(x*x + y*y + z*z) ); }

void zero()
{
Expand Down
1 change: 1 addition & 0 deletions Core/Libraries/Include/Lib/trig.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ Real Cos(Real);
Real Tan(Real);
Real ACos(Real);
Real ASin(Real x);
double Sqrt(double x);
6 changes: 6 additions & 0 deletions Core/Libraries/Source/WWVegas/WWMath/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -91,5 +91,11 @@ target_link_libraries(core_wwmath PRIVATE
core_wwsaveload
)

if (NOT IS_VS6_BUILD)
target_link_libraries(core_wwmath PUBLIC
gamemath
)
endif()

# @todo Test its impact and see what to do with the legacy functions.
#add_compile_definitions(core_wwmath PUBLIC ALLOW_TEMPORARIES) # Enables legacy math with "temporaries"
Loading