Adjusted dice mass and friction and added velocity window for dice throwing
This commit is contained in:
parent
3be729d4a0
commit
c99e5bf5f8
@ -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();
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user