Browse Source

math: improve the 2D and 3D box classes.

Box objects (AABB) now have the long awaited extent() and center()
methods. Corners are now called “aa” and “bb” for convenience. The
WorldEntity class uses a box3 for its AABB instead of two vec3s.
This allows us to simplify a lot of verbose code.
undefined
Sam Hocevar 9 years ago
parent
commit
2fa398926d
12 changed files with 125 additions and 100 deletions
  1. +2
    -2
      doc/samples/meshviewer/meshviewer.cpp
  2. +2
    -2
      doc/tutorial/11_fractal.cpp
  3. +8
    -8
      src/debug/lines.cpp
  4. +5
    -9
      src/gpu/renderer.cpp
  5. +8
    -8
      src/gradient.cpp
  6. +8
    -8
      src/image/crop.cpp
  7. +12
    -12
      src/lol/algorithm/aabb_tree.h
  8. +62
    -34
      src/lol/math/geometry.h
  9. +11
    -12
      src/tileset.cpp
  10. +1
    -3
      src/video.cpp
  11. +5
    -1
      src/worldentity.cpp
  12. +1
    -1
      src/worldentity.h

+ 2
- 2
doc/samples/meshviewer/meshviewer.cpp View File

@@ -75,8 +75,8 @@ public:
//This considers the box usage A to B as top-left to bottom-right
void AddTarget(box3 new_target)
{
vec3 base_off = .5f * (new_target.B - new_target.A);
vec3 base_pos = new_target.A + base_off;
vec3 base_off = .5f * new_target.extent();
vec3 base_pos = new_target.center();
int pass = 0;
while (pass < 3)
{


+ 2
- 2
doc/tutorial/11_fractal.cpp View File

@@ -120,8 +120,8 @@ public:
#endif

m_position = vec3::zero;
m_bbox[0] = m_position;
m_bbox[1] = vec3((vec2)m_window_size, 0);
m_aabb.aa = m_position;
m_aabb.bb = vec3((vec2)m_window_size, 0);
//Input::TrackMouse(this);

#if LOL_FEATURE_THREADS


+ 8
- 8
src/debug/lines.cpp View File

@@ -212,20 +212,20 @@ void Debug::DrawArrow(vec2 a, vec2 b, vec3 s, vec4 color, float az, float bz)
}

//-- BOX: 3D -2D - 3D_to_2D ---------------------------------------------------
void Debug::DrawBox(box3 a) { Debug::DrawBox(a.A, a.B, Scene::GetLineColor()); }
void Debug::DrawBox(box2 a) { Debug::DrawBox(a.A, a.B, Scene::GetLineColor()); }
void Debug::DrawBox(box3 a, vec4 color) { Debug::DrawBox(a.A, a.B, color); }
void Debug::DrawBox(box2 a, vec4 color) { Debug::DrawBox(a.A, a.B, color); }
void Debug::DrawBox(box3 a) { Debug::DrawBox(a.aa, a.bb, Scene::GetLineColor()); }
void Debug::DrawBox(box2 a) { Debug::DrawBox(a.aa, a.bb, Scene::GetLineColor()); }
void Debug::DrawBox(box3 a, vec4 color) { Debug::DrawBox(a.aa, a.bb, color); }
void Debug::DrawBox(box2 a, vec4 color) { Debug::DrawBox(a.aa, a.bb, color); }
void Debug::DrawBox(vec3 a, vec3 b) { Debug::DrawBox(a, b, Scene::GetLineColor()); }
void Debug::DrawBox(vec2 a, vec2 b) { Debug::DrawBox(a, b, Scene::GetLineColor()); }
void Debug::DrawBox(vec2 a, float s) { Debug::DrawBox(a, s, Scene::GetLineColor()); }
void Debug::DrawBox(vec3 a, vec3 b, vec4 color) { Debug::DrawBox(a, b, mat4::identity, color); }
void Debug::DrawBox(vec2 a, vec2 b, vec4 color) { Debug::DrawBox(a, b, mat2::identity, color); }
void Debug::DrawBox(vec2 a, float s, vec4 color) { Debug::DrawBox(a, s, mat2::identity, color); }
void Debug::DrawBox(box3 a, mat4 transform) { Debug::DrawBox(a.A, a.B, transform, Scene::GetLineColor()); }
void Debug::DrawBox(box2 a, mat2 transform) { Debug::DrawBox(a.A, a.B, transform, Scene::GetLineColor()); }
void Debug::DrawBox(box3 a, mat4 transform, vec4 color) { Debug::DrawBox(a.A, a.B, transform, color); }
void Debug::DrawBox(box2 a, mat2 transform, vec4 color) { Debug::DrawBox(a.A, a.B, transform, color); }
void Debug::DrawBox(box3 a, mat4 transform) { Debug::DrawBox(a.aa, a.bb, transform, Scene::GetLineColor()); }
void Debug::DrawBox(box2 a, mat2 transform) { Debug::DrawBox(a.aa, a.bb, transform, Scene::GetLineColor()); }
void Debug::DrawBox(box3 a, mat4 transform, vec4 color) { Debug::DrawBox(a.aa, a.bb, transform, color); }
void Debug::DrawBox(box2 a, mat2 transform, vec4 color) { Debug::DrawBox(a.aa, a.bb, transform, color); }
void Debug::DrawBox(vec3 a, vec3 b, mat4 transform) { Debug::DrawBox(a, b, transform, Scene::GetLineColor()); }
void Debug::DrawBox(vec2 a, vec2 b, mat2 transform) { Debug::DrawBox(a, b, transform, Scene::GetLineColor()); }
void Debug::DrawBox(vec2 a, float s, mat2 transform) { Debug::DrawBox(a, s, transform, Scene::GetLineColor()); }


+ 5
- 9
src/gpu/renderer.cpp View File

@@ -235,12 +235,12 @@ void Renderer::SetViewport(ibox2 viewport)
return;

#if defined USE_D3D9 || defined _XBOX
D3DVIEWPORT9 vp = { viewport.A.x, viewport.A.y,
viewport.B.x, viewport.B.y,
D3DVIEWPORT9 vp = { viewport.aa.x, viewport.aa.y,
viewport.bb.x, viewport.bb.y,
0.0f, 1.0f };
m_data->m_d3d_dev->SetViewport(&vp);
#else
glViewport(viewport.A.x, viewport.A.y, viewport.B.x, viewport.B.y);
glViewport(viewport.aa.x, viewport.aa.y, viewport.bb.x, viewport.bb.y);
#endif

m_data->m_viewport = viewport;
@@ -253,17 +253,13 @@ ibox2 Renderer::GetViewport() const

float Renderer::GetXYRatio() const
{
ibox2 a = GetViewport();
ibox2 b(a.A, a.B);
ivec2 s = b.B - b.A;
ivec2 s = GetViewport().extent();
return (float)s.x / s.y;
}

float Renderer::GetYXRatio() const
{
ibox2 a = GetViewport();
ibox2 b(a.A, a.B);
ivec2 s = b.B - b.A;
ivec2 s = GetViewport().extent();
return (float)s.y / s.x;
}



+ 8
- 8
src/gradient.cpp View File

@@ -38,8 +38,8 @@ Gradient::Gradient(vec3 aa, vec3 bb)
{
/* FIXME: this should not be hardcoded */
m_position = aa;
m_bbox[0] = aa;
m_bbox[1] = bb;
m_aabb.aa = aa;
m_aabb.bb = bb;

data->shader = nullptr;
}
@@ -53,12 +53,12 @@ void Gradient::TickDraw(float seconds, Scene &scene)
{
Entity::TickDraw(seconds, scene);

float const vertex[] = { m_bbox[0].x, m_bbox[0].y, 0.0f,
m_bbox[1].x, m_bbox[0].y, 0.0f,
m_bbox[0].x, m_bbox[1].y, 0.0f,
m_bbox[1].x, m_bbox[1].y, 0.0f,
m_bbox[0].x, m_bbox[1].y, 0.0f,
m_bbox[1].x, m_bbox[0].y, 0.0f, };
float const vertex[] = { m_aabb.aa.x, m_aabb.aa.y, 0.0f,
m_aabb.bb.x, m_aabb.aa.y, 0.0f,
m_aabb.aa.x, m_aabb.bb.y, 0.0f,
m_aabb.bb.x, m_aabb.bb.y, 0.0f,
m_aabb.aa.x, m_aabb.bb.y, 0.0f,
m_aabb.bb.x, m_aabb.aa.y, 0.0f, };

float const color[] = { 0.73f, 0.85f, 0.85f, 1.0f,
0.73f, 0.85f, 0.85f, 1.0f,


+ 8
- 8
src/image/crop.cpp View File

@@ -22,7 +22,7 @@ namespace lol
Image Image::Crop(ibox2 box) const
{
ivec2 const srcsize = GetSize();
ivec2 const dstsize = box.B - box.A;
ivec2 const dstsize = box.extent();

Image dst(dstsize);
PixelFormat format = GetFormat();
@@ -36,24 +36,24 @@ Image Image::Crop(ibox2 box) const

int len = dstsize.x;

if (box.A.x < 0)
if (box.aa.x < 0)
{
len += box.A.x;
box.A.x = 0;
len += box.aa.x;
box.aa.x = 0;
}

if (box.A.x + len > srcsize.x)
len = srcsize.x - box.A.x;
if (box.aa.x + len > srcsize.x)
len = srcsize.x - box.aa.x;

if (len > 0)
{
for (int y = 0; y < dstsize.y; y++)
{
if (y + box.A.y < 0 || y + box.A.y >= srcsize.y)
if (y + box.aa.y < 0 || y + box.aa.y >= srcsize.y)
continue;

memcpy(dstp + y * dstsize.x * bpp,
srcp + ((y + box.A.y) * srcsize.x + box.A.x) * bpp,
srcp + ((y + box.aa.y) * srcsize.x + box.aa.x) * bpp,
len * bpp);
}
}


+ 12
- 12
src/lol/algorithm/aabb_tree.h View File

@@ -81,8 +81,8 @@ void Draw(Quadtree<TE>* tree, vec4 color)
//vec3 add = vec3(0.0f, 0.1f, 0.0f);
while (boxes.Count() > 0)
{
Debug::DrawBox(vec3(boxes[0].m1.A.x, tree->m_debug_y_offset, boxes[0].m1.A.y),
vec3(boxes[0].m1.B.x, tree->m_debug_y_offset, boxes[0].m1.B.y),
Debug::DrawBox(vec3(boxes[0].m1.aa.x, tree->m_debug_y_offset, boxes[0].m1.aa.y),
vec3(boxes[0].m1.bb.x, tree->m_debug_y_offset, boxes[0].m1.bb.y),
boxes[0].m2);
boxes.Remove(0);
}
@@ -90,8 +90,8 @@ void Draw(Quadtree<TE>* tree, vec4 color)
{
while (elements[0].m2 > 0)
{
Debug::DrawBox(vec3(elements[0].m1->GetAABB().A.x, tree->m_debug_y_offset, elements[0].m1->GetAABB().A.y) + off * (float)elements[0].m2,
vec3(elements[0].m1->GetAABB().B.x, tree->m_debug_y_offset, elements[0].m1->GetAABB().B.y) + off * (float)elements[0].m2,
Debug::DrawBox(vec3(elements[0].m1->GetAABB().aa.x, tree->m_debug_y_offset, elements[0].m1->GetAABB().aa.y) + off * (float)elements[0].m2,
vec3(elements[0].m1->GetAABB().bb.x, tree->m_debug_y_offset, elements[0].m1->GetAABB().bb.y) + off * (float)elements[0].m2,
elements[0].m3);
elements[0].m2--;
}
@@ -112,9 +112,9 @@ void Draw(Octree<TE>* tree, vec4 color)
//vec3 add = vec3(0.0f, 0.1f, 0.0f);
while (boxes.Count() > 0)
{
//float size = boxes[0].m1.B.x - boxes[0].m1.A.x;
Debug::DrawBox(vec3(boxes[0].m1.A.x, boxes[0].m1.A.y, boxes[0].m1.A.z) /* + off * (m_size.x / size) */,
vec3(boxes[0].m1.B.x, boxes[0].m1.B.y, boxes[0].m1.B.z) /* + off * (m_size.x / size) */,
//float size = boxes[0].m1.bb.x - boxes[0].m1.aa.x;
Debug::DrawBox(vec3(boxes[0].m1.aa.x, boxes[0].m1.aa.y, boxes[0].m1.aa.z) /* + off * (m_size.x / size) */,
vec3(boxes[0].m1.bb.x, boxes[0].m1.bb.y, boxes[0].m1.bb.z) /* + off * (m_size.x / size) */,
boxes[0].m2);
//off += add;
boxes.Remove(0);
@@ -123,8 +123,8 @@ void Draw(Octree<TE>* tree, vec4 color)
{
while (elements[0].m2 > 0)
{
Debug::DrawBox(vec3(elements[0].m1->GetAABB().A.x, elements[0].m1->GetAABB().A.y, elements[0].m1->GetAABB().A.z) + off * (float)elements[0].m2,
vec3(elements[0].m1->GetAABB().B.x, elements[0].m1->GetAABB().B.y, elements[0].m1->GetAABB().B.z) + off * (float)elements[0].m2,
Debug::DrawBox(vec3(elements[0].m1->GetAABB().aa.x, elements[0].m1->GetAABB().aa.y, elements[0].m1->GetAABB().aa.z) + off * (float)elements[0].m2,
vec3(elements[0].m1->GetAABB().bb.x, elements[0].m1->GetAABB().bb.y, elements[0].m1->GetAABB().bb.z) + off * (float)elements[0].m2,
elements[0].m3);
elements[0].m2--;
}
@@ -341,9 +341,9 @@ public:
virtual TB GetSubAABB(const TB& bbox, int sub)
{
TV v(GetSubOffset(sub));
TV half_vec = (bbox.B - bbox.A) * .5f;
return TB(bbox.A + half_vec * v,
bbox.A + half_vec * (v + TV(1.f)));
TV half_vec = bbox.extent() * .5f;
return TB(bbox.aa + half_vec * v,
bbox.aa + half_vec * (v + TV(1.f)));
}

//--


+ 62
- 34
src/lol/math/geometry.h View File

@@ -87,23 +87,23 @@ LOL_BOX_TYPEDEFS(Box3, box3)
template <typename T> struct Box2
{
inline Box2()
: A(T(0)),
B(T(0))
: aa(T(0)),
bb(T(0))
{}

inline Box2(vec_t<T,2> const &a, vec_t<T,2> const &b)
: A(a),
B(b)
: aa(a),
bb(b)
{}

inline Box2(T const &ax, T const &ay, T const &bx, T const &by)
: A(ax, ay),
B(bx, by)
: aa(ax, ay),
bb(bx, by)
{}

Box2<T> operator +(vec_t<T,2> const &v) const
{
return Box2<T>(A + v, B + v);
return Box2<T>(aa + v, bb + v);
}

Box2<T> &operator +=(vec_t<T,2> const &v)
@@ -113,7 +113,7 @@ template <typename T> struct Box2

Box2<T> operator -(vec_t<T,2> const &v) const
{
return Box2<T>(A - v, B - v);
return Box2<T>(aa - v, bb - v);
}

Box2<T> &operator -=(vec_t<T,2> const &v)
@@ -123,7 +123,7 @@ template <typename T> struct Box2

Box2<T> operator *(vec_t<T,2> const &v) const
{
return Box2<T>(A * v, B * v);
return Box2<T>(aa * v, bb * v);
}

Box2<T> &operator *=(vec_t<T,2> const &v)
@@ -131,17 +131,31 @@ template <typename T> struct Box2
return *this = *this * v;
}

bool operator ==(Box2<T> const &box)
Box2<T> operator *(T const &s) const
{
return A == box.A && B == box.B;
return Box2<T>(aa * s, bb * s);
}

bool operator !=(Box2<T> const &box)
Box2<T> &operator *=(T const &s)
{
return A != box.A || B != box.B;
return *this = *this * s;
}

vec_t<T,2> A, B;
bool operator ==(Box2<T> const &box) const
{
return aa == box.aa && bb == box.bb;
}

bool operator !=(Box2<T> const &box) const
{
return aa != box.aa || bb != box.bb;
}

inline vec_t<T,2> center() const { return (bb + aa) / 2; }

inline vec_t<T,2> extent() const { return bb - aa; }

vec_t<T,2> aa, bb;
};

/*
@@ -151,24 +165,24 @@ template <typename T> struct Box2
template <typename T> struct Box3
{
inline Box3()
: A(T(0)),
B(T(0))
: aa(T(0)),
bb(T(0))
{}

inline Box3(vec_t<T,3> const &a, vec_t<T,3> const &b)
: A(a),
B(b)
: aa(a),
bb(b)
{}

inline Box3(T const &ax, T const &ay, T const &az,
T const &bx, T const &by, T const &bz)
: A(ax, ay, az),
B(bx, by, bz)
: aa(ax, ay, az),
bb(bx, by, bz)
{}

Box3<T> operator +(vec_t<T,3> const &v) const
{
return Box3<T>(A + v, B + v);
return Box3<T>(aa + v, bb + v);
}

Box3<T> &operator +=(vec_t<T,3> const &v)
@@ -178,7 +192,7 @@ template <typename T> struct Box3

Box3<T> operator -(vec_t<T,3> const &v) const
{
return Box3<T>(A - v, B - v);
return Box3<T>(aa - v, bb - v);
}

Box3<T> &operator -=(vec_t<T,3> const &v)
@@ -188,7 +202,7 @@ template <typename T> struct Box3

Box3<T> operator *(vec_t<T,3> const &v) const
{
return Box3<T>(A * v, B * v);
return Box3<T>(aa * v, bb * v);
}

Box3<T> &operator *=(vec_t<T,3> const &v)
@@ -196,17 +210,31 @@ template <typename T> struct Box3
return *this = *this * v;
}

bool operator ==(Box3<T> const &box)
Box3<T> operator *(T const &s) const
{
return A == box.A && B == box.B;
return Box3<T>(aa * s, bb * s);
}

bool operator !=(Box3<T> const &box)
Box3<T> &operator *=(T const &s)
{
return A != box.A || B != box.B;
return *this = *this * s;
}

vec_t<T,3> A, B;
bool operator ==(Box3<T> const &box) const
{
return aa == box.aa && bb == box.bb;
}

bool operator !=(Box3<T> const &box) const
{
return aa != box.aa || bb != box.bb;
}

inline vec_t<T,3> center() const { return (bb + aa) / 2; }

inline vec_t<T,3> extent() const { return bb - aa; }

vec_t<T,3> aa, bb;
};

/*
@@ -243,9 +271,9 @@ bool operator>=(float value, const TestEpsilon& epsilon);
//--
static inline bool TestAABBVsAABB(box2 const &b1, box2 const &b2)
{
vec2 c = 0.5f * ((b1.A + b1.B) - (b2.A + b2.B));
vec2 e1 = 0.5f * (b1.B - b1.A);
vec2 e2 = 0.5f * (b2.B - b2.A);
vec2 c = b1.center() - b2.center();
vec2 e1 = 0.5f * b1.extent();
vec2 e2 = 0.5f * b2.extent();

return abs(c.x) <= e1.x + e2.x
&& abs(c.y) <= e1.y + e2.y;
@@ -257,9 +285,9 @@ static inline bool TestAABBVsPoint(box2 const &b1, vec2 const &p)

static inline bool TestAABBVsAABB(box3 const &b1, box3 const &b2)
{
vec3 c = 0.5f * ((b1.A + b1.B) - (b2.A + b2.B));
vec3 e1 = 0.5f * (b1.B - b1.A);
vec3 e2 = 0.5f * (b2.B - b2.A);
vec3 c = b1.center() - b2.center();
vec3 e1 = 0.5f * b1.extent();
vec3 e2 = 0.5f * b2.extent();

return abs(c.x) <= e1.x + e2.x
&& abs(c.y) <= e1.y + e2.y


+ 11
- 12
src/tileset.cpp View File

@@ -137,8 +137,8 @@ char const *TileSet::GetName()
ptrdiff_t TileSet::AddTile(ibox2 rect)
{
m_tileset_data->m_tiles.Push(rect,
box2((vec2)rect.A / (vec2)m_data->m_texture_size,
(vec2)rect.B / (vec2)m_data->m_texture_size));
box2((vec2)rect.aa / (vec2)m_data->m_texture_size,
(vec2)rect.bb / (vec2)m_data->m_texture_size));
return m_tileset_data->m_tiles.Count() - 1;
}

@@ -161,8 +161,7 @@ ptrdiff_t TileSet::GetTileCount() const

ivec2 TileSet::GetTileSize(ptrdiff_t tileid) const
{
ibox2 const &box = m_tileset_data->m_tiles[tileid].m1;
return box.B - box.A;
return m_tileset_data->m_tiles[tileid].m1.extent();
}

//Palette ---------------------------------------------------------------------
@@ -186,14 +185,14 @@ void TileSet::BlitTile(uint32_t id, vec3 pos, int o, vec2 scale, float angle,
{
ibox2 pixels = m_tileset_data->m_tiles[id].m1;
box2 texels = m_tileset_data->m_tiles[id].m2;
float dtx = texels.B.x - texels.A.x;
float dty = texels.B.y - texels.A.y;
float tx = texels.A.x;
float ty = texels.A.y;
int dx = (int)((float)(pixels.B.x - pixels.A.x) * scale.x);
int dy = o ? 0 : (int)((float)(pixels.B.y - pixels.A.y) * scale.y);
int dz = o ? (int)((float)(pixels.B.y - pixels.A.y) * scale.y) : 0;
float dtx = texels.extent().x;
float dty = texels.extent().y;
float tx = texels.aa.x;
float ty = texels.aa.y;
int dx = (int)(pixels.extent().x * scale.x);
int dy = o ? 0 : (int)(pixels.extent().y * scale.y);
int dz = o ? (int)(pixels.extent().y * scale.y) : 0;

/* If scaling is negative, switch triangle winding */
if (scale.x * scale.y < 0.0f)


+ 1
- 3
src/video.cpp View File

@@ -132,9 +132,7 @@ void Video::Capture(uint32_t *buffer)

ivec2 Video::GetSize()
{
ibox2 viewport = g_renderer->GetViewport();

return viewport.B - viewport.A;
return g_renderer->GetViewport().extent();
}

} /* namespace lol */


+ 5
- 1
src/worldentity.cpp View File

@@ -20,8 +20,12 @@ namespace lol
*/

WorldEntity::WorldEntity()
: m_aabb(vec3(0.f), vec3(0.f)),
m_position(0.f),
m_velocity(0.f),
m_rotation(1.f),
m_rotation_velocity(0.f)
{
m_bbox[0] = m_bbox[1] = vec3::zero;
}

WorldEntity::~WorldEntity()


+ 1
- 1
src/worldentity.h View File

@@ -28,11 +28,11 @@ public:
virtual char const *GetName();

public:
box3 m_aabb;
vec3 m_position = vec3::zero;
vec3 m_velocity = vec3::zero;
quat m_rotation = quat(1);
vec3 m_rotation_velocity = vec3::zero;
vec3 m_bbox[2];

protected:
WorldEntity();


Loading…
Cancel
Save