Three.js Import Model in GLTF/GLB Format from Blender

This tutorial contains the source code for the video above. For instruction, please see the video.

game.js

import * as THREE from 'https://unpkg.com/three/build/three.module.js';
import { OrbitControls } from 'https://unpkg.com/three@0.127.0/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'https://unpkg.com/three@0.127.0/examples/jsm/loaders/GLTFLoader.js';

var scene, camera, renderer, cube, controls, draughts, board;

const darkPiece = new THREE.MeshStandardMaterial( { color: 0x222222 } );
const lightPiece = new THREE.MeshStandardMaterial( { color: 0xFFFFFF });

function init() {
  draughts = new Draughts();

  scene = new THREE.Scene();
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);

  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);
  document.body.appendChild(renderer.domElement);

  const square = new THREE.BoxGeometry(1, 0.1, 1);
  const lightsquare = new THREE.MeshBasicMaterial( { color: 0xE0C4A8 } );
  const darksquare = new THREE.MeshBasicMaterial( { color: 0x6A4236});
  board = new THREE.Group();

  const light = new THREE.PointLight( 0xffffff, 2, 200 );
  light.position.set(5, 10, 5);
  scene.add(light);

  let cubeNumber = 1;

  for (let x = 0; x < 10; x++) {
    for (let z = 0; z < 10; z++) {
      let cube;
      if (z % 2 == 0) {
        cube = new THREE.Mesh(square, x % 2 == 0 ? lightsquare : darksquare);
        if (x % 2 != 0) {
          cube.userData.cubeNumber = cubeNumber;
          cubeNumber++;
        }
      }
      else {
        cube = new THREE.Mesh(square, x % 2 == 0 ? darksquare : lightsquare);
        if (x % 2 == 0) {
          cube.userData.cubeNumber = cubeNumber;
          cubeNumber++;
        }
      }
      cube.position.set(x, 0, z);
      board.add(cube);
    }
  }

  scene.add(board);

  const loader = new GLTFLoader();
  loader.load( '../checker.glb', function ( gltf ) {
    const checkerMesh = gltf.scene.children.find((child) => child.name === "Checker");
    checkerMesh.scale.set(checkerMesh.scale.x * 0.4, checkerMesh.scale.y * 0.4, checkerMesh.scale.z * 0.4);
    checkerMesh.geometry.computeBoundingBox();
    console.log(checkerMesh.geometry.boundingBox);
    checkerMesh.position.y += checkerMesh.scale.y + 0.05;
    addCheckers(checkerMesh);
  }, undefined, function ( error ) {

    console.error( error );

  } );

  camera.position.y = 8;

  camera.position.set(4.5, 5, 4.5);
  camera.lookAt(5, 0, 5);

  controls = new OrbitControls(camera, renderer.domElement);

  controls.target.set(4.5, 0, 4.5);
  controls.enablePan = false;
  controls.maxPolarAngle = Math.PI / 2;

  controls.enableDamping = true;

  window.requestAnimationFrame(animate);
}

function animate() {
  controls.update();
  renderer.render(scene, camera);
  window.requestAnimationFrame(animate);
}

function positionForSquare(square) {
  const found = board.children.find((child) => child.userData.cubeNumber == square);
  if (found)
    return found.position;
  return null;
}

function addCheckers(checkerMesh) {
  console.log(draughts.fen());

  for (let i = 1; i < 51; i++) {
    let pieceOn = draughts.get(i);

    const squarePosition = positionForSquare(i);

    if (pieceOn === 'b') {
      const piece = checkerMesh.clone(true);
      piece.material = darkPiece;
      piece.userData.color = 'b';
      piece.userData.currentSquare = i;
      piece.position.set(squarePosition.x, piece.position.y, squarePosition.z);
      scene.add(piece);
    } else if (pieceOn === 'w') {
      const piece = checkerMesh.clone(true);
      piece.material = lightPiece;
      piece.userData.color = 'w';
      piece.userData.currentSquare = i;
      piece.position.set(squarePosition.x, piece.position.y, squarePosition.z);
      scene.add(piece);
    }
  }
}

function onWindowResize() {

  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();

  renderer.setSize( window.innerWidth, window.innerHeight );
}


window.addEventListener('resize', onWindowResize);

window.onload = init;