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 ). 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
What do you think?