How to bend models using a spline or similar?

Im currently trying to make a game that uses conveyor belts similar to Satisfactory. I’ve tried for many hours now trying to get a system to work but it only works sometimes. Below is the code I have now which breaks if you set the destination z cord to something other than the source z cord. I found a video (video link) of someone making the same thing but in unity, which I tried to port with no success. They also never released their source code so I only based it off of what was shown during the video which was a major chunk of it. Ill upload the port also if that is helpful. Please let me know if anyone has any idea how I can do it!

bezier.ts (6.7 KB)

Plus current code:

function cubicBezierCurve(source: THREE.Vector3, destination: THREE.Vector3): THREE.Vector3[] {
    // Function to calculate a point on the cubic Bézier curve
    function cubicBezierPoint(t: number, P0: THREE.Vector3, P1: THREE.Vector3, P2: THREE.Vector3, P3: THREE.Vector3): THREE.Vector3 {
        const u = 1 - t;
        const tt = t * t;
        const uu = u * u;
        const uuu = uu * u;
        const ttt = tt * t;

        const x = uuu * P0.x + 3 * uu * t * P1.x + 3 * u * tt * P2.x + ttt * P3.x;
        const y = uuu * P0.y + 3 * uu * t * P1.y + 3 * u * tt * P2.y + ttt * P3.y;
        const z = uuu * P0.z + 3 * uu * t * P1.z + 3 * u * tt * P2.z + ttt * P3.z;

        return new THREE.Vector3(x, y, z);
    }

    // Calculate control points for a smooth transition
    const controlPoint1 = new THREE.Vector3(source.x + 10, source.y, source.z); // Example control point
    const controlPoint2 = new THREE.Vector3(destination.x - 10, destination.y, destination.z); // Example control point

    // Generate points along the cubic Bézier curve
    const points: THREE.Vector3[] = [];
    for (let t = 0; t <= 1; t += 0.01) { // Adjust the step size as needed
        const point = cubicBezierPoint(t, source, controlPoint1, controlPoint2, destination);
        points.push(point);
    }

    return points;
}

// Example usage:
const source = new THREE.Vector3(0, 0, 0);
const destination = new THREE.Vector3(10, 5, 10);

const pointsCurve = cubicBezierCurve(source, destination);

var closedSpline = new THREE.CatmullRomCurve3(pointsCurve, false, "catmullrom");

// Set up settings for later extrusion
var extrudeSettings = {
    steps           : 100,
    bevelEnabled    : false,
    extrudePath     : closedSpline
};

const beltWidth = 1

// Define a rectangle
var pts = [
    new THREE.Vector2(0, 0), // bottom-left corner
    new THREE.Vector2(beltWidth, 0), // bottom-right corner
    new THREE.Vector2(beltWidth, 0.1), // bottom-right corner
    new THREE.Vector2(0, 0.1), // bottom-left corner
];
var shape = new THREE.Shape(pts);

// Extrude the rectangle along the CatmullRom curve
var geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings);
var material = new THREE.MeshBasicMaterial({ color: 0x000000, wireframe: false });

// Create mesh with the resulting geometry
var mesh = new THREE.Mesh(geometry, material);

scene.add(mesh)

EDIT: Also should be noted that this approach I have now doesn’t work with rotation of the source and destinations which is vital to this. Then again, that most likely is handled via control points.

curve modifier? three.js examples

Ahh, hopefully this will work

So I ended up implementing it and works for the most part although here is the problem. The top of the square has to stay flat on the top, and not curve like a NASCAR track.

Can you do something with that?

1 Like

This looks exactly what I’m looking for and it keeps the top flat. Can’t thank you enough. Ill check to see if it works.

A simpler highway based on the same principle:
Christmas 2021

from the Collection of examples from discourse.threejs.org

1 Like