How to rotate a camera around a target object in Speckle Viewer?

I’m trying to generate 24 screenshots from different camera views by moving the camera around a target object in Speckle Viewer. I want the object to remain stationary while the camera moves around its center and takes screenshots.

The problem I’m facing is that, for some reason, the camera sometimes moves above and below the model instead of maintaining a fixed height relative to the surface. I want the camera to simply go around the object in a circular motion (XZ plane) while keeping the height locked.

export const createScreenshots = async (viewer: Viewer, cameraController: CameraController): Promise<string[]> => {
    const snapshots = [];

    const center = cameraController.getTarget().clone(); // The model center
    const initialPosition = cameraController.getPosition().clone(); // Get the initial camera position

    const radius = Math.sqrt(Math.pow(initialPosition.x - center.x, 2) + Math.pow(initialPosition.z - center.z, 2)); // Fixed orbit radius
    const fixedHeight = initialPosition.y; // Fixed height

    const SCREENSHOTS_COUNT = 24;
    for (let i = 0; i < SCREENSHOTS_COUNT; i++) {
        const angle = (i * (2 * Math.PI)) / SCREENSHOTS_COUNT; // Full 360° rotation divided into SCREENSHOTS_COUNT steps

        // Compute the new camera position on a perfect circular orbit
        const position = new Vector3(
            center.x + Math.cos(angle) * radius, // Rotate around X-axis
            fixedHeight, // Keep height constant (no up/down movement)
            center.z + Math.sin(angle) * radius, // Rotate around Z-axis
        );

        // Move the camera to the new position
        await cameraController.setCameraView({ position, target: center }, false);
        
        // Wait new view
        await new Promise((resolve) => setTimeout(resolve, 50));

        const screenshot = await viewer.screenshot();
        snapshots.push(screenshot);
    }

    return snapshots;
};

Thank you in advance for your help!

Hi @Vitalii

Your approach for this is correct! However Speckle uses a coordinate system where Z is up, so you’d have to change

const fixedHeight = initialPosition.z; // Fixed height

and

const position = new Vector3(
  center.x + Math.cos(angle) * radius, 
  center.y + Math.sin(angle) * radius, 
  fixedHeight 
)

Alternatively, this 360 screenshot is already implemented in our sandbox by pressing the ‘360’ button. The implementation is here. Using either will get you the result you are looking for

Cheers

1 Like