Gamp v0.0.7-36-g24b1eb6
Gamp: Graphics, Audio, Multimedia and Processing
Loading...
Searching...
No Matches
GearsES2.cpp
Go to the documentation of this file.
1/*
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright Gothel Software e.K.
4 *
5 * SPDX-License-Identifier: MIT
6 *
7 * This Source Code Form is subject to the terms of the MIT License
8 * If a copy of the MIT was not distributed with this file,
9 * you can obtain one at https://opensource.org/license/mit/.
10 */
11
12#include <gamp/Gamp.hpp>
13
14#include <cstdio>
15#include <cmath>
16#include <memory>
17
18#include <jau/basic_types.hpp>
19#include <jau/file_util.hpp>
20#include <jau/float_types.hpp>
21#include <jau/fraction_type.hpp>
22
23#include <gamp/Gamp.hpp>
25
26#include "../demos/GearsES2.hpp"
28
29using namespace jau::math;
30using namespace jau::math::util;
31
32using namespace gamp::wt;
33using namespace gamp::wt::event;
34
35class Example : public GearsES2 {
36 private:
37 class MyKeyListener : public KeyListener {
38 private:
39 GearsES2& m_parent;
40
41 public:
42 MyKeyListener(GearsES2& p): m_parent(p) { }
43
44 void keyPressed(KeyEvent& e, const KeyboardTracker&) override {
45 const VKeyCode kc = e.keySym();
46 if( e.keySym() == VKeyCode::VK_ESCAPE ) {
47 WindowRef win = e.source().lock();
48 if( win ) {
49 win->dispose(e.when());
50 }
51 } else if( kc == VKeyCode::VK_PAUSE || kc == VKeyCode::VK_P ) {
52 m_parent.setDoRotate(!m_parent.doRotate());
53 } else if( kc == VKeyCode::VK_W ) {
54 WindowRef win = e.source().lock();
55 jau::fprintf_td(e.when().to_ms(), stdout, "Source: %s\n", win ? win->toString().c_str() : "null");
56 } else if( VKeyCode::VK_LEFT == kc ) {
57 m_parent.rotEuler().y -= jau::adeg_to_rad(1.0f);
58 } else if( VKeyCode::VK_RIGHT == kc ) {
59 m_parent.rotEuler().y += jau::adeg_to_rad(1.0f);
60 } else if( VKeyCode::VK_UP == kc ) {
61 m_parent.rotEuler().x -= jau::adeg_to_rad(1.0f);
62 } else if( VKeyCode::VK_DOWN == kc ) {
63 m_parent.rotEuler().x += jau::adeg_to_rad(1.0f);
64 }
65 }
66 };
67 typedef std::shared_ptr<MyKeyListener> MyKeyListenerRef;
68
69 class MyPointerListener : public PointerListener {
70 private:
71 GearsES2& m_parent;
72 jau::math::Vec2i preWinPos;
73 jau::math::Vec3f startPos;
74 GearsObjectES2* m_picked = nullptr;
75 bool m_dragInit = true;
76
77 bool mapWinToObj(const GearsObjectES2& shape, const jau::math::Vec2i& winPos, jau::math::Vec3f& viewPos) noexcept {
78 // OK global: m_parent.m_pmvMatrix, m_parent.m_viewport
79 const jau::math::Vec3f& ctr = shape.objBounds().center();
80 if( m_parent.pmvMatrix().mapObjToWin(ctr, m_parent.viewport(), viewPos) ) {
81 const float winZ = viewPos.z;
82 return m_parent.pmvMatrix().mapWinToObj((float)winPos.x, (float)winPos.y, winZ, m_parent.viewport(), viewPos);
83 }
84 return false;
85 }
86 bool mapWinToObjRay(const jau::math::Vec2i& pos, jau::math::Ray3f& ray, const Mat4f& mPmvi) noexcept {
87 // OK global: m_parent.m_pmvMatrix, m_parent.m_viewport
88 constexpr float winZ0 = 0.0f;
89 constexpr float winZ1 = 0.3f;
90 return Mat4f::mapWinToAnyRay((float)pos.x, (float)pos.y, winZ0, winZ1, mPmvi, m_parent.viewport(), ray);
91 }
92
93 bool pick(const PointerEvent& e, const WindowRef&, GearsObjectES2& shape) noexcept {
94 // While being processed fast w/o matrix traversal of shapes,
95 // we still need to use the cached PMvi matrix for win->obj ray for accuracy.
96 // A win->view ray fails in certain angles in edge cases!
97 jau::math::Vec3f objPos;
98 jau::math::Ray3f objRay;
99 const jau::math::Vec2i& winPos = e.position();
100 if( !mapWinToObjRay(winPos, objRay, shape.matPMvi()) ) {
101 return false;
102 }
103 const jau::math::geom::AABBox3f& objBox = shape.objBounds();
104
105 if( !objBox.intersectsRay(objRay) ) {
106 return false;
107 }
108 if( !objBox.getRayIntersection(objPos, objRay, std::numeric_limits<float>::epsilon(), /*assumeIntersection=*/true) ) {
109 printf("obj getRayIntersection failed\n");
110 return false;
111 }
112 preWinPos = winPos;
113 printf("XXX pick: mouse %s -> %s\n", winPos.toString().c_str(), objPos.toString().c_str());
114 printf("XXX pick: %s\n", shape.toString().c_str());
115 return true;
116 }
117
118 bool navigate(const PointerEvent& e, const WindowRef& win, GearsObjectES2& shape) noexcept {
119 jau::math::Vec3f objPos;
120 const jau::math::Vec2i& winPos = e.position();
121 if( !mapWinToObj(shape, winPos, objPos) ) {
122 return false;
123 }
124 if( e.isControlDown() ) {
125 if( m_dragInit ) {
126 m_dragInit = false;
127 startPos = objPos;
128 } else {
130 jau::math::Vec3f diffPos = ( objPos - startPos ).mul(flip);
131 m_parent.pan() += diffPos;
132 }
133 } else {
134 const jau::math::Vec2i& sdim = win->surfaceSize();
135 const float thetaY = 360.0f * ((float)(winPos.x - preWinPos.x) / (float)sdim.x);
136 const float thetaX = 360.0f * ((float)(preWinPos.y - winPos.y) / (float)sdim.y);
137 m_parent.rotEuler().x += jau::adeg_to_rad(thetaX);
138 m_parent.rotEuler().y += jau::adeg_to_rad(thetaY);
139 m_dragInit = true;
140 }
141 preWinPos = winPos;
142 // printf("XXX navi: mouse %s -> %s\n", winPos.toString().c_str(), objPos.toString().c_str());
143 return true;
144 }
145
146 PointerShapeAction pickAction, navigateAction;
147
148 public:
149 MyPointerListener(GearsES2& p): m_parent(p) {
150 pickAction = jau::bind_member(this, &MyPointerListener::pick);
151 navigateAction = jau::bind_member(this, &MyPointerListener::navigate);
152 }
153 void pointerPressed(PointerEvent& e) override {
154 if( e.pointerCount() == 1 ) {
155 WindowRef win = e.source().lock();
156 if( !win ) {
157 return;
158 }
159 GearsObjectES2* new_pick = m_parent.findPick(pickAction, e, win); // no matrix traversal
160 if( m_picked ) {
161 m_picked->picked() = false;
162 }
163 m_picked = new_pick;
164 if( m_picked ) {
165 m_picked->picked() = true;
166 }
167 }
168 }
169 void pointerDragged(PointerEvent& e) override {
170 if( m_picked ) {
171 WindowRef win = e.source().lock();
172 if( !win ) {
173 return;
174 }
175 if( !m_parent.dispatchForShape(*m_picked, navigateAction, e, win) ) { // matrix traversal
176 if( m_picked ) {
177 m_picked->picked() = false;
178 }
179 m_picked = nullptr;
180 printf("XXX shape: lost\n");
181 }
182 }
183 }
184 void pointerWheelMoved(PointerEvent& e) override {
185 const jau::math::Vec3f& rot = e.rotation();
186 if( e.isControlDown() ) {
187 // alternative zoom
188 float incr = e.isShiftDown() ? rot.x : rot.y * 0.5f;
189 m_parent.pan().z += incr;
190 } else {
191 // panning
192 m_parent.pan().x -= rot.x; // positive -> left
193 m_parent.pan().y += rot.y; // positive -> up
194 }
195 }
196 void pointerReleased(PointerEvent&) override {
197 if( m_picked ) {
198 m_picked->picked() = false;
199 printf("XXX shape: released\n");
200 }
201 m_picked = nullptr;
202 m_dragInit = true;
203 }
204 };
205 typedef std::shared_ptr<MyPointerListener> MyPointerListenerRef;
206
207 MyKeyListenerRef m_kl;
208 MyPointerListenerRef m_pl;
209
210 public:
212 : GearsES2(),
213 m_kl(std::make_shared<MyKeyListener>(*this)),
214 m_pl(std::make_shared<MyPointerListener>(*this))
215 { }
216
217 bool init(const WindowRef& win, const jau::fraction_timespec& when) override {
218 if( !GearsES2::init(win, when) ) {
219 return false;
220 }
221 win->addKeyListener(m_kl);
222 win->addPointerListener(m_pl);
223 return true;
224 }
225 void dispose(const WindowRef& win, const jau::fraction_timespec& when) override {
226 win->removeKeyListener(m_kl);
227 win->removePointerListener(m_pl);
228 GearsES2::dispose(win, when);
229 }
230};
231
232int main(int argc, char *argv[]) // NOLINT(bugprone-exception-escape)
233{
234 return launch("GearsES2.hpp",
236 std::make_shared<Example>(), argc, argv);
237}
int launch(std::string_view sfile, const GLLaunchProps &props, const RenderListenerRef &demo, int argc, char *argv[])
int main(int argc, char *argv[])
Definition GearsES2.cpp:232
jau::function< bool(const PointerEvent &e, const WindowRef &win, GearsObjectES2 &shape)> PointerShapeAction
Definition GearsES2.hpp:49
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
Definition GearsES2.cpp:217
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
Definition GearsES2.cpp:225
constexpr Vec3f & pan() noexcept
Definition GearsES2.hpp:430
bool init(const WindowRef &win, const jau::fraction_timespec &when) override
Called by the drawable immediately after the render context is initialized.
Definition GearsES2.hpp:452
constexpr bool doRotate() const noexcept
Definition GearsES2.hpp:423
constexpr void setDoRotate(bool rotate) noexcept
Definition GearsES2.hpp:424
GearsObjectES2 * findPick(const PointerShapeAction &action, const PointerEvent &e, const WindowRef &win)
Fast loop through all shapes using PointerShapeAction w/o matrix traversal using view-coordinates.
Definition GearsES2.hpp:614
constexpr jau::math::Vec3f & rotEuler() noexcept
Definition GearsES2.hpp:431
constexpr const jau::math::Recti & viewport() const noexcept
Definition GearsES2.hpp:429
bool dispatchForShape(GearsObjectES2 &shape, const PointerShapeAction &action, const PointerEvent &e, const WindowRef &win)
Dispatch PointerShapeAction to given shape w/ matrix traversal.
Definition GearsES2.hpp:634
constexpr PMVMat4f & pmvMatrix() noexcept
Definition GearsES2.hpp:427
void dispose(const WindowRef &win, const jau::fraction_timespec &when) override
Notifies the listener to perform the release of all renderer resources per context,...
Definition GearsES2.hpp:505
GearsObjectES2.
Definition GearsES2.hpp:55
std::string toString() const noexcept
Definition GearsES2.hpp:371
const jau::math::geom::AABBox3f & objBounds() const noexcept
Definition GearsES2.hpp:367
bool & picked() noexcept
Definition GearsES2.hpp:366
const jau::math::Mat4f & matPMvi() const noexcept
Definition GearsES2.hpp:369
Specifies the OpenGL profile.
Definition GLContext.hpp:41
static constexpr std::string_view GLES2
The embedded OpenGL profile ES 2.x, with x >= 0.
Definition GLContext.hpp:64
constexpr const Vec2i & surfaceSize() const noexcept
Returns the surface size of the client area excluding insets (window decorations) in pixel units.
Definition Surface.hpp:171
size_t removeKeyListener(const KeyListenerRef &l)
Definition Window.hpp:311
size_t removePointerListener(const PointerListenerRef &l)
Definition Window.hpp:325
void addPointerListener(const PointerListenerRef &l)
Definition Window.hpp:324
void dispose(const jau::fraction_timespec &when) noexcept override
Definition Window.hpp:355
std::string toString() const noexcept
Definition gamp_wt.cpp:145
void addKeyListener(const KeyListenerRef &l)
Definition Window.hpp:310
constexpr bool isShiftDown() const noexcept
Returns true if modifier() contains InputModifier::shift.
Definition Event.hpp:285
constexpr bool isControlDown() const noexcept
Returns true if modifier() contains InputModifier::ctrl.
Definition Event.hpp:277
constexpr VKeyCode keySym() const noexcept
Returns the virtual key symbol reflecting the current keyboard layout.
Definition KeyEvent.hpp:798
Listener for multiple KeyEvent.
Definition KeyEvent.hpp:894
Pointer event of type PointerType.
constexpr const jau::math::Vec2i & position(size_t index=0) const noexcept
Returns position of given pointer-index in pixel units.
constexpr size_t pointerCount() const noexcept
See details for multiple-pointer events.
constexpr const jau::math::Vec3f & rotation() const noexcept
Returns a 3-component float array filled with the values of the rotational axis in the following orde...
Listener for PointerEvent.
constexpr const WindowWeakPtr & source() const noexcept
Definition Event.hpp:85
constexpr const jau::fraction_timespec & when() const noexcept
Definition Event.hpp:84
static bool mapWinToAnyRay(const value_type winx, const value_type winy, const value_type winz0, const value_type winz1, const Matrix4 &invAny, const Recti &viewport, Ray3 &ray) noexcept
Definition mat4f.hpp:1915
value_type x
Definition vec2i.hpp:65
std::string toString() const noexcept
Definition vec2i.hpp:211
value_type y
Definition vec2i.hpp:66
value_type x
Definition vec3f.hpp:69
value_type y
Definition vec3f.hpp:70
std::string toString() const noexcept
Definition vec3f.hpp:239
value_type z
Definition vec3f.hpp:71
Axis Aligned Bounding Box.
Definition aabbox3f.hpp:43
constexpr bool intersectsRay(const Ray3f &r) const noexcept
Check if Ray intersects this bounding box.
Definition aabbox3f.hpp:533
bool getRayIntersection(Vec3f &result, const Ray3f &ray, const float epsilon, const bool assumeIntersection) const noexcept
Return intersection of a Ray with this bounding box, or false if none exist.
Definition aabbox3f.hpp:578
constexpr const Point3f & center() const noexcept
Returns computed center of this aabbox3f of low() and high().
Definition aabbox3f.hpp:105
bool mapWinToObj(const float winx, const float winy, const float winz, const Recti &viewport, Vec3 &objPos) noexcept
Map window coordinates to object coordinates.
Definition pmvmat4f.hpp:935
bool mapObjToWin(const Vec3 &objPos, const Recti &viewport, Vec3 &winPos) const noexcept
Map object coordinates to window coordinates.
Definition pmvmat4f.hpp:888
constexpr T adeg_to_rad(const T arc_degree) noexcept
Converts arc-degree to radians.
jau::function< R(A...)> bind_member(C1 *base, R(C0::*mfunc)(A...)) noexcept
Bind given class instance and non-void member function to an anonymous function using func_member_tar...
@ verbose
Verbose operations (debugging).
VKeyCode
Virtual key code following UTF16 specification.
Definition KeyEvent.hpp:45
std::shared_ptr< Window > WindowRef
Definition Event.hpp:36
@ VK_ESCAPE
Constant for the ESCAPE function key.
Definition KeyEvent.hpp:129
@ VK_RIGHT
Constant for the cursor- or numerical-pad right arrow key.
Definition KeyEvent.hpp:461
@ VK_DOWN
Constant for the cursor- or numerical pad down arrow key.
Definition KeyEvent.hpp:464
@ VK_UP
Constant for the cursor- or numerical-pad up arrow key.
Definition KeyEvent.hpp:458
@ VK_LEFT
Constant for the cursor- or numerical-pad left arrow key.
Definition KeyEvent.hpp:455
@ VK_PAUSE
Constant for the PAUSE function key.
Definition KeyEvent.hpp:115
Matrix4< float > Mat4f
Definition mat4f.hpp:1973
Vector2I< int > Vec2i
Definition vec2i.hpp:328
Ray3F< float > Ray3f
Definition vec3f.hpp:502
constexpr jau::math::Vec3f getEulerAngleOrientation(const jau::math::Vec3f &eulerRotation) noexcept
Returns an orientation vector for given eurler X/Y/Z angles in radians.
Vector3F< float > Vec3f
Definition vec3f.hpp:436
int fprintf_td(const uint64_t elapsed_ms, FILE *stream, const char *format,...) noexcept
Convenient fprintf() invocation, prepending the given elapsed_ms timestamp.
Definition debug.cpp:270
STL namespace.
Timespec structure using int64_t for its components in analogy to struct timespec_t on 64-bit platfor...
constexpr uint64_t to_ms() const noexcept
Returns time in milliseconds.
int printf(const char *format,...)
Operating Systems predefined macros.