Skip to content

Commit

Permalink
changed canvas into a react component
Browse files Browse the repository at this point in the history
  • Loading branch information
99-Knots committed Jun 3, 2024
1 parent 586019a commit 06eb58f
Show file tree
Hide file tree
Showing 9 changed files with 395 additions and 222 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# EditorDemo
small demo for a babylon.js room editor
small demo for a babylon.js exibition editor
331 changes: 224 additions & 107 deletions package-lock.json

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,17 @@
"@babylonjs/materials": "^7.8.2",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"html-webpack-plugin": "^5.6.0",
"ts-loader": "^9.5.1",
"typescript": "^5.4.5",
"webpack": "^5.91.0",
"webpack-cli": "^5.1.4",
"webpack-dev-server": "^5.0.4",
"html-webpack-plugin": "^5.6.0"
"webpack-dev-server": "^5.0.4"
},
"dependencies": {
"css-loader": "^7.1.2",
"react": "^18.3.1",
"react-dom": "^18.3.1"
"react-dom": "^18.3.1",
"style-loader": "^4.0.0"
}
}
138 changes: 138 additions & 0 deletions src/components/canvas.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import React from "react";
import { Engine } from '@babylonjs/core/Engines/engine';
import { Scene } from '@babylonjs/core/scene';
import { ArcRotateCamera } from '@babylonjs/core/Cameras/arcRotateCamera';
import { HemisphericLight } from '@babylonjs/core/Lights/hemisphericLight';
import { MeshBuilder } from '@babylonjs/core/Meshes/meshBuilder'
import { Vector3, Color3 } from '@babylonjs/core/Maths/math';
import { SkyMaterial } from '@babylonjs/materials/sky';
import { StandardMaterial } from '@babylonjs/core/Materials/standardMaterial';
import { Texture } from '@babylonjs/core/Materials/Textures/texture';
import { Tools } from '@babylonjs/core/Misc/tools'

import floor_tex from '../../assets/floortiles.png';
import floor_norm from '../../assets/floortiles_normal.png';


type CanvasProps = {
//setSelectedNodes: (_: TransformNode[]) => void,
//propertiesSidebarHandle: React.RefObject<PropertiesSidebarHandle>,
//loadingState: [boolean, (_: boolean) => void],
}

export type CanvasHandle = {
getScene(): Scene

loadScene(): Promise<void>

//deleteNode(node: TransformNode): void

//duplicateNode(node: TransformNode): void

//getGizmo(): GizmoManager

//resetGizmo(): void

//getGizmoHandle(): SwitchHandle
}

const CanvasRenderer: React.ForwardRefRenderFunction<CanvasHandle, CanvasProps> = (props, env) => {

const canvas = React.useRef<HTMLCanvasElement>(null);
const engine = React.useRef<Engine>(null);
const scene = React.useRef<Scene|null>(null);


const setupCamera = async () => {
const arcRotCamera = new ArcRotateCamera(
'cameraArc',
Tools.ToRadians(-90),
Tools.ToRadians(60),
10,
Vector3.Zero(),
scene.current);
arcRotCamera.lowerRadiusLimit = 2;
arcRotCamera.upperRadiusLimit = 45;
arcRotCamera.upperBetaLimit = Tools.ToRadians(89.9); // todo: Adjust to mouse wheel ? like in unreal
arcRotCamera.wheelDeltaPercentage = 0.01;
arcRotCamera.speed = 1;
arcRotCamera.attachControl(canvas, true);
}

const setupSky = async () => {
const sunPosition = new Vector3(50, 120, -100);

const skyMaterial = new SkyMaterial('skyMat', scene.current);
skyMaterial.backFaceCulling = false;
skyMaterial.useSunPosition = true;
skyMaterial.sunPosition = sunPosition;

const skybox = MeshBuilder.CreateBox('skyBox', { size: 1000.0 }, scene.current);
skybox.material = skyMaterial;

const light = new HemisphericLight('hemisphereLight', sunPosition, scene.current);
}

const setupFloor = async () => {
const ground = MeshBuilder.CreateGround('ground', {width:15, height:15}, scene.current);
const groundMat = new StandardMaterial('groundMat', scene.current);
const tileTex = new Texture(floor_tex, scene.current);
tileTex.uScale = ground._width;
tileTex.vScale = ground._height;
const tileNormal = new Texture(floor_norm, scene.current);
tileNormal.uScale = ground._width;
tileNormal.vScale = ground._height;
groundMat.diffuseTexture = tileTex;
groundMat.bumpTexture = tileNormal;
groundMat.specularColor = new Color3(0.4, 0.4, 0.4);
groundMat.backFaceCulling = false;
ground.material = groundMat;
}

const addTestObject = async () => {
const cube = MeshBuilder.CreateBox('box', {size: 1}, scene.current);
cube.translate(new Vector3(0, 1, 0), 0.5001); // avoid clipping with ground
}

const setupEngine = async () => {
engine.current = new Engine(canvas.current, true);
};

const setupScene = async () => {
scene.current = new Scene(engine.current);
await setupCamera();
await setupSky();
await setupFloor();
await addTestObject();
}

const runLoop = async () => {
engine.current.runRenderLoop(() => {
scene.current.render();
})
window.addEventListener("resize", () => {
engine.current.resize();
})
}

const handle = {
getScene() {
return scene.current!;
},

async loadScene() {
await setupEngine();
await setupScene();
await runLoop();
}
}
React.useImperativeHandle(env, () => handle);

return (
<div>
<canvas className='babylon-canvas' ref={canvas} ></canvas>
</div>
)
}

export const Canvas = React.forwardRef(CanvasRenderer);
85 changes: 0 additions & 85 deletions src/components/main.tsx

This file was deleted.

23 changes: 19 additions & 4 deletions src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import React from 'react';
import ReactDOM from 'react-dom';
import {setupEngine} from './components/main'
import { createRoot } from 'react-dom/client';
import { Canvas, CanvasHandle } from './components/canvas';
import './style.css'

setupEngine();
ReactDOM.render(<h1>React Test</h1>, document.getElementById('react-root'));

function Test() {
const canvasHandle = React.useRef<CanvasHandle>();
React.useEffect(() => {
canvasHandle.current.loadScene();
}, [])
return (
<Canvas ref={canvasHandle}/>
)
}

const rootElement = document.getElementById('react-root');
if (!!rootElement) {
const root = createRoot(rootElement);
root.render(<Test />);
}
4 changes: 4 additions & 0 deletions src/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.babylon-canvas {
width: 100%;
height: 100%;
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"sourceMap": false,
"strict": true,
//"strict": true,
"jsx": "react",
"outDir": "./dist"
},
Expand Down
24 changes: 3 additions & 21 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,16 @@ module.exports = {
{
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
},{
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
},
//{
// test: /\.js$/,
// exclude: [
// path.resolve(__dirname, 'bundle.js')
// ],
// enforce: 'post',
// use: {
// loader: WebpackObfuscator.loader,
// options: {
// rotateStringArray: true,
// compact: true,
// }
// }
// }
]
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html',
}),
//new WebpackObfuscator ({
// rotateStringArray: true,
// compact: true,
//}, ['bundle.js']),
//new webpack.ProvidePlugin({
// process: 'process/browser',
//}),
],
devServer: {
static: {
Expand Down

0 comments on commit 06eb58f

Please sign in to comment.