Source file: /examples/mesh/meshTopology.js
import Stats from "stats.js";
import { GUI } from "dat.gui"
import {
MeshMaterial3D,
BasicMaterial,
PrimitiveTopology,
WebGLRenderer,
PerspectiveProjection,
Camera,
WebGLRenderDevice,
PlaneMeshBuilder,
Mesh,
MeshMaterialPlugin,
CanvasTarget,
CameraPlugin
} from "chorama"
const canvas = document.createElement('canvas')
const renderTarget = new CanvasTarget(canvas)
const renderDevice = new WebGLRenderDevice(canvas,{
depth:true
})
const renderer = new WebGLRenderer({
plugins:[
new CameraPlugin(),
new MeshMaterialPlugin(),
]
})
const camera = new Camera(renderTarget)
document.body.append(canvas)
updateView()
const meshBuilder = new PlaneMeshBuilder()
const material = new BasicMaterial()
/**@type {[Mesh, Mesh, Mesh, Mesh, Mesh, Mesh, Mesh]} */
const meshes = [
meshBuilder.build(),
meshBuilder.build(),
meshBuilder.build(),
meshBuilder.build(),
meshBuilder.build(),
meshBuilder.build(),
meshBuilder.build()
]
meshes[0].topology = PrimitiveTopology.Points
meshes[1].topology = PrimitiveTopology.Lines
meshes[2].topology = PrimitiveTopology.LineLoop
meshes[3].topology = PrimitiveTopology.LineStrip
meshes[4].topology = PrimitiveTopology.Triangles
meshes[5].topology = PrimitiveTopology.TriangleStrip
meshes[6].topology = PrimitiveTopology.TriangleFan
//create objects
const objects = meshes.map(object => new MeshMaterial3D(object, material))
//transform objects to their positions
objects.forEach((object, i) => {
const stepX = 1.6
const stepY = 2
const startX = -1.6
const startY = 1.6
const number = 3
object.transform.position.x = startX + stepX * (i % number)
object.transform.position.y = startY - Math.floor(i / number) * stepY
})
//set up the camera
camera.transform.position.z = 5
if (camera.projection instanceof PerspectiveProjection) {
camera.projection.fov = Math.PI / 180 * 120
camera.projection.aspect = innerWidth / innerHeight
}
requestAnimationFrame(update)
function update() {
stats.begin()
renderer.render([...objects, camera],renderDevice)
stats.end()
requestAnimationFrame(update)
}
addEventListener("resize", updateView)
// demo-only GUI controls
const controls = new GUI()
const buildOptionsFolder = controls.addFolder("Settings")
buildOptionsFolder
.add(meshBuilder, "width", 0, 4, 0.01)
.name("Width")
.onFinishChange(buildMeshes)
buildOptionsFolder
.add(meshBuilder, "height", 0, 4, 0.01)
.name("Height")
.onFinishChange(buildMeshes)
buildOptionsFolder
.add(meshBuilder, "widthSegments", 1, 100, 1)
.name("Width Segments")
.onFinishChange(buildMeshes)
buildOptionsFolder
.add(meshBuilder, "heightSegments", 1, 100, 1)
.name("Height Segments")
.onFinishChange(buildMeshes)
buildOptionsFolder.open()
function updateView() {
canvas.style.width = innerWidth + "px"
canvas.style.height = innerHeight + "px"
canvas.width = innerWidth * devicePixelRatio
canvas.height = innerHeight * devicePixelRatio
if (camera.projection instanceof PerspectiveProjection) {
camera.projection.aspect = innerWidth / innerHeight
}
}
function buildMeshes() {
for (let i = 0; i < meshes.length; i++) {
const mesh = meshBuilder.build()
switch (i) {
case 0:
mesh.topology = PrimitiveTopology.Points
break
case 1:
mesh.topology = PrimitiveTopology.Lines
break
case 2:
mesh.topology = PrimitiveTopology.LineLoop
break
case 3:
mesh.topology = PrimitiveTopology.LineStrip
break
case 4:
mesh.topology = PrimitiveTopology.Triangles
break
case 5:
mesh.topology = PrimitiveTopology.TriangleStrip
break
case 6:
mesh.topology = PrimitiveTopology.TriangleFan
break
}
meshes[i] = mesh
const object = objects[i]
if (object) {
object.mesh = mesh
}
}
}
// demo-only performance monitor
const stats = new Stats()
stats.showPanel(1)
document.body.append(stats.dom)
stats.dom.removeAttribute('style')
stats.dom.classList.add('performance-monitor')