mirror of
https://github.com/scummvm/scummvm.git
synced 2025-04-02 10:52:32 -04:00
175 lines
4.2 KiB
C++
175 lines
4.2 KiB
C++
/* ScummVM - Graphic Adventure Engine
|
|
*
|
|
* ScummVM is the legal property of its developers, whose names
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
* file distributed with this source distribution.
|
|
*
|
|
* 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/>.
|
|
*
|
|
*/
|
|
|
|
#ifndef SCUMM_HE_BASKETBALL_AI_H
|
|
#define SCUMM_HE_BASKETBALL_AI_H
|
|
|
|
#ifdef ENABLE_HE
|
|
|
|
#include "scumm/he/intern_he.h"
|
|
#include "scumm/he/logic_he.h"
|
|
|
|
#include "scumm/he/basketball/collision/bball_collision_support_obj.h"
|
|
|
|
|
|
namespace Scumm {
|
|
|
|
#define FLOAT_EPSILON 0.001F
|
|
|
|
inline int square(int x) { return x * x; }
|
|
|
|
class Line2D {
|
|
public:
|
|
Line2D(float x_coef, float y_coef, float constant) {
|
|
_a = x_coef;
|
|
_b = y_coef;
|
|
_c = constant;
|
|
}
|
|
|
|
Line2D(const U32FltVector2D &point1, const U32FltVector2D &point2) {
|
|
LineFromTwoPoints(point1, point2);
|
|
}
|
|
|
|
void LineFromTwoPoints(U32FltVector2D pt1, U32FltVector2D pt2) {
|
|
float temp = (pt2.x - pt1.x);
|
|
|
|
if (fabs(temp) < FLOAT_EPSILON) {
|
|
assert(((fabs(pt2.y - pt1.y) >= FLOAT_EPSILON)));
|
|
_a = 1;
|
|
_b = 0;
|
|
} else {
|
|
float m = (pt2.y - pt1.y) / temp;
|
|
_a = -m;
|
|
_b = 1;
|
|
}
|
|
|
|
_c = -(_a * pt2.x + _b * pt2.y);
|
|
}
|
|
|
|
inline float distance(U32FltVector2D point) {
|
|
return fabs((_a * point.x + _b * point.y + _c) / sqrt(square(_a) + square(_b)));
|
|
}
|
|
|
|
inline float distance2(U32FltVector2D point) {
|
|
return fabs(square(_a * point.x + _b * point.y + _c) / (square(_a) + square(_b)));
|
|
}
|
|
|
|
inline float angle() {
|
|
return atan2(-_a, _b);
|
|
}
|
|
|
|
bool inBetween(U32FltVector2D point, U32FltVector2D end1, U32FltVector2D end2) {
|
|
assert((!onLine(end1) || !onLine(end2)));
|
|
|
|
point = projectPoint(point);
|
|
float distance2 = end1.distance2(end2);
|
|
|
|
return (point.distance2(end1) <= distance2 && point.distance2(end2) <= distance2) ? true : false;
|
|
}
|
|
|
|
bool onLine(U32FltVector2D point) {
|
|
return (distance2(point) < 1.0F) ? true : false;
|
|
}
|
|
|
|
U32FltVector2D projectPoint(U32FltVector2D point) {
|
|
return intersection(perpendicular(point));
|
|
}
|
|
|
|
float getY(float x) {
|
|
if (_b != 0.0F)
|
|
return (-_a * x - _c) / _b;
|
|
|
|
return 0.0F;
|
|
}
|
|
|
|
float getX(float y) {
|
|
if (_a != 0.0F)
|
|
return (-_b * y - _c) / _a;
|
|
|
|
return 0.0F;
|
|
}
|
|
|
|
U32FltVector2D intersection(Line2D line) {
|
|
U32FltVector2D result(0.0F, 0.0F);
|
|
|
|
assert(!sameSlope(line));
|
|
|
|
if (_b == 0.0F) {
|
|
result.x = -_c / _a;
|
|
result.y = line.getY(result.x);
|
|
return result;
|
|
}
|
|
|
|
if (line._b == 0.0F) {
|
|
result.x = -line._c / line._a;
|
|
result.y = getY(result.y);
|
|
return result;
|
|
}
|
|
|
|
result.x = (_c * line._b - _b * line._c) / (line._a * _b - _a * line._b);
|
|
result.y = getY(result.x);
|
|
return result;
|
|
}
|
|
|
|
Line2D perpendicular(U32FltVector2D point) {
|
|
return Line2D(_b, -_a, _a * point.y - _b * point.x);
|
|
}
|
|
|
|
Line2D shiftY(float val) {
|
|
return Line2D(_a, _b, _c - val * _b);
|
|
}
|
|
|
|
Line2D shiftX(float val) {
|
|
return Line2D(_a, _b, _c - val * _a);
|
|
}
|
|
|
|
// Returns whether the projection of point1 is closer to targPoint than the projection of point2
|
|
bool isPointCloserToPointOnLine(U32FltVector2D point1, U32FltVector2D point2, U32FltVector2D targPoint) {
|
|
|
|
assert(!onLine(targPoint));
|
|
|
|
point1 = projectPoint(point1);
|
|
point2 = projectPoint(point2);
|
|
|
|
return (point1.distance(targPoint) < point2.distance(targPoint)) ? true : false;
|
|
}
|
|
|
|
bool halfPlaneTest(U32FltVector2D point) {
|
|
if (_b == 0)
|
|
return (point.x < -_c / _a) ? true : false;
|
|
|
|
return (point.y > getY(point.x)) ? true : false;
|
|
}
|
|
|
|
bool sameSlope(Line2D line) {
|
|
return ((_b == 0 && line._b == 0) || ((_a / _b) == (line._a / line._b))) ? true : false;
|
|
}
|
|
|
|
private:
|
|
float _a, _b, _c; // The three coeffs in the line equation:
|
|
// Ax + By + C = 0
|
|
};
|
|
|
|
} // End of namespace Scumm
|
|
|
|
#endif // ENABLE_HE
|
|
|
|
#endif // SCUMM_HE_BASKETBALL_AI_H
|