11#ifndef JAU_GAMP_GRAPH_UI_SHAPE_HPP_
12#define JAU_GAMP_GRAPH_UI_SHAPE_HPP_
40 using namespace jau::math;
41 using namespace jau::math::util;
42 using namespace jau::math::geom;
44 using namespace gamp::wt;
45 using namespace gamp::wt::event;
47 using namespace gamp::graph;
49 using namespace jau::int_literals;
51 using namespace jau::enums;
171 bool iMatIdent =
true;
172 bool iMatDirty =
false;
175 std::mutex dirtySync;
231 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
232 constexpr float&
zOffset() noexcept { iMatDirty=
true;
return m_zOffset; }
240 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
241 constexpr Vec3f&
scale() noexcept { iMatDirty=
true;
return m_scale; }
246 constexpr const Vec4f&
color() const noexcept {
return m_color; }
286 const bool _isPressed =
isPressed(), _isToggleOn = isToggleOn();
318 synchronized ( dirtySync ) {
322 if( null != onDrawListener ) {
323 if( onDrawListener.run(
this,
gl, renderer) ) {
324 onDrawListener = null;
338 synchronized ( dirtySync ) {
339 if( isShapeDirty() ) {
357 synchronized ( dirtySync ) {
358 if( isShapeDirty() ) {
405 void updateMat() noexcept {
406 bool hasPos = !m_position.
is_zero();
409 bool hasRotPivot =
false;
411 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
413 if( sameScaleRotatePivot ) {
421 }
else if( hasRotate || hasScale ) {
439 iMat.translate(
Vec3f(ctr).mul(m_scale));
441 iMat.translate(
Vec3f(-ctr).mul(m_scale));
443 }
else if( hasPos ) {
445 iMat.setToTranslation(m_position);
462 GearsObjectES2* m_picked =
nullptr;
463 bool m_dragInit =
true;
469 const float winZ = viewPos.z;
476 constexpr float winZ0 = 0.0f;
477 constexpr float winZ1 = 0.3f;
481 bool pick(
const PointerEvent& e,
const WindowRef&, GearsObjectES2& shape)
noexcept {
488 if( !mapWinToObjRay(winPos, objRay, shape.matPMvi()) ) {
491 const jau::math::geom::AABBox3f& objBox = shape.objBounds();
496 if( !objBox.
getRayIntersection(objPos, objRay, std::numeric_limits<float>::epsilon(),
true) ) {
497 printf(
"obj getRayIntersection failed\n");
502 printf(
"XXX pick: %s\n", shape.toString().c_str());
506 bool navigate(
const PointerEvent& e,
const WindowRef& win, GearsObjectES2& shape)
noexcept {
509 if( !mapWinToObj(shape, winPos, objPos) ) {
512 if( e.isControlDown() ) {
519 m_parent.
pan() += diffPos;
523 const float thetaY = 360.0f * ((float)(winPos.
x - preWinPos.
x) / (float)sdim.
x);
524 const float thetaX = 360.0f * ((float)(preWinPos.
y - winPos.
y) / (float)sdim.
y);
537 MyPointerListener(GearsES2& p): m_parent(p) {
541 void pointerPressed(PointerEvent& e)
override {
547 GearsObjectES2* new_pick = m_parent.
findPick(pickAction, e, win);
549 m_picked->
picked() =
false;
553 m_picked->
picked() =
true;
557 void pointerDragged(PointerEvent& e)
override {
565 m_picked->
picked() =
false;
568 printf(
"XXX shape: lost\n");
572 void pointerWheelMoved(PointerEvent& e)
override {
577 m_parent.
pan().
z += incr;
580 m_parent.
pan().
x -= rot.
x;
581 m_parent.
pan().
y += rot.
y;
584 void pointerReleased(PointerEvent&)
override {
586 m_picked->
picked() =
false;
587 printf(
"XXX shape: released\n");
593 typedef std::shared_ptr<MyPointerListener> MyPointerListenerRef;
jau::function< bool(const PointerEvent &e, const WindowRef &win, GearsObjectES2 &shape)> PointerShapeAction
constexpr Vec3f & pan() noexcept
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.
constexpr jau::math::Vec3f & rotEuler() noexcept
constexpr const jau::math::Recti & viewport() const noexcept
bool dispatchForShape(GearsObjectES2 &shape, const PointerShapeAction &action, const PointerEvent &e, const WindowRef &win)
Dispatch PointerShapeAction to given shape w/ matrix traversal.
PMVMat4f & pmvMatrix() noexcept
A Generic shape objects which is defined by a list of Outlines.
const AABBox3f & bounds() const noexcept
Container interface of UI Shapes.
jau::math::geom::AABBox3f box
virtual bool hasColorChannel() const noexcept
Returns true if implementation uses an extra color channel or texture which will be modulated with th...
constexpr void setColor(const Vec4f &c) noexcept
virtual void validateImpl(const render::gl::GL &gl, const render::gl::GLProfile &glp) noexcept
virtual void destroyImpl0(const render::gl::GL &gl, RegionRenderer &renderer)
Custom destroy(GL2ES2, RegionRenderer) task, called 1st.
jau::function< void(ShapeRef &s, const Vec3f &pos, const PointerEvent &e)> PointerEventCallback
Shape pointer listener, e.g.
constexpr const Vec3f & position() const noexcept
virtual void clearImpl0(const render::gl::GL &gl, RegionRenderer &renderer)
Custom clear(GL2ES2, RegionRenderer) task, called 1st.
static constexpr Vec4f toggleOnRGBAModulate
Default toggle color-factor (darker), modulates base-color.
jau::function< bool(ShapeRef &s, PMVMat4f &pmv)> Visitor2Func
Visitor2 method.
Shape & setPressed(bool b) noexcept
constexpr Quat4f & rotation() noexcept
static constexpr Vec4f rgbaColor
Default base-color w/o color channel, will be modulated w/ pressed- and toggle color.
constexpr const Quat4f & rotation() const noexcept
constexpr const Vec3f & scale() const noexcept
static constexpr const uint32_t DIRTY_STATE
virtual void drawToSelectImpl0(const render::gl::GL &gl, RegionRenderer &renderer)
Actual draw implementation, called by drawToSelect(GL2ES2, RegionRenderer).
final Shape validate(final GLProfile glp)
Validates the shape's underlying GLRegion w/o a current GL2ES2 object.
constexpr Vec3f & rotationPivot() noexcept
constexpr const float & zOffset() const noexcept
bool isPressed() const noexcept
bool isToggleable() const noexcept
Returns true if this shape is toggable, i.e.
static constexpr Vec4f toggleOffRGBAModulate
Default toggle color-factor (original), modulates base-color.
static constexpr Vec4f cWhite
void draw(render::gl::GL &gl, RegionRenderer &renderer) noexcept
Renders the shape.
virtual Container * asContainer() const noexcept
static constexpr const uint32_t DIRTY_SHAPE
Shape draw listener action returning a boolean value
constexpr const Vec4f & color() const noexcept
bool activeRGBAModulateOn
virtual void drawImpl0(const render::gl::GL &gl, RegionRenderer &renderer, const Vec4f &rgba) noexcept
Actual draw implementation, called by draw(GL2ES2, RegionRenderer).
final Shape validate(final GL2ES2 gl, final GLProfile glp)
Validate the shape via validate(GL2ES2) if gl is not null, otherwise uses validate(GLProfile).
jau::function< void(ShapeRef &s, const Vec3f &origin, const Vec3f &dest, const PointerEvent &e)> MoveEventCallback
Shape move listener
jau::function< bool(ShapeRef &s)> Visitor1Func
Visitor1 method.
constexpr const OutlineShape & outlines() const noexcept
constexpr OutlineShape & outlines() noexcept
constexpr Vec3f & scale() noexcept
constexpr Vec3f & position() noexcept
static constexpr Vec4f pressedRGBAModulate
Default pressed color-factor (darker and slightly transparent), modulates base-color.
Shape & setToggleable(bool toggleable) noexcept
Set this shape toggleable, default is off.
constexpr float & zOffset() noexcept
final Shape validate(final GL2ES2 gl)
Validates the shape's underlying GLRegion.
constexpr const Vec3f & rotationPivot() const noexcept
jau::function< void(ShapeRef &s)> ShapeEventCallback
General Shape listener action.
static constexpr Vec4f activeRGBAModulate
Default active color-factor (dark), modulates base-color.
void applyMatToMv(PMVMat4f &pmvMat) noexcept
Applies the internal Matrix4f to the given modelview matrix, i.e.
Specifies the OpenGL profile.
Pointer event of type PointerType.
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
Implementation of a Copy-On-Write (CoW) using jau::darray as the underlying storage,...
Class template jau::function is a general-purpose static-polymorphic function wrapper.
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
constexpr Matrix4 & scale(const value_type x, const value_type y, const value_type z) noexcept
Scale this matrix, i.e.
constexpr_cxx26 Matrix4 & rotate(const value_type ang_rad, const value_type x, const value_type y, const value_type z) noexcept
Rotate this matrix about give axis and angle in radians, i.e.
constexpr Matrix4 & translate(const value_type x, const value_type y, const value_type z) noexcept
Translate this matrix, i.e.
constexpr Matrix4 & setToTranslation(const value_type x, const value_type y, const value_type z) noexcept
Set this matrix to translation.
constexpr bool isIdentity() const noexcept
Returns true if this quaternion has identity.
std::string toString() const noexcept
constexpr bool is_zero() const noexcept
std::string toString() const noexcept
static constexpr const value_type one
constexpr Vector4F & mul(const Vector4F &s) noexcept
this = this * {s.x, s.y, s.z}, component wise.
constexpr Vector4F & set(const Vec3f &o, const value_type w_) noexcept
TODO constexpr std::strong_ordering operator<=>(const vec4f_t& rhs) const noexcept { return ....
Axis Aligned Bounding Box.
constexpr bool intersectsRay(const Ray3f &r) const noexcept
Check if Ray intersects this bounding box.
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.
constexpr const Point3f & center() const noexcept
Returns computed center of this aabbox3f of low() and high().
bool mapWinToObj(const float winx, const float winy, const float winz, const Recti &viewport, Vec3 &objPos) noexcept
Map window coordinates to object coordinates.
bool mapObjToWin(const Vec3 &objPos, const Recti &viewport, Vec3 &winPos) const noexcept
Map object coordinates to window coordinates.
ordered_atomic< uint32_t, std::memory_order_relaxed > relaxed_atomic_uint32
Relaxed non-SC atomic integral scalar uint32_t.
#define JAU_MAKE_BITFIELD_ENUM_STRING(type,...)
constexpr bool is_set(const E mask, const E bits) noexcept
constexpr E & write(E &store, const E bits, bool set) noexcept
If set==true, sets the bits in store, i.e.
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...
std::shared_ptr< Shape > ShapeRef
std::shared_ptr< Window > WindowRef
constexpr jau::math::Vec3f getEulerAngleOrientation(const jau::math::Vec3f &eulerRotation) noexcept
Returns an orientation vector for given eurler X/Y/Z angles in radians.
Quaternion< float > Quat4f
PMVMatrix4< float > PMVMat4f
int printf(const char *format,...)
Operating Systems predefined macros.