Skip to main content

How To Move Camera

In DynaMaker there are in-built easy-to-use functions to handle camera movements. Not only the camera can go from A to B, but also how it goes and how fast are parameters that can be controlled. Also there are other functions that autocenter the camera based on the existing model. All the settings can be found in its STUDIO library section.

Here we present some of the most common cases for the camera, including them in an app below:

Things to consider:

  • updating the camera can only be done in the UI, where Studio exists.
  • most of the camera-related functions contain 2 common optional arguments:
    • travelTime in milliseconds says how much the camera-update will take (instantly or 0 ms if undefined).
    • easing defines the camera transition. There are 4 options available ('CubicIn' by default). You can read more about them here.

Move from A to B

The most intuitive way is to move from one known 3D-position A to another known 3D-position B. Knowing that the camera is defined by the user's eye position (camera position) and where the user is looking at (camera target), then:

const targetPosition = new SKYMATH.Vector3D(0, 0, 0)
const A = new SKYMATH.Vector3D(-500, -500, 300)
const B = new SKYMATH.Vector3D(500, -500, 300)
Studio.setCameraTarget(targetPosition)
Studio.setCameraPosition(A)
Studio.setCameraPosition(B, { travelTime: 1500 })

Reset Camera

Another typical example is that we want to reset the camera when we switch tab, when we just updated a parameter of a configurator or even when we click on a QuickBar item. We could say that the only thing that we are interested in when resetting the camera is that the view covers the product with a preferred direction, regardless of the exact camera position and target, then you can use:

Studio.setCameraToFitBounds({
direction: new SKYMATH.Vector3D(1, 1, -0.75), // from user's eye towards target
travelTime: 1000,
})

This function takes the whole model presented in the preview, gets its bounds and updates the camera depending on them. However, you can define your own bounds, even with some boundsOffset (e.g. the user is configuring the handle of the door in the 2nd app tab, so the camera should focus on the bounds of the handle, regardless of the door and its size). Then this can be done by using its extra optional arguments:

Studio.setCameraToFitBounds({
direction: new SKYMATH.Vector3D(1, 1, -0.75),
travelTime: 1000,
bounds: ACTIONS.getDoorHandleBounds(), // doorHandleGeometry.getBounds()
boundsOffset: 50, // bounds + 50 in all 3D-directions (also accepts negative values)
})

Alternatively, you can use the opposite functionality. Let's say you have a door in a wall with curtains, but you want to fit the camera to the bounds of the door, regardless of the curtains and wall perhaps. Then you would want to only ignore the geometry of the wall and curtains. Then:

Studio.setCameraToFitBounds({
direction: new SKYMATH.Vector3D(1, 1, -0.75),
travelTime: 1000,
ignoreGeometryGroups: ['wall', 'curtains'],
})

bounds are ignoreGeometryGroups are exclusive where the latter is ignored if the first is used. The strings of ignoreGeometryGroups need to match the tag added in the respective geometry groups (e.g. geometryGroup.addGeometry(wallModel, { tag: 'wall' })).

Lock Top view

Another common example is that you might be configuring your product in a plane. For example, in a wall-builder type app, you might want to look at the product from above (top view) locking any rotation possibilities while drawing the walls with lines. However, when you are done with a certain configuration or perhaps you just change to another UI tab that allows the visualization of 3D models from those drawn lines, then the view can be switched to perspective and naturally allow the 3D rotation again. This can be done by updating the camera settings like:

Studio.updateCameraSettings({
allowRotate: false,
orthographic: true,
})

Studio.setCameraToFitBounds({
direction: new SKYMATH.Vector3D(0, 0, -1), // top view
travelTime: 1000,
})

Remember that the settings need to be "restored" in other places so that you need to include that setting change (allowRotate: true and orthographic: false) anywhere else that needs it.

Zoom In & Out

To ease any type of user handling basic camera functions (e.g. zoom in & out due to lack of mouse-wheel), you might want to keep these as QuickBar items. You can do that with:

Studio.setQuickBarItems([
{
icon: 'zoom-in',
action: () => {
Studio.cameraZoomIn()
},
tooltip: 'Zoom in',
},
{
icon: 'zoom-out',
action: () => {
Studio.cameraZoomOut()
},
tooltip: 'Zoom out',
},
])

Also, the ability to zoom in or out is limited by the max and min camera distances. For example, when having very small or very large products, we want to limit the max camera distance so that the user doesn't get lost when zooming out a lot by accident perhaps.

Studio.updateCameraSettings({
maxTargetDistance: 1000,
minTargetDistance: 0,
})

Additionally, it's good to know that the default behavior for the camera zooming is based on the mouse position. If you want to zoom in/out always from the center of the preview, regardless of where your mouse is located, you can do that by disabling that option:

Studio.updateCameraSettings({
zoomToMouse: false,
})

Rotation Below Ground

Sometimes we have products that need to be inspected from below the ground. In DynaMaker the setting for changing the polar angle (angle in spherical coordinates that goes from the z-axis towards the XY-plane) defaults to 90 degrees (from north to equator) but it can be changed like:

Studio.updateCameraSettings({
maxPolarAngle: Math.PI,
})

The pan movement (mouse-wheel button) is based on the ground by default and therefore the camera target is placed in the ground. We can remove this limitation with:

Studio.updateCameraSettings({
groundLock: false,
})

However, be aware that when panning the view we are updating the camera target too, since the movement is now parallel to the user's eye and the old camera target, and therefore the camera rotation (which is based on the camera target) might seem odd. Having a button in the QuickBar to reset the camera solves this situation quite handily.

Rebind Camera Buttons

We might be used to other camera controls depending on the software we use every day. But don't worry, in DynaMaker you can rebind these very easily giving the behaviors in strings as:

  • select to interact with the product (e.g. selection)
  • rotate to rotate the camera
  • pan to pan the view
  • zoom to zoom in
// Default behaviors:
Studio.updateCameraSettings({
mouseButtons: {
left: 'select',
right: 'rotate',
middle: 'pan', // mouse-wheel button
scroll: 'zoom', // mouse-wheel
},
})

Would you like to contribute with other camera behaviors or request new ones? Reach us at support@dynamaker.com and help the community to code faster!