Restricting the rotation of a camera in Three.js

Within my Three.js project, there is a 3D scene featuring a floor and an orthographic camera.

I have successfully enabled the user to navigate the scene using their mouse. However, I am facing a challenge in restricting the camera's movement within the boundaries of the floor.

Currently, everything works fine when the camera is oriented at -90 degrees on the x-axis, providing a top-down view of the floor.

The problem arises when I adjust the camera to a different angle, such as -40 degrees, which leads to issues with the restrictions. This results in unintended visibility beyond what should be visible from that perspective.

Is there a way for me to incorporate the camera's rotation into the solution outlined below?

// Setting up the orthographic camera
this.camera = new THREE.OrthographicCamera(...);
this.camera.rotation.x = THREE.MathUtils.degToRad(-90);

// Dimensions of the floor
const modelBoundingBoxWidth = 14;
const modelBoundingBoxHeight = 14;

// Camera movement constraints in world units
const cameraLimits = {
    left: -modelBoundingBoxWidth / 2,
    right: modelBoundingBoxWidth / 2,
    top: -modelBoundingBoxHeight / 2,
    bottom: modelBoundingBoxHeight / 2,
};

// Calculating the new camera position based on mouse input
// (...)

// Enforcing the camera limits on the updated position
if ((cameraPosNew.x - cameraHalfWidth) < cameraLimits.left) {
    cameraPosNew.x = cameraLimits.left + cameraHalfWidth;
}
else if ((cameraPosNew.x + cameraHalfWidth) > cameraLimits.right) {
    cameraPosNew.x = cameraLimits.right - cameraHalfWidth;
}
if ((cameraPosNew.z - cameraHalfHeight) < cameraLimits.top) {
    cameraPosNew.z = cameraLimits.top + cameraHalfHeight;
}
else if ((cameraPosNew.z + cameraHalfHeight) > cameraLimits.bottom) {
    cameraPosNew.z = cameraLimits.bottom - cameraHalfHeight;
}

// Applying the new position to the camera
this.camera.position.set(
    cameraPosNew.x,
    cameraPosNew.y,
    cameraPosNew.z
);

My hypothesis is that I need to project the vertical length of the floor onto the vertical length seen by the camera while considering its rotation angle. However, I'm struggling with the mathematical aspect of this task. Various attempts involving dot product and vector projection haven't yielded any progress.

Additionally, at an angle of -40, I've observed an inequality in the space above and below the floor. This suggests the need for potential adjustments to either the top and bottom clamp limits or altering the camera's position due to rotation effects.

It's worth noting that at -40 degrees, more of the scene becomes visible compared to the -90-degree orientation.


Update: Following further consideration, it seems like my original question may have introduced unnecessary complexities related to panning. Therefore, I believe it would be prudent to focus on understanding how camera rotation impacts visibility first. For this specific query, I've created a separate post: How does rotation influence an orthographic camera in Three.js

Answer №1

To restrict the position vector's movement, you have the option to utilize the THREE.Vector3.clamp() method.

const boxMin = new THREE.Vector3(-7, 0, -7);
const boxMax = new THREE.Vector3(7, 100, 7);

// Determine the updated camera position after mouse panning
// (...)

// Apply clamping to keep it within the defined box boundaries
cameraPosNew.clamp(boxMin, boxMax);

this.camera.position.copy(cameraPosNew);

Although the impact of rotations on the position inside the box is not demonstrated here, accounting for rotations in determining the bounding limits may involve manual calculations with trigonometric functions.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Shader in THREE.js only appears when the window is resized

I recently started working with THREE.js and have been experimenting with shaders. Strangely, I've noticed that this particular shader only displays correctly when I resize the window. You can find the code here. Any ideas on why it's behaving th ...

What is the best strategy for managing pagination when dealing with a large number of pages?

Up until now, I have understood that pagination only links different pages together. This works fine when dealing with a limited number of pages or posts to display. However, what if I have 30 or more pages to paginate? Wouldn't it be impractical to c ...

Troubleshooting: Unable to load template file content in AngularJS ng-view

Setting up a demo angular app has been quite the challenge for me. Despite my efforts, the content from my partial file (partials/test.html) is not loading into the layout file as expected. Below is a snippet of my index.html: <!DOCTYPE html> <ht ...

Continuously encountering a Login Required message while attempting to upload a file on Google Drive

I am currently developing a chrome extension that is designed to intercept specific downloads, like .doc and .docx files, and automatically upload them to a designated folder in Google Drive. Below is the manifest for this extension: { // Manifest det ...

The HSET command in the Redis client for Node.js is not working

I have been developing a DAO (data access object) for the project I am currently working on, which acts as an abstraction of a redis database. Below is the code relevant to my upcoming query: var redis = require("redis"); var _ = require("underscore"); va ...

Loop through each object within an array and verify if a specific property containing an array matches a given value in JavaScript

I am looking for a way to iterate over objects within an array that contains another array called userHandle. I need to loop through the userHandle array and check if any of the values match a string I define as uid. Can anyone provide me with Javascript ...

Utilizing Three.js to import models directly from a database

Currently, I have a MySQL database containing FBX models. The client-side of my application is able to read these models from the database. However, the model data is stored in a JavaScript variable. How can I utilize THREE.FBXLoader() to load the model da ...

Adding a listener to an element within a loop

I'm currently exploring a way to add an event listener in my script. Here's the variable I have: var inputs = data.context.find(':input').not(':button'); Following that, I have a FOR loop where I utilize this variable to ap ...

Is JSON formatting essential for Highcharts? How to divide and preprocess data for creating charts?

Seeking assistance with extracting data from a JSON at the following link: I am attempting to integrate this data into highcharts for visualization. Although I have a functioning chart, I am struggling with properly formatting the JSON mentioned above du ...

Fullpage.js paired with a carousel

Is there a reason why two carousels are not aligning side by side when using fullpage.js? It seems to work perfectly fine without fullpage.js! In Fullpage.js, even after separating the columns for the two carousels, they end up overlapping each other. How ...

Efficiently reducing the size of a CSS selector string with javascript

Is there a library that already performs this function? I've only been able to find online tools. The reason I am interested in accomplishing this task using JavaScript is because I need to ensure that the strings a > b, a and a> b,a are conside ...

Unusual glitch found in Angular application's JavaScript code

I am completely puzzled by this issue: I have a Angular app and I'm trying to update the class using a simple JavaScript string update where the class name is bound to the DOM. The strange thing is that in my application, the most basic statement for ...

Tips for linking two project routes in NodeJS and incorporating React (I am interested in invoking React within the NodeJS project)

I'm in the process of linking two projects, one using reactJS and the other NodeJS. Currently, NodeJS is running smoothly on localhost:3000. Next, I want to call a React application which redirects to port localhost:3001. How can I seamlessly connect ...

NextJS encountered a JavaScript heap out of memory issue

While developing my NextJs project, it suddenly encountered an unknown issue that resulted in the following error message being logged: <--- Last few GCs ---> [8728:000001A567CE5290] 8719226 ms: Mark-sweep (reduce) 1827.7 (1944.2) -> 1827.7 (189 ...

"Incorporating splice in a for loop is causing issues and not functioning

I've been attempting to remove an item from an array, but for some reason, it's not working. Here's the code I'm using: vm.Continue = function () { $scope.invalidList = []; if (vm.errorexsist === true) { var table = doc ...

There appears to be an issue with the onmousemove function

I am currently troubleshooting an issue with a script that I wrote for my button. Interestingly, the code works flawlessly when I test it on CodePen, but I encountered an error when I attempted to run it in VSCode. Even after trying to recreate the script ...

The current layout of the div is hindering the ability to switch from vertical scrolling to horizontal scrolling

I'm currently utilizing this scroll converter tool to transform vertical scrolling into horizontal scrolling. However, despite correct script inclusion and initialization, the conversion is not working as expected. It seems like there might be an issu ...

Sending Multiple Checkbox Values to PHP Using jQuery's Ajax Function

Using jQuery to retrieve values from multiple checkboxes is simple and effective. To see a demonstration, check out this link The jQuery function works well; when a checkbox is checked, we can see the selection based on the data-id after clicking btnUpda ...

Should I fork and customize npm package: Source or Distribution? How to handle the distribution files?

Currently, I am in the process of developing a VueJS web application. Within this project, there is a module that utilizes a wrapper for a JavaScript library obtained through npm and designed to seamlessly integrate with VueJS. However, it doesn't com ...

Press the button to activate the function

<table class="calc" cellpadding=2> <td><input type="button" class="calc" id="screen" value="0" ></td> <td><input type="button" class="calc" id="screen" value="0" ></td> <tr> </ ...