Ver código fonte

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 anos atrás
pai
commit
2fa398926d
12 arquivos alterados com 125 adições e 100 exclusões
  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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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 Ver arquivo

@@ -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();


Carregando…
Cancelar
Salvar