11#ifndef JAU_GAMP_DAG_SHAPE_HPP_
12#define JAU_GAMP_DAG_SHAPE_HPP_
158 bool m_iMatIdent =
true;
159 bool m_iMatDirty =
false;
162 std::recursive_mutex m_dirtySync;
167 std::vector<KeyListenerRef> m_keyListener;
168 std::vector<PointerListenerRef> m_pointerListener;
222 constexpr Vec3f&
position() noexcept { m_iMatDirty=
true;
return m_position; }
224 constexpr const float&
zOffset() const noexcept {
return m_zOffset; }
225 constexpr float&
zOffset() noexcept { m_iMatDirty=
true;
return m_zOffset; }
233 constexpr const Vec3f&
scale() const noexcept {
return m_scale; }
234 constexpr Vec3f&
scale() noexcept { m_iMatDirty=
true;
return m_scale; }
265 return "dirty[shape, state]";
267 return "dirty[shape]";
269 return "dirty[state]";
314 const std::lock_guard<std::recursive_mutex> lock(m_dirtySync);
318 if( m_onDrawCallback) {
319 if( m_onDrawCallback(*
this, gl, rs) ) {
320 m_onDrawCallback =
nullptr;
335 const std::lock_guard<std::recursive_mutex> lock(m_dirtySync);
355 const std::lock_guard<std::recursive_mutex> lock(m_dirtySync);
403 void updateMat() noexcept {
404 bool hasPos = !m_position.
is_zero();
407 bool hasRotPivot =
false;
408 const Vec3f& ctr = m_outlines.bounds().center();
409 bool sameScaleRotatePivot = hasScale && hasRotate && ( !hasRotPivot || m_rotPivot == ctr );
411 if( sameScaleRotatePivot ) {
413 iMat.setToTranslation(m_position);
415 iMat.translate(
Vec3f(ctr).mul(m_scale));
416 iMat.rotate(m_rotation);
418 iMat.translate(-ctr);
419 }
else if( hasRotate || hasScale ) {
421 iMat.setToTranslation(m_position);
425 iMat.translate(
Vec3f(m_rotPivot).mul(m_scale));
426 iMat.rotate(m_rotation);
427 iMat.translate(
Vec3f(-m_rotPivot).mul(m_scale));
430 iMat.translate(
Vec3f(ctr).mul(m_scale));
431 iMat.rotate(m_rotation);
432 iMat.translate(
Vec3f(-ctr).mul(m_scale));
437 iMat.translate(
Vec3f(ctr).mul(m_scale));
439 iMat.translate(
Vec3f(-ctr).mul(m_scale));
441 }
else if( hasPos ) {
443 iMat.setToTranslation(m_position);
460 GearsObjectES2* m_picked =
nullptr;
461 bool m_dragInit =
true;
467 const float winZ = viewPos.z;
474 constexpr float winZ0 = 0.0f;
475 constexpr float winZ1 = 0.3f;
479 bool pick(
const PointerEvent& e,
const WindowRef&, GearsObjectES2& shape)
noexcept {
486 if( !mapWinToObjRay(winPos, objRay, shape.matPMvi()) ) {
489 const jau::math::geom::AABBox3f& objBox = shape.objBounds();
494 if( !objBox.
getRayIntersection(objPos, objRay, std::numeric_limits<float>::epsilon(),
true) ) {
495 printf(
"obj getRayIntersection failed\n");
500 printf(
"XXX pick: %s\n", shape.toString().c_str());
504 bool navigate(
const PointerEvent& e,
const WindowRef& win, GearsObjectES2& shape)
noexcept {
507 if( !mapWinToObj(shape, winPos, objPos) ) {
510 if( e.isControlDown() ) {
517 m_parent.
pan() += diffPos;
521 const float thetaY = 360.0f * ((float)(winPos.
x - preWinPos.
x) / (float)sdim.
x);
522 const float thetaX = 360.0f * ((float)(preWinPos.
y - winPos.
y) / (float)sdim.
y);
535 MyPointerListener(GearsES2& p): m_parent(p) {
539 void pointerPressed(PointerEvent& e)
override {
545 GearsObjectES2* new_pick = m_parent.
findPick(pickAction, e, win);
547 m_picked->
picked() =
false;
551 m_picked->
picked() =
true;
555 void pointerDragged(PointerEvent& e)
override {
563 m_picked->
picked() =
false;
566 printf(
"XXX shape: lost\n");
570 void pointerWheelMoved(PointerEvent& e)
override {
575 m_parent.
pan().
z += incr;
578 m_parent.
pan().
x -= rot.
x;
579 m_parent.
pan().
y += rot.
y;
582 void pointerReleased(PointerEvent&)
override {
584 m_picked->
picked() =
false;
585 printf(
"XXX shape: released\n");
591 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
Shape & validate(render::gl::GL &gl) noexcept
Validates the shape's underlying GLRegion.
constexpr Vec3f & rotationPivot() noexcept
constexpr float & zOffset() noexcept
virtual void validateImpl(const render::gl::GLProfile &glp) noexcept
constexpr Vec3f & scale() noexcept
jau::function< void(Shape &s, const Vec3f &origin, const Vec3f &dest, const PointerEvent &e)> MoveEventCallback
Shape move listener
void draw(render::gl::GL &gl, RenderState &rs) noexcept
Renders the shape.
bool isStateDirty() const noexcept
Returns the rendering dirty state, see markStateDirty().
virtual void validateImpl(render::gl::GL &gl) noexcept
jau::function< bool(Shape &s)> Visitor1Func
Visitor1 method.
jau::function< bool(Shape &s, render::gl::GL &gl, RenderState &rs)> DrawCallback
Shape draw listener action returning a boolean value
jau::function< bool(Shape &s, PMVMat4f &pmv)> Visitor2Func
Visitor2 method.
void onDrawOneShot(DrawCallback l)
Set a user one-shot initializer callback or custom draw(GL2ES2, RegionRenderer) hook.
virtual void clearImpl0(render::gl::GL &gl, RenderState &rs)
Custom clear(GL2ES2, RenderState) task, called 1st.
constexpr Vec3f & position() noexcept
bool isPressed() const noexcept
virtual void drawImpl0(render::gl::GL &gl, RenderState &rs) noexcept
Actual draw implementation, called by draw(GL2ES2, RenderState).
Shape & setPressed(bool b) noexcept
jau::function< void(Shape &s, const Vec3f &pos, const PointerEvent &e)> PointerEventCallback
Shape pointer listener, e.g.
static constexpr const uint32_t DIRTY_STATE
std::string_view getDirtyString() const noexcept
constexpr const float & zOffset() const noexcept
void applyMatToMv(PMVMat4f &pmvMat) noexcept
Applies the internal Matrix4f to the given modelview matrix, i.e.
final Shape validate(final GL2ES2 gl, final GLProfile glp)
Validate the shape via validate(GL2ES2) if gl is not null, otherwise uses validate(GLProfile).
constexpr Quat4f & rotation() noexcept
static constexpr const uint32_t DIRTY_SHAPE
Shape & validate(render::gl::GLProfile &glp)
Validates the shape's underlying GLRegion w/o a current GL2ES2 object.
jau::math::geom::AABBox3f m_box
constexpr const Quat4f & rotation() const noexcept
bool isToggleable() const noexcept
Returns true if this shape is toggable, i.e.
constexpr const Vec3f & scale() const noexcept
virtual bool hasColorChannel() const noexcept
Returns true if implementation uses an extra color channel or texture which will be modulated with th...
constexpr const Vec3f & position() const noexcept
jau::function< void(Shape &s)> ShapeEventCallback
General Shape listener action.
constexpr const Vec3f & rotationPivot() const noexcept
virtual void destroyImpl0(render::gl::GL &gl, RenderState &rs)
Custom destroy(GL2ES2, RenderState) task, called 1st.
bool isShapeDirty() const noexcept
Returns the shape's dirty state, see markShapeDirty().
void markShapeDirty() noexcept
Marks the shape dirty, causing next draw() to recreate the Graph shape and reset the region.
void markStateDirty() noexcept
Marks the rendering state dirty, causing next draw() to notify the Graph region to reselect shader an...
Shape & setToggleable(bool toggleable) noexcept
Set this shape toggleable, default is off.
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
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 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
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.
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::vector< ShapeRef > ShapeList
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
Author: Sven Gothel sgothel@jausoft.com Copyright Gothel Software e.K.
int printf(const char *format,...)
Operating Systems predefined macros.