first commit

This commit is contained in:
Irlan Robson
2016-12-18 18:39:47 -02:00
commit 8f29bc7e21
232 changed files with 103257 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_DRAW_H
#define B3_DRAW_H
#include <bounce\common\math\math.h>
#include <bounce\collision\shapes\aabb3.h>
// Color channels used by the debug b3Draw interface.
struct b3Color
{
b3Color() { }
b3Color(float32 R, float32 G, float32 B, float32 A = 1.0f) : r(R), g(G), b(B), a(A) { }
float32 r, g, b, a;
};
// Implement this interface and set to a world so it can b3Draw the physics entities.
class b3Draw
{
public :
// Bit flags to tell the world what needs to be b3Draw.
enum b3Flags
{
e_shapesFlag = 0x0001,
e_centerOfMassesFlag = 0x0002,
e_jointsFlag = 0x0004,
e_contactPointsFlag = 0x0008,
e_contactNormalsFlag = 0x0010,
e_contactTangentsFlag = 0x0020,
e_aabbsFlag = 0x0040,
};
b3Draw()
{
m_flags = 0;
}
~b3Draw()
{
}
void SetFlags(u32 flags);
void AppendFlags(u32 flags);
// Draw a point.
virtual void DrawPoint(const b3Vec3& point, const b3Color& color) = 0;
// Draw a line segment.
virtual void DrawSegment(const b3Vec3& a, const b3Vec3& b, const b3Color& color) = 0;
// Draw a polygon with vertices ordered CCW.
virtual void DrawPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) = 0;
// Draw a solid polygon with vertices ordered CCW.
virtual void DrawSolidPolygon(const b3Vec3* vertices, u32 count, const b3Color& color) = 0;
// Draw a circle with center, normal, and radius.
virtual void DrawCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) = 0;
// Draw a solid circle with center, normal, and radius.
virtual void DrawSolidCircle(const b3Vec3& normal, const b3Vec3& center, float32 radius, const b3Color& color) = 0;
// Draw a sphere with center and radius.
virtual void DrawSphere(const b3Vec3& center, float32 radius, const b3Color& color) = 0;
// Draw a solid sphere with center and radius.
virtual void DrawSolidSphere(const b3Vec3& center, float32 radius, const b3Color& color) = 0;
// Draw a AABB.
virtual void DrawAABB(const b3AABB3& aabb, const b3Color& color) = 0;
// Draw a b3Transform.
virtual void DrawTransform(const b3Transform& xf) = 0;
// Debug b3Draw flags.
u32 m_flags;
};
inline void b3Draw::SetFlags(u32 flags)
{
m_flags = flags;
}
inline void b3Draw::AppendFlags(u32 flags)
{
m_flags |= flags;
}
#endif

View File

@@ -0,0 +1,190 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_GEOMETRY_H
#define B3_GEOMETRY_H
#include <bounce\common\math\math.h>
#include <bounce\common\math\transform.h>
// A triangle in indexed form.
struct b3Triangle
{
// Does nothing for performance.
b3Triangle() { }
// Set this triangle from three vertices.
b3Triangle(u32 _v1, u32 _v2, u32 _v3)
{
v1 = _v1;
v2 = _v2;
v3 = _v3;
}
// Set this triangle from three vertices.
void Set(u32 _v1, u32 _v2, u32 _v3)
{
v1 = _v1;
v2 = _v2;
v3 = _v3;
}
// Test if this triangle contains a given vertex.
bool TestVertex(u32 v) const
{
return v == v1 || v == v2 || v == v3;
}
// Test if this triangle contains two vertices.
bool TestEdge(u32 _v1, u32 _v2) const
{
return TestVertex(_v1) && TestVertex(_v2);
}
u32 v1, v2, v3;
};
// A plane in constant normal form.
// dot(n, p) - d = 0.
struct b3Plane
{
// Does nothing for performance.
b3Plane() { }
// Set this plane from a normal and a signed distance from its origin.
b3Plane(const b3Vec3& _normal, float32 _offset)
{
normal = _normal;
offset = _offset;
}
// Set this plane from a normal and a point on the plane.
b3Plane(const b3Vec3& _normal, const b3Vec3& _point)
{
normal = _normal;
offset = b3Dot(_normal, _point);
}
// Compute this plane from three non-colinear points.
b3Plane(const b3Vec3& A, const b3Vec3& B, const b3Vec3& C)
{
b3Vec3 N = b3Cross(B - A, C - A);
normal = b3Normalize(N);
offset = b3Dot(normal, A);
}
b3Vec3 normal;
float32 offset;
};
// Transform a plane by a given frame.
inline b3Plane operator*(const b3Transform& T, const b3Plane& plane)
{
b3Vec3 normal = b3Mul(T.rotation, plane.normal);
return b3Plane(normal, plane.offset + b3Dot(normal, T.position));
}
// Transform a plane by a given frame.
inline b3Plane b3Mul(const b3Transform& T, const b3Plane& plane)
{
b3Vec3 normal = b3Mul(T.rotation, plane.normal);
return b3Plane(normal, plane.offset + b3Dot(normal, T.position));
}
inline float32 b3Distance(const b3Vec3& P, const b3Plane& plane)
{
return b3Dot(plane.normal, P) - plane.offset;
}
// Project a point onto a plane.
// The plane must be normalized.
inline b3Vec3 b3Project(const b3Vec3& P, const b3Plane& plane)
{
float32 fraction = b3Distance(P, plane);
return P - fraction * plane.normal;
}
// Compute barycentric coordinates (u, v) for point Q to segment AB.
// The last output value is the divisor.
inline void b3Barycentric(float32 out[3],
const b3Vec3& A, const b3Vec3& B,
const b3Vec3& Q)
{
b3Vec3 AB = B - A;
b3Vec3 QA = A - Q;
b3Vec3 QB = B - Q;
//float32 divisor = b3Dot(AB, AB);
out[0] = b3Dot(QB, AB);
out[1] = -b3Dot(QA, AB);
out[2] = out[0] + out[1];
}
// Compute barycentric coordinates (u, v, w) for point Q to triangle ABC.
// The last output value is the divisor.
inline void b3Barycentric(float32 out[4],
const b3Vec3& A, const b3Vec3& B, const b3Vec3& C,
const b3Vec3& Q)
{
// RTCD, 140.
b3Vec3 AB = B - A;
b3Vec3 AC = C - A;
b3Vec3 QA = A - Q;
b3Vec3 QB = B - Q;
b3Vec3 QC = C - Q;
b3Vec3 QB_x_QC = b3Cross(QB, QC);
b3Vec3 QC_x_QA = b3Cross(QC, QA);
b3Vec3 QA_x_QB = b3Cross(QA, QB);
b3Vec3 AB_x_AC = b3Cross(AB, AC);
//float32 divisor = b3Dot(AB_x_AC, AB_x_AC);
out[0] = b3Dot(QB_x_QC, AB_x_AC);
out[1] = b3Dot(QC_x_QA, AB_x_AC);
out[2] = b3Dot(QA_x_QB, AB_x_AC);
out[3] = out[0] + out[1] + out[2];
}
// Compute barycentric coordinates (u, v, w, x) for point Q to tetrahedron ABCD.
// The last output value is the (positive) divisor.
inline void b3Barycentric(float32 out[5],
const b3Vec3& A, const b3Vec3& B, const b3Vec3& C, const b3Vec3& D,
const b3Vec3& Q)
{
// RTCD, 48, 49.
b3Vec3 AB = B - A;
b3Vec3 AC = C - A;
b3Vec3 AD = D - A;
b3Vec3 QA = A - Q;
b3Vec3 QB = B - Q;
b3Vec3 QC = C - Q;
b3Vec3 QD = D - Q;
float32 divisor = b3Det(AB, AC, AD);
float32 sign = b3Sign(divisor);
out[0] = sign * b3Det(QB, QC, QD);
out[1] = sign * b3Det(QA, QD, QC);
out[2] = sign * b3Det(QA, QB, QD);
out[3] = sign * b3Det(QA, QC, QB);
out[4] = sign * divisor;
}
#endif

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_MAT_H
#define B3_MAT_H
#include <bounce\common\math\math.h>
// A vector stored in column-major order.
template<u32 n>
struct b3Vec
{
b3Vec() { }
const float32& operator[](u32 i) const
{
return e[i];
}
float32& operator[](u32 i)
{
return e[i];
}
void operator+=(const b3Vec<n>& v)
{
for (u32 i = 0; i < n; ++i)
{
e[i] += v[i];
}
}
float32 e[n];
};
template<u32 n>
inline b3Vec<n> operator-(const b3Vec<n>& v)
{
b3Vec<n> result;
for (u32 i = 0; i < n; ++i)
{
result[i] = -v[i];
}
return result;
}
// A matrix stored in column-major order.
template<u32 n, u32 m>
struct b3Mat
{
b3Mat() { }
const float32& operator()(u32 i, u32 j) const
{
return e[i + n * j];
}
float32& operator()(u32 i, u32 j)
{
return e[i + n * j];
}
float32 e[n * m];
};
// Solve Ax = b.
// Warning: Make sure to pass a copy of A to the function. It will be invalidated.
bool b3Solve(float32* b, float32* A, u32 n);
#endif

View File

@@ -0,0 +1,59 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_MAT_22_H
#define B3_MAT_22_H
#include <bounce\common\math\vec2.h>
// A 2-by-2 matrix stored in column-major order.
struct b3Mat22
{
// Does nothing for performance.
b3Mat22() { }
// Set this matrix from two vector elements.
b3Mat22(const b3Vec2& _x, const b3Vec2& _y) : x(_x), y(_y) { }
// Solve Ax = b.
// It doesn't compute the inverse.
// Therefore, is more efficient.
// Returns the zero vector if the matrix is singular.
b3Vec2 Solve(const b3Vec2& b) const;
b3Vec2 x, y;
};
// Multiply a matrix times a vector.
inline b3Vec2 operator*(const b3Mat22& A, const b3Vec2& v)
{
return v.x * A.x + v.y * A.y;
}
// Multiply a matrix times a vector.
inline b3Vec2 b3Mul(const b3Mat22& A, const b3Vec2& v)
{
return v.x * A.x + v.y * A.y;
}
// Invert a matrix.
// If the matrix determinant is zero this returns
// the zero matrix.
inline b3Mat22 b3Inverse(const b3Mat22& A);
#endif

View File

@@ -0,0 +1,257 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_MAT_33_H
#define B3_MAT_33_H
#include <bounce\common\math\vec3.h>
// A 3-by-3 matrix stored in column-major order.
struct b3Mat33
{
// Does nothing for performance.
b3Mat33() { }
// Set this matrix from three elements.
b3Mat33(const b3Vec3& _x, const b3Vec3& _y, const b3Vec3& _z) : x(_x), y(_y), z(_z) { }
// Read an indexed column vector from this matrix.
const b3Vec3& operator[](u32 i) const
{
return (&x)[i];
}
// Write an indexed column vector to this matrix.
b3Vec3& operator[](u32 i)
{
return (&x)[i];
}
// Add a matrix to this matrix.
void operator+=(const b3Mat33& B)
{
x += B.x;
y += B.y;
z += B.z;
}
// Set this matrix to the zero matrix.
void SetZero()
{
x.SetZero();
y.SetZero();
z.SetZero();
}
// Set this matrix to the identity matrix.
void SetIdentity()
{
x.Set(1.0f, 0.0f, 0.0f);
y.Set(0.0f, 1.0f, 0.0f);
z.Set(0.0f, 0.0f, 1.0f);
}
// Solve Ax = b.
// It doesn't compute the inverse.
// Therefore, is more efficient.
// Returns the zero vector if the matrix is singular.
b3Vec3 Solve(const b3Vec3& b) const;
float32 operator()(u32 i, u32 j) const
{
return (&x.x)[i + 3 * j];
}
b3Vec3 x, y, z;
};
// Add two matrices.
inline b3Mat33 operator+(const b3Mat33& A, const b3Mat33& B)
{
return b3Mat33(A.x + B.x, A.y + B.y, A.z + B.z);
}
// Subtract two matrices.
inline b3Mat33 operator-(const b3Mat33& A, const b3Mat33& B)
{
return b3Mat33(A.x - B.x, A.y - B.y, A.z - B.z);
}
// Multiply a scalar times a matrix.
inline b3Mat33 operator*(float32 s, const b3Mat33& A)
{
return b3Mat33(s * A.x, s * A.y, s * A.z);
}
// Negate a matrix.
inline b3Mat33 operator-(const b3Mat33& A)
{
return -1.0f * A;
}
// Multiply a matrix times a vector. If the matrix
// represents a rotation this transforms the vector
// from one frame to another.
inline b3Vec3 operator*(const b3Mat33& A, const b3Vec3& v)
{
return v.x * A.x + v.y * A.y + v.z * A.z;
}
// Multiply two matrices.
inline b3Mat33 operator*(const b3Mat33& A, const b3Mat33& B)
{
return b3Mat33(A * B.x, A * B.y, A * B.z);
}
// Multiply a matrix times a vector. If the matrix
// represents a rotation this transforms the vector
// from one frame to another.
inline b3Vec3 b3Mul(const b3Mat33& A, const b3Vec3& v)
{
return v.x * A.x + v.y * A.y + v.z * A.z;
}
// Multiply two matrices.
inline b3Mat33 b3Mul(const b3Mat33& A, const b3Mat33& B)
{
return b3Mat33( b3Mul(A, B.x), b3Mul(A, B.y), b3Mul(A, B.z));
}
// Multiply the transpose of a matrix times a vector. If
// the matrix represents a rotation frame this transforms the
// vector from one frame to another (inverse b3Transform).
inline b3Vec3 b3MulT(const b3Mat33& A, const b3Vec3& v)
{
return b3Vec3(b3Dot(A.x, v), b3Dot(A.y, v), b3Dot(A.z, v));
}
// Multiply the transpose of a matrix times another.
inline b3Mat33 b3MulT(const b3Mat33& A, const b3Mat33& B)
{
return b3Mat33(
b3Vec3(b3Dot(A.x, B.x), b3Dot(A.y, B.x), b3Dot(A.z, B.x)),
b3Vec3(b3Dot(A.x, B.y), b3Dot(A.y, B.y), b3Dot(A.z, B.y)),
b3Vec3(b3Dot(A.x, B.z), b3Dot(A.y, B.z), b3Dot(A.z, B.z)));
}
// Transpose a matrix.
inline b3Mat33 b3Transpose(const b3Mat33& A)
{
return b3Mat33(
b3Vec3(A.x.x, A.y.x, A.z.x),
b3Vec3(A.x.y, A.y.y, A.z.y),
b3Vec3(A.x.z, A.y.z, A.z.z)
);
}
// Uniform scale matrix.
inline b3Mat33 b3Diagonal(float32 s)
{
return b3Mat33(
b3Vec3(s, 0.0f, 0.0f),
b3Vec3(0.0f, s, 0.0f),
b3Vec3(0.0f, 0.0f, s)
);
}
// Uniform or non-uniform scale matrix.
inline b3Mat33 b3Diagonal(float32 x, float32 y, float32 z)
{
return b3Mat33(
b3Vec3(x, 0.0f, 0.0f),
b3Vec3(0.0f, y, 0.0f),
b3Vec3(0.0f, 0.0f, z)
);
}
// Invert a matrix.
// If the matrix is singular this
// returns the zero matrix.
b3Mat33 b3Inverse(const b3Mat33& A);
// Return a skew (anti-symmetric) matrix for a vector.
inline b3Mat33 b3Skew(const b3Vec3& v)
{
return b3Mat33(
b3Vec3(0.0f, v.z, -v.y),
b3Vec3(-v.z, 0.0f, v.x),
b3Vec3(v.y, -v.x, 0.0f)
);
}
// Compute the dot product of two vectors.
inline float32 b3Inner(const b3Vec3& a, const b3Vec3& b)
{
return b3Dot(a, b);
}
// Compute the outer product of two vectors.
// The result is a matrix A = a * b^T.
inline b3Mat33 b3Outer(const b3Vec3& a, const b3Vec3& b)
{
return b3Mat33(b.x * a, b.y * a, b.z * a);
}
// Move an inertia tensor from the its current center
// to another.
inline b3Mat33 b3MoveToCOM(const b3Mat33& inertia, float32 mass, const b3Vec3& center)
{
// Paralell Axis Theorem
// J = I + m * dot(r, r) * E - outer(r, r)
// where
// I - inertia about the center of mass
// m - mass
// E - identity 3x3
// r - displacement vector from the current com to the new com
// J - inertia tensor at the new center of rotation
float32 dd = b3Dot(center, center);
b3Mat33 A = b3Diagonal(mass * dd);
b3Mat33 B = b3Outer(center, center);
return inertia + A - B;
}
// Compute the inertia matrix of a body measured in
// inertial frame (variable over time) given the
// inertia matrix in body-fixed frame (constant)
// and a rotation matrix representing the orientation
// of the body frame relative to the inertial frame.
inline b3Mat33 b3RotateToFrame(const b3Mat33& inertia, const b3Mat33& rotation)
{
return rotation * inertia * b3Transpose(rotation);
}
// Compute an orthogonal basis given one of its vectors.
// The vector must be normalized.
inline b3Mat33 b3Basis(const b3Vec3& a)
{
// Box2D
b3Mat33 A;
if (b3Abs(a.x) >= float32(0.57735027))
{
A.y.Set(a.y, -a.x, 0.0f);
}
else
{
A.y.Set(0.0f, a.z, -a.y);
}
A.y = b3Normalize(A.y);
A.z = b3Cross(a, A.y);
return A;
}
#endif

View File

@@ -0,0 +1,96 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_MATH_H
#define B3_MATH_H
#include <cmath>
#include <bounce\common\settings.h>
inline bool b3IsValid(float32 fx)
{
u32 ix = *(u32*)(&fx);
return (ix & 0x7F800000) != 0x7F800000;
}
inline float32 b3Sqrt(float32 x)
{
return sqrtf(x);
}
template <class T>
inline T b3Abs(T x)
{
return abs(x);
}
template <class T>
inline T b3Min(T a, T b)
{
return a < b ? a : b;
}
template <class T>
inline T b3Max(T a, T b)
{
return a > b ? a : b;
}
template <class T>
inline T b3Clamp(T a, T low, T high)
{
return b3Max(low, b3Min(a, high));
}
template <class T>
inline void b3Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
template <class T>
inline T b3Sign(T x)
{
return T(T(0) < x) - T(T(x) < T(0));
}
template <class T>
inline u32 b3UniqueCount(T* V, u32 N)
{
u32 count = 0;
for (u32 i = 0; i < N; ++i)
{
u32 j;
for (j = 0; j < N; ++j)
{
if (V[i] == V[j])
{
break;
}
}
if (i == j)
{
++count;
}
}
return count;
}
#endif

View File

@@ -0,0 +1,237 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_QUAT_H
#define B3_QUAT_H
#include <bounce\common\math\math.h>
#include <bounce\common\math\mat33.h>
// A quaternion represents an orientation with 4 real numbers.
struct b3Quat
{
// Default constructor does nothing for performance.
b3Quat() { }
// Set this quaternion from four values.
b3Quat(float32 _x, float32 _y, float32 _z, float32 _w) : x(_x), y(_y), z(_z), w(_w) { }
// Set this quaternion from an axis and an angle
// of rotation about the axis.
b3Quat(const b3Vec3& axis, float32 angle)
{
float32 theta = 0.5f * angle;
float32 s = sin(theta);
x = s * axis.x;
y = s * axis.y;
z = s * axis.z;
w = cos(theta);
}
// Add a quaternion to this quaternion.
void operator+=(const b3Quat& q)
{
x += q.x;
y += q.y;
z += q.z;
w += q.w;
}
// Subtract a quaternion from this quaternion.
void operator-=(const b3Quat& q)
{
x -= q.x;
y -= q.y;
z -= q.z;
w -= q.w;
}
// Set this quaternion to identity.
void SetIdentity()
{
x = y = z = 0.0f;
w = 1.0f;
}
// Set this quaternion from four values.
void Set(float32 _x, float32 _y, float32 _z, float32 _w)
{
x = _x;
y = _y;
z = _z;
w = _w;
}
// Set this quaternion from an axis and an angle
// of rotation about the axis.
void Set(const b3Vec3& axis, float32 angle)
{
float32 theta = 0.5f * angle;
float32 s = sin(theta);
x = s * axis.x;
y = s * axis.y;
z = s * axis.z;
w = cos(theta);
}
// Normalize this quaternion.
void Normalize()
{
float32 s = b3Sqrt(x * x + y * y + z * z + w * w);
if (s != 0.0f)
{
x /= s;
y /= s;
z /= s;
w /= s;
}
}
float32 x, y, z, w;
};
// Add two quaternions.
inline b3Quat operator+(const b3Quat& a, const b3Quat& b)
{
return b3Quat(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w);
}
// Sobtract two quaternions.
inline b3Quat operator-(const b3Quat& a, const b3Quat& b)
{
return b3Quat(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w);
}
// Multiply a quaternion by a scalar.
inline b3Quat operator*(float32 s, const b3Quat& q)
{
return b3Quat(s * q.x, s * q.y, s * q.z, s * q.w);
}
// Negate a quaternion.
inline b3Quat operator-(const b3Quat& q)
{
return b3Quat(-q.x, -q.y, -q.z, -q.w);
}
// Compute a quaternion-quaternion product.
inline b3Quat operator*(const b3Quat& a, const b3Quat& b)
{
return b3Quat(
a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
a.w * b.y + a.y * b.w + a.z * b.x - a.x * b.z,
a.w * b.z + a.z * b.w + a.x * b.y - a.y * b.x,
a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z);
}
// Compute the length of a quaternion.
inline float32 b3Length(const b3Quat& q)
{
return b3Sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
}
// Normalize a quarternion.
inline b3Quat b3Normalize(const b3Quat& q)
{
float32 s = b3Length(q);
if (s != 0.0f)
{
s = 1.0f / s;
return s * q;
}
return b3Quat(0.0f, 0.0f, 0.0f, 1.0f);
}
// Compute the dot poduct of two quaternions.
inline float b3Dot(const b3Quat& a, const b3Quat& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
}
// Compute the conjugate of a quaternion.
inline b3Quat b3Conjugate(const b3Quat& q)
{
return b3Quat(-q.x, -q.y, -q.z, q.w);
}
// Rotate a vector by an orientation quaternion.
inline b3Vec3 b3Mul(const b3Quat& q, const b3Vec3& v)
{
b3Vec3 qv(q.x, q.y, q.z);
float32 qs = q.w;
b3Vec3 t = 2.0f * b3Cross(qv, v);
return v + qs * t + b3Cross(qv, t);
}
// Convert a quaternion to a 3-by-3 rotation matrix.
inline b3Mat33 b3ConvertQuatToRot(const b3Quat& q)
{
float32 x = q.x, y = q.y, z = q.z, w = q.w;
float32 x2 = x + x, y2 = y + y, z2 = z + z;
float32 xx = x * x2, xy = x * y2, xz = x * z2;
float32 yy = y * y2, yz = y * z2, zz = z * z2;
float32 wx = w * x2, wy = w * y2, wz = w * z2;
return b3Mat33(
b3Vec3(1.0f - (yy + zz), xy + wz, xz - wy),
b3Vec3( xy - wz, 1.0f - (xx + zz), yz + wx),
b3Vec3( xz + wy, yz - wx, 1.0f - (xx + yy)));
}
// Perform a linear interpolation between two quaternions.
inline b3Quat b3Lerp(const b3Quat& a, const b3Quat& b, float32 fraction)
{
B3_ASSERT(fraction >= 0.0f);
B3_ASSERT(fraction <= 1.0f);
float32 w1 = 1.0f - fraction;
float32 w2 = fraction;
return w1 * a + w2 * b;
}
// Perform a spherical interpolation between two quaternions.
inline b3Quat b3Slerp(const b3Quat& a, const b3Quat& b, float32 fraction)
{
B3_ASSERT(fraction >= 0.0f);
B3_ASSERT(fraction <= 1.0f);
float32 w1 = 1.0f - fraction;
float32 w2 = fraction;
float32 cosine = b3Dot(a, b);
b3Quat b2 = b;
if (cosine <= FLT_EPSILON * FLT_EPSILON)
{
b2 = -b;
cosine = -cosine;
}
if (cosine > 1.0f - FLT_EPSILON)
{
return w1 * a + w2 * b2;
}
float32 angle = acos(cosine);
float32 sine = sin(angle);
b3Quat q1 = sin(w1 * angle) * a;
b3Quat q2 = sin(w2 * angle) * b2;
float32 invSin = 1.0f / sine;
return invSin * (q1 + q2);
}
#endif

View File

@@ -0,0 +1,160 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_TRANSFORM_H
#define B3_TRANSFORM_H
#include <bounce\common\math\mat33.h>
#include <bounce\common\math\quat.h>
// A b3Transform represents a rigid frame.
// It has a translation representing a position
// and a rotation representing an orientation.
struct b3Transform
{
// Default ctor does nothing for performance.
b3Transform() { }
// Set this b3Transform from a translation vector and an orientation
// quaternion.
b3Transform(const b3Vec3& p, const b3Quat& q)
{
position = p;
rotation = b3ConvertQuatToRot(q);
}
// Set this b3Transform to the identity.
void SetIdentity()
{
position.SetZero();
rotation.SetIdentity();
}
b3Vec3 position; // in fact a translation
b3Mat33 rotation;
};
// Motion proxy for TOI computation.
struct b3Sweep
{
b3Vec3 localCenter; // local center
b3Vec3 worldCenter0; // last world center
b3Quat orientation0; // last orientation
float32 t0; // last fraction between [0, 1]
b3Vec3 worldCenter; // world center
b3Quat orientation; // world orientation
// Get this sweep b3Transform at a given time between [0, 1]
b3Transform GetTransform(float32 t) const;
// Advance to a new initial state.
void Advance(float32 t);
};
inline b3Transform b3Sweep::GetTransform(float32 t) const
{
b3Vec3 c = (1.0f - t) * worldCenter0 + t * worldCenter;
b3Quat q = (1.0f - t) * orientation0 + t * orientation;
q.Normalize();
b3Transform xf;
xf.rotation = b3ConvertQuatToRot(q);
xf.position = c - b3Mul(q, localCenter);
return xf;
}
inline void b3Sweep::Advance(float32 t)
{
B3_ASSERT(t < 1.0f);
float32 dt = (t - t0) / (1.0f / t0);
worldCenter += dt * (worldCenter - worldCenter0);
orientation += dt * (orientation - orientation0);
orientation.Normalize();
t0 = t;
}
// Multiply a b3Transform times a vector. If the b3Transform
// represents a frame this returns the vector in terms
// of the frame.
inline b3Vec3 operator*(const b3Transform& T, const b3Vec3& v)
{
return b3Mul(T.rotation, v) + T.position;
}
// Multiply a b3Transform times another b3Transform (composed b3Transform).
// [A y][B x] = [AB Ax+y]
// [0 1][0 1] [0 1 ]
inline b3Transform operator*(const b3Transform& A, const b3Transform& B)
{
b3Transform C;
C.rotation = b3Mul(A.rotation, B.rotation);
C.position = b3Mul(A.rotation, B.position) + A.position;
return C;
}
// Multiply a b3Transform times a vector.
inline b3Vec3 b3Mul(const b3Transform& T, const b3Vec3& v)
{
return b3Mul(T.rotation, v) + T.position;
}
// Multiply a b3Transform times another b3Transform.
// [A y][B x] = [AB Ax+y]
// [0 1][0 1] [0 1 ]
inline b3Transform b3Mul(const b3Transform& A, const b3Transform& B)
{
b3Transform C;
C.rotation = b3Mul(A.rotation, B.rotation);
C.position = b3Mul(A.rotation, B.position) + A.position;
return C;
}
// Multiply the transpose of one b3Transform (inverse
// b3Transform) times another b3Transform (composed b3Transform).
//[A^-1 -A^-1*y][B x] = [A^-1*B A^-1(x-y)]
//[0 1 ][0 1] [0 1 ]
inline b3Transform b3MulT(const b3Transform& A, const b3Transform& B)
{
b3Transform C;
C.rotation = b3MulT(A.rotation, B.rotation);
C.position = b3MulT(A.rotation, B.position - A.position);
return C;
}
// Multiply the transpose of a b3Transform times a vector.
// If the b3Transform represents a frame then this transforms
// the vector from one frame to another (inverse b3Transform).
//[A^-1 -A^-1*y][x] = A^-1*x - A^-1*y = A^-1 * (x - y)
//[0 1 ][1]
inline b3Vec3 b3MulT(const b3Transform& A, const b3Vec3& v)
{
return b3MulT(A.rotation, v - A.position);
}
// Inverse b3Transform.
inline b3Transform b3Inverse(const b3Transform& T)
{
b3Transform B;
B.rotation = b3Transpose(T.rotation);
B.position = b3MulT(T.rotation, -T.position);
return B;
}
#endif

View File

@@ -0,0 +1,154 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_VEC2_H
#define B3_VEC2_H
#include <bounce\common\math\math.h>
// A 2D column vector.
struct b3Vec2
{
// Does nothing for performance.
b3Vec2() { }
// Set this vector from two components.
b3Vec2(float32 _x, float32 _y) : x(_x), y(_y) { }
// Read an indexed component from this vector.
float32 operator[](u32 i) const { return (&x)[i]; }
// Write an indexed component to this vector.
float32& operator[](u32 i) { return (&x)[i]; }
// Add a vector to this vector.
void operator+=(const b3Vec2& v)
{
x += v.x;
y += v.y;
}
// Subtract a vector from this vector.
void operator-=(const b3Vec2& v)
{
x -= v.x;
y -= v.y;
}
// Scale this vector.
void operator*=(float32 s)
{
x *= s;
y *= s;
}
// Scale this vector.
void operator/=(float32 s)
{
x /= s;
y /= s;
}
// Set this vector to the zero vector.
void SetZero()
{
x = y = 0.0f;
}
// Set this vector from two components.
void Set(float32 _x, float32 _y)
{
x = _x;
y = _y;
}
// Normalize this vector.
void Normalize()
{
float32 s = b3Sqrt(x * x + y * y);
if (s > B3_EPSILON)
{
x /= s;
y /= s;
}
}
float32 x, y;
};
// Negate a vector.
inline b3Vec2 operator-(const b3Vec2& v)
{
return b3Vec2(-v.x, -v.y);
}
// Add two vectors.
inline b3Vec2 operator+(const b3Vec2& a, const b3Vec2& b)
{
return b3Vec2(a.x + b.x, a.y + b.y);
}
// Subtract two vectors.
inline b3Vec2 operator-(const b3Vec2& a, const b3Vec2& b)
{
return b3Vec2(a.x - b.x, a.y - b.y);
}
// Multiply a vector by a scalar.
inline b3Vec2 operator*(float32 s, const b3Vec2& v)
{
return b3Vec2(s * v.x, s * v.y);
}
// Compute the dot product of two vectors.
inline float32 b3Dot(const b3Vec2& a, const b3Vec2& b)
{
return a.x * b.x + a.y * b.y;
}
// Compute the length of a vector.
inline float32 b3Length(const b3Vec2& v)
{
return b3Sqrt(v.x * v.x + v.y * v.y);
}
// Normalize a vector.
inline b3Vec2 b3Normalize(const b3Vec2& v)
{
float32 length = b3Length(v);
if (length > B3_EPSILON)
{
float32 s = 1.0f / length;
return s * v;
}
return v;
}
// Compute the euclidean distance between two points.
inline float32 b3Distance(const b3Vec2& a, const b3Vec2& b)
{
return b3Length(a - b);
}
// Compute the determinant of two 2D vectors.
inline float32 b3Det(const b3Vec2& a, const b3Vec2& b)
{
return a.x * b.y - a.y * b.x;
}
#endif

View File

@@ -0,0 +1,248 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_VEC_3_H
#define B3_VEC_3_H
#include <bounce\common\math\math.h>
// A 3D column vector.
struct b3Vec3
{
// Does nothing for performance.
b3Vec3() { }
// Set this vector from three components.
b3Vec3(float32 _x, float32 _y, float32 _z) : x(_x), y(_y), z(_z) { }
// Read an indexed component from this vector.
float32 operator[](u32 i) const
{
return (&x)[i];
}
// Write an indexed component to this vector.
float32& operator[](u32 i)
{
return (&x)[i];
}
// Add a vector to this vector.
void operator+=(const b3Vec3& b)
{
x += b.x;
y += b.y;
z += b.z;
}
// Subtract this vector from another vector.
void operator-=(const b3Vec3& b)
{
x -= b.x;
y -= b.y;
z -= b.z;
}
// Scale this vector.
void operator*=(float32 s)
{
x *= s;
y *= s;
z *= s;
}
// Scale this vector.
void operator/=(float32 s)
{
x /= s;
y /= s;
z /= s;
}
// Set this vector to the zero vector.
void SetZero()
{
x = y = z = 0.0f;
}
// Normalize this vector.
void Normalize()
{
float32 lenght = b3Sqrt(x * x + y * y + z * z);
if (lenght > B3_EPSILON)
{
x /= lenght;
y /= lenght;
z /= lenght;
}
}
// Set this vector from three coordinates.
void Set(float32 _x, float32 _y, float32 _z)
{
x = _x;
y = _y;
z = _z;
}
float32 x, y, z;
};
// Negate a vector.
inline b3Vec3 operator-(const b3Vec3& v)
{
return b3Vec3(-v.x, -v.y, -v.z);
}
// Compute the sum of two vectors.
inline b3Vec3 operator+(const b3Vec3& a, const b3Vec3& b)
{
return b3Vec3(a.x + b.x, a.y + b.y, a.z + b.z);
}
// Compute the subtraction of two vectors.
inline b3Vec3 operator-(const b3Vec3& a, const b3Vec3& b)
{
return b3Vec3(a.x - b.x, a.y - b.y, a.z - b.z);
}
// Compute a scalar-vector product.
inline b3Vec3 operator*(float32 s, const b3Vec3& v)
{
return b3Vec3(s * v.x, s * v.y, s * v.z);
}
// Inverse multiply a scalar-vector.
inline b3Vec3 operator/(const b3Vec3& v, float32 s)
{
return b3Vec3(v.x / s, v.y / s, v.z / s);
}
// Compute the dot-product of two vectors.
inline float32 b3Dot(const b3Vec3& a, const b3Vec3& b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
// Compute the cross-product of two vectors.
inline b3Vec3 b3Cross(const b3Vec3& a, const b3Vec3& b)
{
return b3Vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x);
}
// Compute the determinant of a matrix whose columns are three given vectors.
// Useful property: det(a, b, c) = det(c, a, b) = det(b, c, a).
inline float32 b3Det(const b3Vec3& a, const b3Vec3& b, const b3Vec3& c)
{
return b3Dot(a, b3Cross(b, c));
}
// Compute the length of a vector.
inline float32 b3Length(const b3Vec3& v)
{
return b3Sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
}
// Compute the squared length of a vector.
inline float32 b3LengthSquared(const b3Vec3& v)
{
return v.x * v.x + v.y * v.y + v.z * v.z;
}
// Compute the normalized vector of a (non-zero!) vector.
inline b3Vec3 b3Normalize(const b3Vec3& v)
{
float32 length = b3Length(v);
if (length > B3_EPSILON)
{
float32 s = 1.0f / length;
return s * v;
}
return v;
}
// Compute the euclidean distance between two points.
inline float32 b3Distance(const b3Vec3& a, const b3Vec3& b)
{
return b3Length(a - b);
}
// Compute the squared distance between two points.
inline float32 b3DistanceSquared(const b3Vec3& a, const b3Vec3& b)
{
b3Vec3 v = a - b;
return b3LengthSquared(v);
}
// Compute the triangle area.
inline float32 b3Area(const b3Vec3& a, const b3Vec3& b, const b3Vec3& c)
{
return b3Length(b3Cross(b - a, c - a));
}
// Compute the squared triangle area.
inline float32 b3AreaSquared(const b3Vec3& a, const b3Vec3& b, const b3Vec3& c)
{
return b3LengthSquared(b3Cross(b - a, c - a));
}
// Compute the tetrahedron volume.
inline float32 b3Volume(const b3Vec3& a, const b3Vec3& b, const b3Vec3& c, const b3Vec3& d)
{
float32 volume = b3Det(b - a, c - a, d - a);
// Force a positive volume.
float32 sign = b3Sign(volume);
const float32 inv6 = 1.0f / 6.0f;
return sign * inv6 * volume;
}
// Compute the squared tetrahedron volume.
inline float32 b3VolumeSquared(const b3Vec3& a, const b3Vec3& b, const b3Vec3& c, const b3Vec3& d)
{
float32 volume = b3Volume(a, b, c, d);
return volume * volume;
}
// Compute the minimum vector between two vector (per-element).
inline b3Vec3 b3Min(const b3Vec3& a, const b3Vec3& b)
{
return b3Vec3(b3Min(a.x, b.x), b3Min(a.y, b.y), b3Min(a.z, b.z));
}
// Compute the maximum vector between two vector (per-element).
inline b3Vec3 b3Max(const b3Vec3& a, const b3Vec3& b)
{
return b3Vec3(b3Max(a.x, b.x), b3Max(a.y, b.y), b3Max(a.z, b.z));
}
// Find a perpendicular vector to a vector.
inline b3Vec3 b3Perp(const b3Vec3& v)
{
// Box2D
// Suppose vector a has all equal components and is a unit vector: a = (s, s, s)
// Then 3*s*s = 1, s = sqrt(1/3) = 0.57735. This means that at least one component of a
// unit vector must be greater or equal to 0.57735.
if (b3Abs(v.x) >= float32(0.57735027))
{
return b3Vec3(v.y, -v.x, 0.0f);
}
return b3Vec3(0.0f, v.z, -v.y);
}
#endif

View File

@@ -0,0 +1,55 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_BLOCK_POOL_H
#define B3_BLOCK_POOL_H
#include <bounce\common\settings.h>
// Number of blocks per chunk.
const u32 b3_blockCount = 32;
// A pool of memory blocks.
class b3BlockPool
{
public:
b3BlockPool(u32 blockSize);
~b3BlockPool();
void* Allocate();
void Free(void* p);
private:
struct b3Block
{
b3Block* next;
};
struct b3Chunk
{
b3Block* freeBlocks;
b3Chunk* next;
};
u32 m_blockSize;
u32 m_chunkSize;
b3Chunk* m_chunks;
u32 m_chunkCount;
};
#endif

View File

@@ -0,0 +1,53 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_STACK_ALLOCATOR_H
#define B3_STACK_ALLOCATOR_H
#include <bounce\common\settings.h>
// Allocate 10 MiB from the stack.
// Increase as you want.
const u32 b3_maxStackSize = B3_MiB(10);
// An stack allocator.
class b3StackAllocator
{
public :
b3StackAllocator();
~b3StackAllocator();
void* Allocate(u32 size);
void Free(void* p);
private :
struct b3Block
{
u32 size;
u8* data;
bool parent;
};
u32 m_blockCapacity;
b3Block* m_blocks;
u32 m_blockCount;
u32 m_allocatedSize; // marker
u8 m_memory[b3_maxStackSize];
};
#endif

View File

@@ -0,0 +1,152 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_SETTINGS_H
#define B3_SETTINGS_H
#include <assert.h>
#include <cstring>
#include <new>
#include <float.h>
typedef signed int i32;
typedef signed short i16;
typedef signed char i8;
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef unsigned long long u64;
typedef double float64;
typedef float float32;
// You can modify the following parameters as long
// as you know what you're doing.
#define B3_PI (3.14159265359f)
#define B3_MAX_FLOAT (FLT_MAX)
#define B3_EPSILON (FLT_EPSILON)
// Collision
// Maximum number of vertices, edges, and faces a
// polyhedron can have. Don't increase this value.
#define B3_MAX_HULL_FEATURES (256)
// How much an AABB in the broad-phase should be extended by
// to disallow unecessary proxy updates.
// A larger value increases performance when there are
// no objects closer to the AABB because no contacts are
// even created.
#define B3_AABB_EXTENSION (0.2f)
// This is used to extend AABBs in the broad-phase.
// Is used to predict the future position based on the current displacement.
// This is a dimensionless multiplier.
#define B3_AABB_MULTIPLIER (2.0f)
// Collision and constraint tolerance.
#define B3_LINEAR_SLOP (0.005f)
// Collision and constraint tolerance.
#define B3_ANGULAR_SLOP (2.0f / 180.0f * B3_PI)
// The radius of the hull shape skin.
#define B3_HULL_RADIUS (2.0f * B3_LINEAR_SLOP)
// Twice the radius of the hull shape skin.
#define B3_HULL_RADIUS_SUM (2.0f * B3_HULL_RADIUS)
// Dynamics
// The maximum number of manifolds that can be build
// for all contacts.
#define B3_MAX_MANIFOLDS (3)
// If this is equal to 4 then the contact generator
// will keep the hull-hull manifold clipped points up to 4 such that
// still creates a stable manifold to the solver. More points
// usually means better torque balance but can decrease
// the performance of the solver significantly.
// Therefore, keep this to 4 for greater performance.
#define B3_MAX_MANIFOLD_POINTS (4)
// Maximum translation per step to prevent numerical instability
// due to large linear velocity.
#define B3_MAX_TRANSLATION (2.0f)
#define B3_MAX_TRANSLATION_SQUARED (B3_MAX_TRANSLATION * B3_MAX_TRANSLATION)
// Maximum rotation per step to prevent numerical instability due to
// large angular velocity.
#define B3_MAX_ROTATION (0.5f * B3_PI)
#define B3_MAX_ROTATION_SQUARED (B3_MAX_ROTATION * B3_MAX_ROTATION)
// The maximum linear position correction used when solving constraints. This helps to
// prevent overshoot.
#define B3_MAX_LINEAR_CORRECTION (0.2f)
// The maximum angular position correction used when solving constraints. This helps to
// prevent overshoot.
#define B3_MAX_ANGULAR_CORRECTION (8.0f / 180.0f * B3_PI)
// This controls how faster overlaps should be resolved per step.
// This is less than and would be close to 1, so that the all overlap is resolved per step.
// However values very close to 1 may lead to overshoot.
#define B3_BAUMGARTE (0.1f)
// If the relative velocity of a contact point is below
// the threshold then restitution is not applied.
#define B3_VELOCITY_THRESHOLD (1.0f)
// Sleep
#define B3_TIME_TO_SLEEP (0.2f )
#define B3_SLEEP_LINEAR_TOL (0.05f)
#define B3_SLEEP_ANGULAR_TOL (2.0f / 180.0f * B3_PI)
// Memory
#define B3_NOT_USED(x) ((void)(x))
#define B3_ASSERT(c) assert(c)
#define B3_STATIC_ASSERT(c) static_assert(c)
#define B3_KiB(n) (1024 * n)
#define B3_MiB(n) (1024 * B3_KiB(n))
#define B3_GiB(n) (1024 * B3_MiB(n))
// You should implement this function to use your own memory allocator.
void* b3Alloc(u32 size);
// You must implement this function if you have implemented b3Alloc.
void b3Free(void* block);
// You should implement this function to visualize log messages coming
// from this software.
void b3Log(const char* string, ...);
// The current version this software.
struct b3Version
{
u32 major; //significant changes
u32 minor; //minor features
u32 revision; //patches
};
// The current version of Bounce.
extern b3Version b3_version;
#endif

View File

@@ -0,0 +1,243 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_ARRAY_POD_H
#define B3_ARRAY_POD_H
#include <bounce\common\settings.h>
// An array for bytes (POD).
template <typename T>
class b3Array
{
public:
const T& operator[](u32 i) const
{
B3_ASSERT(i < m_count);
return m_elements[i];
}
T& operator[](u32 i)
{
B3_ASSERT(i < m_count);
return m_elements[i];
}
const T* Get(u32 i) const
{
B3_ASSERT(i < m_count);
return m_elements + i;
}
T* Get(u32 i)
{
B3_ASSERT(i < m_count);
return m_elements + i;
}
const T* Elements() const
{
return m_elements;
}
T* Elements()
{
return m_elements;
}
void PushBack(const T& ele)
{
if (m_count == m_capacity)
{
T* oldElements = m_elements;
m_capacity *= 2;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
memcpy(m_elements, oldElements, m_count * sizeof(T));
if (oldElements != m_localElements)
{
b3Free(oldElements);
}
}
B3_ASSERT(m_count < m_capacity);
m_elements[m_count] = ele;
++m_count;
}
void PopBack()
{
B3_ASSERT(m_count > 0);
--m_count;
}
const T& Back() const
{
B3_ASSERT(m_count > 0);
return m_elements[m_count - 1];
}
T& Back()
{
B3_ASSERT(m_count > 0);
return m_elements[m_count - 1];
}
u32 Count() const
{
return m_count;
}
bool IsEmpty() const
{
return m_count == 0;
}
void Remove(u32 index)
{
B3_ASSERT(m_count > 0);
B3_ASSERT(index < m_count);
--m_count;
// Swap current element with its next.
for (u32 i = index; i < m_count; ++i)
{
m_elements[i] = m_elements[i + 1];
}
}
void Reserve(u32 size)
{
if (m_capacity < size)
{
T* oldElements = m_elements;
m_capacity = 2 * size;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
memcpy(m_elements, oldElements, m_count * sizeof(T));
if (oldElements != m_localElements)
{
b3Free(oldElements);
}
}
B3_ASSERT(m_capacity >= size);
}
void Resize(u32 size)
{
if (m_capacity < size)
{
T* oldElements = m_elements;
m_capacity = 2 * size;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
memcpy(m_elements, oldElements, m_count * sizeof(T));
if (oldElements != m_localElements)
{
b3Free(oldElements);
}
}
B3_ASSERT(m_capacity >= size);
m_count = size;
}
void Swap(const b3Array<T>& other)
{
if (m_elements == other.m_elements)
{
return;
}
// Ensure sufficient capacity for copy.
if (m_capacity < other.m_count)
{
if (m_elements != m_localElements)
{
b3Free(m_elements);
}
m_capacity = other.m_capacity;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
}
// Copy.
B3_ASSERT(m_capacity >= other.m_count);
m_count = other.m_count;
memcpy(m_elements, other.m_elements, other.m_count * sizeof(T));
}
void operator=(const b3Array<T>& other)
{
Swap(other);
}
protected:
b3Array(T* elements, u32 N)
{
B3_ASSERT(N > 0);
m_localElements = elements;
m_capacity = N;
m_elements = m_localElements;
m_count = 0;
}
b3Array(const b3Array<T>& other)
{
Swap(other);
}
~b3Array()
{
if (m_elements != m_localElements)
{
b3Free(m_elements);
}
}
u32 m_capacity;
T* m_elements;
u32 m_count;
T* m_localElements;
};
template <typename T, u32 N>
class b3StackArray : public b3Array<T>
{
public :
b3StackArray<T, N>() : b3Array<T>(m_stackElements, N)
{
}
b3StackArray<T, N>(const b3StackArray<T, N>& other) : b3Array<T>(other)
{
}
b3StackArray<T, N>(const b3Array<T>& other) : b3Array<T>(other)
{
}
void operator=(const b3StackArray<T, N>& other)
{
Swap(other);
}
void operator=(const b3Array<T>& other)
{
Swap(other);
}
protected:
T m_stackElements[N];
};
#endif

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_LIST_H
#define B3_LIST_H
#include <bounce\common\settings.h>
// A singly-linked list.
template<class T>
class b3List1
{
public:
b3List1()
{
m_head = nullptr;
m_count = 0;
}
~b3List1() { }
void PushFront(T* link)
{
link->m_next = m_head;
m_head = link;
++m_count;
}
void Remove(T* link)
{
m_head = link->m_next;
--m_count;
}
T* m_head;
u32 m_count;
};
// A doubly-linked list.
template<class T>
class b3List2
{
public:
b3List2()
{
m_head = nullptr;
m_count = 0;
}
~b3List2() { }
void PushFront(T* link)
{
link->m_prev = nullptr;
link->m_next = m_head;
if (m_head)
{
m_head->m_prev = link;
}
m_head = link;
++m_count;
}
void Remove(T* link)
{
if (link->m_prev)
{
link->m_prev->m_next = link->m_next;
}
if (link->m_next)
{
link->m_next->m_prev = link->m_prev;
}
if (link == m_head)
{
m_head = link->m_next;
}
--m_count;
}
T* m_head;
u32 m_count;
};
#endif

View File

@@ -0,0 +1,283 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_OBJECT_ARRAY_H
#define B3_OBJECT_ARRAY_H
#include <bounce\common\settings.h>
// An array for objects.
template <typename T>
class b3ObjectArray
{
public:
const T& operator[](u32 i) const
{
B3_ASSERT(i < m_count);
return m_elements[i];
}
T& operator[](u32 i)
{
B3_ASSERT(i < m_count);
return m_elements[i];
}
const T* Get(u32 i) const
{
B3_ASSERT(i < m_count);
return m_elements + i;
}
T* Get(u32 i)
{
B3_ASSERT(i < m_count);
return m_elements + i;
}
const T* Elements() const
{
return m_elements;
}
T* Elements()
{
return m_elements;
}
void PushBack(const T& ele)
{
if (m_count == m_capacity)
{
// There is no capacity for one more element.
T* oldElements = m_elements;
m_capacity *= 2;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
for (u32 i = 0; i < m_count; ++i)
{
T* old = oldElements + i;
T* e = m_elements + i;
new (e) T(*old);
old->~T();
}
if (oldElements != m_localElements)
{
b3Free(oldElements);
}
}
B3_ASSERT(m_count < m_capacity);
T* e = m_elements + m_count;
new(e) T(ele);
++m_count;
}
void PopBack()
{
B3_ASSERT(m_count > 0);
--m_count;
}
const T& Back() const
{
B3_ASSERT(m_count > 0);
return m_elements[m_count - 1];
}
T& Back()
{
B3_ASSERT(m_count > 0);
return m_elements[m_count - 1];
}
u32 Count() const
{
return m_count;
}
bool Empty() const
{
return m_count == 0;
}
void Resize(u32 size)
{
if (m_capacity < size)
{
// There is no capacity for the requested size.
T* oldElements = m_elements;
m_capacity = 2 * size;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
// Construct and copy objects.
for (u32 i = 0; i < m_count; ++i)
{
T* old = oldElements + i;
T* e = m_elements + i;
new (e) T(*old);
old->~T();
}
// Construct objects up to the requested size.
for (u32 i = m_count; i < size; ++i)
{
T* e = m_elements + i;
new (e) T();
}
if (oldElements != m_localElements)
{
b3Free(oldElements);
}
m_count = size;
return;
}
B3_ASSERT(m_capacity >= size);
if (size < m_count)
{
// Destroy objects beyond the requested size.
for (u32 i = size; i < m_count; ++i)
{
T* e = m_elements + i;
e->~T();
}
}
else
{
// Construct objects up to the requested size.
for (u32 i = m_count; i < size; ++i)
{
T* e = m_elements + i;
new (e) T();
}
}
m_count = size;
}
void Swap(const b3ObjectArray<T>& other)
{
if (m_elements == other.m_elements)
{
return;
}
// Destroy all objects.
for (u32 i = 0; i < m_count; ++i)
{
T* e = m_elements + i;
e->~T();
}
// Ensure sufficient capacity for a copy.
if (m_capacity < other.m_count)
{
if (m_elements != m_localElements)
{
b3Free(m_elements);
}
m_capacity = 2 * other.m_count;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
}
// Copy.
B3_ASSERT(m_capacity >= other.m_count);
for (u32 i = 0; i < other.m_count; ++i)
{
T* e2 = other.m_elements + i;
T* e1 = m_elements + i;
new (e1) T(*e2);
}
m_count = other.m_count;
}
protected:
b3ObjectArray(T* elements, u32 N)
{
B3_ASSERT(N > 0);
m_localElements = elements;
m_capacity = N;
m_elements = m_localElements;
m_count = 0;
}
b3ObjectArray(const b3ObjectArray<T>& other)
{
Swap(other);
}
~b3ObjectArray()
{
if (m_elements != m_localElements)
{
for (u32 i = 0; i < m_count; ++i)
{
T* e = m_elements + i;
e->~T();
}
b3Free(m_elements);
}
}
void operator=(const b3ObjectArray<T>& other)
{
Swap(other);
}
u32 m_capacity;
T* m_elements;
u32 m_count;
T* m_localElements;
};
template <typename T, u32 N>
class b3StackObjectArray : public b3ObjectArray<T>
{
public:
b3StackObjectArray<T, N>() : b3ObjectArray<T>(m_stackElements, N)
{
}
b3StackObjectArray<T, N>(const b3StackObjectArray<T, N>& other) : b3ObjectArray<T>(other)
{
}
b3StackObjectArray<T, N>(const b3ObjectArray<T>& other) : b3ObjectArray<T>(other)
{
}
void operator=(const b3StackObjectArray<T, N>& other)
{
Swap(other);
}
void operator=(const b3ObjectArray<T>& other)
{
Swap(other);
}
protected:
//@todo
// u8 m_bytes[N * sizeof(T)];
T m_stackElements[N];
};
#endif

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_STACK_H
#define B3_STACK_H
#include <bounce\common\settings.h>
// A growable stack for plain-old-data (POD).
template <typename T, u32 N>
class b3Stack
{
public:
b3Stack()
{
m_capacity = N;
m_elements = m_stackElements;
m_count = 0;
}
~b3Stack()
{
if (m_elements != m_stackElements)
{
b3Free(m_elements);
}
m_elements = nullptr;
}
const T& Top() const
{
B3_ASSERT(m_count);
return m_elements[m_count - 1];
}
T& Top()
{
B3_ASSERT(m_count);
return m_elements[m_count - 1];
}
void Push(const T& ele)
{
if (m_count == m_capacity)
{
T* oldElements = m_elements;
m_capacity *= 2;
m_elements = (T*)b3Alloc(m_capacity * sizeof(T));
memcpy(m_elements, oldElements, m_count * sizeof(T));
if (oldElements != m_stackElements)
{
b3Free(oldElements);
}
}
B3_ASSERT(m_count < m_capacity);
m_elements[m_count] = ele;
++m_count;
}
void Pop()
{
B3_ASSERT(m_count);
--m_count;
}
u32 Count() const
{
return m_count;
}
bool IsEmpty() const
{
return m_count == 0;
}
private:
u32 m_capacity;
T* m_elements;
u32 m_count;
T m_stackElements[N];
};
#endif

View File

@@ -0,0 +1,63 @@
/*
* Copyright (c) 2016-2016 Irlan Robson http://www.irlan.net
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef B3_TIME_H
#define B3_TIME_H
#include <bounce\common\settings.h>
// A timer class that accumulates time.
// Usefull for measuring elapsed times of
// sections of code.
class b3Time
{
public :
b3Time();
// Get the accumulated time in miliseconds
// from this timer.
float64 GetCurMilis() const;
// Get the elapsed time since this timer was updated.
float64 GetElapsedMilis() const;
// Add the elapsed time since this function
// was called to this timer.
void Update();
// Add a given ammout of time to this timer.
void UpdateBy(float64 dt);
private:
static float64 m_invFrequency;
u64 m_lastRealTime;
float64 m_lastTime;
float64 m_curTime;
};
inline float64 b3Time::GetCurMilis() const
{
return m_curTime;
}
inline float64 b3Time::GetElapsedMilis() const
{
return m_curTime - m_lastTime;
}
#endif