Moved to new dice mesh and added remaining dice types
@ -1,12 +1,7 @@
|
||||
import React from "react";
|
||||
import { Flex, IconButton } from "theme-ui";
|
||||
|
||||
import ColorDice from "../../../dice/color/ColorDice";
|
||||
import GemStoneDice from "../../../dice/gemStone/GemStoneDice";
|
||||
import GlassDice from "../../../dice/glass/GlassDice";
|
||||
import MetalDice from "../../../dice/metal/MetalDice";
|
||||
import MetalStoneDice from "../../../dice/metalStone/MetalStoneDice";
|
||||
import WoodDice from "../../../dice/wood/WoodDice";
|
||||
import SunsetDice from "../../../dice/sunset/SunsetDice";
|
||||
|
||||
import D20Icon from "../../../icons/D20Icon";
|
||||
import D12Icon from "../../../icons/D12Icon";
|
||||
@ -21,42 +16,42 @@ function DiceControls({ onDiceAdd }) {
|
||||
<IconButton
|
||||
title="Add D20"
|
||||
aria-label="Add D20"
|
||||
onClick={() => onDiceAdd(ColorDice, "d20")}
|
||||
onClick={() => onDiceAdd(SunsetDice, "d20")}
|
||||
>
|
||||
<D20Icon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
title="Add D12"
|
||||
aria-label="Add D12"
|
||||
onClick={() => onDiceAdd(GemStoneDice, "d20")}
|
||||
onClick={() => onDiceAdd(SunsetDice, "d12")}
|
||||
>
|
||||
<D12Icon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
title="Add D10"
|
||||
aria-label="Add D10"
|
||||
onClick={() => onDiceAdd(GlassDice, "d20")}
|
||||
onClick={() => onDiceAdd(SunsetDice, "d10")}
|
||||
>
|
||||
<D10Icon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
title="Add D8"
|
||||
aria-label="Add D8"
|
||||
onClick={() => onDiceAdd(MetalDice, "d20")}
|
||||
onClick={() => onDiceAdd(SunsetDice, "d8")}
|
||||
>
|
||||
<D8Icon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
title="Add D6"
|
||||
aria-label="Add D6"
|
||||
onClick={() => onDiceAdd(MetalStoneDice, "d20")}
|
||||
onClick={() => onDiceAdd(SunsetDice, "d6")}
|
||||
>
|
||||
<D6Icon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
title="Add D4"
|
||||
aria-label="Add D4"
|
||||
onClick={() => onDiceAdd(WoodDice, "d20")}
|
||||
onClick={() => onDiceAdd(SunsetDice, "d4")}
|
||||
>
|
||||
<D4Icon />
|
||||
</IconButton>
|
||||
|
@ -25,7 +25,7 @@ function DiceScene({ onSceneMount }) {
|
||||
|
||||
let camera = new BABYLON.TargetCamera(
|
||||
"camera",
|
||||
new BABYLON.Vector3(0, 34, 0),
|
||||
new BABYLON.Vector3(0, 27, 0),
|
||||
scene
|
||||
);
|
||||
camera.fov = 0.65;
|
||||
|
@ -54,6 +54,7 @@ function DiceTray({ isOpen }) {
|
||||
scene
|
||||
);
|
||||
ground.isVisible = false;
|
||||
ground.position.y = 0.2;
|
||||
|
||||
function createWall(name, x, z, yaw) {
|
||||
let wall = BABYLON.Mesh.CreateBox(
|
||||
@ -75,10 +76,10 @@ function DiceTray({ isOpen }) {
|
||||
wall.isVisible = false;
|
||||
}
|
||||
|
||||
createWall("wallTop", 0, -34.5, 0);
|
||||
createWall("wallRight", -29.5, 0, Math.PI / 2);
|
||||
createWall("wallBottom", 0, 34.5, Math.PI);
|
||||
createWall("wallLeft", 29.5, 0, -Math.PI / 2);
|
||||
createWall("wallTop", 0, -32.5, 0);
|
||||
createWall("wallRight", -28.5, 0, Math.PI / 2);
|
||||
createWall("wallBottom", 0, 32.5, Math.PI);
|
||||
createWall("wallLeft", 28.5, 0, -Math.PI / 2);
|
||||
|
||||
var roof = BABYLON.Mesh.CreateGround("roof", 100, 100, 2, scene);
|
||||
roof.physicsImpostor = new BABYLON.PhysicsImpostor(
|
||||
@ -125,7 +126,7 @@ function DiceTray({ isOpen }) {
|
||||
}
|
||||
}
|
||||
dieSleepRef.current[i] = true;
|
||||
const newNumber = parseInt(highestLocator.name.slice(8));
|
||||
const newNumber = parseInt(highestLocator.name.slice(12));
|
||||
setDieNumbers((prevNumbers) => {
|
||||
let newNumbers = [...prevNumbers];
|
||||
newNumbers[i] = newNumber;
|
||||
@ -160,8 +161,8 @@ function DiceTray({ isOpen }) {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
width: "250px",
|
||||
height: "500px",
|
||||
width: "275px",
|
||||
height: "550px",
|
||||
borderRadius: "4px",
|
||||
display: isOpen ? "block" : "none",
|
||||
position: "relative",
|
||||
@ -173,7 +174,7 @@ function DiceTray({ isOpen }) {
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
top: "8px",
|
||||
bottom: "8px",
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
display: "flex",
|
||||
@ -194,7 +195,7 @@ function DiceTray({ isOpen }) {
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "24px",
|
||||
top: "24px",
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
}}
|
||||
|
@ -1,16 +1,30 @@
|
||||
import * as BABYLON from "babylonjs";
|
||||
|
||||
import d20SharpSource from "./meshes/d20Sharp.glb";
|
||||
import d20RoundSource from "./meshes/d20Round.glb";
|
||||
import d4Source from "./meshes/d4.glb";
|
||||
import d6Source from "./meshes/d6.glb";
|
||||
import d8Source from "./meshes/d8.glb";
|
||||
import d10Source from "./meshes/d10.glb";
|
||||
import d12Source from "./meshes/d12.glb";
|
||||
import d20Source from "./meshes/d20.glb";
|
||||
import d100Source from "./meshes/d100.glb";
|
||||
|
||||
class Dice {
|
||||
static instanceCount = 0;
|
||||
|
||||
static async loadMeshes(diceStyle, material, scene) {
|
||||
static async loadMeshes(material, scene, sourceOverrides) {
|
||||
let meshes = {};
|
||||
const d20Source = diceStyle === "round" ? d20RoundSource : d20SharpSource;
|
||||
const d20Mesh = await this.loadMesh(d20Source, material, scene);
|
||||
meshes.d20 = d20Mesh;
|
||||
const addToMeshes = async (type, defaultSource) => {
|
||||
let source = sourceOverrides ? sourceOverrides[type] : defaultSource;
|
||||
const mesh = await this.loadMesh(source, material, scene);
|
||||
meshes[type] = mesh;
|
||||
};
|
||||
await addToMeshes("d4", d4Source);
|
||||
await addToMeshes("d6", d6Source);
|
||||
await addToMeshes("d8", d8Source);
|
||||
await addToMeshes("d10", d10Source);
|
||||
await addToMeshes("d12", d12Source);
|
||||
await addToMeshes("d20", d20Source);
|
||||
await addToMeshes("d100", d100Source);
|
||||
return meshes;
|
||||
}
|
||||
|
||||
|
@ -1,27 +0,0 @@
|
||||
import Dice from "../Dice";
|
||||
|
||||
import albedo from "./albedo.jpg";
|
||||
import metalRoughness from "./metalRoughness.jpg";
|
||||
import normal from "./normal.jpg";
|
||||
|
||||
class ColorDice extends Dice {
|
||||
static meshes;
|
||||
static material;
|
||||
|
||||
static async createInstance(diceType, scene) {
|
||||
if (!this.material) {
|
||||
this.material = this.loadMaterial(
|
||||
"color_pbr",
|
||||
{ albedo, metalRoughness, normal },
|
||||
scene
|
||||
);
|
||||
}
|
||||
if (!this.meshes) {
|
||||
this.meshes = await this.loadMeshes("round", this.material, scene);
|
||||
}
|
||||
|
||||
return Dice.createInstance(this.meshes[diceType], scene);
|
||||
}
|
||||
}
|
||||
|
||||
export default ColorDice;
|
Before Width: | Height: | Size: 673 KiB |
Before Width: | Height: | Size: 365 KiB |
Before Width: | Height: | Size: 257 KiB |
@ -1,48 +0,0 @@
|
||||
import * as BABYLON from "babylonjs";
|
||||
|
||||
import Dice from "../Dice";
|
||||
|
||||
import albedo from "./albedo.jpg";
|
||||
import metalRoughness from "./metalRoughness.jpg";
|
||||
import normal from "./normal.jpg";
|
||||
|
||||
class GemStoneDice extends Dice {
|
||||
static meshes;
|
||||
static material;
|
||||
|
||||
static loadMaterial(materialName, textures, scene) {
|
||||
let pbr = new BABYLON.PBRMaterial(materialName, scene);
|
||||
|
||||
pbr.albedoTexture = new BABYLON.Texture(textures.albedo);
|
||||
pbr.normalTexture = new BABYLON.Texture(textures.normal);
|
||||
pbr.metallicTexture = new BABYLON.Texture(textures.metalRoughness);
|
||||
pbr.useRoughnessFromMetallicTextureAlpha = false;
|
||||
pbr.useRoughnessFromMetallicTextureGreen = true;
|
||||
pbr.useMetallnessFromMetallicTextureBlue = true;
|
||||
|
||||
pbr.subSurface.isTranslucencyEnabled = true;
|
||||
pbr.subSurface.translucencyIntensity = 1.0;
|
||||
pbr.subSurface.minimumThickness = 5;
|
||||
pbr.subSurface.maximumThickness = 10;
|
||||
pbr.subSurface.tintColor = new BABYLON.Color3(0, 1, 0);
|
||||
|
||||
return pbr;
|
||||
}
|
||||
|
||||
static async createInstance(diceType, scene) {
|
||||
if (!this.material) {
|
||||
this.material = this.loadMaterial(
|
||||
"gem_stone_pbr",
|
||||
{ albedo, metalRoughness, normal },
|
||||
scene
|
||||
);
|
||||
}
|
||||
if (!this.meshes) {
|
||||
this.meshes = await this.loadMeshes("round", this.material, scene);
|
||||
}
|
||||
|
||||
return Dice.createInstance(this.meshes[diceType], scene);
|
||||
}
|
||||
}
|
||||
|
||||
export default GemStoneDice;
|
Before Width: | Height: | Size: 493 KiB |
Before Width: | Height: | Size: 646 KiB |
Before Width: | Height: | Size: 263 KiB |
@ -1,49 +0,0 @@
|
||||
import * as BABYLON from "babylonjs";
|
||||
|
||||
import Dice from "../Dice";
|
||||
|
||||
import albedo from "./albedo.png";
|
||||
import mask from "./mask.png";
|
||||
import normal from "./normal.jpg";
|
||||
|
||||
class GlassDice extends Dice {
|
||||
static meshes;
|
||||
static material;
|
||||
|
||||
static loadMaterial(materialName, textures, scene) {
|
||||
let pbr = new BABYLON.PBRMaterial(materialName, scene);
|
||||
pbr.albedoTexture = new BABYLON.Texture(textures.albedo);
|
||||
pbr.normalTexture = new BABYLON.Texture(textures.normal);
|
||||
|
||||
pbr.roughness = 0.25;
|
||||
pbr.metallic = 0;
|
||||
|
||||
pbr.subSurface.isRefractionEnabled = true;
|
||||
pbr.subSurface.indexOfRefraction = 1.0;
|
||||
pbr.subSurface.isTranslucencyEnabled = true;
|
||||
pbr.subSurface.translucencyIntensity = 1.0;
|
||||
pbr.subSurface.minimumThickness = 10;
|
||||
pbr.subSurface.maximumThickness = 10;
|
||||
pbr.subSurface.tintColor = new BABYLON.Color3(43 / 255, 1, 115 / 255);
|
||||
pbr.subSurface.thicknessTexture = new BABYLON.Texture(textures.mask);
|
||||
pbr.subSurface.useMaskFromThicknessTexture = true;
|
||||
|
||||
return pbr;
|
||||
}
|
||||
|
||||
static async createInstance(diceType, scene) {
|
||||
if (!this.material) {
|
||||
this.material = this.loadMaterial(
|
||||
"glass_pbr",
|
||||
{ albedo, mask, normal },
|
||||
scene
|
||||
);
|
||||
}
|
||||
if (!this.meshes) {
|
||||
this.meshes = await this.loadMeshes("round", this.material, scene);
|
||||
}
|
||||
return Dice.createInstance(this.meshes[diceType], scene);
|
||||
}
|
||||
}
|
||||
|
||||
export default GlassDice;
|
Before Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 174 KiB |
Before Width: | Height: | Size: 257 KiB |
BIN
src/dice/meshes/d10.glb
Normal file
BIN
src/dice/meshes/d100.glb
Normal file
BIN
src/dice/meshes/d12.glb
Normal file
BIN
src/dice/meshes/d20.glb
Normal file
BIN
src/dice/meshes/d4.glb
Normal file
BIN
src/dice/meshes/d6.glb
Normal file
BIN
src/dice/meshes/d8.glb
Normal file
@ -1,26 +0,0 @@
|
||||
import Dice from "../Dice";
|
||||
|
||||
import albedo from "./albedo.jpg";
|
||||
import metalRoughness from "./metalRoughness.jpg";
|
||||
import normal from "./normal.jpg";
|
||||
|
||||
class MetalDice extends Dice {
|
||||
static meshes;
|
||||
static material;
|
||||
|
||||
static async createInstance(diceType, scene) {
|
||||
if (!this.material) {
|
||||
this.material = this.loadMaterial(
|
||||
"metal_pbr",
|
||||
{ albedo, metalRoughness, normal },
|
||||
scene
|
||||
);
|
||||
}
|
||||
if (!this.meshes) {
|
||||
this.meshes = await this.loadMeshes("round", this.material, scene);
|
||||
}
|
||||
return Dice.createInstance(this.meshes[diceType], scene);
|
||||
}
|
||||
}
|
||||
|
||||
export default MetalDice;
|
Before Width: | Height: | Size: 327 KiB |
Before Width: | Height: | Size: 418 KiB |
Before Width: | Height: | Size: 259 KiB |
@ -1,27 +0,0 @@
|
||||
import Dice from "../Dice";
|
||||
|
||||
import albedo from "./albedo.jpg";
|
||||
import metalRoughness from "./metalRoughness.jpg";
|
||||
import normal from "./normal.jpg";
|
||||
|
||||
class MetalStoneDice extends Dice {
|
||||
static meshes;
|
||||
static material;
|
||||
|
||||
static async createInstance(diceType, scene) {
|
||||
if (!this.material) {
|
||||
this.material = this.loadMaterial(
|
||||
"metal_stone_pbr",
|
||||
{ albedo, metalRoughness, normal },
|
||||
scene
|
||||
);
|
||||
}
|
||||
if (!this.meshes) {
|
||||
this.meshes = await this.loadMeshes("round", this.material, scene);
|
||||
}
|
||||
|
||||
return Dice.createInstance(this.meshes[diceType], scene);
|
||||
}
|
||||
}
|
||||
|
||||
export default MetalStoneDice;
|
Before Width: | Height: | Size: 943 KiB |
Before Width: | Height: | Size: 776 KiB |
Before Width: | Height: | Size: 261 KiB |
@ -4,24 +4,24 @@ import albedo from "./albedo.jpg";
|
||||
import metalRoughness from "./metalRoughness.jpg";
|
||||
import normal from "./normal.jpg";
|
||||
|
||||
class WoodDice extends Dice {
|
||||
class SunsetDice extends Dice {
|
||||
static meshes;
|
||||
static material;
|
||||
|
||||
static async createInstance(diceType, scene) {
|
||||
if (!this.material) {
|
||||
this.material = this.loadMaterial(
|
||||
"wood_pbr",
|
||||
"sunset_pbr",
|
||||
{ albedo, metalRoughness, normal },
|
||||
scene
|
||||
);
|
||||
}
|
||||
if (!this.meshes) {
|
||||
this.meshes = await this.loadMeshes("sharp", this.material, scene);
|
||||
this.meshes = await this.loadMeshes(this.material, scene);
|
||||
}
|
||||
|
||||
return Dice.createInstance(this.meshes[diceType], scene);
|
||||
}
|
||||
}
|
||||
|
||||
export default WoodDice;
|
||||
export default SunsetDice;
|
BIN
src/dice/sunset/albedo.jpg
Normal file
After Width: | Height: | Size: 486 KiB |
BIN
src/dice/sunset/metalRoughness.jpg
Normal file
After Width: | Height: | Size: 361 KiB |
BIN
src/dice/sunset/normal.jpg
Normal file
After Width: | Height: | Size: 132 KiB |
Before Width: | Height: | Size: 911 KiB |
Before Width: | Height: | Size: 288 KiB |
Before Width: | Height: | Size: 342 KiB |