Skip to content

Commit

Permalink
add material edit
Browse files Browse the repository at this point in the history
  • Loading branch information
AmyangXYZ committed Oct 4, 2024
1 parent e54ad64 commit 222212c
Show file tree
Hide file tree
Showing 10 changed files with 104 additions and 26 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
- [x] Model selection
- [x] Ollama support ([electron version](https://github.com/AmyangXYZ/MiKaPo-Electron))
- [ ] VMD export
- [x] MMD editor: bone, material, mesh edit
- [ ] Custom model, vmd import
- [ ] Multi-user co-editing

## Project Setup

Expand Down
3 changes: 2 additions & 1 deletion src/Animation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ function Animation({ setSelectedAnimation }: { setSelectedAnimation: (animation:
>
{availableAnimations.map((animation) => (
<FormControlLabel
key={animation}
value={animation}
control={<Radio sx={{ color: "lightgray" }} size="small" />}
control={<Radio sx={{ color: "#a2c9f5", "&.Mui-checked": { color: "#a2c9f5" } }} size="small" />}
label={<Typography sx={{ fontSize: ".9rem" }}>{animation}</Typography>}
/>
))}
Expand Down
11 changes: 8 additions & 3 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useState } from "react"
import Motion from "./Motion"
import MMDScene from "./MMDScene"
import Outfit from "./Outfit"
import Materials from "./Materials"
import Model from "./Model"
import Animation from "./Animation"
import Header from "./Header"
Expand All @@ -27,7 +27,8 @@ function App(): JSX.Element {
const [selectedAnimation, setSelectedAnimation] = useState<string>("")

const [boneRotation, setBoneRotation] = useState<{ name: string; axis: string; value: number } | null>(null)

const [materials, setMaterials] = useState<string[]>([])
const [materialVisible, setMaterialVisible] = useState<{ name: string; visible: boolean } | null>(null)
return (
<>
<Header fps={fps}></Header>
Expand All @@ -44,6 +45,8 @@ function App(): JSX.Element {
lerpFactor={lerpFactor}
setFps={setFps}
boneRotation={boneRotation}
setMaterials={setMaterials}
materialVisible={materialVisible}
></MMDScene>
<Drawer
variant="persistent"
Expand All @@ -68,7 +71,9 @@ function App(): JSX.Element {
setLerpFactor={setLerpFactor}
style={{ display: activeTab === "motion" ? "block" : "none" }}
></Motion>
{activeTab === "outfit" && <Outfit></Outfit>}
{activeTab === "material" && (
<Materials materials={materials} setMaterialVisible={setMaterialVisible}></Materials>
)}
{activeTab === "skeleton" && <Skeleton setBoneRotation={setBoneRotation}></Skeleton>}
{activeTab === "animation" && <Animation setSelectedAnimation={setSelectedAnimation}></Animation>}
{activeTab === "model" && <Model setSelectedModel={setSelectedModel}></Model>}
Expand Down
34 changes: 23 additions & 11 deletions src/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import { faBone, faFilm, faPanorama, faRunning, faShirt, faUser } from "@fortawesome/free-solid-svg-icons"
import { Fab, Tooltip } from "@mui/material"

function Footer({ setOpenDrawer, setActiveTab }: { setOpenDrawer: (open: boolean) => void, setActiveTab: (tab: string) => void }): JSX.Element {
function Footer({
setOpenDrawer,
setActiveTab,
}: {
setOpenDrawer: (open: boolean) => void
setActiveTab: (tab: string) => void
}): JSX.Element {
const colorPalette = {
motion: "#4A90E2", // Soft Blue
skeleton: "#3498DB", // Peter River Blue
outfit: "#2ECC71", // Emerald Green
motion: "#4A90E2", // Soft Blue
skeleton: "#3498DB", // Peter River Blue
material: "#2ECC71", // Emerald Green
background: "#9B59B6", // Amethyst
model: "#FF8C00", // Dark Orange
animation: "#E74C3C" // Alizarin Red
};
model: "#FF8C00", // Dark Orange
animation: "#E74C3C", // Alizarin Red
}

return (
<div className="footer">
Expand All @@ -24,14 +30,17 @@ function Footer({ setOpenDrawer, setActiveTab }: { setOpenDrawer: (open: boolean
height: "106px",
backgroundColor: colorPalette.motion,
}}
onClick={() => { setActiveTab("motion"); setOpenDrawer(true) }}
onClick={() => {
setActiveTab("motion")
setOpenDrawer(true)
}}
>
<FontAwesomeIcon icon={faRunning} color="white" size="6x" />
</Fab>
</Tooltip>
{[
{ name: "Model", icon: faUser, angle: -20, color: colorPalette.model },
{ name: "Outfit", icon: faShirt, angle: 10, color: colorPalette.outfit },
{ name: "Material", icon: faShirt, angle: 10, color: colorPalette.material },
{ name: "Background", icon: faPanorama, angle: 40, color: colorPalette.background },
{ name: "Skeleton", icon: faBone, angle: 70, color: colorPalette.skeleton },
{ name: "Animation", icon: faFilm, angle: 100, color: colorPalette.animation },
Expand All @@ -46,7 +55,10 @@ function Footer({ setOpenDrawer, setActiveTab }: { setOpenDrawer: (open: boolean
height: "36px",
backgroundColor: color,
}}
onClick={() => { setActiveTab(name.toLowerCase()); setOpenDrawer(true) }}
onClick={() => {
setActiveTab(name.toLowerCase())
setOpenDrawer(true)
}}
>
<FontAwesomeIcon icon={icon} color="white" size="lg" />
</Fab>
Expand All @@ -56,4 +68,4 @@ function Footer({ setOpenDrawer, setActiveTab }: { setOpenDrawer: (open: boolean
)
}

export default Footer
export default Footer
21 changes: 20 additions & 1 deletion src/MMDScene.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
DirectionalLight,
Engine,
HemisphericLight,
Material,
Matrix,
Mesh,
MeshBuilder,
Expand Down Expand Up @@ -104,6 +105,8 @@ function MMDScene({
selectedAnimation,
setSelectedAnimation,
boneRotation,
setMaterials,
materialVisible,
}: {
pose: NormalizedLandmark[] | null
face: NormalizedLandmark[] | null
Expand All @@ -116,6 +119,8 @@ function MMDScene({
selectedAnimation: string
setSelectedAnimation: (animation: string) => void
boneRotation: { name: string; axis: string; value: number } | null
setMaterials: (materials: string[]) => void
materialVisible: { name: string; visible: boolean } | null
}): JSX.Element {
const canvasRef = useRef<HTMLCanvasElement>(null)
const sceneRef = useRef<Scene | null>(null)
Expand Down Expand Up @@ -148,6 +153,19 @@ function MMDScene({
}
}, [boneRotation])

useEffect(() => {
if (materialVisible) {
const material = mmdModelRef.current!.mesh.metadata.materials.find(
(m: Material) => m.name === materialVisible.name
)
const mesh = mmdModelRef.current!.mesh.metadata.meshes.find((m: Mesh) => m.name === materialVisible.name)
if (material && mesh) {
material.alpha = materialVisible.visible ? 1 : 0
mesh.visibility = materialVisible.visible ? 1 : 0
}
}
}, [materialVisible])

useEffect(() => {
const createScene = async (canvas: HTMLCanvasElement): Promise<Scene> => {
const engine = new Engine(canvas, true, {}, true)
Expand Down Expand Up @@ -260,6 +278,7 @@ function MMDScene({
for (const m of mesh.metadata.meshes) {
m.receiveShadows = true
}
setMaterials(mesh.metadata.materials.map((m: Material) => m.name))
shadowGeneratorRef.current!.addShadowCaster(mesh)
mmdModelRef.current = mmdRuntimeRef.current!.createMmdModel(mesh as Mesh, {
buildPhysics: {
Expand All @@ -275,7 +294,7 @@ function MMDScene({
)
}
loadMMD()
}, [sceneRendered, sceneRef, mmdWasmInstanceRef, mmdRuntimeRef, selectedModel, setSelectedAnimation])
}, [sceneRendered, sceneRef, mmdWasmInstanceRef, mmdRuntimeRef, selectedModel, setSelectedAnimation, setMaterials])

useEffect(() => {
if (
Expand Down
38 changes: 38 additions & 0 deletions src/Materials.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { Checkbox, List, ListItem, Typography } from "@mui/material"

function Materials({
materials,
setMaterialVisible,
}: {
materials: string[]
setMaterialVisible: (material: { name: string; visible: boolean }) => void
}): JSX.Element {
return (
<List className="material" dense>
{materials.map((material) => (
<ListItem
key={material}
secondaryAction={
<Checkbox
defaultChecked
onChange={(e) => {
setMaterialVisible({ name: material, visible: e.target.checked })
}}
size="small"
sx={{
color: "#a2c9f5",
"&.Mui-checked": {
color: "#a2c9f5",
},
}}
/>
}
>
<Typography>{material}</Typography>
</ListItem>
))}
</List>
)
}

export default Materials
7 changes: 6 additions & 1 deletion src/Model.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,12 @@ function Model({ setSelectedModel }: { setSelectedModel: (model: string) => void
<FormControlLabel
key={model}
value={model}
control={<Radio sx={{ color: "lightgray", marginLeft: 2, marginBottom: 2 }} size="small" />}
control={
<Radio
sx={{ color: "#a2c9f5", "&.Mui-checked": { color: "#a2c9f5" }, marginLeft: 2, marginBottom: 2 }}
size="small"
/>
}
label={
<Box sx={{ display: "flex", alignItems: "center", marginBottom: 2 }}>
<Avatar src={`/avatar/${model}.png`} alt={model} sx={{ width: 64, height: 64, marginRight: 1 }} />
Expand Down
5 changes: 0 additions & 5 deletions src/Outfit.tsx

This file was deleted.

6 changes: 3 additions & 3 deletions src/Skeleton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Dispatch, SetStateAction, useState } from "react"
import React, { useState } from "react"
import { List, ListItem, ListItemText, Collapse, IconButton, Slider, Typography, ListItemButton } from "@mui/material"
import { ExpandLess, ExpandMore } from "@mui/icons-material"

Expand Down Expand Up @@ -94,7 +94,7 @@ const categories = {
function Skeleton({
setBoneRotation,
}: {
setBoneRotation: Dispatch<SetStateAction<{ name: string; axis: string; value: number } | null>>
setBoneRotation: (boneRotation: { name: string; axis: string; value: number }) => void
}): JSX.Element {
const [openCategory, setOpenCategory] = useState<string | null>(null)
const [openBones, setOpenBones] = useState<Record<string, boolean>>({})
Expand Down Expand Up @@ -160,7 +160,7 @@ function Skeleton({
step={0.001}
min={-Math.PI}
max={Math.PI}
sx={{ ml: 2, width: "80%" }}
sx={{ ml: 2, width: "80%", color: "#a2c9f5" }}
/>
</ListItem>
))}
Expand Down
2 changes: 1 addition & 1 deletion src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ video {

.animation,
.model,
.outfit,
.material,
.background {
position: absolute;
top: 4rem;
Expand Down

0 comments on commit 222212c

Please sign in to comment.