import React, {createContext, useContext, useState, useEffect, useRef} from 'react';
import {TreeView, TreeItem} from '@mui/lab';
import {styled} from '@mui/system';
import Box from '@mui/material/Box';
import ExpandMoreIcon from "@mui/icons-material/ExpandMore";
import ChevronRightIcon from '@mui/icons-material/ChevronRight';
import {
Accordion,
AccordionSummary,
AccordionDetails,
Button,
FormControl,
Radio,
RadioGroup,
FormLabel,
FormControlLabel,
Typography
} from '@mui/material';
import Checkbox from "@mui/material/Checkbox";
import Slider from "@mui/material/Slider";
import {SketchPicker} from "react-color";
import NumberInput from "./NumberInput.js";
const CustomTreeView = styled(TreeView)`
height: 240px;
overflow-y: auto;
`;
const transformControlObjNames = ["Hemisphere Light", "Directional Light"];
let transformControlValues = {"Hemisphere Light": "none", "Directional Light": "none"};
const treeItemObjNames = ["Scene", "mainObject", "Hemisphere Light", "Directional Light", "Ground", "Grid", "Axis", "Preview Camera"];
const visibleControlObjNames = ["Directional Light", "Ground", "Grid", "Axis"];
let visibleValues = {"Directional Light": true, "Ground": true, "Grid": true, "Axis": true};
const ObjectContext = createContext([]);
function useObjectUpdate() {
const context = useContext(ObjectContext);
if (!context) {
throw new Error('useObjectUpdate must be used within ObjectProvider');
}
return context;
}
function ObjectProvider({children}) {
const [objects, setObjects] = useState([]);
const updateObjects = (newObjects) => {
setObjects(newObjects);
};
return (
{children}
);
}
function processNode(node, handleSelectedObject, setSelectedObj, transformControlMap) {
if (!node) {
return null;
}
if (!(treeItemObjNames.includes(node.name) || node.name.startsWith("mainObject"))) {
return null;
}
return ( {
const objName = objEvent.target.innerHTML;
handleSelectedObject(objName, transformControlMap[objName]);
setSelectedObj(objName);
}}>
{node.children && node.children.map((child) => processNode(child, handleSelectedObject, setSelectedObj, transformControlMap))}
);
}
function ScenePanel({
refreshSceneTree,
handleSelectedObject,
setVisible,
setCameraNear,
setCameraFar,
setCameraFOV,
setCanvasBgColor,
removeObject
}) {
return (
)
}
function SceneTree({handleSelectedObject, setSelectedObj, transformControlMap}) {
const {objects} = useObjectUpdate();
return (}
defaultExpandIcon={}
defaultEndIcon={}
>
{processNode(objects.object, handleSelectedObject, setSelectedObj, transformControlMap)}
);
}
function SceneTreeWrapper({
refreshSceneTree,
handleSelectedObject,
setVisible,
setCameraNear,
setCameraFar,
setCameraFOV,
setCanvasBgColor,
removeObject
}) {
const [selectedObj, setSelectedObj] = useState(null);
const [far, setFar] = useState(1000);
const [near, setNear] = useState(0.1);
const [fov, setFOV] = useState(45);
const [visibleMap, setVisibleMap] = useState(visibleValues);
const [transformControlMap, setTransformControlMap] = useState(transformControlValues);
const [bgColor, setBgColor] = useState();
const {updateObjects} = useObjectUpdate();
const updateObjectsRef = useRef();
updateObjectsRef.current = updateObjects;
useEffect(() => {
window.updateObjects = (newObjects) => {
if (updateObjectsRef.current) {
updateObjectsRef.current(newObjects);
}
};
return () => {
window.updateObjects = null;
};
}, []);
return (
}>
Scene
{(transformControlObjNames.includes(selectedObj) || (selectedObj && selectedObj.startsWith("mainObject"))) &&
Operate
{
handleSelectedObject(selectedObj, event.target.value);
const updatedMap = {...transformControlMap};
updatedMap[selectedObj] = event.target.value;
setTransformControlMap(updatedMap);
}}
>
} label="None"
checked={transformControlMap[selectedObj] === "none" || !transformControlMap[selectedObj]}/>
} label="Translate"
checked={transformControlMap[selectedObj] === "translate"}/>
} label="Rotate"
checked={transformControlMap[selectedObj] === "rotate"}/>
}
{(visibleControlObjNames.includes(selectedObj) || (selectedObj && selectedObj.startsWith("mainObject"))) &&
{
setVisible(selectedObj, event.target.checked);
const updatedMap = {...visibleMap};
updatedMap[selectedObj] = event.target.checked;
setVisibleMap(updatedMap);
}}
color="primary"
/>
}
label='Visible'
/>
}
{
selectedObj === "Preview Camera" &&
Near
{
setNear(newValue);
setCameraNear(newValue);
}}
aria-labelledby="continuous-slider"
/>
Far
{
setFar(newValue);
setCameraFar(newValue)
}}
aria-labelledby="continuous-slider"
/>
FOV
{
setFOV(newValue);
setCameraFOV(newValue);
}}
aria-labelledby="continuous-slider"
/>
}
{
selectedObj && selectedObj.startsWith("mainObject") &&
}
{
selectedObj === "Scene" && {
setBgColor(color);
setCanvasBgColor(color);
}}
disableAlpha={true}
/>
}
);
}
export default ScenePanel;