byWulf/threejs-dice

trying to throw a die..

Opened this issue · 1 comments

hi, i am trying to throw a die like in the eample but I cannot make it work...

this is my code deployed here: https://trusting-pasteur-e49332.netlify.com/

Is there a specific order in which the physics and the DIemanger need to be initialized ?

import * as THREE from "three";
import OrbitControls from "orbit-controls-es6";
import { DiceD6, DiceManager } from "threejs-dice";
import C from 'cannon'

export default class DiceStage {
  constructor() {
    this.$stage = document.getElementById('stage');
    // Set Three components
    this.scene = new THREE.Scene();
    this.scene.fog = new THREE.Fog(0x202533, -1, 100);

    this.world = new C.World();
    // this.world.gravity.set(0, -50, 0);
    this.world.gravity.set(0, -9.82 * 20, 0);
    this.world.broadphase = new C.NaiveBroadphase();
    this.world.solver.iterations = 16;

    this.clock = new THREE.Clock();

    // Set options of our scene
    this.bindEvents();
    this.setRender();
    this.setCamera();
    this.setLights();
    //add DiceManager to the world
    DiceManager.setWorld(this.world);

    this.setupFloor();
    this.addObjects();

    setInterval(this.throwDice.bind(this), 3000);
    this.throwDice();

    this.animate();
  }

  bindEvents() {
    window.addEventListener('resize', () => {
      this.onResize()
    })
  }

  onResize() {
    const { W, H } = APP.Layout;

    this.camera.aspect = W / H;

    this.camera.top = this.distance;
    this.camera.right = this.distance * this.camera.aspect;
    this.camera.bottom = -this.distance;
    this.camera.left = -this.distance * this.camera.aspect;

    this.camera.updateProjectionMatrix();
    this.renderer.setSize(W, H);
  }

  setCamera() {
    const aspect = window.innerWidth / window.innerHeight;
    this.distance = 15;

    // this.camera = new THREE.OrthographicCamera(-this.distance * aspect, this.distance * aspect, this.distance, -this.distance, -1, 100)
    var VIEW_ANGLE = 45, NEAR = 0.01, FAR = 20000;
    this.camera = new THREE.PerspectiveCamera(VIEW_ANGLE, aspect, NEAR, FAR);

    this.controls = new OrbitControls(this.camera, this.$stage);

    this.camera.position.set(-10, 10, 10);
    this.camera.lookAt(new THREE.Vector3());
    this.camera.updateProjectionMatrix();
  }

  setLights() {
    const ambient = new THREE.AmbientLight(0xcccccc);
    this.scene.add(ambient);

    const foreLight = new THREE.DirectionalLight(0xffffff, 0.5);
    foreLight.position.set(5, 5, 20);
    this.scene.add(foreLight);

    const backLight = new THREE.DirectionalLight(0xffffff, 1);
    backLight.position.set(-5, -5, -10);
    this.scene.add(backLight);

    let light = new THREE.SpotLight(0xefdfd5, 1.3);
    light.position.y = 100;
    light.target.position.set(0, 0, 0);
    light.castShadow = true;
    light.shadow.camera.near = 50;
    light.shadow.camera.far = 110;
    light.shadow.mapSize.width = 1024;
    light.shadow.mapSize.height = 1024;
    this.scene.add(light);

  }

  setRender() {
    this.renderer = new THREE.WebGLRenderer({
      antialias: true,
      canvas: this.$stage,
    });

    this.renderer.setClearColor(0x1a1e1c);
    this.renderer.setSize(APP.Layout.W, APP.Layout.H);
    this.renderer.setPixelRatio(window.devicePixelRatio);
    this.renderer.shadowMap.enabled = true;
    this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
  }

  animate() {
    this.draw();
    requestAnimationFrame(this.animate.bind(this));
  }

  draw() {
    this.updatePhysics();
    this.renderer.render(this.scene, this.camera);
    if (this.controls) {
      this.controls.update();
    }
  }

  updatePhysics() {
    this.world.step(1 / 60);
    this.dice.updateBodyFromMesh();
  }

  setupFloor() {
// FLOOR
    var floorMaterial = new THREE.MeshPhongMaterial({ color: '#22eeff', side: THREE.DoubleSide });
    var floorGeometry = new THREE.PlaneGeometry(30, 30, 10, 10);
    var floor = new THREE.Mesh(floorGeometry, floorMaterial);
    floor.receiveShadow = true;
    floor.rotation.x = Math.PI / 2;

    this.scene.add(floor);

    let floorBody = new C.Body({ mass: 0, shape: new C.Plane(), material: DiceManager.floorBodyMaterial });
    floorBody.quaternion.setFromAxisAngle(new C.Vec3(1, 0, 0), -Math.PI / 2);
    this.world.add(floorBody);
  }

  addObjects() {
    this.dice = new DiceD6({ size: 1.5, backColor: '#990000' });
    this.scene.add(this.dice.getObject());
    this.dice.getObject().position.y = 2;
    this.dice.getObject().rotation.x = 20 * Math.PI / 180;
  }

  throwDice() {
    let rand = Math.random() * 5;
    let i = 0;
    let yRand = Math.random() * 20;
    this.dice.getObject().position.x = 0;
    this.dice.getObject().position.y = 4 + Math.floor(i / 3) * 1.5;
    this.dice.getObject().position.z = 0;
    this.dice.getObject().quaternion.x = (Math.random() * 90 - 45) * Math.PI / 180;
    this.dice.getObject().quaternion.z = (Math.random() * 90 - 45) * Math.PI / 180;
    this.dice.updateBodyFromMesh();
    this.dice.getObject().body.velocity.set(25 + rand, 40 + yRand, 15 + rand);
    this.dice.getObject().body.angularVelocity.set(20 * Math.random() - 10, 20 * Math.random() - 10, 20 * Math.random() - 10);

    DiceManager.prepareValues([{ dice: this.dice, value: 2 }]);
  }
}
m1ket commented

Hey! Did you figure this out in the end? I'm facing the similar problems having just started to try using this code. Thanks!