Implement clipping for DrawableLine.
This commit is contained in:
parent
634503bf00
commit
488c31c57e
11 changed files with 309 additions and 8 deletions
|
@ -40,7 +40,7 @@ namespace cloonel {
|
|||
m_bounceCallback(&DoNothing),
|
||||
m_texture(new Texture(parPath, parMain, false))
|
||||
#if defined(WITH_DEBUG_VISUALS)
|
||||
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), static_cast<ushort2>(m_bottomBar.From()), static_cast<ushort2>(m_bottomBar.To()))
|
||||
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), static_cast<short2>(m_bottomBar.From()), static_cast<short2>(m_bottomBar.To()))
|
||||
#endif
|
||||
{
|
||||
assert(parMain);
|
||||
|
@ -57,7 +57,7 @@ namespace cloonel {
|
|||
m_bounceCallback(&DoNothing),
|
||||
m_texture(new Texture(parPath, parMain, false))
|
||||
#if defined(WITH_DEBUG_VISUALS)
|
||||
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), static_cast<ushort2>(m_bottomBar.From()), static_cast<ushort2>(m_bottomBar.To()))
|
||||
, m_bottomBarDrawable(parMain, Colour(250, 5, 1), static_cast<short2>(m_bottomBar.From()), static_cast<short2>(m_bottomBar.To()))
|
||||
#endif
|
||||
{
|
||||
assert(parMain);
|
||||
|
|
|
@ -20,15 +20,68 @@
|
|||
|
||||
#include "drawableline.hpp"
|
||||
#include "sdlmain.hpp"
|
||||
#include "geometry_2d.hpp"
|
||||
#if !defined(NDEBUG)
|
||||
# include "line_helpers.hpp"
|
||||
#endif
|
||||
#include <SDL2/SDL.h>
|
||||
#include <algorithm>
|
||||
|
||||
#if defined(WITH_DEBUG_VISUALS)
|
||||
namespace cloonel {
|
||||
namespace {
|
||||
///----------------------------------------------------------------------
|
||||
///----------------------------------------------------------------------
|
||||
void ClipLine (const SDL_Rect& /*parArea*/, Line<uint16_t, 2>& /*parLine*/) {
|
||||
void ClipLine (const SDL_Rect& parArea, Line<int16_t, 2>& parLine) {
|
||||
Line<float, 2> line(static_cast<float2>(parLine[0]), static_cast<float2>(parLine[1]));
|
||||
const float al = static_cast<float>(parArea.x);
|
||||
const float at = static_cast<float>(parArea.y);
|
||||
const float ar = static_cast<float>(parArea.x + parArea.w);
|
||||
const float ab = static_cast<float>(parArea.y + parArea.h);
|
||||
|
||||
{
|
||||
const Line<float, 2> leftLine(al, at, al, ab);
|
||||
const auto intersection(Intersection(line, leftLine));
|
||||
if (intersection.first) {
|
||||
if (line[0] < leftLine)
|
||||
line[0] = intersection.second;
|
||||
if (line[1] < leftLine)
|
||||
line[1] = intersection.second;
|
||||
}
|
||||
}
|
||||
{
|
||||
const Line<float, 2> rightLine(ar, at, ar, ab);
|
||||
const auto intersection(Intersection(line, rightLine));
|
||||
if (intersection.first) {
|
||||
if (line[0] > rightLine)
|
||||
line[0] = intersection.second;
|
||||
if (line[1] > rightLine)
|
||||
line[1] = intersection.second;
|
||||
}
|
||||
}
|
||||
{
|
||||
const Line<float, 2> topLine(al, at, ar, at);
|
||||
const auto intersection(Intersection(line, topLine));
|
||||
if (intersection.first) {
|
||||
if (line[0] < topLine)
|
||||
line[0] = intersection.second;
|
||||
if (line[1] < topLine)
|
||||
line[1] = intersection.second;
|
||||
}
|
||||
}
|
||||
{
|
||||
const Line<float, 2> bottomLine(al, ab, ar, ab);
|
||||
const auto intersection(Intersection(line, bottomLine));
|
||||
if (intersection.first) {
|
||||
if (line[0] > bottomLine)
|
||||
line[0] = intersection.second;
|
||||
if (line[1] > bottomLine)
|
||||
line[1] = intersection.second;
|
||||
}
|
||||
}
|
||||
|
||||
parLine[0] = static_cast<short2>(line[0]);
|
||||
parLine[1] = static_cast<short2>(line[1]);
|
||||
}
|
||||
} //unnamed namespace
|
||||
|
||||
|
@ -56,18 +109,18 @@ namespace cloonel {
|
|||
SDL_SetRenderDrawColor(m_sdlmain->GetRenderer(), m_colour.r, m_colour.g, m_colour.b, m_colour.a);
|
||||
|
||||
LineBase scaledLine(*this);
|
||||
scaledLine += static_cast<ushort2>(parPos);
|
||||
scaledLine += static_cast<short2>(parPos);
|
||||
scaledLine *= parScaling;
|
||||
{
|
||||
SDL_Rect screen;
|
||||
screen.x = screen.y = 0;
|
||||
const ushort2 wh(m_sdlmain->WidthHeight());
|
||||
const short2 wh(static_cast<short2>(m_sdlmain->WidthHeight()));
|
||||
screen.w = wh.x();
|
||||
screen.h = wh.y();
|
||||
|
||||
ClipLine(screen, scaledLine);
|
||||
}
|
||||
const uint16_t h = m_sdlmain->WidthHeight().y();
|
||||
const int16_t h = static_cast<int16_t>(m_sdlmain->WidthHeight().y());
|
||||
if (scaledLine[0] != scaledLine[1]) {
|
||||
SDL_RenderDrawLine(
|
||||
m_sdlmain->GetRenderer(),
|
||||
|
|
|
@ -30,8 +30,8 @@
|
|||
namespace cloonel {
|
||||
class SDLMain;
|
||||
|
||||
class DrawableLine : public Line<uint16_t, 2> {
|
||||
typedef Line<uint16_t, 2> LineBase;
|
||||
class DrawableLine : public Line<int16_t, 2> {
|
||||
typedef Line<int16_t, 2> LineBase;
|
||||
public:
|
||||
explicit DrawableLine ( SDLMain* parMain );
|
||||
explicit DrawableLine ( SDLMain* parMain, Colour parColour );
|
||||
|
|
25
src/geometry.cpp
Normal file
25
src/geometry.cpp
Normal file
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "geometry.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
} //namespace cloonel
|
34
src/geometry.hpp
Normal file
34
src/geometry.hpp
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef id3E40B29606D048569E18083DB682280F
|
||||
#define id3E40B29606D048569E18083DB682280F
|
||||
|
||||
#include "vector.hpp"
|
||||
#include <ciso646>
|
||||
#include <algorithm>
|
||||
|
||||
namespace cloonel {
|
||||
template <typename T, uint32_t S>
|
||||
bool IsPointOnSegment ( const Vector<T, S>& parPoint, const Vector<T, S>& parSegA, const Vector<T, S>& parSegB ) __attribute__((pure));
|
||||
} //namespace cloonel
|
||||
|
||||
#include "geometry.inl"
|
||||
|
||||
#endif
|
31
src/geometry.inl
Normal file
31
src/geometry.inl
Normal file
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace cloonel {
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T, uint32_t S>
|
||||
bool IsPointOnSegment (const Vector<T, S>& parPoint, const Vector<T, S>& parSegA, const Vector<T, S>& parSegB) {
|
||||
for (uint32_t z = 0; z < S; ++z) {
|
||||
if (parPoint[z] <= std::max(parSegA[z], parSegB[z]) and parPoint[z] >= std::min(parSegA[z], parSegB[z]))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} //namespace cloonel
|
23
src/geometry_2d.cpp
Normal file
23
src/geometry_2d.cpp
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "geometry_2d.hpp"
|
||||
|
||||
namespace cloonel {
|
||||
} //namespace cloonel
|
43
src/geometry_2d.hpp
Normal file
43
src/geometry_2d.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "vector.hpp"
|
||||
#include "line.hpp"
|
||||
#include "geometry.hpp"
|
||||
#include <ciso646>
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#ifndef id2B404E7CFDD3470680E572779CB819F6
|
||||
#define id2B404E7CFDD3470680E572779CB819F6
|
||||
|
||||
namespace cloonel {
|
||||
template <typename T>
|
||||
int GetOrientation ( const Vector<T, 2>& parPointA, const Vector<T, 2>& parPointB, const Vector<T, 2>& parPointC ) __attribute__((pure));
|
||||
|
||||
template <typename T>
|
||||
bool Intersection2D ( const Vector<T, 2>& parSegA1, const Vector<T, 2>& parSegA2, const Vector<T, 2>& parSegB1, const Vector<T, 2>& parSegB2 ) __attribute__((pure));
|
||||
|
||||
template <typename T>
|
||||
std::pair<bool, Vector<T, 2>> Intersection ( const Line<T, 2>& parSegA, const Line<T, 2>& parSegB ) __attribute__((pure));
|
||||
} //namespace cloonel
|
||||
|
||||
#include "geometry_2d.inl"
|
||||
|
||||
#endif
|
88
src/geometry_2d.inl
Normal file
88
src/geometry_2d.inl
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2014 Michele "King_DuckZ" Santullo
|
||||
|
||||
This file is part of CloonelJump.
|
||||
|
||||
CloonelJump is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
CloonelJump is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with CloonelJump. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
namespace cloonel {
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
int GetOrientation (const Vector<T, 2>& parPointA, const Vector<T, 2>& parPointB, const Vector<T, 2>& parPointC) {
|
||||
const auto ret =
|
||||
(parPointB.y() - parPointA.y()) * (parPointC.x() - parPointB.x()) -
|
||||
(parPointB.x() - parPointA.x()) * (parPointC.y() - parPointB.y());
|
||||
const T zero(0);
|
||||
if (ret == zero)
|
||||
return 0;
|
||||
else if (ret < zero)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
bool Intersection2D (const Vector<T, 2>& parSegA1, const Vector<T, 2>& parSegA2, const Vector<T, 2>& parSegB1, const Vector<T, 2>& parSegB2) {
|
||||
const int o1 = GetOrientation(parSegA1, parSegA2, parSegB1);
|
||||
const int o2 = GetOrientation(parSegA1, parSegA2, parSegB2);
|
||||
const int o3 = GetOrientation(parSegB1, parSegB2, parSegA1);
|
||||
const int o4 = GetOrientation(parSegB1, parSegB2, parSegA2);
|
||||
|
||||
if (o1 != o2 and o3 != o4)
|
||||
return true;
|
||||
|
||||
if (0 == o1 and IsPointOnSegment(parSegA1, parSegB1, parSegA2))
|
||||
return true;
|
||||
if (0 == o2 and IsPointOnSegment(parSegA1, parSegB2, parSegA2))
|
||||
return true;
|
||||
if (0 == o3 and IsPointOnSegment(parSegB1, parSegA1, parSegB2))
|
||||
return true;
|
||||
if (0 == o4 and IsPointOnSegment(parSegB1, parSegA2, parSegB2))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
///--------------------------------------------------------------------------
|
||||
///http://www.gidforums.com/t-20866.html
|
||||
///--------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
std::pair<bool, Vector<T, 2>> Intersection (const Line<T, 2>& parSegA, const Line<T, 2>& parSegB) {
|
||||
typedef Line<T, 2> LineType;
|
||||
|
||||
const typename LineType::Point& startA = parSegA[0];
|
||||
const typename LineType::Point& endA = parSegA[1];
|
||||
const typename LineType::Point& startB = parSegB[0];
|
||||
const typename LineType::Point& endB = parSegB[1];
|
||||
|
||||
const T A1(endA.y() - startA.y());
|
||||
const T A2(endB.y() - startB.y());
|
||||
const T B1(startA.x() - endA.x());
|
||||
const T B2(startB.x() - endB.x());
|
||||
const T det(A1 * B2 - A2 * B1);
|
||||
|
||||
if (det == 0) {
|
||||
return std::make_pair(false, typename LineType::Point(0));
|
||||
}
|
||||
else {
|
||||
const T C1(A1 * startA.x() + B1 * startA.y());
|
||||
const T C2(A2 * startB.x() + B2 * startB.y());
|
||||
return std::make_pair(true, typename LineType::Point((B2 * C1 - B1 * C2) / det, (A1 * C2 - A2 * C1) / det));
|
||||
}
|
||||
}
|
||||
} //namespace cloonel
|
|
@ -44,6 +44,7 @@ namespace cloonel {
|
|||
void MoverSine::ApplyMotion (float parDelta) {
|
||||
const float pitwo = static_cast<float>(M_PI) * 2.0f;
|
||||
m_alpha += parDelta * 2.6f;
|
||||
//TODO: optimize - see https://groups.google.com/forum/#!topic/comp.graphics.api.opengl/FFl3djAYERs
|
||||
while (m_alpha >= pitwo)
|
||||
m_alpha -= pitwo;
|
||||
}
|
||||
|
|
|
@ -116,6 +116,9 @@ namespace cloonel {
|
|||
|
||||
typedef Vector<float, 2> float2;
|
||||
typedef Vector<uint16_t, 2> ushort2;
|
||||
#if !defined(NDEBUG)
|
||||
typedef Vector<int16_t, 2> short2;
|
||||
#endif
|
||||
typedef Vector<int32_t, 2> int2;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
|
|
Loading…
Reference in a new issue