How can I create walls in ThreeJS using a path or 2D array?

I am faced with the task of creating a 3D house model, specifically the walls, using a 2D path or array that I receive from a FabricJS editor that I have developed. The specific type of data being transferred from the 2D to 3D views is not critical.

My initial attempt, which was the closest to the desired outcome, involved creating an array of 1s and 0s based on the room layout I intended to draw. I then proceeded to render it in ThreeJS as individual cuboids per 'grid'. This approach was inspired by a ThreeJS game demo found at this link. Here is an example of what the array might look like:

var map = [ //1  2  3  4  5  6  7  8
          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1,],
          [1, 1, 0, 0, 0, 0, 0, 1, 1, 1,], // 1
          [1, 1, 0, 0, 1, 0, 0, 0, 0, 1,], // 2
          [1, 0, 0, 0, 1, 1, 0, 0, 0, 1,], // 3
          [1, 0, 0, 1, 1, 1, 1, 0, 0, 1,], // 4
          [1, 0, 0, 0, 1, 1, 0, 0, 1, 1,], // 5
          [1, 1, 1, 0, 0, 0, 0, 1, 1, 1,], // 6
          [1, 1, 1, 0, 0, 1, 0, 0, 1, 1,], // 7
          [1, 1, 1, 1, 1, 1, 0, 0, 1, 1,], // 8
          [1, 1, 1, 1, 1, 1, 1, 1, 1, 1,],
       ];

By iterating through the array, I was able to render a block for each '1', positioning it based on the indexes from the 2D 'map' (my array).

var UNITSIZE = 250, units = mapW;
for (var i = 0; i < mapW; i++) {
    for (var j = 0, m = map[i].length; j < m; j++) {
        if (map[i][j]) {
            var wall = new t.Mesh(cube, material);
            wall.position.x = (i - units/2) * UNITSIZE;
            wall.position.y = WALLHEIGHT/2;
            wall.position.z = (j - units/2) * UNITSIZE;
            scene.add(wall);
        }
    }
}

While this method worked well for the walls, it presented challenges when I tried to position other models (in .obj format, for example) near the walls. These furniture pieces have their (x=0, y=0, z=0) point at the center of the model. Since the walls are cubes with the same coordinate system and a center at 0, the furniture models ended up being rendered in the center of the walls, resulting in only a quarter of the model being visible when placed in a corner. This is illustrated in the image below:

https://i.sstatic.net/hWBV6.png (black - desired wall appearance, blue - individual cuboids of the wall, red - furniture piece)

That's why I am considering rendering the walls as planes, possibly using a 2D closed patch that can be exported from Fabric without any issues. I do not require the walls to have thickness or be visible from the back when the camera moves through them. Any suggestions on how to achieve this type of rendering?

"Help me StackOverflow, you're my only hope."

Answer №1

If you have a closed path that you need to export as an array of coordinates, you can manually populate the vertex and face arrays of a THREE.js mesh. This way, you can iterate over the array and push the necessary information to create your wall object.

Here is an example:

var coordArray = [...]; // Array of coordinates for a closed shape
// Assuming coordinates are THREE.Vector2() for simplicity

var walls = new THREE.Geometry();

for (var i = 0; i < coordArray.length; i++) {
  var coordinates = coordArray[i];
  walls.vertices.push(new THREE.Vector3(coordinates.x, coordinates.y, 0)); // Vertex at floor level
  walls.vertices.push(new THREE.Vector3(coordinates.x, coordinates.y, 10)); // Vertex at the top of the wall
}

var prevVertexIndex = walls.vertices.length - 2; 

for (var i = 0; i < walls.vertices.length; i += 2) {
  walls.faces.push(new THREE.Face3(i, i + 1, prevVertexIndex));
  walls.faces.push(new THREE.Face3(i + 1, prevVertexIndex + 1, prevVertexIndex));
  prevVertexIndex = i;
}

walls.computeVertexNormals();
walls.computeFaceNormals();

scene.add(new THREE.Mesh(walls, new THREE.MeshLambertMaterial()));

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

The vue-croppa component is showing unusual behavior, with an error message stating "Failed to mount component: template or render function not

I recently tried utilizing vue-croppa for image cropping in my project. I installed it using the npm package manager with the command: npm install --save vue-croppa However, when attempting to implement it as usual: import Croppa from 'vue-croppa&a ...

Ways to reset a JQuery/JavaScript filter

I am currently working on a list of div items that are being filtered and sorted using JavaScript. Each item animates as it enters the screen, scaling up to its final size. However, when I apply filters using buttons, items that are already displayed do n ...

The pdf2json encountered an error when attempting to process a PDF file sent via an HTTP

I am encountering an issue while attempting to extract information from PDF files using a nodejs script. Upon running the program, I encounter the following error: Error: stream must have data at error (eval at <anonymous> (/Users/.../node_modules/ ...

Encountering a 404 error when utilizing ngx-monaco-editor within an Angular application

I have been encountering an issue while attempting to utilize the editor within my Angular 8 application. Despite researching similar errors on Stack Overflow and GitHub discussions, I haven't found a solution yet. Here's how my angular.json asse ...

Switch out external CSS stylesheets automatically using toggle scripting

Hello there! I've been trying to figure out a way for this script to switch back to the original CSS external stylesheet. Here is the code that I currently have: $(document).ready(function() { $("#css-master2").click(function() { $("link[title=chang ...

Modify the height of every div after a successful ajax request

I need assistance in reducing the height of a div within an ajax response that has a class called .shorten-post, but I am unsure how to accomplish this task. I specifically want to decrease the height only for those within the ajax response, not throughou ...

Stop the interval when the variable equals "x"

I've created a function that controls a specific row in my database using AJAX. The function is triggered by a click event and placed within a setInterval function to check ten times per second. Initially, it will return 0, but eventually (usually wi ...

Menu button is expanded without the need to click

The Bootstrap 5 button extends the default behavior and does not collapse. Here is the code: <nav id="header-nav" class="navbar navbar-expand-lg navbar-light"> <div class="container"> <a class= ...

Pass multiple variables as input to a function, then query a JSON array to retrieve multiple array values as the output

My JavaScript function contains a JSON array, where it takes an input and searches for the corresponding key/value pair to return the desired value. I am attempting to input a string of variables like this: 1,2,3,4,5 Into this function: function getF(f ...

The CSS_MODULES encountered a module build error when utilizing the extract-text-webpack-plugin

While processing CSS with CSS modules in a production environment, I encounter an error, but everything works fine in the development environment. Here is the configuration for webpack.base.js: const path = require("path") const webpack = require("webpac ...

Initiating a horizontal scroll menu at the center of the screen: Step-by

I need assistance setting up a horizontal scrolling menu for my project. The requirement is to position the middle button in the center of the .scrollmenu div. Currently, I am working with HTML and CSS, but open to suggestions involving javascript as well ...

How does ES6 impact the connection between Angular, jQuery, and Vue.js?

Searching for tutorials on implementing ES6 with Vue.js but struggling to find a clear connection between the two. Curious if ES6 can be utilized directly or if it requires integration with libraries such as jQuery, Angular, or Vue.js. If using a script ...

The Vue pagination component is optimized to load a single page at a time

There seems to be an issue with my paginate component as it is only displaying the first page despite the total number of objects I want to show: https://i.sstatic.net/rEonp8Rk.png Pagination Component Code: <paginate v-if="searchResults.length & ...

Methods for altering the color of a div using addEventListener

Why doesn't the color change when I click on the div with the class "round"? Also, how can I implement a color change onclick? var round = document.querySelector(".round"); round.addEventListener("click", function() { round.style.backgroundCol ...

Displaying iterative content using Vue.js from an array of items

Looking to style questions and answers differently when rendering them. The data structure is as follows: dialogTut:{ mainTab:{ q:"data with 42 people?", a:"hehe", q:"Are awesome people?", a:"sometimes", ...

Implement Next.js deployment on NGINX server with a 403 forbidden error

I am currently utilizing Next.js for the frontend and Django for the backend. During development, everything is functioning properly. However, when transitioning to production, I am encountering a 403 Forbidden Error related to /_next/static/chunks. It app ...

Touchwipe incorporation - single-page website script

Today has been dedicated to troubleshooting and searching for a solution regarding the integration of TouchWipe () on a custom one-page-site script based on Parallax that I found perfect for my latest project (). The script itself performs beautifully wit ...

Set values for all variables that begin with a specific string

[WARNING! Proceed with caution] One of my most recent coding dilemmas involves creating a JavaScript script that can identify specific surveys. These surveys use variables that share a common string followed by a random number, like this: variableName_46 ...

Get rid of unsafe-eval in the CSP header

I am facing an issue with my old JavaScript code as it is using unsafe-eval. The client has requested to remove unsafe-eval, but the code relies on the eval method in all JavaScript libraries. Removing unsafe-eval breaks the functionality of the code. How ...

Retrieve data from a form on the server side using an Ajax request

I am currently working on submitting form data through an Ajax call. Here is the relevant form code: <form target="_blank" id="addCaseForm" class="form-horizontal col-md-12" action="" method="POST> <div class="form-group"> <labe ...