Creating broken lines with Three.js using BufferGeometry

I find myself in a situation where I need to create a Line with holes, essentially a discontinuous line. This entails my Line being composed of multiple segments that are visually separate but conceptually connected. These segments contain more than just two points, unlike how THREE.LinePieces operates.

Currently, I am utilizing a BufferGeometry to hold my vertices. A colleague mentioned that in WebGL, it is feasible to generate two extra arrays alongside the vertices: one for the vertex indices and one for defining the order in which vertices should be connected. Here's an illustration of what I mean:

indices = [0, 1, 2, 3, 4, 5]
vertices = [x0, y0, z0, x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4, x5, y5, z5]
order = [0, 1, 1, 2, 3, 4, 4, 5]

By employing this method, I would be able to create two lines: the initial one from Point 0 to 1 and then to 2, followed by a hole, and finally, a second line from 3 to 4 and then to 5.

Essentially, it would look like this:

.___.___.   .___.___.
0   1   2   3   4   5

Although I lack expertise in WebGL, I am relying on my colleague's assurance that such a structure is possible. However, I am curious if this can also be achieved using Three.js. If so, what would be the process?


UPDATE: After a further discussion with my colleague, he provided me with the following code snippet

indexBufferData = [0, 1, 1, 2, 3, 4, 4, 5];
gl.glBindBuffer(GL.GL_ELEMENT_ARRAY_BUFFER, indexBufferID);
gl.glBufferData(GL.GL_ELEMENT_ARRAY_BUFFER,
             indexBufferData.limit() * Buffers.SIZEOF_INT,
             indexBufferData, GL.GL_STATIC_DRAW);

He mentioned that duplicating the indices and not the vertices (although possible but not recommended) would result in line segments.

I delved into the WebGLRenderer and observed on line 2380 that if there is an attribute index in my BufferGeometry, the necessary buffer will be established. However, setting this attribute did not yield the expected outcome. When utilizing THREE.LinePieces, it still only connects two points.

Answer №1

Check out this code snippet with an interactive demo for you to experiment with:

// .---.---.---.   .---.
// 0   1   2   3   4   5

// create a basic line material
var material = new THREE.LineBasicMaterial({
    color: 0xffffff
});

var vertices = [
    new THREE.Vector3(0, 0, 0),
    new THREE.Vector3(10, 0, 0),
    new THREE.Vector3(20, 0, 0),
    new THREE.Vector3(30, 0, 0),
    new THREE.Vector3(40, 0, 0),
    new THREE.Vector3(50, 0, 0)
];

var positions = new Float32Array(vertices.length * 3);

for (var i = 0; i < vertices.length; i++) {
    positions[i * 3] = vertices[i].x;
    positions[i * 3 + 1] = vertices[i].y;
    positions[i * 3 + 2] = vertices[i].z;
}

var indices = [0, 1, 1, 2, 2, 3, 4, 5];

var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(positions, 3));
geometry.setIndex(new THREE.BufferAttribute(new Uint16Array(indices), 1));

var line = new THREE.LineSegments(geometry, material);
scene.add(line);

Answer №2

To create a sequence of connected line segments with a gap in between, you can utilize the THREE.LineSegments function.

For instance, if you want to draw a line consisting of three segments followed by another line with a single segment, you can follow this pattern:

v0, v1, v1, v2, v2, v3, v4, v5

When rendered, it will look like this:

.___.___.___.   .___.
0   1   2   3   4   5

Updated for three.js version r.91

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

Error: The function user.comparePassword does not exist or is not defined

I am facing an error that says TypeError: user.comparePassword is not a function. I have ensured that all dependencies are installed and the APP is linked to all the libraries. I tried using Postman to retrieve data, but it doesn't seem to be workin ...

Strangely compressed HTML image

I am facing an issue with using a base64-encoded png retrieved from a server in WebGL. To incorporate the encoded png, I load it into an html Image object. For my specific needs, it is crucial that the png data remains completely lossless, however, I&apos ...

Converting strings into time formats in MongoDB

My string appears as follows: schedule_time = { start_time : "13:00", end_time : "14:10" } Now I need to convert it into time in MongoDB. I attempted using dateFromString but encountered some issues. The aggregation query: db.getCollection('appoi ...

Tips for updating specific properties of an object within a MongoDB database using arrays

I have encountered a problem with updating only specific properties of an object in my MongoDB database. While the query I'm using is working for most variables, it unexpectedly sets certain arrays (media: [] and sports: []) in the athleteProfile back ...

The beauty of asynchronous GET requests in VueJS

As a newcomer to VueJS, I am exploring how to make a GET request to the GitHub API. Initially, I made a request to sort users by follower count, resulting in an array ordered in descending order of user logins. Following that, I sent another GET request to ...

Guide on setting the href value within a $.each loop in AJAX requests

I am struggling with downloading a file within a thread. The issue I'm facing is that I can't set the file name in the href and download attributes, so when I attempt to download it, it shows no file available. However, I did realize that replaci ...

Exploring the functionalities of the componentDidUpdate() method in React JS

In my project, I am trying to dynamically change an API parameter using a click function and render new data accordingly. The issue I encountered is that when I trigger the componentDidUpdate method with an onclick event listener, the first click works fin ...

Maximizing efficiency when retrieving information from JSON files

Is there a way to optimize data retrieval for faster loading and determining data length without loading the entire JSON data? Check out this code snippet: const url = "https://jsonplaceholder.typicode.com/comments"; const [data, setData] = useState([] ...

Angular 6 - detecting clicks outside of a menu

Currently, I am working on implementing a click event to close my aside menu. I have already created an example using jQuery, but I want to achieve the same result without using jQuery and without direct access to the 'menu' variable. Can someon ...

Preventing template rendering in Angular until an event is triggered - but how?

I am currently working on a directive that functions well, but I had to resort to using inline template code in order to delay rendering until the click event occurs. However, I believe it would be more streamlined if I could assign the directive template ...

What is the process for instructing GitHub to disregard the three.js dependencies that are currently installed on my project

As a student embarking on the journey to learn front-end web development, I am currently delving into HTML, CSS, and some JS frameworks. I have been using VSCode to push my code to a GitHub repository for practice and understanding. Recently, I decided to ...

The hit detection algorithm seems to be malfunctioning, and the reason behind it is unclear. (Using Javascript/Processing

I am a beginner in game programming and programming in general. In the past, I have created a clone of "Flappy Bird" and some other games using the hit detection algorithm from the Mozilla Developer Network here. Currently, I am facing an issue while tryi ...

Utilizing optional parameters with React Router

Imagine I have a page at http://www.example.com/page/#/search set up with the following routing: <Router history={hashHistory}> <Route path='/search/' component={SearchPage} /> </Router> When a user performs a search using t ...

Ways to display a JSON object in CSV format

Is there a way to export a JSON object to a CSV file, where the sub-fields contain arrays of objects? I am unsure how to properly represent this embedded data in the CSV format. ...

Acquire information from a JSON formatted string

I am having trouble extracting the first name from the JSON data provided below. While I am able to display the entire string using JavaScript [ alert(data); ], I am struggling to isolate just the first names. Any assistance would be greatly appreciated! ...

Alternative names for Firefox's "error console" in different browsers

Are there similar tools to Firefox's "Error console" available in other web browsers? I rely on the error console for identifying JavaScript errors, but I haven't found a straightforward way to view error messages in other browsers like Internet ...

Having trouble loading this JSON data into my table

So I have a little challenge on my hands: I've got a JSON file with information about various books, each including details like title, author, and year of publication. The goal is to select an option from the list and display the chosen property in ...

Error occurs when incorporating OrbitalControl into Three.js leads to TypeError

Attempting to incorporate OrbitalControls into a Three.js Script to allow users to view two spheres in an empty space. However, upon running the code, the following error is encountered: three.js:5353 Uncaught TypeError: Cannot read property 'center& ...

How does ng-repeat determine the presence of duplicates within an array of objects?

angular.module("myApp",[]) .controller("myCtrl",function($scope) { $scope.persons = [{name:"teja",age:11}, {name:"Ash",age:12}, {name:"teja",age:11}]; }); In ...

Ways to prompt a specific text value to generate varied responses

Whenever I try to input the letter "h", I expect a specific value in return but for some reason, it's not working as intended. Despite my best efforts to troubleshoot the issue, I have been unsuccessful in finding a solution. It's frustrating bec ...