159 lines
4.3 KiB
C

/*
** Command & Conquer Generals(tm)
** Copyright 2025 Electronic Arts 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/>.
*/
////////////////////////////////////////////////////////////////////////////////
// //
// (c) 2001-2003 Electronic Arts Inc. //
// //
////////////////////////////////////////////////////////////////////////////////
// FILE: QuickTrig.h ////////////////////////////////////////////////////////////////////////////////
// Author: Mark Lorenzen (adapted by srj)
// Desc: fast trig
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __QUICKTRIG_H_
#define __QUICKTRIG_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
extern Real TheQuickSinTable[];
extern Real TheQuickTanTable[];
// yes, Real. No, really.
extern Real TheQuickSinTableCount;
extern Real TheQuickTanTableCount;
//-----------------------------------------------------------------------------
#define QUARTER_CIRCLE (PI/2)
//-----------------------------------------------------------------------------
// quick magnitude estimation, without the square root
// NOTE, this is a very rough estimate, and may be off by 10% or more, so
// use it only when you don't need accuracy
//-----------------------------------------------------------------------------
inline Real QMag(Real x, Real y, Real z)
{
Real sTempV;
Real sMaxV = fabs(x);
Real sMedV = fabs(y);
Real sMinV = fabs(z);
if (sMaxV < sMedV)
{
sTempV = sMaxV;
sMaxV = sMedV;
sMedV = sTempV;
}
if (sMaxV < sMinV)
{
sTempV = sMaxV;
sMaxV = sMinV;
sMinV = sTempV;
}
sMedV += sMinV;
sMaxV += (sMedV*0.25f);
return sMaxV;
}
//-----------------------------------------------------------------------------
// table based trig functions
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
inline Real QSin(Real a)
{
register Real angle = a;
register long sgn = 1;
if (angle < 0) // DO POSITIVE MATH AND PRESERVE SIGN
{
sgn = -1;
angle = -angle;
}
while ( angle > (PI)) // MODULATE ANGLE INTO RANGE OF PI
{
angle -= PI;
sgn = -sgn;
}
if (angle > PI/2)
{
angle = PI - angle; // FLIP
}
register int index = REAL_TO_INT((angle/QUARTER_CIRCLE) * TheQuickTanTableCount);
register Real x = TheQuickSinTable[index];
return x * sgn;
/*
Real remainder = node - index;
Real next = TheQuickSinTable[index + 1];
Real range = next - x;
Real scalar = remainder / SIN_TABLE_BRACKET;
Real finetune = scalar * range;
x += finetune;
*/
}
//-----------------------------------------------------------------------------
inline Real QCos(Real angle)
{
return QSin((QUARTER_CIRCLE) - angle);
}
//-----------------------------------------------------------------------------
inline Real QTan(Real angle)
{
return TheQuickTanTable[REAL_TO_INT(angle * TheQuickSinTableCount)];
}
//-----------------------------------------------------------------------------
inline Real QCsc(Real angle)
{
return 1.0f / QSin(angle);
}
//-----------------------------------------------------------------------------
inline Real QSec(Real angle)
{
return 1.0f / QCos(angle);
}
//-----------------------------------------------------------------------------
inline Real QCot(Real angle)
{
return 1.0f / QTan(angle);
}
#endif