import React, {createContext, useContext, useEffect, useRef, useState} from 'react'; import { Accordion, AccordionSummary, AccordionDetails, FormControl, FormLabel, RadioGroup, FormControlLabel, Radio, } from '@mui/material'; import ExpandMoreIcon from '@mui/icons-material/ExpandMore'; import Box from '@mui/material/Box'; import {Button} from "@mui/material"; import {TreeItem, TreeView} from "@mui/lab"; import ChevronRightIcon from "@mui/icons-material/ChevronRight"; 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, handlePoseSelectedObject, setSelectedObj, transformControlMap) { if (!node) { return null; } return ( { const objName = objEvent.target.innerHTML; setSelectedObj(objName); handlePoseSelectedObject(objName, transformControlMap[objName]); }}> {node.children && node.children.map((child) => processNode(child, handlePoseSelectedObject, setSelectedObj, transformControlMap))} ); } const boneNameTransformMap = { 'hips': "none", 'spine': "none", 'chest': "none", 'upperChest': "none", 'neck': "none", 'head': "none", 'leftShoulder': "none", 'leftUpperArm': "none", 'leftLowerArm': "none", 'leftHand': "none", 'leftThumbMetacarpal': "none", 'leftThumbProximal': "none", 'leftThumbDistal': "none", 'leftIndexProximal': "none", 'leftIndexIntermediate': "none", 'leftIndexDistal': "none", 'leftMiddleProximal': "none", 'leftMiddleIntermediate': "none", 'leftMiddleDistal': "none", 'leftRingProximal': "none", 'leftRingIntermediate': "none", 'leftRingDistal': "none", 'leftLittleProximal': "none", 'leftLittleIntermediate': "none", 'leftLittleDistal': "none", 'rightShoulder': "none", 'rightUpperArm': "none", 'rightLowerArm': "none", 'rightHand': "none", 'rightLittleProximal': "none", 'rightLittleIntermediate': "none", 'rightLittleDistal': "none", 'rightRingProximal': "none", 'rightRingIntermediate': "none", 'rightRingDistal': "none", 'rightMiddleProximal': "none", 'rightMiddleIntermediate': "none", 'rightMiddleDistal': "none", 'rightIndexProximal': "none", 'rightIndexIntermediate': "none", 'rightIndexDistal': "none", 'rightThumbMetacarpal': "none", 'rightThumbProximal': "none", 'rightThumbDistal': "none", 'leftUpperLeg': "none", 'leftLowerLeg': "none", 'leftFoot': "none", 'leftToes': "none", 'rightUpperLeg': "none", 'rightLowerLeg': "none", 'rightFoot': "none", 'rightToes': "none" }; const boneNameList = { "name": "body", "children": [ { "name": "mainBody", "children": [ { "name": "hips", }, { "name": "spine", }, { "name": "chest", }, { "name": "upperChest", }, { "name": "head", } ] }, { "name": "leftArm", "children": [ { "name": "leftShoulder", }, { "name": "leftUpperArm", }, { "name": "leftLowerArm", }, { "name": "leftHand", "children": [ { "name": "leftThumb", "children": [ { "name": "leftThumbMetacarpal", }, { "name": "leftThumbProximal", }, { "name": "leftThumbDistal", }, ] }, { "name": "leftIndex", "children": [ { "name": "leftIndexProximal", }, { "name": "leftIndexIntermediate", }, { "name": "leftIndexDistal", }, ] }, { "name": "leftMiddle", "children": [ { "name": "leftMiddleProximal", }, { "name": "leftMiddleIntermediate", }, { "name": "leftMiddleDistal", }, ] }, { "name": "leftRing", "children": [ { "name": "leftRingProximal", }, { "name": "leftRingIntermediate", }, { "name": "leftRingDistal", }, ] }, { "name": "leftLittle", "children": [ { "name": "leftLittleProximal", }, { "name": "leftLittleIntermediate", }, { "name": "leftLittleDistal", } ] }, ] }, ] }, { "name": "rightArm", "children": [ { "name": "rightShoulder", }, { "name": "rightUpperArm", }, { "name": "rightLowerArm", }, { "name": "rightHand", "children": [ { "name": "rightThumb", "children": [ { "name": "rightThumbMetacarpal", }, { "name": "rightThumbProximal", }, { "name": "rightThumbDistal", }, ] }, { "name": "rightIndex", "children": [ { "name": "rightIndexProximal", }, { "name": "rightIndexIntermediate", }, { "name": "rightIndexDistal", }, ] }, { "name": "rightMiddle", "children": [ { "name": "rightMiddleProximal", }, { "name": "rightMiddleIntermediate", }, { "name": "rightMiddleDistal", }, ] }, { "name": "rightRing", "children": [ { "name": "rightRingProximal", }, { "name": "rightRingIntermediate", }, { "name": "rightRingDistal", }, ] }, { "name": "rightLittle", "children": [ { "name": "rightLittleProximal", }, { "name": "rightLittleIntermediate", }, { "name": "rightLittleDistal", }, ] } ] }, ] }, { "name": "leftLeg", "children": [ { "name": "leftUpperLeg", }, { "name": "leftLowerLeg", }, { "name": "leftFoot", }, { "name": "leftToes", } ] }, { "name": "rightLeg", "children": [ { "name": "rightUpperLeg", }, { "name": "rightLowerLeg", }, { "name": "rightFoot", }, { "name": "rightToes", } ] } ] } function BodyTree({handlePoseSelectedObject, setSelectedObj, transformControlMap}) { return (} defaultExpandIcon={} defaultEndIcon={
} > {processNode(boneNameList, handlePoseSelectedObject, setSelectedObj, transformControlMap)} ); } export default function PosePanel({ setPoseModelFileName, handlePoseSelectedObject, }) { return ( ) } function BodyTreeWrapper({ setPoseModelFileName, handlePoseSelectedObject }) { const [selectedObj, setSelectedObj] = useState(null); const loadPoseModel = () => { setPoseModelFileName("pose.vrm"); }; const {updateObjects} = useObjectUpdate(); const [transformControlMap, setTransformControlMap] = useState(boneNameTransformMap); const updateObjectsRef = useRef(); updateObjectsRef.current = updateObjects; useEffect(() => { window.updateObjects = (newObjects) => { if (updateObjectsRef.current) { updateObjectsRef.current(newObjects); } }; return () => { window.updateObjects = null; }; }, []); return (
}> Pose
Pose edit only supports VRM file currently.
{ (selectedObj in boneNameTransformMap) && Operate { handlePoseSelectedObject(selectedObj, event.target.value); const updatedMap = {...transformControlMap}; updatedMap[selectedObj] = event.target.value; setTransformControlMap(updatedMap); }} > } label="None" checked={transformControlMap[selectedObj] === "none"}/> } label="Rotate" checked={transformControlMap[selectedObj] === "rotate"}/> }
); }