Skip to content

Commit

Permalink
Merge pull request #2071 from gemrb/float_t
Browse files Browse the repository at this point in the history
optimize some of our math
  • Loading branch information
lynxlynxlynx committed Mar 26, 2024
2 parents afe0fd0 + d03760a commit 975b0d0
Show file tree
Hide file tree
Showing 30 changed files with 132 additions and 132 deletions.
4 changes: 2 additions & 2 deletions gemrb/core/Bitmap.h
Expand Up @@ -97,12 +97,12 @@ class GEM_EXPORT Bitmap final
}

BitProxy operator[](int i) noexcept {
div_t res = div(i, 8);
div_t res = std::div(i, 8);
return BitProxy(data[res.quot], res.rem);
}

bool operator[](int i) const noexcept {
div_t res = div(i, 8);
div_t res = std::div(i, 8);
return data[res.quot] & (1 << res.rem);
}

Expand Down
24 changes: 12 additions & 12 deletions gemrb/core/Core.cpp
Expand Up @@ -71,7 +71,7 @@ unsigned int PersonalDistance(const Point &p, const Scriptable *b)
{
long x = p.x - b->Pos.x;
long y = p.y - b->Pos.y;
int ret = (int) std::hypot(x, y);
auto ret = std::hypot(x, y);
if (b->Type==ST_ACTOR) {
ret -= static_cast<const Actor*>(b)->CircleSize2Radius() * DistanceFactor;
}
Expand Down Expand Up @@ -119,7 +119,7 @@ unsigned int PersonalDistance(const Scriptable *a, const Scriptable *b)
{
long x = a->Pos.x - b->Pos.x;
long y = a->Pos.y - b->Pos.y;
int ret = (int) std::hypot(x, y);
auto ret = std::hypot(x, y);
if (a->Type==ST_ACTOR) {
ret -= static_cast<const Actor*>(a)->CircleSize2Radius() * DistanceFactor;
}
Expand All @@ -145,8 +145,8 @@ unsigned int SquaredPersonalDistance(const Scriptable *a, const Scriptable *b)
return (unsigned int) ret;
}

unsigned int PersonalLineDistance(const Point &v, const Point &w, const Scriptable *s, double *proj) {
double t;
unsigned int PersonalLineDistance(const Point& v, const Point& w, const Scriptable* s, float_t* proj) {
float_t t;
Point p;

int len = SquaredDistance(w, v);
Expand All @@ -156,7 +156,7 @@ unsigned int PersonalLineDistance(const Point &v, const Point &w, const Scriptab
p = v;
} else {
// find the projection of Pos onto the line
t = ((s->Pos.x - v.x) * (w.x - v.x) + (s->Pos.y - v.y) * (w.y - v.y)) / (double) len;
t = ((s->Pos.x - v.x) * (w.x - v.x) + (s->Pos.y - v.y) * (w.y - v.y)) / (float_t) len;
if (t < 0.0) {
// projection beyond the v end of the line
p = v;
Expand Down Expand Up @@ -205,11 +205,11 @@ unsigned int PersonalLineDistance(const Point &v, const Point &w, const Scriptab
// Potential optimisation through precomputing:
// rounding the angle into 5° intervals [0-90] gives these values per foot:
// 16 16 16 16 15 15 15 14 14 14 13 13 13 12 12 12 12 12 12
double Feet2Pixels(int feet, double angle)
float_t Feet2Pixels(int feet, float_t angle)
{
double sin2 = pow(sin(angle) / 12, 2);
double cos2 = pow(cos(angle) / 16, 2);
double r = sqrt(1 / (cos2 + sin2));
float_t sin2 = std::pow(std::sin(angle) / 12, 2);
float_t cos2 = std::pow(std::cos(angle) / 16, 2);
float_t r = std::sqrt(1 / (cos2 + sin2));
return r * feet;
}

Expand All @@ -227,19 +227,19 @@ bool WithinAudibleRange(const Actor *actor, const Point &dest)

bool WithinRange(const Scriptable *actor, const Point &dest, int distance)
{
double angle = AngleFromPoints(actor->Pos, dest);
float_t angle = AngleFromPoints(actor->Pos, dest);
return Distance(dest, actor) <= Feet2Pixels(distance, angle);
}

bool WithinPersonalRange(const Scriptable *actor, const Point &dest, int distance)
{
double angle = AngleFromPoints(actor->Pos, dest);
float_t angle = AngleFromPoints(actor->Pos, dest);
return PersonalDistance(dest, actor) <= Feet2Pixels(distance, angle);
}

bool WithinPersonalRange(const Scriptable* scr1, const Scriptable* scr2, int distance)
{
double angle = AngleFromPoints(scr1->Pos, scr2->Pos);
float_t angle = AngleFromPoints(scr1->Pos, scr2->Pos);
return PersonalDistance(scr2, scr1) <= Feet2Pixels(distance, angle);
}

Expand Down
4 changes: 2 additions & 2 deletions gemrb/core/GUI/EventMgr.cpp
Expand Up @@ -412,10 +412,10 @@ Event EventMgr::CreateTouchEvent(const TouchEvent::Finger fingers[], int numFing
for (int i = 0; i < numFingers; ++i) {
e.touch.x += fingers[i].x;
e.touch.y += fingers[i].y;
if (abs(fingers[i].deltaX) > abs(e.touch.deltaX)) {
if (std::abs(fingers[i].deltaX) > std::abs(e.touch.deltaX)) {
e.touch.deltaX = fingers[i].deltaX;
}
if (abs(fingers[i].deltaY) > abs(e.touch.deltaY)) {
if (std::abs(fingers[i].deltaY) > std::abs(e.touch.deltaY)) {
e.touch.deltaY = fingers[i].deltaY;
}
e.touch.fingers[i] = fingers[i];
Expand Down
12 changes: 6 additions & 6 deletions gemrb/core/GUI/GameControl.cpp
Expand Up @@ -148,7 +148,7 @@ Point GameControl::GetFormationOffset(size_t formation, uint8_t pos) const
return Formations::GetFormation(formation)[pos];
}

Point GameControl::GetFormationPoint(const Point& origin, size_t pos, double angle, const std::vector<Point>& exclude) const
Point GameControl::GetFormationPoint(const Point& origin, size_t pos, float_t angle, const std::vector<Point>& exclude) const
{
Point vec;

Expand Down Expand Up @@ -184,7 +184,7 @@ Point GameControl::GetFormationPoint(const Point& origin, size_t pos, double ang
Point dest = vec + origin;
int step = 0;
constexpr int maxStep = 4;
double stepAngle = 0.0;
float_t stepAngle = 0.0;
const Point& start = vec;

auto NextDest = [&]() {
Expand Down Expand Up @@ -244,7 +244,7 @@ Point GameControl::GetFormationPoint(const Point& origin, size_t pos, double ang
}

GameControl::FormationPoints GameControl::GetFormationPoints(const Point& origin, const std::vector<Actor*>& actors,
double angle) const
float_t angle) const
{
FormationPoints formation;
for (size_t i = 0; i < actors.size(); ++i) {
Expand All @@ -253,7 +253,7 @@ GameControl::FormationPoints GameControl::GetFormationPoints(const Point& origin
return formation;
}

void GameControl::DrawFormation(const std::vector<Actor*>& actors, const Point& formationPoint, double angle) const
void GameControl::DrawFormation(const std::vector<Actor*>& actors, const Point& formationPoint, float_t angle) const
{
std::vector<Point> formationPoints = GetFormationPoints(formationPoint, actors, angle);
for (size_t i = 0; i < actors.size(); ++i) {
Expand Down Expand Up @@ -612,7 +612,7 @@ void GameControl::DrawSelf(const Region& screen, const Region& /*clip*/)
const Point& gameMousePos = GameMousePos();
// draw reticles
if (isFormationRotation) {
double angle = AngleFromPoints(gameMousePos, gameClickPoint);
float_t angle = AngleFromPoints(gameMousePos, gameClickPoint);
DrawFormation(game->selected, gameClickPoint, angle);
} else {
for (const auto& selectee : game->selected) {
Expand Down Expand Up @@ -2301,7 +2301,7 @@ void GameControl::CommandSelectedMovement(const Point& p, bool formation, bool a
if (party.empty())
return;

double angle = isFormationRotation ? AngleFromPoints(GameMousePos(), p) : formationBaseAngle;
float_t angle = isFormationRotation ? AngleFromPoints(GameMousePos(), p) : formationBaseAngle;
bool doWorldMap = ShouldTriggerWorldMap(party[0]);

std::vector<Point> formationPoints = GetFormationPoints(p, party, angle);
Expand Down
8 changes: 4 additions & 4 deletions gemrb/core/GUI/GameControl.h
Expand Up @@ -67,7 +67,7 @@ class GEM_EXPORT GameControl : public View {
Point screenMousePos;
Point vpOrigin;
bool updateVPTimer = true;
double formationBaseAngle = 0.0;
float_t formationBaseAngle = 0.0;

// currently selected targeting type, such as talk, attack, cast, ...
// private to enforce proper cursor changes
Expand Down Expand Up @@ -111,10 +111,10 @@ class GEM_EXPORT GameControl : public View {
Region SelectionRect() const;
/** Draws an arrow on the edge of the screen based on the point (points at offscreen actors) */
void DrawArrowMarker(const Point& p, const Color& color) const;
void DrawFormation(const std::vector<Actor*>& actors, const Point& formationPoint, double angle) const;
void DrawFormation(const std::vector<Actor*>& actors, const Point& formationPoint, float_t angle) const;

Point GetFormationPoint(const Point& origin, size_t pos, double angle, const FormationPoints& exclude = FormationPoints()) const;
FormationPoints GetFormationPoints(const Point& origin, const std::vector<Actor*>& actors, double angle) const;
Point GetFormationPoint(const Point& origin, size_t pos, float_t angle, const FormationPoints& exclude = FormationPoints()) const;
FormationPoints GetFormationPoints(const Point& origin, const std::vector<Actor*>& actors, float_t angle) const;

void Scroll(const Point& amt);

Expand Down
2 changes: 1 addition & 1 deletion gemrb/core/GUI/TextSystem/Font.cpp
Expand Up @@ -88,7 +88,7 @@ bool Font::GlyphAtlasPage::AddGlyph(ieWord chr, const Glyph& g)
return false;
}

int glyphH = g.size.h + abs(g.pos.y);
int glyphH = g.size.h + std::abs(g.pos.y);
if (glyphH > SheetRegion.h) {
// must grow to accommodate this glyph
if (Sheet) {
Expand Down
4 changes: 2 additions & 2 deletions gemrb/core/GameScript/Actions.cpp
Expand Up @@ -6821,7 +6821,7 @@ void GameScript::UseItem(Scriptable* Sender, Action* parameters)
}
gamedata->FreeItem(itm, itemres, false);

double angle = AngleFromPoints(Sender->Pos, tar->Pos);
float_t angle = AngleFromPoints(Sender->Pos, tar->Pos);
unsigned int dist = GetItemDistance(itemres, header, angle);
if (PersonalDistance(Sender, tar) > dist) {
MoveNearerTo(Sender, tar, dist);
Expand Down Expand Up @@ -6871,7 +6871,7 @@ void GameScript::UseItemPoint(Scriptable* Sender, Action* parameters)
return;
}

double angle = AngleFromPoints(Sender->Pos, parameters->pointParameter);
float_t angle = AngleFromPoints(Sender->Pos, parameters->pointParameter);
unsigned int dist = GetItemDistance(itemres, header, angle);
if (PersonalDistance(parameters->pointParameter, Sender) > dist) {
MoveNearerTo(Sender, parameters->pointParameter, dist, 0);
Expand Down
8 changes: 4 additions & 4 deletions gemrb/core/GameScript/GSUtils.cpp
Expand Up @@ -1534,7 +1534,7 @@ void AttackCore(Scriptable *Sender, Scriptable *target, int flags)
}
}

double angle = AngleFromPoints(attacker->Pos, target->Pos);
float_t angle = AngleFromPoints(attacker->Pos, target->Pos);
if (attacker->GetCurrentArea() != target->GetCurrentArea() ||
!WithinPersonalRange(attacker, target, weaponRange) ||
!attacker->GetCurrentArea()->IsVisibleLOS(attacker->Pos, target->Pos) ||
Expand Down Expand Up @@ -2450,7 +2450,7 @@ unsigned int GetSpellDistance(const ResRef& spellRes, Scriptable* Sender, const
}

if (!target.IsZero()) {
double angle = AngleFromPoints(Sender->Pos, target);
float_t angle = AngleFromPoints(Sender->Pos, target);
return Feet2Pixels(dist, angle);
}

Expand All @@ -2460,7 +2460,7 @@ unsigned int GetSpellDistance(const ResRef& spellRes, Scriptable* Sender, const

/* returns an item's casting distance, it depends on the used header, and targeting mode too
the used header is explicitly given */
unsigned int GetItemDistance(const ResRef& itemres, int header, double angle)
unsigned int GetItemDistance(const ResRef& itemres, int header, float_t angle)
{
const Item* itm = gamedata->GetItem(itemres);
if (!itm) {
Expand Down Expand Up @@ -3065,7 +3065,7 @@ void RunAwayFromCore(Scriptable* Sender, const Action* parameters, int flags)
}

// estimate max distance with time and actor speed
double speed = actor->GetSpeed();
float_t speed = actor->GetSpeed();
int maxDistance = parameters->int0Parameter;
if (speed) {
maxDistance = static_cast<int>(maxDistance * gamedata->GetStepTime() / speed);
Expand Down
2 changes: 1 addition & 1 deletion gemrb/core/GameScript/GSUtils.h
Expand Up @@ -137,7 +137,7 @@ GEM_EXPORT bool VariableExists(const Scriptable *Sender, const StringParam& VarN
Action* GenerateActionCore(const char *src, const char *str, unsigned short actionID);
Trigger *GenerateTriggerCore(const char *src, const char *str, int trIndex, int negate);
GEM_EXPORT unsigned int GetSpellDistance(const ResRef& spellRes, Scriptable* Sender, const Point& target = Point());
unsigned int GetItemDistance(const ResRef& itemres, int header, double angle);
unsigned int GetItemDistance(const ResRef& itemres, int header, float_t angle);
void SetupWishCore(Scriptable *Sender, TableMgr::index_t column, int picks);
void AmbientActivateCore(const Scriptable *Sender, const Action *parameters, bool flag);
void SpellCore(Scriptable *Sender, Action *parameters, int flags);
Expand Down
14 changes: 7 additions & 7 deletions gemrb/core/GameScript/Triggers.cpp
Expand Up @@ -1564,17 +1564,17 @@ int GameScript::InLine(Scriptable *Sender, const Trigger *parameters)
return 0;
}

double fdm1 = SquaredDistance(Sender, scr1);
double fdm2 = SquaredDistance(Sender, scr2);
double fd12 = SquaredDistance(scr1, scr2);
double dm1 = sqrt(fdm1);
double dm2 = sqrt(fdm2);
float_t fdm1 = SquaredDistance(Sender, scr1);
float_t fdm2 = SquaredDistance(Sender, scr2);
float_t fd12 = SquaredDistance(scr1, scr2);
float_t dm1 = std::sqrt(fdm1);
float_t dm2 = std::sqrt(fdm2);

if (fdm1>fdm2 || fd12>fdm2) {
return 0;
}
double angle = acos(( fdm2 + fdm1 - fd12 ) / (2*dm1*dm2));
if (angle*180.0*M_PI<30.0) return 1;
float_t angle = std::acos((fdm2 + fdm1 - fd12) / (2 * dm1 * dm2));
if (angle * (180.0 / M_PI) < 30.0) return 1;
return 0;
}

Expand Down
26 changes: 13 additions & 13 deletions gemrb/core/Geometry.cpp
Expand Up @@ -29,39 +29,39 @@ namespace GemRB {
// with a maximum error of 0.1620 degrees
// rcor's rational approximation that can be arbitrarily
// improved if we ever want greater precision
static float pseudoAtan2(float y, float x)
static float_t pseudoAtan2(float_t y, float_t x)
{
static const uint32_t signMask = 0x80000000;
static const float b = 0.596227F;
static const float_t b = 0.596227F;

// Extract the sign bits
uint32_t xS = signMask & (uint32_t&) x;
uint32_t yS = signMask & (uint32_t&) y;

// Determine the quadrant offset
float q = (float) ((~xS & yS) >> 29 | xS >> 30);
float_t q = float_t((~xS & yS) >> 29 | xS >> 30);

// Calculate the arctangent in the first quadrant
float bxy = std::fabs(b * x * y);
float num = bxy + y * y;
float atan1q = num / (x * x + bxy + num);
float_t bxy = std::fabs(b * x * y);
float_t num = bxy + y * y;
float_t atan1q = num / (x * x + bxy + num);

// Translate it to the proper quadrant
uint32_t uatan2q = (xS ^ yS) | (uint32_t&) atan1q;
return (q + (float&) uatan2q) * M_PI_2;
return (q + (float_t&) uatan2q) * M_PI_2;
}

double AngleFromPoints(float y, float x)
float_t AngleFromPoints(float_t y, float_t x)
{
return pseudoAtan2(y, x);
}

double AngleFromPoints(const Point& p1, const Point& p2, bool exact)
float_t AngleFromPoints(const Point& p1, const Point& p2, bool exact)
{
double xdiff = p1.x - p2.x;
double ydiff = p1.y - p2.y;
float_t xdiff = p1.x - p2.x;
float_t ydiff = p1.y - p2.y;

double angle;
float_t angle;
if (exact) {
angle = std::atan2(ydiff, xdiff);
} else {
Expand All @@ -70,7 +70,7 @@ double AngleFromPoints(const Point& p1, const Point& p2, bool exact)
return angle;
}

Point RotatePoint(const Point& p, double angle)
Point RotatePoint(const Point& p, float_t angle)
{
int newx = static_cast<int>(p.x * std::cos(angle) - p.y * std::sin(angle));
int newy = static_cast<int>(p.x * std::sin(angle) + p.y * std::cos(angle));
Expand Down
6 changes: 3 additions & 3 deletions gemrb/core/Geometry.h
Expand Up @@ -29,9 +29,9 @@

namespace GemRB {

GEM_EXPORT double AngleFromPoints(const Point& p1, const Point& p2, bool exact = false);
GEM_EXPORT double AngleFromPoints(float y, float x);
GEM_EXPORT Point RotatePoint(const Point& p, double angle);
GEM_EXPORT float_t AngleFromPoints(const Point& p1, const Point& p2, bool exact = false);
GEM_EXPORT float_t AngleFromPoints(float_t y, float_t x);
GEM_EXPORT Point RotatePoint(const Point& p, float_t angle);
GEM_EXPORT unsigned int Distance(const Point &pos, const Point &pos2);
GEM_EXPORT unsigned int SquaredDistance(const Point &pos, const Point &pos2);

Expand Down
6 changes: 3 additions & 3 deletions gemrb/core/Map.cpp
Expand Up @@ -2533,10 +2533,10 @@ PathMapFlags Map::GetBlockedInLine(const Point &s, const Point &d, bool stopOnIm
PathMapFlags ret = PathMapFlags::IMPASSABLE;
Point p = s;
const SearchmapPoint sms = ConvertCoordToTile(s);
double factor = caller && caller->GetSpeed() ? double(gamedata->GetStepTime()) / double(caller->GetSpeed()) : 1;
float_t factor = caller && caller->GetSpeed() ? float_t(gamedata->GetStepTime()) / float_t(caller->GetSpeed()) : 1;
while (p != d) {
double dx = d.x - p.x;
double dy = d.y - p.y;
float_t dx = d.x - p.x;
float_t dy = d.y - p.y;
NormalizeDeltas(dx, dy, factor);
p.x += dx;
p.y += dy;
Expand Down
2 changes: 1 addition & 1 deletion gemrb/core/Map.h
Expand Up @@ -430,7 +430,7 @@ class GEM_EXPORT Map : public Scriptable {
public:
Map(TileMap *tm, TileProps tileProps, Holder<Sprite2D> sm);
~Map(void) override;
static void NormalizeDeltas(double &dx, double &dy, double factor = 1);
static void NormalizeDeltas(float_t &dx, float_t &dy, float_t factor = 1);
static Point ConvertCoordToTile(const Point&);
static Point ConvertCoordFromTile(const Point&);

Expand Down
6 changes: 3 additions & 3 deletions gemrb/core/Orientation.h
Expand Up @@ -116,11 +116,11 @@ inline orient_t GetOrient(const Point& from, const Point& to)
if (!deltaX) return deltaY >= 0 ? S : N;

// reverse Y to match our game coordinate system
float angle = AngleFromPoints(-deltaY, deltaX);
float_t angle = AngleFromPoints(-deltaY, deltaX);

// calculate which segment the angle falls into and which orientation that represents
constexpr float M_PI_8 = M_PI / 8;
float segment = std::fmod(angle + M_PI_8 / 2 + 2 * M_PI, 2.0F * M_PI);
constexpr float_t M_PI_8 = M_PI / 8;
float_t segment = std::fmod(angle + M_PI_8 / 2 + 2 * M_PI, 2.0F * M_PI);
return PrevOrientation(E, int(segment / M_PI_8));
}

Expand Down
2 changes: 1 addition & 1 deletion gemrb/core/Palette.cpp
Expand Up @@ -31,7 +31,7 @@ Palette::Palette(const Color &color, const Color &back) noexcept
{
col[0] = Color(0, 0xff, 0, 0);
for (int i = 1; i < 256; i++) {
float p = i / 255.0f;
float_t p = i / 255.0f;
col[i].r = std::min<int>(back.r * (1 - p) + color.r * p, 255);
col[i].g = std::min<int>(back.g * (1 - p) + color.g * p, 255);
col[i].b = std::min<int>(back.b * (1 - p) + color.b * p, 255);
Expand Down

0 comments on commit 975b0d0

Please sign in to comment.