TombEngine/TR5Main/Specific/trmath.cpp

179 lines
4.1 KiB
C++
Raw Normal View History

#include "framework.h"
2021-09-08 18:31:35 +03:00
#include "Specific\trmath.h"
2020-04-24 19:15:05 +02:00
#include <cmath>
2021-09-08 18:31:35 +03:00
#include "Specific\prng.h"
2020-10-24 01:05:59 -03:00
2021-08-30 18:03:21 +03:00
using namespace TEN::Math::Random;
2020-04-24 19:15:05 +02:00
2020-04-28 12:24:10 -03:00
short ANGLE(float angle)
{
2020-05-27 20:08:19 +02:00
return angle * 65536.0f / 360.0f;
2019-12-15 16:19:01 +01:00
}
short FROM_DEGREES(float angle)
{
return angle * 65536.0f / 360.0f;
}
short FROM_RAD(float angle)
{
return angle / RADIAN * 65536.0f / 360.0f;
}
float TO_DEGREES(short angle)
2019-12-15 16:19:01 +01:00
{
return lround(angle * 360.0f / 65536.0f);
}
float TO_RAD(short angle)
2020-04-28 12:24:10 -03:00
{
2020-05-27 20:08:19 +02:00
return angle * 360.0f / 65536.0f * RADIAN;
2020-04-28 12:24:10 -03:00
}
2020-05-27 19:37:01 +02:00
const float lerp(float v0, float v1, float t)
{
return (1 - t) * v0 + t * v1;
}
2020-04-24 19:15:05 +02:00
2020-08-16 16:01:24 +02:00
const Vector3 getRandomVector()
{
2021-09-17 16:07:53 +03:00
Vector3 v = {GenerateFloat(-1,1),GenerateFloat(-1,1),GenerateFloat(-1,1)};
2020-08-16 16:01:24 +02:00
v.Normalize();
return v;
}
const Vector3 getRandomVectorInCone(const Vector3& direction, const float angleDegrees)
{
2021-09-17 16:07:53 +03:00
float x = GenerateFloat(-angleDegrees, angleDegrees) * RADIAN;
float y = GenerateFloat(-angleDegrees, angleDegrees) * RADIAN;
float z = GenerateFloat(-angleDegrees, angleDegrees) * RADIAN;
2020-08-16 16:01:24 +02:00
Matrix m = Matrix::CreateRotationX(x)* Matrix::CreateRotationY(y) * Matrix::CreateRotationZ(z);
Vector3 result = direction.TransformNormal(direction, m);
result.Normalize();
return result;
}
2020-10-05 22:24:57 -03:00
float phd_sin(short a)
2020-04-24 19:15:05 +02:00
{
2020-10-05 22:24:57 -03:00
return sin(TO_RAD(a));
2020-04-24 19:15:05 +02:00
}
2020-10-05 22:24:57 -03:00
float phd_cos(short a)
2020-04-24 19:15:05 +02:00
{
2020-10-05 22:24:57 -03:00
return cos(TO_RAD(a));
2020-04-24 19:15:05 +02:00
}
int mGetAngle(int x1, int y1, int x2, int y2)
{
return (65536 - phd_atan(x2 - x1, y2 - y1)) % 65536;
2020-04-24 19:15:05 +02:00
}
2020-04-25 16:23:53 +02:00
int phd_atan(int x, int y)
2020-04-24 19:15:05 +02:00
{
return FROM_RAD(atan2(y, x));
2020-04-25 16:23:53 +02:00
}
void phd_GetVectorAngles(int x, int y, int z, short* angles)
{
const auto angle = atan2(x, z);
2020-04-25 16:23:53 +02:00
auto vector = Vector3(x, y, z);
const auto matrix = Matrix::CreateRotationY(-angle);
Vector3::Transform(vector, matrix, vector);
2020-04-25 16:23:53 +02:00
angles[0] = FROM_RAD(angle);
angles[1] = FROM_RAD(-atan2(y, vector.z));
2020-04-25 16:23:53 +02:00
}
2020-07-25 18:02:35 +02:00
void phd_RotBoundingBoxNoPersp(PHD_3DPOS* pos, BOUNDING_BOX* bounds, BOUNDING_BOX* tbounds)
2020-04-25 16:23:53 +02:00
{
Matrix world = Matrix::CreateFromYawPitchRoll(
TO_RAD(pos->yRot),
TO_RAD(pos->xRot),
TO_RAD(pos->zRot)
);
2020-07-25 18:02:35 +02:00
Vector3 bMin = Vector3(bounds->X1, bounds->Y1, bounds->Z1);
Vector3 bMax = Vector3(bounds->X2, bounds->Y2, bounds->Z2);
2020-04-25 16:23:53 +02:00
bMin = Vector3::Transform(bMin, world);
bMax = Vector3::Transform(bMax, world);
2020-07-25 18:02:35 +02:00
tbounds->X1 = bMin.x;
tbounds->X2 = bMax.x;
tbounds->Y1 = bMin.y;
tbounds->Y2 = bMax.y;
tbounds->Z1 = bMin.z;
tbounds->Z2 = bMax.z;
}
2021-09-15 17:40:00 +03:00
void InterpolateAngle(short angle, short* rotation, short* outAngle, int shift)
{
int deltaAngle = angle - *rotation;
if (deltaAngle < -32768)
deltaAngle += 65536;
else if (deltaAngle > 32768)
deltaAngle -= 65536;
if (outAngle)
*outAngle = static_cast<short>(deltaAngle);
*rotation += static_cast<short>(deltaAngle >> shift);
}
void GetMatrixFromTrAngle(Matrix* matrix, short* frameptr, int index)
{
short* ptr = &frameptr[0];
ptr += 9;
for (int i = 0; i < index; i++)
{
ptr += ((*ptr & 0xc000) == 0 ? 2 : 1);
}
int rot0 = *ptr++;
int frameMode = (rot0 & 0xc000);
int rot1;
int rotX;
int rotY;
int rotZ;
switch (frameMode)
{
case 0:
rot1 = *ptr++;
rotX = ((rot0 & 0x3ff0) >> 4);
rotY = (((rot1 & 0xfc00) >> 10) | ((rot0 & 0xf) << 6) & 0x3ff);
rotZ = ((rot1) & 0x3ff);
*matrix = Matrix::CreateFromYawPitchRoll(rotY * (360.0f / 1024.0f) * RADIAN,
rotX * (360.0f / 1024.0f) * RADIAN,
rotZ * (360.0f / 1024.0f) * RADIAN);
break;
case 0x4000:
*matrix = Matrix::CreateRotationX((rot0 & 0xfff) * (360.0f / 4096.0f) * RADIAN);
break;
case 0x8000:
*matrix = Matrix::CreateRotationY((rot0 & 0xfff) * (360.0f / 4096.0f) * RADIAN);
break;
case 0xc000:
*matrix = Matrix::CreateRotationZ((rot0 & 0xfff) * (360.0f / 4096.0f) * RADIAN);
break;
}
}
BoundingOrientedBox TO_DX_BBOX(PHD_3DPOS pos, BOUNDING_BOX* box)
{
Vector3 boxCentre = Vector3((box->X2 + box->X1) / 2.0f, (box->Y2 + box->Y1) / 2.0f, (box->Z2 + box->Z1) / 2.0f);
Vector3 boxExtent = Vector3((box->X2 - box->X1) / 2.0f, (box->Y2 - box->Y1) / 2.0f, (box->Z2 - box->Z1) / 2.0f);
Quaternion rotation = Quaternion::CreateFromYawPitchRoll(TO_RAD(pos.yRot), TO_RAD(pos.xRot), TO_RAD(pos.zRot));
BoundingOrientedBox result;
BoundingOrientedBox(boxCentre, boxExtent, Vector4::UnitY).Transform(result, 1, rotation, Vector3(pos.xPos, pos.yPos, pos.zPos));
return result;
2020-04-24 19:15:05 +02:00
}