Skip to content

Commit

Permalink
Merge pull request #65 from M3-org/Atlas-Option-In-Creation
Browse files Browse the repository at this point in the history
Display Atlas Options when download avatar
  • Loading branch information
madjin authored Nov 14, 2023
2 parents d008d82 + e4a742d commit 48592bd
Show file tree
Hide file tree
Showing 7 changed files with 403 additions and 210 deletions.
46 changes: 28 additions & 18 deletions src/components/ExportMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { SceneContext } from "../context/SceneContext"
import CustomButton from "./custom-button"

import { downloadGLB, downloadVRMWithAvatar } from "../library/download-utils"
import { getAtlasSize } from "../library/utils"

import styles from "./ExportMenu.module.css"
import { local } from "../library/store"
Expand All @@ -16,6 +17,31 @@ export const ExportMenu = ({getFaceScreenshot}) => {
const [name] = React.useState(localStorage.getItem("name") || defaultName)
const { model, avatar,templateInfo } = useContext(SceneContext)

const getOptions = () =>{
const currentOption = local["mergeOptions_sel_option"] || 0;
const screenshot = getFaceScreenshot();
console.log(local["mergeOptions_create_atlas"]);
const createTextureAtlas = local["mergeOptions_create_atlas"] == null ? true:local["mergeOptions_create_atlas"]
return {
isVrm0 : true,
createTextureAtlas : createTextureAtlas,
mToonAtlasSize:getAtlasSize(local["mergeOptions_atlas_mtoon_size"] || 6),
mToonAtlasSizeTransp:getAtlasSize(local["mergeOptions_atlas_mtoon_transp_size"] || 6),
stdAtlasSize:getAtlasSize(local["mergeOptions_atlas_std_size"] || 6),
stdAtlasSizeTransp:getAtlasSize(local["mergeOptions_atlas_std_transp_size"] || 6),
exportStdAtlas:(currentOption === 0 || currentOption == 2),
exportMtoonAtlas:(currentOption === 1 || currentOption == 2),
screenshot:screenshot,
scale:templateInfo.exportScale||1,
vrmMeta:templateInfo.vrmMeta
}
}

const downloadModel = () =>{
const options = getOptions();
downloadVRMWithAvatar(model, avatar, name, options)
}

return (
<React.Fragment>
<CustomButton
Expand All @@ -40,27 +66,11 @@ export const ExportMenu = ({getFaceScreenshot}) => {
/>
<CustomButton
theme="light"
text="VRM (No Atlas)"
icon="download"
size={14}
className={styles.button}
onClick={() => {
const screenshot = getFaceScreenshot();
const options = {screenshot:screenshot, atlasSize: 4096, scale:templateInfo.exportScale||1, isVrm0:true, vrmMeta:templateInfo.vrmMeta,createTextureAtlas:false}
downloadVRMWithAvatar(model, avatar, name, options)
}}
/>
<CustomButton
theme="light"
text="VRM (Atlas)"
text="VRM"
icon="download"
size={14}
className={styles.button}
onClick={() => {
const screenshot = getFaceScreenshot();
const options = {screenshot:screenshot, atlasSize: 4096, scale:templateInfo.exportScale||1, isVrm0:true, vrmMeta:templateInfo.vrmMeta,createTextureAtlas:true}
downloadVRMWithAvatar(model, avatar, name, options)
}}
onClick={downloadModel}
/>
</React.Fragment>
)
Expand Down
210 changes: 210 additions & 0 deletions src/components/MergeOptions.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import React, { useState } from "react"
import styles from "./MergeOptions.module.css"
import MenuTitle from "../components/MenuTitle"
import Slider from "../components/Slider"
import { local } from "../library/store"
import { getAtlasSize } from "../library/utils"

function MergeOptions({showDropToDownload, showCreateAtlas}) {


const [atlasStd, setAtlasStd] = useState(local["mergeOptions_atlas_std_size"] || 6);
const [atlasStdTransp, setAtlasStdTransp] = useState(local["mergeOptions_atlas_std_transp_size"] || 6);
const [atlasMtoon, setAtlasMtoon] = useState(local["mergeOptions_atlas_mtoon_size"] || 6);
const [atlasMtoonTransp, setAtlasMtoonTransp] = useState(local["mergeOptions_atlas_mtoon_transp_size"] || 6);
const [currentOption, setCurrentOption] = useState(local["mergeOptions_sel_option"] || 0);
const [options] = useState(["Merge to Standard", "Merge to MToon", "Keep Both"])

// optimizer
const [downloadOnDrop, setDownloadOnDrop] = useState(local["mergeOptions_drop_download"] || false)

// creator
const [createAtlas, setCreateAtlas] = useState(local["mergeOptions_create_atlas"] == null ? true : local["mergeOptions_create_atlas"])

const handleDropDownloadEnable = (event) => {
setDownloadOnDrop(event.target.checked);
local["mergeOptions_drop_download"] = event.target.checked;
}

const handleCreateAtlas = (event) => {
setCreateAtlas(event.target.checked)
local["mergeOptions_create_atlas"] = event.target.checked;
}


const prevOption = () => {
let cur = currentOption;
if (currentOption <= 0)
cur = options.length-1
else
cur -= 1

setCurrentOption(cur);
local["mergeOptions_sel_option"] = cur;
}

const nextOption = () => {
let cur = currentOption;
if (currentOption >= options.length - 1)
cur = 0;
else
cur +=1;

setCurrentOption(cur);
local["mergeOptions_sel_option"] = cur;
}

const handleChangeAtlasSize = async (event, type) => {
let val = parseInt(event.target.value);
if (val > 8)
val = 8;
else if (val < 0)
val = 0;

const setAtlasSize = (size) => {
switch (type){
case 'standard opaque':
// save to user prefs
setAtlasStd(size);
local["mergeOptions_atlas_std_size"] = size;
break;
case 'standard transparent':
setAtlasStdTransp(size);
local["mergeOptions_atlas_std_transp_size"] = size;
break;
case 'mtoon opaque':
setAtlasMtoon(size);
local["mergeOptions_atlas_mtoon_size"] = size;
break;
case 'mtoon transparent':
setAtlasMtoonTransp(size);
local["mergeOptions_atlas_mtoon_transp_size"] = size;
break;
}
}
setAtlasSize(val)
}

return (

<div className={styles["InformationContainerPos"]}>

<MenuTitle title="Optimizer Options" width={180} left={20}/>
<div className={styles["scrollContainer"]}>

{showCreateAtlas && (
<>
<div className={styles["traitInfoTitle"]}>
Create Atlas
</div>
<div className={styles["traitInfoText"]}>
<div className={styles["checkboxHolder"]}>
<div>
</div>

<label className={styles["custom-checkbox"]}>
<input
type="checkbox"
checked={createAtlas}
onChange={handleCreateAtlas}
/>
<div className={styles["checkbox-container"]}></div>
</label>
<div/><div/>
{createAtlas ? "True": "False"}

</div>
</div>
<br /><br />
</>
)}
{(showCreateAtlas == false || createAtlas)&&(<>
<div className={styles["traitInfoTitle"]}>
Merge Atlas Type
</div>
<br />
<div className={styles["flexSelect"]}>
<div
className={`${styles["arrow-button"]} ${styles["left-button"]}`}
onClick={prevOption}
></div>
<div className={styles["traitInfoText"]} style={{ marginBottom: '0' }}>{options[currentOption]}</div>
<div
//`${styles.class1} ${styles.class2}`
className={`${styles["arrow-button"]} ${styles["right-button"]}`}
onClick={nextOption}
></div>
</div>
<br /><br /><br />

{(currentOption === 0 || currentOption == 2)&&(
<>
<div className={styles["traitInfoTitle"]}>
Standard Atlas Size
</div>
<br />
<div className={styles["traitInfoText"]}>
Opaque: {getAtlasSize(atlasStd) + " x " + getAtlasSize(atlasStd)}
</div>

<Slider value = {atlasStd} onChange={(value) => handleChangeAtlasSize(value, 'standard opaque')} min={1} max={8} step={1}/>
<br/>
<div className={styles["traitInfoText"]}>
Transparent: {getAtlasSize(atlasStdTransp) + " x " + getAtlasSize(atlasStdTransp)}
</div>
<Slider value = {atlasStdTransp} onChange={(value) => handleChangeAtlasSize(value, 'standard transparent')} min={1} max={8} step={1}/>
<br/> <br/> <br/>
</>
)}

{(currentOption === 1 || currentOption == 2)&&(
<>
<div className={styles["traitInfoTitle"]}>
MToon Atlas Size
</div>
<br />
<div className={styles["traitInfoText"]}>
Opaque: {getAtlasSize(atlasMtoon) + " x " + getAtlasSize(atlasMtoon)}
</div>

<Slider value = {atlasMtoon} onChange={(value) => handleChangeAtlasSize(value, 'mtoon opaque')} min={1} max={8} step={1}/>
<br/>
<div className={styles["traitInfoText"]}>
Transparent: {getAtlasSize(atlasMtoonTransp) + " x " + getAtlasSize(atlasMtoonTransp)}
</div>
<Slider value = {atlasMtoonTransp} onChange={(value) => handleChangeAtlasSize(value, 'mtoon transparent')} min={1} max={8} step={1}/>
<br/> <br/> <br/>
</>
)}
{showDropToDownload && (
<>
<div className={styles["traitInfoTitle"]}>
Drag Drop - Download
</div>
<div className={styles["traitInfoText"]}>
<div className={styles["checkboxHolder"]}>
<div>
</div>

<label className={styles["custom-checkbox"]}>
<input
type="checkbox"
checked={downloadOnDrop}
onChange={handleDropDownloadEnable}
/>
<div className={styles["checkbox-container"]}></div>
</label>
<div/><div/>
{downloadOnDrop ? "True": "False"}

</div>
</div>
</>
)}
</>)}
</div>
</div>
)
}

export default MergeOptions
116 changes: 116 additions & 0 deletions src/components/MergeOptions.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
.InformationContainerPos {
position: fixed;
left: 32px;
top: 98px;
width:300px;
height: -webkit-calc(100vh - 176px);
height: calc(100vh - 176px);
backdrop-filter: blur(22.5px);
background: rgba(5, 11, 14, 0.8);
z-index: 1000;
user-select: none;
}
.traitInfoTitle {
color: white;
text-transform: uppercase;
text-shadow: 1px 1px 2px black;
font-size: 16px;
word-spacing: 2px;
margin-bottom: 10px;
text-align: center;
}
.traitInfoText {
color: rgb(179, 179, 179);
/* text-transform: uppercase; */
text-shadow: 1px 1px 2px black;
font-size: 16px;
word-spacing: 2px;
margin-bottom: 10px;
display: flex;
justify-content: center;
}

.flexSelect{
display: flex;
justify-content: space-between;
width: 100%;
height:40px;
align-items: center;
}
.arrow-button {
cursor: pointer;
overflow: hidden;
opacity: 0.8;
width: 32px;
height: 32px;
margin: 2px;
text-align: center;
outline-color: #3b434f;
outline-width: 2px;
outline-style: solid;
align-items: center;
background-color: #1e2530;
}
.left-button{
background: url('/ui/backButton_small.png');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}

.right-button{
background: url('/ui/nextButton_small.png');
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}

.scrollContainer {
height: 100%;
width: 80%;
overflow-y: scroll;
position: relative;
overflow-x: hidden !important;
margin: 30px;
height: -webkit-calc(100% - 40px);
height: calc(100% - 40px);
}
/* Hide the default checkbox */
.custom-checkbox input[type="checkbox"] {
display: none;
}

/* Style the custom checkbox */
.custom-checkbox .checkbox-container {
display: inline-block;
width: 20px;
height: 20px;
border: 2px solid #284b39; /* Change border color as needed */
border-radius: 5px;
cursor: pointer;
}

.custom-checkbox .checkbox-container.checked {
background-color: #5eb086; /* Change background color when checked */
}

.custom-checkbox .checkbox-container .checkmark {
display: none;
}

/* Style the checkmark when the checkbox is checked */
.custom-checkbox input[type="checkbox"]:checked + .checkbox-container {
background-color: #5eb086; /* Change background color when checked */
}

.custom-checkbox input[type="checkbox"]:checked + .checkbox-container .checkmark {
display: block;
}

.checkboxHolder {
display: flex;
gap: 5px;
align-items: center;
justify-content: left;
height: 40px;
}
Loading

0 comments on commit 48592bd

Please sign in to comment.