JavaFX 3D
Richard Bair
richard.bair at oracle.com
Mon Jun 4 14:11:54 PDT 2012
Hi Anthony,
On May 27, 2012, at 2:42 AM, Anthony Vanelverdinghe wrote:
> I agree with having a unified scene graph, but wouldn't it be possible to see everything as 3D objects, where 2D nodes are merely part of the surface of those 3D objects? (to me this would imply discarding 2.5D transforms altogether)
I don't think so. The problem is that for a typical 2D application, 2.5D is semantically correct (and easy!) whereas for a 3D program 2.5D is incorrect. So if you are building a 3D app, then yes you want to be able to take any normal 2D content and texture map it onto the 3D surface. That will need to be supported. But for a predominantly 2D application, you really want 2.5D (in terms of semantics).
For example, suppose you have a 3D flip rotation in a 2D app. Really you just want to write:
RotateTransition tx = new RotateTransition(nodeToRotate, Duration.seconds(3));
tx.setRotationAxis(Rotate.Y_AXIS);
tx.play();
(or whatnot)
And that would be it. However in a 3D scene graph, this would look different than in a 2.5D. In 2.5D, the camera used to draw the result of the rotation will be positioned differently than one that is observing the entire application as a 3D scene. In the former case, the camera is positioned such that it is looking directly at the node being rotated, whereas in the latter case the camera is positioned "head on" looking at the entire scene. The perspective on the flipping content will be different depending on where that camera is positioned.
In addition, some things like "opacity" just have different semantic meaning between a 2D and 3D scene graph, so I think we can't just treat the whole scene as if it were a pure 3D scene graph. I mean, we could, but then "normal" or typical operations in a 2D world would acquire surprising new behaviors.
For example, observe the difference between these two scene's:
Rectangle r1 = new Rectangle(10, 10, 100, 100);
Rectangle r2 = new Rectangle(20, 20, 90, 90);
Rectangle r3 = new Rectangle(30, 30, 80, 80);
Rectangle r4 = new Rectangle(40, 40, 70, 70);
Group g = new Group(r1, r2, r3, r4);
g.setOpacity(.5);
vs.
Rectangle r1 = new Rectangle(10, 10, 100, 100);
Rectangle r2 = new Rectangle(20, 20, 90, 90);
Rectangle r3 = new Rectangle(30, 30, 80, 80);
Rectangle r4 = new Rectangle(40, 40, 70, 70);
Group g = new Group(r1, r2, r3, r4);
for (Node n : g.getChildren()) n.setOpacity(.5);
The first scene shows the normal 2D semantic for setting opacity on the group. The second scene shows what it would look like if you had set the opacity on the group but with normal 3D semantics (which essentially just pass the state down onto the children).
So ultimately I don't think we can just treat everything as 3D. That makes sense if you are writing a 3D app, but it doesn't make sense if you are writing a 2D app. So some provision for 2.5D I think makes sense.
> Just an idea that may or may not be useful, but suppose, as an example:
> * a cube
> * a property "paint" (of type Paint) for the surface of a 3D object
> * make a new subclass of Paint, ScenicPaint, which has the same behavior of a Scene, but allows to be used as the paint of the surface of a 3D object
> * a property "interactive" (a boolean) for a surface. This means it allows the user to double-click on the surface, which would cause the camera to be centered on this surface, so that it fills the whole scene (cfr. the lookAt property of Camera)
>
> So i would then be able to create a cube, create 6 scenes exactly the same as i currently would for a 2D application. Then i would set each of those scenes on a different surface of the cube & make the whole cube interactive. Then the user could watch the cube from different angles & double-click any surface. The scene is then centered on that surface, allowing the user to interact with the controls on it (e.g. filling in a form) and when the user is done, it 's easy to go back to the "3D world" (so a ScenicPaint would only be interactive while the surface "has focus"). Of course there may be menu's & such, allowing to immediately center on another surface in the 3D world. It should thus also be possible to disable "going 3D" altogether, so that the application appears as a simple 2D program, but is really 3D behind the curtains (e.g. have a simple cube, centered on the front side, where the paint property is changed every time the user switches scenes).
Yes I think that makes sense, although I would not have an "interactive" property. Instead you just have an event handler on the node in question and when it fires you then adjust the camera etc manually (ie: the "interactive" property is too use case specific, but you should be able to implement this use case on top of the scene graph we define).
Cheers
Richard
More information about the openjfx-dev
mailing list