[Swogl] RFE: Provide a public Camera interface

Currently, the camera is used only internally, and can only be affected indirectly by switching the SwoglContainer into the CAMERA ControlMode. A public interface for the camera could be very beneficial, offering more fine-grained and customizable control over the camera behavior, and even allow nifty things camera flights…

The Camera itself has a very basic structure, so that a Camera interface may easily be exctracted, keeping the current camera as its default implementation. The implementations of the Mouse*Listener interfaces should, however, be pulled out of the Camera, and could possibly reside in inner classes of the SwoglContainer, which then delegate the appropriate calls to the actual camera.

Nevertheless, some possible interdependencies between the camera and the picking will have to be taken into account.

I suggest, as a first step, to set the visibility of SwoglContainer.getCamera() to public. So it would be possible to combine the given camera movement with own implementations of “LayoutManager3D”

Btw: I think, the name “LayoutManager3D” is misleading as it also implements some eventhandlers. Maybe it should be split up oder renamed… .

Simply passing the current „Camera“ to the outside world would have the undesirable effect of people using this class in its current form, although it will not exist for a long time. If someone writes a LayoutManager3D implementation and relies, e.g., on the existance of the Camera#startMovement or even the Camera#mousePressed etc. methods, it will not work after the update of the Camera interface.

A simple camera interface might, for example, reflect the basic information that is contained in a camera model:

interface Camera
{
    void set/getEyePoint(Point3f point)
    void set/getViewPoint(Point3f point)
    void set/getUpVector(Vector3f vector)
    void setFovY(float fovYdeg);
    float getFovY();
}

(This is only sketched according to the fields currently stored in the camera)

Things like the viewport size could be required, although this does not really belong to the camera model. Nevertheless, it may be important, since users may want to display SwoglComponents in their original size. E.g. a JButton with size 200x50 should appear with a size of 200x50 pixels on the screen.

The „behavioral“ methods that are currently provided by the camera, namely

    private void startArcballRotate(Point point)
    private void doArcballRotate(Point point)

    private void startMovement(Point point)
    private void doMovement(Point point)

are specific for a certain camera behavior, namely, the „Arcball Camera“. This behavior is strongly linked to the user interaction. This linking shows up in the current Camera class (which does not offer these methods directly, but only indirectly via the Mouse*Listener methods), as well as in the application cases of this behavior: It gives the user the possibility to „examine“ the Object of interest, and rotate around it intuitively - nothing more and nothing less.

But alternative behaviors may be possible. Another camera behavior could be that of a „First Person Shooter“: Moving and rotating with the cursor keys, and looking around with the mouse. (I’m not sure about realistic application cases for this … but imagine walking through a 3D gallery where the walls are showing Swing Components :smiley: ). Additional behaviors could be imagined, as well as possible constraints for the camera movement (e.g. to only allow to „turn the head“ by +/- 45 degrees to the left or right…)

These behaviors could be considered as a „link“ between the Mouse*Listener interface and the Camera interface: Implementations of these behaviors could „translate“ the user input into appropriate Camera actions.

Alternatively, the camera may be controlled without any certain behavior, e.g. by a class that performs a camera flight by directly calling the set/get EyePoint/ViewPoint/UpVector methods of the interface sketched above, and interpolating between certain camera configurations - possibly using the Java Timing Framework.

You are correct: Similar questions will arise for the LayoutManager3D. I’m also not so happy with the interface list in „LayoutManager3D extends MouseListener, MouseMotionListener, MouseWheelListener, KeyListener“. It would be nice to have a LayoutManager3D that does its layout, and does NOT need to implement all these interfaces. (I thought about how to alleviate this problem a while ago, but found that it was far from trivial - the last thing I did was to add some methods for configuring the basic behavior of the LayoutManager3D implementations, but have to admit that this was somehow half-a**ed…).

Once again, as for the camera, there must be the possibility to translate user input into layout actions, and it has to be easily configurable and provide simple and sensible defaults. I thought about a concept similar to the concept of „InputMap“/„ActionMap“ in Swing, but currently have no idea of how to extend this concept to mouse movements…

Favorable would be a somehow „generic“ solution, which allows to configure the mappings of „UserAction->CameraMovement“ and „UserAction->LayoutMovement“ in a similar way.

In fact, there are some cases where the Camera movement and the Layout movement are interchangeable: The GridLayout3D currently moves selected SwoglComponents into the focus when they are double-clicked, but does not change the arrangement of the SwoglComponents - the same effect could be achieved with camera flights.

Many things to consider :slight_smile:
What do you think?

Okay, those are definitely a lot of things.
I think, organizing Swogl in „Layers“ from which an developer can choose and how much to do „by hand“ to fulfill his reqs might be good.

Those Layers could be, for example:

  • Rendering Swing Components in an GLComponent (GLCanvas, GLJPanel) with full functionality (dispatching Events)

  • API to ease acess to some useful JOGL switches and preferences, like Camera, Light

  • Automatic Positioning (e.g. via LayoutManager3D)

  • API to Combine some Userinteraction into the Scenery
    ** Moving Objects or Camera ?

  • Add an API for Animation / link in TimingFramework
    ** might be needed to visualize the mentioned „interaction“

So, one could choose, only to use the Swing Rendering/ Mouse Picking Capabilities of Swogl and do whatever he wants with pure JOGL. Or, on the other extreme, use Swogl APIs to add some Animation and additional Light to build his interaction.

From this point of view, i think most important for swogl would be to get the Swing Rendering / input picking to a solid state and show in detail how to interact with JOGL (use standard jogl inside the SwoglContainer) . From that, some „do’s“ and „dont’s“ might evolve to best practices which show the way to those higher-level-swogl-apis :slight_smile:

That definitely sounds feasible. We could work out plans how the structure of these Layers could be. I’ll think about it, and post my thoughts here - hoping for further ideas as well :slight_smile:

I wonder how these Layers should be made available to the user.

This first point (basic rendering of SwoglComponents) is already available - thus, I think the question is how to „elegantly leave out“ things like LayoutManagers and Camera at this level. Do you think there really should be a hierarchy of classes

class BasicSwoglContainer
{
    void add/removeSwoglComponent(...)

   // Leaving camera & layout to the user
   // but offering some custom rendering API
}

class LayoutSwoglContainer extends BasicSwoglContainer
{
    void setLayoutManager3D(...);
}

class SwoglContainer extends LayoutSwoglContainer
{
    Camera getCamera();
}

? I’m not sure if this makes sense. One the one hand, it’s undesirable to bloat the API with features that are rarely used, but I think offering „sensible“ defaults of Layout and Camera in a single SwoglContainer could be appropriate, if the (optional) usage of Camera and Layout is possible through a clear interface.
Could you explain how you intend to model these layers in the API?

It would also be helpful if you could point out which aspects of Rendering and Picking have to be made more solid. The Picking could possibly be refactored to some extent, if we find a more elegant solution for this, and concerning the rendering there may be some issues concerning the usage of JOGL 2.0, the Geometry interface and the usage of a GLCanvas, but hopefully, this should hardly affect the API.

BTW: I tested the GLCanvas once more - it basically works, except for things like the JSplitPane, which internally uses a heavyweight component for the divider, and gets messed up during dragging :frowning:

Concerning the custom rendering, I’ll post some thoughts in http://forum.byte-welt.de/showthread.php?t=2390

I wonder how these Layers should be made available to the user.

This first point (basic rendering of SwoglComponents) is already available - thus, I
think the question is how to „elegantly leave out“ things like LayoutManagers
and Camera at this level. Do you think there really should be a hierarchy of classes

hm, not nessesarily a hierachy. Could also be composition or sth similar :wink:

? I’m not sure if this makes sense. One the one hand, it’s undesirable to bloat the API
with features that are rarely used, but I think offering „sensible“ defaults
of Layout and Camera in a single SwoglContainer could be appropriate, if the (optional)
usage of Camera and Layout is possible through a clear interface.
Could you explain how you intend to model these layers in the API?

My intention is to provide a way to easily combine Swogl with classic JOGL. Didn’t have time to think about an detailed structure, yet, sorry.
That could, of course, accomplished by an very open api, giving someone the opportunity to manipulate whatever he needs to…
a disadvantage of defaults is, that you make assumptions how the components might be used. That often limits the way, components can be used…

It would also be helpful if you could point out which aspects of Rendering and Picking
have to be made more solid. The Picking could possibly be refactored to some extent,
if we find a more elegant solution for this, and concerning the rendering there may
be some issues concerning the usage of JOGL 2.0, the Geometry interface and the
usage of a GLCanvas, but hopefully, this should hardly affect the API.

Jupp. Those aspects :slight_smile:

BTW: I tested the GLCanvas once more - it basically works, except for things like the JSplitPane, which internally uses a heavyweight component for the divider, and gets messed up during dragging

Uh, even the Picking / Event dispatching to Swing Components? That was the main issue i discovered by switching to glCanvas.

cheers
Markus

hm, not nessesarily a hierachy. Could also be composition or sth similar :wink:

My intention is to provide a way to easily combine Swogl with classic JOGL. Didn’t have time to think
about an detailed structure, yet, sorry.
That could, of course, accomplished by an very open api, giving someone the opportunity to manipulate
whatever he needs to…
a disadvantage of defaults is, that you make assumptions how the components might be used. That
often limits the way, components can be used…

I’m not sure in how far a composition could be „configurable“ at compile time for the API user, as long as the basic means for all features are not already included in the API. For example, in any case, there has to be „something“ which provides the perspective matrix. Currently, it is provided by the camera. If someone does not wish to use a user-controllable camera, he will require some „default perspective matrix“ (which could be provided by the default camera :wink: ). Similarly with the light setup…

I think that some aspects of this could be covered with the approach I mentioned in http://forum.byte-welt.de/showpost.php?p=10372&postcount=3 - but the challenging part will IMHO be the case when the user wants to configure things in more detail.

You’re right: Currently, the API-user has nearly no influence on the behavior of the Camera (which IS an Arcball rotation) or the LayoutManagers (which ARE controlled the way they are). You said that defaults often limit the possibilites. Currently, this is definitely (and unfortunately) true. But I think these design issues are so hard to decide because it should not be so.

For example: The WheelLayout3D currently is activated by the MouseWheel. What if someone wants to activate it by ATL+MouseDrags …? It should be possible - and it should be easy!

WheelLayout3D wheelLayout = new WheelLayout3D();
swoglContainer.setLayout3D(wheelLayout); 
...

That’s fine so far - the layout is activated by the mouse wheel by default. But now it should be possible to do something like

somewhere.addMouseListener(new MouseAdapter()
{
    public void mouseDragged(MouseEvent event)
    {
        if (altIsPressed())
        {
            int delta = computeMovementFrom(event);
            wheelLayout.rotate(delta);
        }
    }
}

but preferably without having to register an anonymous listener „somewhere“, checking modifier flags, computing the movement from … whereever and so on.

As I mentioned, a concept like the InputMap/ActionMap could be interesting…

class MouseInteractionInput 
{ 
    // Describes a mouse event type (not an event, but only its TYPE) 
    // Analogous to the "KeyStoke" class in Swing
}

MouseInteractionInput mouseInteractionInput = MouseInteractionInput.create("drag button0 ALT");
swoglComponent.getInteractionInputMap().put(mouseInteractionInput, "XXX");

InteractionAction wheelLayoutRotateAction = // ... An action describing the rotation of the wheel layout
swoglComponent.getInteractionActionMap().put("XXX", wheelLayoutRotateAction);

This would allow to „plug togeher“ certain inputs (keystrokes or mouse events) and the respective actions (modifying the layout or the camera). This would even be a relatively easy way to specify things like "When CTRL+ALT are pressed and the Mouse Wheel is rotated, then some SwoglComponent and the Camera should simultaneously rotate left by 10 degrees :verzweifel: "…
But this is only a rough thought … one of the main questions would be: How should things like the current mouse position (or even the SwoglComponent under the mouse) be passed through this?

I’ll think about this, but I’d be happy to hear any ideas :slight_smile:

BTW: I tested the GLCanvas once more - it basically works…
Uh, even the Picking / Event dispatching to Swing Components?

Well the „handleMouseEvent“ method of SwoglContainer required some adoption: The Event currently only is modified according to the SwoglComponent that was hit, and then processed normally - when using a GLCanvas, there have to be another 8-10 lines which manually dispatch the event to the target component (but this was just a short test, anyhow)

I think i would prefer a pretty low level API and happily provide those default
values as s the initial perspective matrix best fitting to the application…

First thought on this: misleading naming? Isn’t it more an EventListener,
processing input?

The sketch of an Input/ActionMap sounds interesting, I’m not sure if it
encapsulates too much, …
Would there still be a possibility to use classic listeners? Or can we definitely
say that there would be no need for such as everything can be done with
the maps? I see another concept, but yet don’t realize the advantages…

[QUOTE=Marco13;10377]
Well the „handleMouseEvent“ method of SwoglContainer required some
adoption: The Event currently only is modified according to the SwoglComponent
that was hit, and then processed normally - when using a GLCanvas, there have to
be another 8-10 lines which manually dispatch the event to the target component
(but this was just a short test, anyhow)[/QUOTE]

Could you drop those lines here or maybe as an update to the repository?
I’m very curious as I’ve played around with dispatchin Events to Swing
Components by hand, too :wink:

cheers
Markus

[QUOTE=Markus]I think i would prefer a pretty low level API and happily provide those default
values as s the initial perspective matrix best fitting to the application…[/quote]

„Best fitting“ - that’s another point … a „zoom to fit“ functionality should also be provided :wink:
So do you think it’s sufficient to provide a default camera with the default matrix, but also allow to access to the Camera interface for those who like a more fine-grained control…?

[QUOTE=Markus;10409]First thought on this: misleading naming? Isn’t it more an EventListener,
processing input?[/quote]

I think the main problem is not the naming, but the missing separation of concerns (or mixed responsibilities). The purpose of the WheelLayout3D should be to lay out the Components as a wheel with a modifiable wheel rotation. The question who modifies the wheel rotation is independent of this functionality. It could be modified directly by user input (and, to point this out more preciesely: By many different kinds of user input!). Alternatively, it may be rotated „programmatically“, e.g. when showing components in a slide show (without any user interaction).

What do you mean when you say that the Input/ActionMap may „encapsulate too much“?

[QUOTE=Markus;10409]Would there still be a possibility to use classic listeners? Or can we definitely
say that there would be no need for such as everything can be done with
the maps? I see another concept, but yet don’t realize the advantages…[/quote]

Of course it would still be possible to manually attach an own MouseListener to a SwoglContainer, and use it to control the WheelLayout as sketched in my previous post. Similarly, it is still possible in Swing to use a KeyListener instead of a InputMap. The intention or advantage of the mapping could be an easier configuration. When someone says

MouseInteractionInput mouseInteractionInput = MouseInteractionInput.create("drag button0 ALT");
swoglComponent.getInteractionInputMap().put(mouseInteractionInput, "rotateWheel");
 
InteractionAction wheelLayoutRotateAction = // ... An action describing the rotation of the wheel layout
swoglComponent.getInteractionActionMap().put("rotateWheel", wheelLayoutRotateAction);

then he could, for example, change this to rotate the mouse wheel with the cursor keys with something like

swoglComponent.getInteractionInputMap().put(KeyStrokegetKeyStroke(...), "rotateWheel");

without having to detach the old MouseListener and implement and attach a new KeyListener (which would only work when the component was focussed). But this is still a very rough idea, with many open questions…

Concerning the GLCanvas/GLJPanel: I added a compile-time-flag for switching between GLCanvas/GLJPanel (but as I mentioned, the GLCanvas does not yet work for all Components). I’ll update the repository ASAP.

quinceanera wedding dressesquinceanera wedding dressesfrom http://www.weddinggownswholesale.com/quinceanera-wedding-dresses-p-4763.htmlnow sign up=free shipping this week.free tailor-made,7days refundbe free to check the fabric before your purchase