Okay, this is where I have got to. I am hoping that Brian Zinn will pick up on this!!
The image shows the issue.
I have used Brian’s react-babylon-viewer-1 script and partially integrated it into the main UI script modified from Girauld (see links in other posts) - it all looks very nice except that I need now to pass the selected model into Brian’s viewer script to achieve the change.
If anyone can help that would be awesome.
I am learning react and babylonjs by actually trying to create something that I will use as I do a lot of photogrammetry. So, I picked a script that did what I needed from a functional point of view and modified it. It originally had a unity component using unity-react-webgl as the unityloader and I wanted to replace it with babylon viewer. I just now need to understand how to pass the selected model to Brian’s viewer component.
Any advice and help is very much appreciated - and thank you to imerso for his replies too!
Here is the code from the FormatPopup.js component shown in the figure above. At present th emodel shown in the Viewer is simply one I have set in the Render.tsx file i.e. pointing the rootUrl and sceneFilename to my model folder.
import React from 'react';
import Popup from './Popup'
import { makeStyles } from '@material-ui/core/styles';
import GridList from '@material-ui/core/GridList';
import Link from '@material-ui/core/Link';
import GridListTile from '@material-ui/core/GridListTile';
import GridListTileBar from '@material-ui/core/GridListTileBar';
import IconButton from '@material-ui/core/IconButton';
import OpenInNewIcon from '@material-ui/icons/OpenInNew';
const useStyles = makeStyles((theme) => ({
root: {
display: 'flex',
flexWrap: 'wrap',
justifyContent: 'space-around',
overflow: 'hidden',
backgroundColor: theme.palette.background.paper,
margin: 0,
padding: 0
},
gridList: {
},
icon: {
color: 'rgba(255, 255, 255, 0.5)',
},
header: {
marginBottom: 20,
},
tile: {
cursor: "pointer",
opacity: 0.7,
'&:hover': {
opacity: 1
}
},
}));
export default function FormatPopup(props) {
const classes = useStyles();
const onModelClick = (model) => {
props.setOpen(false);
if(model.file.startsWith("http")) props.setFile(model.file);
else props.setFile(window.location + model.file);
}
const content = props.format ? (
<div>
<div className={classes.header}>
{props.format.description}
<span> <Link href={props.format.url} target="_blank">Open booklet...<OpenInNewIcon fontSize="inherit" /></Link></span>
</div>
<div className={classes.root}>
<GridList cellHeight={180} className={classes.gridList}>
{props.format.models.map((model) => (
<GridListTile
key={model.file}
onClick={() => onModelClick(model)}
className={classes.tile}
>
<img src={model.thumbnail} alt = ""/>
<GridListTileBar
title={model.name}
subtitle={<span>{model.size}</span>}
actionIcon={
<Link href={model.file} target="_blank">
<IconButton
className={classes.icon}>
<OpenInNewIcon />
</IconButton>
</Link>
}
/>
</GridListTile>
))}
</GridList>
</div>
</div>
) : null
return (
<Popup
innerContent={content}
icon={<img src={"formats/" + props.format?.id + "/icon.png"} alt = ""/>}
closeText="Close"
title={props.format?.name + " (" + props.format?.category + ")"}
{...props}
/>
)
}
I need to understand how this can update RenderModel found in the Render.tsx component that is sent to App.js.
Sorry if I sound like I am confused… its because I am learning!!!
And this is Brian’s Render.tsx code
import React from 'react';
import { useRef } from "react";
import { Engine, ILoadedModel, Scene } from "react-babylonjs";
import {
Vector3,
Color3,
ArcRotateCamera,
Nullable,
FramingBehavior,
} from "@babylonjs/core";
import ScaledModelWithProgress from "./ScaledModelWithProgress";
import "@babylonjs/loaders";
import "@babylonjs/inspector";
export const RenderModel = () => {
const camera = useRef<Nullable<ArcRotateCamera>>(null);
const onModelLoaded = (e: ILoadedModel) => {
if (camera && camera.current) {
if (e.loaderName === "gltf") {
camera.current.alpha += Math.PI;
}
// Enable camera's behaviors (done declaratively)
camera.current.useFramingBehavior = true;
var framingBehavior = camera.current.getBehaviorByName(
"Framing"
) as FramingBehavior;
framingBehavior.framingTime = 0;
framingBehavior.elevationReturnTime = -1;
if (e.rootMesh) {
camera.current.lowerRadiusLimit = null;
var worldExtends = e.rootMesh
.getScene()
.getWorldExtends(
(mesh) =>
mesh.isVisible &&
mesh.isEnabled() &&
!mesh.name.startsWith("Background") &&
!mesh.name.startsWith("box")
);
framingBehavior.zoomOnBoundingInfo(worldExtends.min, worldExtends.max);
} else {
console.warn("no root mesh");
}
camera.current.pinchPrecision = 200 / camera.current.radius;
camera.current.upperRadiusLimit = 5 * camera.current.radius;
}
};
return (
<Engine
antialias
adaptToDeviceRatio
canvasId="babylonJS"
canvasStyle={{ width: "100%", height: "89%" }}
>
<Scene>
<arcRotateCamera
ref={camera}
name="arc"
target={Vector3.Zero()}
position={Vector3.Zero()}
alpha={Math.PI}
beta={0.5 + Math.PI / 4}
minZ={0.001}
wheelPrecision={50}
useAutoRotationBehavior
allowUpsideDown={false}
checkCollisions
radius={2}
lowerRadiusLimit={25}
upperRadiusLimit={75}
useFramingBehavior={true}
wheelDeltaPercentage={0.01}
pinchDeltaPercentage={0.01}
/>
<environmentHelper
options={{
enableGroundShadow: false,
createGround: false,
skyboxSize: 1000,
}}
setMainColor={[Color3.FromHexString("#ffffff")]}
/>
<ScaledModelWithProgress
rootUrl={'formats/1/models/'}
sceneFilename="Roman_Ritual_Beaker.glb"
progressBarColor={Color3.FromInts(135, 206, 235)}
center={Vector3.Zero()}
modelRotation={Vector3.Zero()}
onModelLoaded={(e: ILoadedModel) => {
onModelLoaded(e);
}}
/>
</Scene>
</Engine>
);
};
Basically trying to integrate the two scripts.
the JSON is called catalog.json as per Girauld’s original script
{
"formats": [
{
"url": "formats/1/",
"description": "By being able to sort pottery by shape and form we can begin to analyse pottery from contexts within a site. There may be a good mixture of different forms or there may only be blackened cooking pots. Alternatively, only small decorated ware may be present. Information of this type will begin to tell us about the usage of this context and hopefully its date, if similar dated pottery is known from elsewhere. There should be 44 sherds of Roman pottery in this pack. Unfortunately the following sherds are missing :Missing sherds 1.8, 1.12, 1.14, 1.16, 1.25, 1.33, 1.35, 1.37, 1.39 ",
"name": "The first category",
"category": "Introduction to Roman pottery 1",
"id": "1",
"models": [
{
"file": "formats/1/Roman_Ritual_Beaker.glb",
"name": "Roman ritual beaker",
"size": "501,3 Kb",
"thumbnail": "formats/1/models/Roman Ritual Beaker.png"
},
{
"file": "formats/1/models/statue.glb",
"name": "statue",
"size": "16,8 Kb",
"thumbnail": "formats/1/models/placeholder.png"
}
]
},