Chapter 02Tori

Using the CreateTorus() method of the MeshBuilder class, we can make tori.

let torus = BABYLON.MeshBuilder.CreateTorus("name", {options}, scene);

The first argument of CreateTorus() is a String that we can use to retrieve the entire torus mesh and data about the torus later. The second argument is an object that specifies various properties of the torus. The last argument is a reference to the scene in which the tori will be inserted into.

<script>
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);

function createScene(canvas, engine){
    let scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(1, 1, 1);
    let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 2, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);

    let mat = new BABYLON.StandardMaterial("mat", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let torus = BABYLON.MeshBuilder.CreateTorus("torus", {}, scene);
    torus.material = mat;
    
    return scene;
};

var scene = createScene(canvas, engine);

engine.runRenderLoop(function(){
    scene.render();
});

window.addEventListener("resize", function(){
    engine.resize();
});
</script>

<canvas id="renderCanvas"></canvas>
Figure 1. Default Babylon.js Torus.

Properties

Diameter

The diameter of the torus is the distance from one side to the other through the origin, as illustrated below. The default value is 1.

<script>
var canvas5 = document.getElementById("renderCanvas5");
var engine5 = new BABYLON.Engine(canvas5, true);

function createScene5(canvas, engine){
    let scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(1, 1, 1);
    let camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI/2, -Math.PI, 5, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);

    let mat = new BABYLON.StandardMaterial("mat", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let diameter = 3;

    let torus = BABYLON.MeshBuilder.CreateTorus("torus", {diameter: diameter}, scene);
    torus.material = mat;
    
    let diamV = [new BABYLON.Vector3(-((diameter / 2) + 0.25), 0.25, 0), new BABYLON.Vector3((diameter / 2) + 0.25, 0.25, 0)];
    let rightV = [new BABYLON.Vector3(-((diameter / 2) + 0.25), 0.25, -.15), new BABYLON.Vector3(-((diameter / 2) + 0.25), 0.25, .15)];
    let leftV = [new BABYLON.Vector3((diameter / 2) + 0.25, 0.25, -.15), new BABYLON.Vector3((diameter / 2) + 0.25, 0.25, .15)];

    let diam = BABYLON.Mesh.CreateLines("diam", diamV, scene);
    diam.color = new BABYLON.Color3(1, 0, 0);

    let right = BABYLON.Mesh.CreateLines("right", rightV, scene);
    right.color = new BABYLON.Color3(1, 0, 0);

    let left = BABYLON.Mesh.CreateLines("left", leftV, scene);
    left.color = new BABYLON.Color3(1, 0, 0);

    return scene;
};

var scene5 = createScene5(canvas5, engine5);

engine5.runRenderLoop(function(){
    scene5.render();
});

window.addEventListener("resize", function(){
    engine5.resize();
});
</script>

<canvas id="renderCanvas5"></canvas>
Figure 2. The diameter property is set to 3.

Thickness

The thickness of the torus is the distance from one side of the tube to the other side of the tube, as illustrated below. The default value is 0.5.

<script>
var canvas2 = document.getElementById("renderCanvas2");
var engine2 = new BABYLON.Engine(canvas2, true);

function createScene2(canvas, engine){
    let scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(1, 1, 1);
    let camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI/2, -Math.PI, 2, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);

    let mat = new BABYLON.StandardMaterial("mat", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let thickness = .65;

    let torus = BABYLON.MeshBuilder.CreateTorus("torus", {thickness: thickness}, scene);
    torus.material = mat;

    let thickV = [new BABYLON.Vector3(0.45 - (0.45 * thickness), thickness / 2, 0), new BABYLON.Vector3(0.5 + (0.35 * thickness), thickness / 2, 0)];
    let rightV = [new BABYLON.Vector3(0.45 - (0.45 * thickness), thickness / 2, -.15), new BABYLON.Vector3(0.45 - (0.45 * thickness), thickness / 2, .15)];
    let leftV = [new BABYLON.Vector3(0.5 + (0.35 * thickness), thickness / 2, -.15), new BABYLON.Vector3(0.5 + (0.35 * thickness), thickness / 2, .15)];

    let thick = BABYLON.Mesh.CreateLines("thick", thickV, scene);
    thick.color = new BABYLON.Color3(1, 0, 0);

    let right = BABYLON.Mesh.CreateLines("right", rightV, scene);
    right.color = new BABYLON.Color3(1, 0, 0);

    let left = BABYLON.Mesh.CreateLines("left", leftV, scene);
    left.color = new BABYLON.Color3(1, 0, 0);

    return scene;
};

var scene2 = createScene2(canvas2, engine2);

engine2.runRenderLoop(function(){
    scene2.render();
});

window.addEventListener("resize", function(){
    engine2.resize();
});
</script>

<canvas id="renderCanvas2"></canvas>
Figure 3. The thickness property is set to 0.65.

Tessellation

The tessellation property specifies the number of sides on the torus. The more sides the torus has, the smoother it will appear. The default value is 16.

<script>
var canvas3 = document.getElementById("renderCanvas3");
var engine3 = new BABYLON.Engine(canvas3, true);

function createScene3(canvas, engine){
    let scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(1, 1, 1);
    let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, -Math.PI, 2, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);

    let mat = new BABYLON.StandardMaterial("mat", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let torus = BABYLON.MeshBuilder.CreateTorus("torus", {tessellation: 4}, scene);
    torus.material = mat;
    
    return scene;
};

var scene3 = createScene3(canvas3, engine3);

engine3.runRenderLoop(function(){
    scene3.render();
});

window.addEventListener("resize", function(){
    engine3.resize();
});
</script>

<canvas id="renderCanvas3"></canvas>
Figure 4. The tessellation property is set to 4, which makes the torus appear square-shaped.

Updatable

If we want the torus to be able to have its internal geometry changed after creation, we can set the Boolean parameter updatable equal to true. The default value is false.

SideOrientation

The sideOrientation property allows us to change what sides of the torus are visible. The default value is FRONTSIDE, which only makes the front of the torus mesh visible in the scene.

The different values for the sideOrientation property are:

FrontUVs and BackUVs

If the torus is double-sided, we can choose what parts of a texture we crop and stick on the front and back sides of our mesh with the frontUVs and backUVs properties, respectively. The default value for both is Vector4(0, 0, 1, 1), which is the entire texture.

<script>
var canvas6 = document.getElementById("renderCanvas6");
var engine6 = new BABYLON.Engine(canvas6, true);

function createScene6(canvas, engine){
    let scene = new BABYLON.Scene(engine);
    scene.clearColor = new BABYLON.Color3(1, 1, 1);
    let camera = new BABYLON.ArcRotateCamera("Camera", Math.PI / 4, Math.PI / 4, 2, BABYLON.Vector3.Zero(), scene);
    camera.attachControl(canvas, true);
    let light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(1, 1, 0), scene);

    let front = new BABYLON.Vector4(0, 0, 1, 1);
    let back = new BABYLON.Vector4(0, 0, 1, 1);

    let mat = new BABYLON.StandardMaterial("mat", scene);
    mat.diffuseTexture = new BABYLON.Texture("https://www.babylonjs-playground.com/textures/fur.jpg", scene);
    mat.diffuseColor = new BABYLON.Color3(0, 1, 0);

    let torus = BABYLON.MeshBuilder.CreateTorus("torus", {sideOrientation: BABYLON.Mesh.DOUBLESIDE, frontUVs: front, backUVs: back}, scene);
    torus.material = mat;

    return scene;
};

var scene6 = createScene6(canvas6, engine6);

engine6.runRenderLoop(function(){
    scene6.render();
});

window.addEventListener("resize", function(){
    engine6.resize();
});
</script>

<canvas id="renderCanvas6"></canvas>
Figure 5. A texture is applied to the torus using the frontUVs and backUVs properties.

References