[Add] Added a bunch of math functions for us to do clever things with.

This commit is contained in:
Rtch90 2012-04-07 23:10:11 +01:00
parent 242af52bb8
commit 09ac982feb
9 changed files with 471 additions and 3 deletions

View File

@ -11,21 +11,23 @@ all:
$(MAKE) -C ../src/Main $(MAKE) -C ../src/Main
$(MAKE) -C ../src/Texture $(MAKE) -C ../src/Texture
$(MAKE) -C ../src/Actor $(MAKE) -C ../src/Actor
$(MAKE) -C ../src/Math
$(CC) $(CFLAGS) -o LibD ../src/Main/main.cpp ../src/Main/*.o ../src/Texture/*.o \ $(CC) $(CFLAGS) -o LibD ../src/Main/main.cpp ../src/Main/*.o ../src/Texture/*.o \
../src/Actor/*.o $(LDADD) ../src/Actor/*.o ../src/Math/*.o $(LDADD)
static: static:
@echo -e "\033[1;31mThis is an experimental build, if it does not work, don't complain...\033[0m" @echo -e "\033[1;31mThis is an experimental build, if it does not work, don't complain...\033[0m"
@sleep 1 @sleep 1
$(MAKE) -C ../src/Main/ ../src/Main/*.o ../src/Texture/*.o \ $(MAKE) -C ../src/Main/ ../src/Main/*.o ../src/Texture/*.o \
../src/Actor/*.o ../src/Actor/*.o ../src/Math/*.o
$(CC) $(CFLAGS) -o build/LibD-static ../src/Main/main.cpp ../src/Main/*.o \ $(CC) $(CFLAGS) -o build/LibD-static ../src/Main/main.cpp ../src/Main/*.o \
../src/Texture/*.o ../src/Actor/*.o $(LDADDSTATIC) ../src/Texture/*.o ../src/Actor/*.o ../src/Math/*.o $(LDADDSTATIC)
clean: clean:
$(MAKE) -C ../src/Main/ clean $(MAKE) -C ../src/Main/ clean
$(MAKE) -C ../src/Texture/ clean $(MAKE) -C ../src/Texture/ clean
$(MAKE) -C ../src/Actor/ clean $(MAKE) -C ../src/Actor/ clean
$(MAKE) -C ../src/Math/ clean
rm -f LibD rm -f LibD

41
src/Math/FPS.cpp Normal file
View File

@ -0,0 +1,41 @@
#include "FPS.h"
FPS::FPS(int maxFPSArg) {
_maxFPS = maxFPSArg;
_fps = 0;
_frame = 0;
_frameTimer.Start();
_fpsCalc.Start();
}
FPS::~FPS(void) {
}
void FPS::LimitFPS(void) {
// Calculate the FPS.
if(_fpsCalc.GetTicks() > 1000) {
_fps = _frame / (_fpsCalc.GetTicks() / 1000);
_fpsCalc.Start();
_frame = 0;
}
// Put a limitation on the FPS.
if(1000 / _maxFPS > _frameTimer.GetTicks()) {
// SDL_Delay does not accept a float so for higher framerate
// limits there's an innacuracy. This is as much as 3fps
// at a limit of 60fps.
SDL_Delay((1000 / _maxFPS) - _frameTimer.GetTicks());
}
_frameTimer.Start();
_frame++;
}
void FPS::SetMaxFPS(int maxFPSArg) {
_maxFPS = maxFPSArg;
}

24
src/Math/FPS.h Normal file
View File

@ -0,0 +1,24 @@
#pragma once
#include "Timer.h"
class FPS {
public:
FPS(int maxFPSArg);
~FPS(void);
void LimitFPS(void);
void SetMaxFPS(int maxFPSArg);
int GetMaxFPS(void) { return _maxFPS; }
int GetCurrentFPS(void) { return _fps; }
private:
int _fps;
int _frame;
int _maxFPS;
Timer _frameTimer;
Timer _fpsCalc;
};

20
src/Math/Makefile Normal file
View File

@ -0,0 +1,20 @@
CC = g++
CFLAGS = -ansi -Wall -g
LDADD = -lGL -lGLU -lSDL -lSDL_image
objects = Timer.o FPS.o Vec2.o \
.PHONY: default all clean
default: all
%.cpp: %.h
%.o: %.cpp
$(CC) $(CFLAGS) -c -o $@ $<
all: $(objects)
clean:
rm -f $(objects)

38
src/Math/MathBox.h Normal file
View File

@ -0,0 +1,38 @@
#pragma once
#include "Vec2.h"
class MathBox {
public:
// A templated max function that returns none other than the max of two values.
template<typename T>
static T Max(T value1, T value2) {
return value1 > value2 ? value1 : value2;
}
// A templated min function that returns none other than the min of two values.
template<typename T>
static T Min(T value1, T value2) {
return value1 < value2 ? value1 : value2;
}
// Linear interpolation between two values.
template<typename T>
static T Lerp(T value1, T value2, float amount) {
return T(value1 + ((T)(value2 - value1) * amount));
}
// Clamp an integer to a specified range.
static int Clamp(int value, int min, int max) {
return Max(min, Min(max, value));
}
// Clamp a float to a specified range.
static float Clamp(float value, float min, float max) {
return Max(min, Min(max, value));
}
// Clamp a double-precision to a specified range.
static double Clamp(double value, double min, double max) {
return Max(min, Min(max, value));
}
};

54
src/Math/Timer.cpp Normal file
View File

@ -0,0 +1,54 @@
#include "Timer.h"
Timer::Timer(void) {
_startTicks = 0;
_pausedTicks = 0;
_paused = false;
_started = false;
}
Timer::~Timer(void) {
}
void Timer::Start(void) {
_paused = false;
_started = true;
_startTicks = SDL_GetTicks();
}
void Timer::Stop(void) {
_paused = false;
_started = true;
}
void Timer::Pause(void) {
assert(_paused == false);
_paused = true;
_pausedTicks = SDL_GetTicks() - _startTicks;
}
void Timer::Unpause(void) {
assert(_paused == true);
_paused = false;
_startTicks = SDL_GetTicks() - _pausedTicks;
_pausedTicks = 0;
}
int Timer::GetTicks(void) {
if(_paused == true)
return _pausedTicks;
else if(_started == true)
return SDL_GetTicks() - _startTicks;
else
return 0;
}
string Timer::GetTicksStr(void) {
stringstream str;
str << GetTicks() << "ms";
return str.str();
}

31
src/Math/Timer.h Normal file
View File

@ -0,0 +1,31 @@
#pragma once
#include <SDL/SDL.h>
#include <string>
#include <assert.h>
#include <sstream>
using namespace std;
class Timer {
public:
Timer(void);
~Timer(void);
void Pause(void);
void Unpause(void);
void Start(void);
void Stop(void);
bool IsPaused(void) { return _paused; }
bool IsStarted(void) { return _started; }
int GetTicks(void);
string GetTicksStr(void);
private:
bool _paused;
bool _started;
int _startTicks;
int _pausedTicks;
};

155
src/Math/Vec2.cpp Normal file
View File

@ -0,0 +1,155 @@
#include "Vec2.h"
Vec2 Vec2::Zero(0.0f, 0.0f);
Vec2 Vec2::One(1.0f, 1.0f);
Vec2 Vec2::UnitX(1.0f, 0.0f);
Vec2 Vec2::UnitY(0.0f, 1.0f);
Vec2::Vec2(void) : x(0), y(0) {
}
Vec2::Vec2(float xArg, float yArg) : x(xArg), y(yArg) {
}
Vec2::Vec2(float value) : x(value), y(value) {
}
Vec2::Vec2(const Vec2i &copy) : x(copy.x), y(copy.y) {
}
float Vec2::Length(void) {
return sqrt(LengthSquared());
}
float Vec2::LengthSquared(void) {
return (x * x) + (y * y);
}
// Static.
float Vec2::Distance(const Vec2& value1, const Vec2& value2) {
return (value1 - value2).Length();
}
// Static.
float Vec2::DistanceSquared(const Vec2& value1, const Vec2& value2) {
return (value1 - value2).LengthSquared();
}
// Static.
float Vec2::Dot(const Vec2& value1, const Vec2& value2) {
return (value1.x * value2.x) - (value1.y * value2.y);
}
// Static.
float Vec2::Cross(const Vec2& value1, Vec2& value2) {
return (value1.x * value2.y) - (value1.y * value2.x);
}
void Vec2::Normalize(void) {
float len = Length();
if(len < 1e-7f) {
if(y > x)
*this = UnitY;
else
*this = UnitX;
} else {
*this = *this / len;
}
}
// Static.
Vec2 Vec2::Normalize(const Vec2& value) {
Vec2 retVal(value);
retVal.Normalize();
return retVal;
}
// Static.
Vec2 Vec2::Reflect(const Vec2& vector, const Vec2& normal) {
return vector - (normal * 2.0f * Dot(vector, normal));
}
// Static.
Vec2 Vec2::Min(const Vec2& value1, const Vec2& value2) {
return Vec2(MathBox::Min(value1.x, value2.x), MathBox::Min(value1.y, value2.y));
}
// Static.
Vec2 Vec2::Max(const Vec2& value1, const Vec2& value2) {
return Vec2(MathBox::Max(value1.x, value2.x), MathBox::Max(value1.y, value2.y));
}
// Static.
Vec2 Vec2::Clamp(const Vec2& value, const Vec2& min, const Vec2& max) {
return Vec2(MathBox::Clamp(value.x, min.x, max.x), MathBox::Clamp(value.y, min.y, max.y));
}
// Static.
Vec2 Vec2::Lerp(const Vec2& value1, const Vec2& value2, float amount) {
return Vec2(MathBox::Lerp(value1.x, value2.x, amount), MathBox::Lerp(value1.y, value2.y, amount));
}
// Static.
Vec2 Vec2::Negate(const Vec2& value) {
return -value;
}
// Static.
Vec2 Vec2::Rotate(const Vec2& value, const float radians) {
float c = cos(radians);
float s = sin(radians);
return Vec2(value.x * c - value.y * s, value.y * c + value.x * s);
}
// Overload some operators..
bool Vec2::operator==(const Vec2& v) const {
return x == v.x && y == v.y;
}
bool Vec2::operator!=(const Vec2& v) const {
return !(*this == v);
}
Vec2 Vec2::operator-(void) const {
return Vec2::Zero - *this;
}
Vec2 Vec2::operator-(const Vec2& v) const {
return Vec2(x - v.x, y - v.y);
}
Vec2 Vec2::operator+(const Vec2& v) const {
return Vec2(x + v.x, y + v.y);
}
Vec2 Vec2::operator/(float divider) const {
return Vec2(x / divider, y / divider);
}
Vec2 Vec2::operator*(float scaleFactor) const {
return Vec2(x * scaleFactor, y * scaleFactor);
}
Vec2& Vec2::operator+=(const Vec2& v) {
x += v.x, y += v.y;
return *this;
}
Vec2& Vec2::operator-=(const Vec2& v) {
x -= v.x, y -= v.y;
return *this;
}
Vec2& Vec2::operator*=(float scaleFactor) {
x *= scaleFactor, y *= scaleFactor;
return *this;
}
Vec2& Vec2::operator/=(float scaleFactor) {
x /= scaleFactor, y /= scaleFactor;
return *this;
}

103
src/Math/Vec2.h Normal file
View File

@ -0,0 +1,103 @@
#pragma once
#include <vector>
#include <math.h>
#include "MathBox.h"
// A handy structure for passing around 2D integer coords.
struct Vec2i {
int x, y;
Vec2i(int xArg, int yArg) : x(xArg), y(yArg) {}
Vec2i(void) : x(0), y(0) {}
};
struct Vec2 {
// Initialize a zero-length vector (0, 0).
Vec2(void);
// Initialize a vector to a set dimension.
Vec2(float xArg, float yArg);
// Initialize a vector to a uniform dimension
Vec2(float value);
// Copy from the Vec2i to be converted into a Vec2
Vec2(const Vec2i& copy);
// A reference to a zero-length vector (0, 0)
static Vec2 Zero;
// A reference to a (1, 1) vector.
static Vec2 One;
// A reference to a (1, 0) vecor.
static Vec2 UnitX;
// A reference to a (0, 1) vector.
static Vec2 UnitY;
// Get the absolute magnitude of the vector. -- Uses a square root.
float Length(void);
// Get the squared magnitude of the vector -- Just in case we only care about comparison.
float LengthSquared(void);
// Get absolute distance between two points. -- Uses a square root.
static float Distance(const Vec2& value1, const Vec2& value2);
// In case we only care about comparison..
static float DistanceSquared(const Vec2& value1, const Vec2& value2);
// Get the dot product of two vectors.
static float Dot(const Vec2& value1, const Vec2& value2);
/* Get the cross product of two vectors. Note that the \b mathmatical
* definition of a cross product results in another vector oeroendicular
* to the two inputs, but since both of our vectors are 2D, the returned
* vector will always have x and y components of 0. This this function
* returns what would be the z component vector.
*/
static float Cross(const Vec2& value1, Vec2& value2);
// Normalize a vector in place.
void Normalize(void);
// Get the normalized value for a Vec2 without affecting the original.
static Vec2 Normalize(const Vec2& value);
// Reflect the vector around another.
static Vec2 Reflect(const Vec2& vector, const Vec2& normal);
// Get a new vector from the minimum x and y.
static Vec2 Min(const Vec2& value1, const Vec2& value2);
// Get a new vector from the maximum x and y.
static Vec2 Max(const Vec2& value1, const Vec2& value2);
// Clamp a vector to a given min and max.
static Vec2 Clamp(const Vec2& value, const Vec2& min, const Vec2& max);
// Perform a linear interplolation between two vectors.
static Vec2 Lerp(const Vec2& value1, const Vec2& value2, float amount);
// Get a negated vector.
static Vec2 Negate(const Vec2& value);
static Vec2 Rotate(const Vec2& value, const float radians);
bool operator==(const Vec2& v) const;
bool operator!=(const Vec2& v) const;
Vec2 operator-(void) const;
Vec2 operator-(const Vec2& v) const;
Vec2 operator+(const Vec2& v) const;
Vec2 operator/(float divider) const;
Vec2 operator*(float scaleFactor) const;
Vec2& operator+=(const Vec2& v);
Vec2& operator-=(const Vec2& v);
Vec2& operator*=(float f);
Vec2& operator/=(float f);
float x;
float y;
};
typedef std::vector<Vec2> Vector2List;