Chapter 02Capsules
Using the CreateCapsule()
method of the MeshBuilder
class, we can make capsules.
let capsule = BABYLON.MeshBuilder.CreateCapsule("name", {options}, scene);
The first argument of the CreateCapsule()
method is a String that we can use to retrieve the entire capsule mesh and data about the capsule later. The second argument is an object that specifies various properties of the capsule. The last argument is a reference to the scene in which the capsule 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 / 2, 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 capsule = BABYLON.MeshBuilder.CreateCapsule("capsule", {}, scene); capsule.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>
Properties
Orientation
The orientation
property specifies the axis which runs through the center of the capsule. The default value is Vector3.Up
, which is straight up and down. We cannot put the capsule on an angle, and can only be on an axis.
<script> var canvas1 = document.getElementById("renderCanvas1"); var engine1 = new BABYLON.Engine(canvas1, true); function createLocalAxes(size, scene) { let [local_axisX, local_axisY, local_axisZ] = createAxis(size, scene); let origin = new BABYLON.TransformNode("origin"); local_axisX.parent = origin; local_axisY.parent = origin; local_axisZ.parent = origin; return origin; } function createAxis(size, scene) { let makeTextPlane = function(text, color, size, camera, billboardMode) { let dynamicTexture = new BABYLON.DynamicTexture("DynamicTexture", 50, scene, true); dynamicTexture.hasAlpha = true; dynamicTexture.drawText(text, 5, 40, "bold 36px Arial", color , "transparent", true); let plane = new BABYLON.MeshBuilder.CreatePlane("TextPlane", {size: size, updatable: true}, scene); plane.material = new BABYLON.StandardMaterial("TextPlaneMaterial", scene); plane.material.specularColor = new BABYLON.Color3(0, 0, 0); plane.material.diffuseTexture = dynamicTexture; plane.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL; return plane; }; let axisX = BABYLON.Mesh.CreateLines("axisX", [ new BABYLON.Vector3.Zero(), new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, 0.05 * size, 0), new BABYLON.Vector3(size, 0, 0), new BABYLON.Vector3(size * 0.95, -0.05 * size, 0) ], scene); axisX.color = new BABYLON.Color3(1, 0, 0); let xChar = makeTextPlane("X", "red", size / 8); xChar.position = new BABYLON.Vector3(0.9 * size, -0.05 * size, 0); xChar.parent = axisX; let axisY = BABYLON.Mesh.CreateLines("axisY", [ new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3( -0.05 * size, size * 0.95, 0), new BABYLON.Vector3(0, size, 0), new BABYLON.Vector3( 0.05 * size, size * 0.95, 0) ], scene); axisY.color = new BABYLON.Color3(0, 1, 0); let yChar = makeTextPlane("Y", "green", size / 8); yChar.position = new BABYLON.Vector3(0, 0.9 * size, -0.05 * size); yChar.parent = axisY; let axisZ = BABYLON.Mesh.CreateLines("axisZ", [ new BABYLON.Vector3.Zero(), new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3( 0 , -0.05 * size, size * 0.95), new BABYLON.Vector3(0, 0, size), new BABYLON.Vector3( 0, 0.05 * size, size * 0.95) ], scene); axisZ.color = new BABYLON.Color3(0, 0, 1); let zChar = makeTextPlane("Z", "blue", size / 8); zChar.position = new BABYLON.Vector3(0, 0.05 * size, 0.9 * size); zChar.parent = axisZ; return [axisX, axisY, axisZ]; } function createScene1(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 / 3, 2.75, 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 capsule = BABYLON.MeshBuilder.CreateCapsule("capsule", {orientation: new BABYLON.Vector3(1, 0, 0)}, scene); capsule.material = mat; let axis_origin = createLocalAxes(1, scene); axis_origin.parent = capsule; return scene; }; var scene1 = createScene1(canvas1, engine1); engine1.runRenderLoop(function(){ scene1.render(); }); window.addEventListener("resize", function(){ engine1.resize(); }); </script> <canvas id="renderCanvas1"></canvas>
Subdivisions
The subdivision
property specifies the number of segments in the cylinder portion of the capsule parallel to the orientation. The default value is 2.
<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, 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); mat.wireframe = true; let capsule1 = BABYLON.MeshBuilder.CreateCapsule("capsule1", {subdivisions: 1}, scene); capsule1.material = mat; capsule1.position = new BABYLON.Vector3(-3, 0, 0); let capsule2 = BABYLON.MeshBuilder.CreateCapsule("capsule2", {subdivisions: 2}, scene); capsule2.material = mat; capsule2.position = new BABYLON.Vector3(-1, 0, 0); let capsule3 = BABYLON.MeshBuilder.CreateCapsule("capsule3", {subdivisions: 3}, scene); capsule3.material = mat; capsule3.position = new BABYLON.Vector3(1, 0, 0); let capsule4 = BABYLON.MeshBuilder.CreateCapsule("capsule4", {subdivisions: 4}, scene); capsule4.material = mat; capsule4.position = new BABYLON.Vector3(3, 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>
Tessellation
The tessellation
property specifies the number of sides on the entire capsule. The more sides we have, the more cylindrical the capsule will be. 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 / 2, Math.PI / 6, 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 capsule = BABYLON.MeshBuilder.CreateCapsule("capsule", {tessellation: 3}, scene); capsule.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>
Height
The height
property specifies the length of the capsule from one cap to the other cap. The default value is 1.
<script> var canvas4 = document.getElementById("renderCanvas4"); var engine4 = new BABYLON.Engine(canvas4, true); function createScene4(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, 3, 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 capsule = BABYLON.MeshBuilder.CreateCapsule("capsule", {height: 2}, scene); capsule.material = mat; return scene; }; var scene4 = createScene4(canvas4, engine4); engine4.runRenderLoop(function(){ scene4.render(); }); window.addEventListener("resize", function(){ engine4.resize(); }); </script> <canvas id="renderCanvas4"></canvas>
Radius
The radius
property specifies the width of the entire capsule from one side to the other side. The default value is 0.25.
<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 / 4, Math.PI / 2, 6, 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 capsule = BABYLON.MeshBuilder.CreateCapsule("capsule", {height: 4, radius: 2.0001}, scene); capsule.material = mat; return scene; }; var scene5 = createScene5(canvas5, engine5); engine5.runRenderLoop(function(){ scene5.render(); }); window.addEventListener("resize", function(){ engine5.resize(); }); </script> <canvas id="renderCanvas5"></canvas>
Notice in figure 6 that when the radius
property is close to half of the height
property, our capsule turns into a sphere. However, should we set the radius property to exactly half of the height, we will get an artifact.
CapSubdivisions
The capSubdivisions
property specifies the number of segments that make up the caps on the ends of the capsule mesh parallel to the orientation. The default value is 6.
<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 / 2, Math.PI / 2, 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); mat.wireframe = true; let capsule1 = BABYLON.MeshBuilder.CreateCapsule("capsule1", {capSubdivisions: 1}, scene); capsule1.material = mat; capsule1.position = new BABYLON.Vector3(-3, 0, 0); let capsule2 = BABYLON.MeshBuilder.CreateCapsule("capsule2", {capSubdivisions: 2}, scene); capsule2.material = mat; capsule2.position = new BABYLON.Vector3(-1, 0, 0); let capsule3 = BABYLON.MeshBuilder.CreateCapsule("capsule3", {capSubdivisions: 3}, scene); capsule3.material = mat; capsule3.position = new BABYLON.Vector3(1, 0, 0); let capsule4 = BABYLON.MeshBuilder.CreateCapsule("capsule4", {capSubdivisions: 4}, scene); capsule4.material = mat; capsule4.position = new BABYLON.Vector3(3, 0, 0); return scene; }; var scene6 = createScene6(canvas6, engine6); engine6.runRenderLoop(function(){ scene6.render(); }); window.addEventListener("resize", function(){ engine6.resize(); }); </script> <canvas id="renderCanvas6"></canvas>
RadiusTop and RadiusBottom
The radiusTop
and radiusBottom
properties overwrite the radius
property for the top half and bottom half of the capsule, respectively. These properties defaults to the radius
property value.
<script> var canvas7 = document.getElementById("renderCanvas7"); var engine7 = new BABYLON.Engine(canvas7, true); function createScene7(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, 3, 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 capsule1 = BABYLON.MeshBuilder.CreateCapsule("capsule1", {radiusTop: -0.5}, scene); capsule1.material = mat; capsule1.position = new BABYLON.Vector3(-1, 0, 0); let capsule2 = BABYLON.MeshBuilder.CreateCapsule("capsule2", {radiusBottom: -0.5}, scene); capsule2.material = mat; capsule2.position = new BABYLON.Vector3(1, 0, 0); return scene; }; var scene7 = createScene7(canvas7, engine7); engine7.runRenderLoop(function(){ scene7.render(); }); window.addEventListener("resize", function(){ engine7.resize(); }); </script> <canvas id="renderCanvas7"></canvas>
TopCapSubdivisions and BottomCapSubdivisions
The topCapSubdivisions
and bottomCapSubdivisions
properties overwrite the capSubdivisions
property for the top cap and bottom cap on the capsule, respectively. These properties defaults to the capSubdivisions
property value.
TopCapSubdivisions
<script> var canvas8 = document.getElementById("renderCanvas8"); var engine8 = new BABYLON.Engine(canvas8, true); function createScene8(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, 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); mat.wireframe = true; let capsule1 = BABYLON.MeshBuilder.CreateCapsule("capsule1", {topCapSubdivisions: 1}, scene); capsule1.material = mat; capsule1.position = new BABYLON.Vector3(-3, 0, 0); let capsule2 = BABYLON.MeshBuilder.CreateCapsule("capsule2", {topCapSubdivisions: 2}, scene); capsule2.material = mat; capsule2.position = new BABYLON.Vector3(-1, 0, 0); let capsule3 = BABYLON.MeshBuilder.CreateCapsule("capsule3", {topCapSubdivisions: 3}, scene); capsule3.material = mat; capsule3.position = new BABYLON.Vector3(1, 0, 0); let capsule4 = BABYLON.MeshBuilder.CreateCapsule("capsule4", {topCapSubdivisions: 4}, scene); capsule4.material = mat; capsule4.position = new BABYLON.Vector3(3, 0, 0); return scene; }; var scene8 = createScene8(canvas8, engine8); engine8.runRenderLoop(function(){ scene8.render(); }); window.addEventListener("resize", function(){ engine8.resize(); }); </script> <canvas id="renderCanvas8"></canvas>
BottomCapSubdivisions
<script> var canvas9 = document.getElementById("renderCanvas9"); var engine9 = new BABYLON.Engine(canvas9, true); function createScene9(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, 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); mat.wireframe = true; let capsule1 = BABYLON.MeshBuilder.CreateCapsule("capsule1", {bottomCapSubdivisions: 1}, scene); capsule1.material = mat; capsule1.position = new BABYLON.Vector3(-3, 0, 0); let capsule2 = BABYLON.MeshBuilder.CreateCapsule("capsule2", {bottomCapSubdivisions: 2}, scene); capsule2.material = mat; capsule2.position = new BABYLON.Vector3(-1, 0, 0); let capsule3 = BABYLON.MeshBuilder.CreateCapsule("capsule3", {bottomCapSubdivisions: 3}, scene); capsule3.material = mat; capsule3.position = new BABYLON.Vector3(1, 0, 0); let capsule4 = BABYLON.MeshBuilder.CreateCapsule("capsule4", {bottomCapSubdivisions: 4}, scene); capsule4.material = mat; capsule4.position = new BABYLON.Vector3(3, 0, 0); return scene; }; var scene9 = createScene9(canvas9, engine9); engine9.runRenderLoop(function(){ scene9.render(); }); window.addEventListener("resize", function(){ engine9.resize(); }); </script> <canvas id="renderCanvas9"></canvas>