72 for(
size_t i=shapes.size(); !picked && i-- > 0; ) {
76 picked = visitor(s, pmv);
77 if( s->asContainer() ) {
78 ShapeRef childPick = pickForAllRenderedDesc(*s->asContainer(), pmv, visitor);
111 final float winZ0 = 0
f;
112 final float winZ1 = 0.3f;
118 final Recti viewport = getViewport();
119 final int[] shapeIdx = { -1 };
120 return pickForAllRenderedDesc(
this, pmv, (
final Shape s,
final PMVMatrix4f pmv2) -> {
122 if( pmv.mapWinToRay(glWinX, glWinY, winZ0, winZ1, viewport, ray) ) {
123 final AABBox sbox = s.getBounds();
124 if( sbox.intersectsRay(ray) ) {
125 if( null == sbox.getRayIntersection(objPos, ray, FloatUtil.EPSILON,
true) ) {
126 throw new InternalError(
"Ray "+ray+
", box "+sbox);
128 if( visitor.visit(s) ) {
142 private final Shape dispatchMouseEventPickShape(
final MouseEvent e,
final int glWinX,
final int glWinY) {
143 final Shape shape = pickShape(dispMEPSPMv, dispMEPSRay, glWinX, glWinY, dispMEPSObjPos, (
final Shape s) -> {
145 if( !s.isInteractive() ) {
146 if( DEBUG_PICKING ) {
147 System.err.printf(
"Pick.X.0: shape %s/%s, [%d, %d]%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY);
151 if( !s.dispatchMouseEvent(e, glWinX, glWinY, dispMEPSObjPos) ) {
152 if( DEBUG_PICKING ) {
153 System.err.printf(
"Pick.X.1: shape %s/%s, [%d, %d], %s%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY, e);
157 if( DEBUG_PICKING ) {
158 System.err.printf(
"Pick.X.S: shape %s/%s, [%d, %d], %s%n", s.getClass().getSimpleName(), s.getName(), glWinX, glWinY, e);
162 if( null != shape ) {
163 if( DEBUG_PICKING ) {
164 System.err.printf(
"Pick.X: shape %s/%s%n%n", shape.getClass().getSimpleName(), shape.getName());
166 setActiveShape(shape);
169 if( DEBUG_PICKING ) {
170 System.err.printf(
"Pick.X: shape null%n%n");
172 releaseActiveShape();
176 private final PMVMatrix4f dispMEPSPMv =
new PMVMatrix4f();
177 private final Ray dispMEPSRay =
new Ray();
178 private final Vec3f dispMEPSObjPos =
new Vec3f();
187 private final void dispatchMouseEventForShape(
final Shape shape,
final MouseEvent e,
final int glWinX,
final int glWinY) {
188 final PMVMatrix4f pmv =
new PMVMatrix4f();
190 winToShapeCoord(shape, glWinX, glWinY, pmv, objPos, () -> { shape.dispatchMouseEvent(e, glWinX, glWinY, objPos); });
191 if( DEBUG_PICKING ) {
192 System.err.printf(
"ForShape: shape %s/%s%n%n", shape.getClass().getSimpleName(), shape.getName());
196 class SBCPointerListener :
public PointerListener {
204 lastPos.
x = -1; lastPos.y = -1; lastId = -1; mouseOver =
false;
206 const ShapeRef& dispatchPickShape(
const PointerEvent& e) {
207 const ShapeRef s = dispatchMouseEventPickShape(e);
214 SBCPointerListener(
Scene& p): scene(p) { clear(); }
216 void pointerPressed(PointerEvent& e)
override {
217 if( -1 == lastId || e.
pointerId() == lastId ) {
224 dispatchPickShape(e);
227 void pointerReleased(PointerEvent& e)
override {
228 if( mouseOver && scene.m_activeShape &&
229 scene.m_activeShape.isInteractive() &&
233 scene.dispatchMouseEventForShape(scene.m_activeShape, e);
235 dispatchPickShape(e);
239 scene.releaseActiveShape();
244 void pointerClicked(PointerEvent& e)
override {
248 dispatchPickShape(e);
251 void pointerDragged(PointerEvent& e)
override {
252 scene.clearToolTip();
254 if( scene.m_activeShape &&
255 scene.m_activeShape.isInteractive() &&
260 scene.dispatchMouseEventForShape(scene.m_activeShape, e);
264 void pointerWheelMoved(PointerEvent&)
override {
265 scene.clearToolTip();
266 if( mouseOver && scene.m_activeShape &&
267 scene.m_activeShape.isInteractive() &&
270 scene.dispatchMouseEventForShape(scene.m_activeShape, e);
272 dispatchPickShape(e);
276 void pointerMoved(PointerEvent&)
override {
277 if( -1 == lastId || e.
pointerId() == lastId ) {
279 lastId = e.getPointerId(0);
281 scene.clearToolTip();
282 const ShapeRef& s = dispatchPickShape(e);
290 void pointerExited(PointerEvent&)
override {
291 scene.clearToolTip();
292 scene.releaseActiveShape();
297 class SBCKeyListener :
public KeyListener {
302 SBCKeyListener(
Scene& p): m_parent(p) { }
304 void keyPressed(KeyEvent& e,
const KeyboardTracker& kt)
override {
305 if( m_parent.m_activeShape && m_parent.activeShape.isInteractive() ) {
306 m_parent.activeShape.dispatchKeyEvent(e, kt);
309 void keyReleased(KeyEvent& e,
const KeyboardTracker& kt)
override {
310 if( m_parent.m_activeShape && m_parent.activeShape.isInteractive() ) {
311 m_parent.activeShape.dispatchKeyEvent(e, kt);
315 typedef std::shared_ptr<SBCKeyListener> SBCKeyListenerRef;