Adjusted dice mass and friction and added velocity window for dice throwing

This commit is contained in:
Mitchell McCaffrey 2020-05-26 10:57:12 +10:00
parent 3be729d4a0
commit c99e5bf5f8
4 changed files with 45 additions and 19 deletions

View File

@ -4,6 +4,8 @@ import * as AMMO from "ammo.js";
import "babylonjs-loaders";
import ReactResizeDetector from "react-resize-detector";
const diceThrowSpeed = 20;
function DiceScene({ onSceneMount, onPointerDown, onPointerUp }) {
const sceneRef = useRef();
const engineRef = useRef();
@ -52,13 +54,22 @@ function DiceScene({ onSceneMount, onPointerDown, onPointerUp }) {
newPosition.y = currentPosition.y;
const delta = newPosition.subtract(currentPosition);
selectedMesh.setAbsolutePosition(newPosition);
selectedMeshDeltaPositionRef.current = delta;
const velocity = delta.scale(1000 / scene.deltaTime);
selectedMeshVelocityWindowRef.current = selectedMeshVelocityWindowRef.current.slice(
Math.max(
selectedMeshVelocityWindowRef.current.length -
selectedMeshVelocityWindowSize,
0
)
);
selectedMeshVelocityWindowRef.current.push(velocity);
}
});
}, [onSceneMount]);
const selectedMeshRef = useRef();
const selectedMeshDeltaPositionRef = useRef();
const selectedMeshVelocityWindowRef = useRef([]);
const selectedMeshVelocityWindowSize = 4;
function handlePointerDown() {
const scene = sceneRef.current;
if (scene) {
@ -78,21 +89,24 @@ function DiceScene({ onSceneMount, onPointerDown, onPointerUp }) {
function handlePointerUp() {
const selectedMesh = selectedMeshRef.current;
const deltaPosition = selectedMeshDeltaPositionRef.current;
const velocityWindow = selectedMeshVelocityWindowRef.current;
// Average velocity window
let velocity = BABYLON.Vector3.Zero();
for (let v of velocityWindow) {
velocity.addInPlace(v);
}
if (velocityWindow.length > 0) {
velocity.scaleInPlace(1 / velocityWindow.length);
}
const scene = sceneRef.current;
if (selectedMesh && scene && deltaPosition) {
let impulse = deltaPosition.scale(1000 / scene.deltaTime);
impulse.scale(5);
impulse.y = Math.max(impulse.length() * 0.1, 0.5);
if (selectedMesh && scene) {
selectedMesh.physicsImpostor.applyImpulse(
impulse,
selectedMesh
.getAbsolutePosition()
.add(new BABYLON.Vector3(0, Math.random() * 0.5 + 0.5, 0))
velocity.scale(diceThrowSpeed),
selectedMesh.physicsImpostor.getObjectCenter()
);
}
selectedMeshRef.current = null;
selectedMeshDeltaPositionRef.current = null;
selectedMeshVelocityWindowRef.current = [];
onPointerUp();
}

View File

@ -66,7 +66,7 @@ function DiceTray({ isOpen }) {
ground.physicsImpostor = new BABYLON.PhysicsImpostor(
ground,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 0, friction: 100.0 },
{ mass: 0, friction: 20.0 },
scene
);
ground.isVisible = false;
@ -88,7 +88,7 @@ function DiceTray({ isOpen }) {
wall.physicsImpostor = new BABYLON.PhysicsImpostor(
wall,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 0, friction: 1.0 },
{ mass: 0, friction: 10.0 },
scene
);
wall.isVisible = false;
@ -105,7 +105,7 @@ function DiceTray({ isOpen }) {
roof.physicsImpostor = new BABYLON.PhysicsImpostor(
roof,
BABYLON.PhysicsImpostor.BoxImpostor,
{ mass: 0, friction: 1.0 },
{ mass: 0, friction: 100.0 },
scene
);
roof.position.y = 10;

View File

@ -10,6 +10,11 @@ import d100Source from "./meshes/d100.glb";
import { diceTraySize } from "./diceTray/DiceTrayMesh";
import { lerp } from "../helpers/shared";
const minDiceRollSpeed = 400;
const maxDiceRollSpeed = 800;
class Dice {
static instanceCount = 0;
@ -67,7 +72,7 @@ class Dice {
instance.physicsImpostor = new BABYLON.PhysicsImpostor(
instance,
BABYLON.PhysicsImpostor.ConvexHullImpostor,
{ mass: 1, friction: 50 },
{ mass: 10, friction: 4 },
scene
);
@ -91,12 +96,15 @@ class Dice {
Math.random() * Math.PI * 2
);
const impulse = BABYLON.Vector3.Zero()
const impulse = new BABYLON.Vector3(0, 0, 0)
.subtract(position)
.normalizeToNew()
.scale(10);
.scale(lerp(minDiceRollSpeed, maxDiceRollSpeed, Math.random()));
instance.physicsImpostor.applyImpulse(impulse, position);
instance.physicsImpostor.applyImpulse(
impulse,
instance.physicsImpostor.getObjectCenter()
);
}
static async createInstance(mesh, scene) {

View File

@ -35,3 +35,7 @@ export function toRadians(angle) {
export function toDegrees(angle) {
return angle * (180 / Math.PI);
}
export function lerp(a, b, alpha) {
return a * (1 - alpha) + b * alpha;
}