Do not show Lipsync Track for Characters that are not capable of Lipsync (#313)

Adds function to check if its a lipsync object.
This commit is contained in:
Miles Ryan authored and GitHub committed 2024-05-06 21:04:33 -07:00
1 parent 50dc150e1c
commit b815d7ba09
4 files changed
+77 -28

No files matched your search

@@ -11,6 +11,7 @@ import { CharacterTrack, ClipGroup, ClipType } from "~/pages/PageEnigma/models";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faAngleDown, faAngleUp } from "@fortawesome/pro-solid-svg-icons";
import { AddToast, ToasterContext } from "~/contexts/ToasterContext";
import { EngineContext } from "~/contexts/EngineContext";
import { environmentVariables } from "~/store";
function buildUpdaters(
@@ -69,6 +70,8 @@ interface Props {
export const Character = ({ character }: Props) => {
const { addToast } = useContext(ToasterContext);
const editorEngine = useContext(EngineContext);
const {
updateClipLipSync,
updateClipPosition,
@@ -148,13 +151,15 @@ export const Character = ({ character }: Props) => {
type={ClipType.EXPRESSION}
/>
)}
<TrackClips
id={character.object_uuid}
clips={lipSyncClips}
updateClip={updateClipLipSync}
group={ClipGroup.CHARACTER}
type={ClipType.AUDIO}
/>
{editorEngine && editorEngine.isObjectLipsync(character.object_uuid) &&
<TrackClips
id={character.object_uuid}
clips={lipSyncClips}
updateClip={updateClipLipSync}
group={ClipGroup.CHARACTER}
type={ClipType.AUDIO}
/>
}
</div>
</div>
);
@@ -0,0 +1,39 @@
import { useContext } from "react";
import { EngineContext } from "~/contexts/EngineContext";
import { toggleLipSyncMute } from "~/pages/PageEnigma/store";
import {
faVolume,
faVolumeSlash
} from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { CharacterTrack } from "~/pages/PageEnigma/models";
export const LipSyncSubHeader = ({
character
}:{
character: CharacterTrack
})=>{
const editorEngine = useContext(EngineContext);
if (editorEngine && editorEngine.isObjectLipsync(character.object_uuid)){
return(
<div className="flex mb-3 h-[36px] flex-col justify-center pl-[22px] text-xs font-medium text-white opacity-80">
<div className="flex gap-3">
Lip Sync
<button
className="text-md text-white transition-colors duration-100 hover:text-white/80"
onClick={() => toggleLipSyncMute(character.object_uuid)}>
{character.muted ? (
<FontAwesomeIcon
icon={faVolumeSlash}
className="text-brand-primary transition-colors duration-100 hover:text-brand-primary/80"
/>
) : (
<FontAwesomeIcon icon={faVolume} />
)}
</button>
</div>
</div>
);
}
return null;
}
@@ -17,6 +17,7 @@ import { CameraHeader } from "~/pages/PageEnigma/comps/Timeline/RowHeaders/Camer
import { ObjectsHeader } from "~/pages/PageEnigma/comps/Timeline/RowHeaders/ObjectsHeader";
import { CharacterHeader } from "~/pages/PageEnigma/comps/Timeline/RowHeaders/CharacterHeader";
import { environmentVariables } from "~/store";
import { LipSyncSubHeader } from "./LipSyncSubHeader";
export const RowHeaders = () => {
useSignals();
@@ -50,10 +51,11 @@ export const RowHeaders = () => {
return (
<div
key={character.object_uuid}
className="mb-4 w-full rounded-l-lg bg-character-groupBg"
style={{
height: environmentVariables.value.EXPRESSIONS ? 247 : 199,
}}>
className="mb-4 w-full rounded-l-lg bg-character-groupBg pb-2"
// style={{
// height: environmentVariables.value.EXPRESSIONS ? 247 : 199,
// }}
>
<div className="h-[47px] text-xs font-medium text-white">
<div
className={[
@@ -74,23 +76,7 @@ export const RowHeaders = () => {
Expression
</div>
)}
<div className="flex h-[36px] flex-col justify-center pl-[22px] text-xs font-medium text-white opacity-80">
<div className="flex gap-3">
Lip Sync
<button
className="text-md text-white transition-colors duration-100 hover:text-white/80"
onClick={() => toggleLipSyncMute(character.object_uuid)}>
{character.muted ? (
<FontAwesomeIcon
icon={faVolumeSlash}
className="text-brand-primary transition-colors duration-100 hover:text-brand-primary/80"
/>
) : (
<FontAwesomeIcon icon={faVolume} />
)}
</button>
</div>
</div>
<LipSyncSubHeader character={character}/>
</div>
);
})}
+19
View File
@@ -558,6 +558,25 @@ class Editor {
});
}
isObjectLipsync(object_uuid: string) {
let object = this.activeScene.get_object_by_uuid(object_uuid);
let hasLipsync = false;
if(object){
object.traverse((c: THREE.Object3D) => {
if (c instanceof THREE.Mesh) {
if (c.morphTargetInfluences && c.morphTargetDictionary) {
const blendShapeIndexE = c.morphTargetDictionary["E"];
console.log(c.morphTargetDictionary, blendShapeIndexE)
if (blendShapeIndexE !== null) {
hasLipsync = true;
}
}
}
});
}
return hasLipsync;
}
isObjectLocked(object_uuid: string) {
let object = this.activeScene.get_object_by_uuid(object_uuid);
if(object){