From f097d5bb5e6e21418ff73601a8d6211019368d18 Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Mon, 16 Oct 2023 12:50:10 -0600 Subject: [PATCH 1/4] add ui --- src/components/Slider.module.css | 4 +- src/components/TraitInformation.jsx | 104 ++++++++++++--------- src/components/TraitInformation.module.css | 98 +++++++++++-------- 3 files changed, 119 insertions(+), 87 deletions(-) diff --git a/src/components/Slider.module.css b/src/components/Slider.module.css index 15867c42..522157a7 100644 --- a/src/components/Slider.module.css +++ b/src/components/Slider.module.css @@ -14,8 +14,8 @@ color: #5eb086; background-color:rgba(5, 11, 14, 0.5); border: none; - font-size: large; - font-weight: 700; + font-size: medium; + font-weight: 500; margin-left: 15px; } .input-box:focus { diff --git a/src/components/TraitInformation.jsx b/src/components/TraitInformation.jsx index e69abf4b..4bfadcb2 100644 --- a/src/components/TraitInformation.jsx +++ b/src/components/TraitInformation.jsx @@ -53,52 +53,64 @@ export default function TraitInformation({currentVRM}){
-
- Trait ID -
-
- {displayTraitOption?.id} -
-
- Trait Name -
-
- {displayTraitOption?.name} -
-
- Culling Layer -
-
- {displayTraitOption?.cullingLayer || "-"} -
-
- Description -
-
- {displayTraitOption?.description || "A nice " + displayTraitOption?.name} -
-
- Culling Options -
-
- Culling Layer - -
-
- Cull Out Distance - -
- Cull In Distance - -
+
+
+ Trait ID +
+
+ {displayTraitOption?.id} +
+
+ Trait Name +
+
+ {displayTraitOption?.name} +
+
+ Culling Layer +
+
+ {displayTraitOption?.cullingLayer || "-"} +
+
+ Description +
+
+ {displayTraitOption?.description || "A nice " + displayTraitOption?.name} +
+
+ Culling Options +
+
+ Culling Layer + +
+
+ Cull Out Distance + +
+ Cull In Distance + +
+
+ Animation +
+
+
+ +
animation name
+ +
+
+
):(<>) diff --git a/src/components/TraitInformation.module.css b/src/components/TraitInformation.module.css index 4924e1f7..cddd36d0 100644 --- a/src/components/TraitInformation.module.css +++ b/src/components/TraitInformation.module.css @@ -1,47 +1,67 @@ + .InformationContainerPos { - position: absolute; - top: 98px; - right: 50px; - height: 500px; - width: 300px; - backdrop-filter: blur(22.5px); - background: rgba(5, 11, 14, 0.5); - z-index: 1000; - display: flex; - flex-direction: column; - padding: 30px; + position: fixed; + right: 32px; + top: 98px; + width:350px; + 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; } + +.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); +} + .traitInfoTitle { - color: white; - text-transform: uppercase; - text-shadow: 1px 1px 2px black; - font-size: 16px; - word-spacing: 2px; - margin-bottom: 10px; + color: white; + text-transform: uppercase; + text-shadow: 1px 1px 2px black; + font-size: 16px; + word-spacing: 2px; + margin-bottom: 10px; } .traitInfoText { - color: rgb(179, 179, 179); - /* text-transform: uppercase; */ - text-shadow: 1px 1px 2px black; - font-size: 16px; - word-spacing: 2px; - margin-bottom: 30px; + color: rgb(179, 179, 179); + /* text-transform: uppercase; */ + text-shadow: 1px 1px 2px black; + font-size: 16px; + word-spacing: 2px; + margin-bottom: 30px; } .input-box { - width: 60px; /* Adjust as needed */ - height: 20px; - color: #5eb086; - background-color:rgba(5, 11, 14, 0.5); - border: none; - font-size: large; - font-weight: 700; - margin-left: 15px; - } - .input-box:focus { - outline: none; - } + width: 60px; /* Adjust as needed */ + height: 20px; + color: #5eb086; + background-color:rgba(5, 11, 14, 0.5); + border: none; + font-size: medium; + font-weight: 500; + margin-left: 15px; +} +.input-box:focus { + outline: none; +} - .input-box::selection { - background-color: #111f17; - color: #5eb086; - } \ No newline at end of file +.input-box::selection { + background-color: #111f17; + color: #5eb086; +} + +.animationSelect{ + display: flex; + justify-content: space-between; + width: 100%; + height:40px; + align-items: center; +} From c800c06b7d939ca0a2e05aeb7992b02353ed36dd Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Mon, 16 Oct 2023 14:31:57 -0600 Subject: [PATCH 2/4] ability to add multiple animations --- src/App.jsx | 5 ++++- src/components/Editor.jsx | 2 +- src/components/TraitInformation.jsx | 23 ++++++++++++++++++++--- src/library/animationManager.js | 29 ++++++++++++++++++++++++++++- src/pages/Appearance.jsx | 2 +- 5 files changed, 54 insertions(+), 7 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 6ec153d3..3b6142ff 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -92,7 +92,10 @@ async function fetchScene() { async function fetchAnimation(templateInfo) { // create an animation manager for all the traits that will be loaded const newAnimationManager = new AnimationManager(templateInfo.offset) - await newAnimationManager.loadAnimations(templateInfo.animationPath, templateInfo.animationPath.endsWith('.fbx')) + const animationPaths = getAsArray(templateInfo.animationPath); + newAnimationManager.storeAnimationPaths(animationPaths); + + await newAnimationManager.loadAnimation(animationPaths, animationPaths[0].endsWith('.fbx')) return newAnimationManager } diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index e7d019c6..51bd2158 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -115,7 +115,7 @@ export default function Editor({confirmDialog,animationManager, blinkManager, lo - + ) } diff --git a/src/components/TraitInformation.jsx b/src/components/TraitInformation.jsx index 4bfadcb2..41c73ee1 100644 --- a/src/components/TraitInformation.jsx +++ b/src/components/TraitInformation.jsx @@ -5,7 +5,7 @@ import { SceneContext } from "../context/SceneContext"; import Slider from "./Slider"; import { cullHiddenMeshes } from "../library/utils"; -export default function TraitInformation({currentVRM}){ +export default function TraitInformation({currentVRM, animationManager}){ const { displayTraitOption, avatar @@ -48,6 +48,17 @@ export default function TraitInformation({currentVRM}){ } }; + const nextAnimation = () => { + animationManager.loadNextAnimation(); + console.log(animationManager); + console.log("next") + } + const prevAnimation = () => { + animationManager.loadPreviousAnimation(); + console.log(animationManager); + console.log("prev") + } + return ( displayTraitOption != null ? (
@@ -105,9 +116,15 @@ export default function TraitInformation({currentVRM}){

- +
animation name
- +
diff --git a/src/library/animationManager.js b/src/library/animationManager.js index 66990aa9..a8c5d16d 100644 --- a/src/library/animationManager.js +++ b/src/library/animationManager.js @@ -3,6 +3,7 @@ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader" import { FBXLoader } from "three/examples/jsm/loaders/FBXLoader" import { addModelData } from "./utils"; import { getMixamoAnimation } from './loadMixamoAnimation'; +import { getAsArray } from './utils'; // make a class that hold all the informarion const fbxLoader = new FBXLoader(); @@ -89,10 +90,13 @@ class AnimationControl { export class AnimationManager{ constructor (offset){ + this.animationPaths = null; this.lastAnimID = null; this.mainControl = null; this.animationControl = null; this.animations = null; + + this.curLoadAnim = 0; this.weightIn = NaN; // note: can't set null, because of check `null < 1` will result `true`. this.weightOut = NaN; @@ -116,8 +120,11 @@ export class AnimationManager{ this.update(); }, 1000/30); } + + - async loadAnimations(path, isfbx = true){ + async loadAnimation(paths, isfbx = true){ + const path = getAsArray(paths)[0]; const loader = isfbx ? fbxLoader : gltfLoader; const animationModel = await loader.loadAsync(path); // if we have mixamo animations store the model @@ -147,6 +154,26 @@ export class AnimationManager{ } + storeAnimationPaths(pathArray){ + this.animationPaths = getAsArray(pathArray); + } + + loadNextAnimation(){ + if (this.curLoadAnim == this.animationPaths.length-1) + this.curLoadAnim = 0; + else + this.curLoadAnim++; + this.loadAnimation(this.animationPaths[this.curLoadAnim]) + } + + loadPreviousAnimation(){ + if (this.curLoadAnim == 0) + this.curLoadAnim = this.animationPaths.length-1; + else + this.curLoadAnim--; + this.loadAnimation(this.animationPaths[this.curLoadAnim]) + } + enableScreenshot() { this.animationControls.forEach(control => { control.reset() diff --git a/src/pages/Appearance.jsx b/src/pages/Appearance.jsx index c72c6727..58dd4780 100644 --- a/src/pages/Appearance.jsx +++ b/src/pages/Appearance.jsx @@ -81,7 +81,7 @@ function Appearance({ if (file && file.name.toLowerCase().endsWith('.fbx')) { console.log('Dropped .fbx file:', file); const path = URL.createObjectURL(file); - animationManager.loadAnimations(path, true); + animationManager.loadAnimation(path, true); // Handle the dropped .fbx file } }; From df1c067020ff09852b2de7883c97badfad809864 Mon Sep 17 00:00:00 2001 From: memelotsqui Date: Mon, 16 Oct 2023 15:40:32 -0600 Subject: [PATCH 3/4] add new assetsLocation support and finish animation integration --- src/App.jsx | 5 ++--- src/components/Editor.jsx | 2 +- src/components/Selector.jsx | 2 +- src/components/TraitInformation.jsx | 22 +++++++++++++--------- src/library/animationManager.js | 22 ++++++++++++++++------ src/library/option-utils.js | 2 +- src/library/utils.js | 7 +++++++ src/pages/Appearance.jsx | 7 +++++-- 8 files changed, 46 insertions(+), 23 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index 3b6142ff..73d5eb3d 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -93,9 +93,8 @@ async function fetchAnimation(templateInfo) { // create an animation manager for all the traits that will be loaded const newAnimationManager = new AnimationManager(templateInfo.offset) const animationPaths = getAsArray(templateInfo.animationPath); - newAnimationManager.storeAnimationPaths(animationPaths); - - await newAnimationManager.loadAnimation(animationPaths, animationPaths[0].endsWith('.fbx')) + newAnimationManager.storeAnimationPaths(animationPaths, templateInfo.assetsLocation || ""); + await newAnimationManager.loadAnimation(animationPaths, animationPaths[0].endsWith('.fbx'), templateInfo.assetsLocation || "") return newAnimationManager } diff --git a/src/components/Editor.jsx b/src/components/Editor.jsx index 51bd2158..5acf8ace 100644 --- a/src/components/Editor.jsx +++ b/src/components/Editor.jsx @@ -103,7 +103,7 @@ export default function Editor({confirmDialog,animationManager, blinkManager, lo size={56} resolution={2048} numFrames={128} - icon={templateInfo.traitIconsDirectorySvg + item.iconSvg} + icon={ (templateInfo.assetsLocation || "") + templateInfo.traitIconsDirectorySvg + item.iconSvg} rarity={currentTraitName !== item.name ? "none" : "mythic"} onClick={() => { selectOption(item) diff --git a/src/components/Selector.jsx b/src/components/Selector.jsx index 2d963658..53102f2d 100644 --- a/src/components/Selector.jsx +++ b/src/components/Selector.jsx @@ -342,7 +342,7 @@ export default function Selector({confirmDialog, templateInfo, animationManager, } - const baseDir = useTemplateBaseDirectory ? templateInfo.traitsDirectory : ""; + const baseDir = useTemplateBaseDirectory ? (templateInfo.assetsLocation || "") + templateInfo.traitsDirectory : ""; // load necesary assets for the options options.map((option, index)=>{ if (option.selected){ diff --git a/src/components/TraitInformation.jsx b/src/components/TraitInformation.jsx index 41c73ee1..e8f2c220 100644 --- a/src/components/TraitInformation.jsx +++ b/src/components/TraitInformation.jsx @@ -14,6 +14,7 @@ export default function TraitInformation({currentVRM, animationManager}){ const [cullOutDistance, setCullOutDistance] = useState(0); // set from the values of the trait const [cullInDistance, setCullInDistance] = useState(0); const [cullLayer, setCullLayer] = useState(0); + const [animationName, setAnimationName] = useState(animationManager.getCurrentAnimationName()); useEffect(() => { if (currentVRM != null){ @@ -22,6 +23,11 @@ export default function TraitInformation({currentVRM, animationManager}){ setCullInDistance(currentVRM?.data?.cullingDistance[1]||0); } }, [currentVRM]) + + useEffect(()=>{ + //console.log(animationManager.currentAnimationName); + setAnimationName(animationManager.getCurrentAnimationName()); + },[animationManager.currentAnimationName]) const handleCullOutChange = (event) => { @@ -48,15 +54,13 @@ export default function TraitInformation({currentVRM, animationManager}){ } }; - const nextAnimation = () => { - animationManager.loadNextAnimation(); - console.log(animationManager); - console.log("next") + const nextAnimation = async () => { + await animationManager.loadNextAnimation(); + setAnimationName(animationManager.getCurrentAnimationName()); } - const prevAnimation = () => { - animationManager.loadPreviousAnimation(); - console.log(animationManager); - console.log("prev") + const prevAnimation = async () => { + await animationManager.loadPreviousAnimation(); + setAnimationName(animationManager.getCurrentAnimationName()); } return ( @@ -120,7 +124,7 @@ export default function TraitInformation({currentVRM, animationManager}){ className={styles["traitInfoText"]} onClick={prevAnimation} >1 -
animation name
+
{animationName}
+ >
{animationName}
- + > diff --git a/src/components/TraitInformation.module.css b/src/components/TraitInformation.module.css index cddd36d0..9e1eed72 100644 --- a/src/components/TraitInformation.module.css +++ b/src/components/TraitInformation.module.css @@ -65,3 +65,37 @@ height:40px; align-items: center; } + +.anim-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; + margin-bottom: 30px; + 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; +} + +.anim-button:hover { + opacity: 1; +} \ No newline at end of file