Search code examples
javascriptxml3d

XML3D: Camera controls & XML3D tools


What is the suggested approach for handling user input and camera controls in XML3D?

Basic interactivity can be added using the DOM tree events, but I'm not sure if that would be enough to provide rotation gizmos (for example). Does library provides some API to handle user input and camera controls?

I've noticed that there is xml3d toolkit that was developed year ago. It seem however that this is rather a loose collection of demos rather than a library for handling user input, also there is no decent use documentation for it.

I need to provide basics functionalities like rotation/translation/scaling of models and controlling the camera.


Solution

  • xml3d.js doesn't provide any cameras or gizmos by itself. They're usually application-specific (there are dozens of ways to implement a camera for instance) so it doesn't really make sense to include them as part of the core library. A very basic camera is provided alongside xml3d.js but it's quite limited.

    The xml3d-toolkit did include transformation gizmos and various camera controllers but it's not in active development anymore since the creator has moved on to other things. Still, it might be a good place to start, or at least to use as a reference in building your own camera or gizmo.

    For example, a simple way to allow the user to change the transformation of a model would be to:

    1. Add an onclick listener to each model that toggles the editing mode

    2. Show 3 buttons somewhere in your UI to let the user switch between editing rotation, translation or scale

    3. Add onmouseup and onmousedown listeners to the <xml3d> element to record click+drag movements
    4. As part of those listeners, convert the change in mouse position to a change in transformation depending on what editing mode the user is in

    5. Apply those transformation changes to the model either by changing its CSS transform, or through the relevant attribute on a <transform> element that's referenced by a <group> around your model.

    6. Exit the editing mode if the user clicks the canvas to deselect the object (rather than a click+drag operation)

    To keep it from conflicting with camera interaction you could use the right mouse button for editing, or simply disable the camera while the user is editing a transformation.

    A 3D gizmo is a bit trickier because it needs to be drawn over top of the model while still being clickable, currently there is no way to do this. You could use the RenderInterface to draw the gizmo in a second pass after clearing the depth buffer, but this would not be done in the internal object picking pass that's required to find out which object a user has clicked on.

    As a workaround, the toolkit library used a second XML3D canvas with a transparent background positioned over the first that intercepted and relayed all mouse events. When an object was selected its transformation was mirrored into the second canvas where the gizmo was drawn. Changes in the gizmo's transformation were then mirrored back to the object in the main canvas.

    Have a look at the classes in the toolkit's xml3doverlay and widgets folders.