diff --git a/app/pages/PageEnigma/comps/Timeline/Character.tsx b/app/pages/PageEnigma/comps/Timeline/Character.tsx
index da0da71d2d..adbe523844 100644
--- a/app/pages/PageEnigma/comps/Timeline/Character.tsx
+++ b/app/pages/PageEnigma/comps/Timeline/Character.tsx
@@ -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}
/>
)}
-
+ {editorEngine && editorEngine.isObjectLipsync(character.object_uuid) &&
+
+ }
);
diff --git a/app/pages/PageEnigma/comps/Timeline/RowHeaders/LipSyncSubHeader.tsx b/app/pages/PageEnigma/comps/Timeline/RowHeaders/LipSyncSubHeader.tsx
new file mode 100644
index 0000000000..2cd6a86640
--- /dev/null
+++ b/app/pages/PageEnigma/comps/Timeline/RowHeaders/LipSyncSubHeader.tsx
@@ -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(
+
+
+ Lip Sync
+
+
+
+ );
+ }
+ return null;
+}
\ No newline at end of file
diff --git a/app/pages/PageEnigma/comps/Timeline/RowHeaders/RowHeaders.tsx b/app/pages/PageEnigma/comps/Timeline/RowHeaders/RowHeaders.tsx
index d30fa0b4e4..f5eeefe7b6 100644
--- a/app/pages/PageEnigma/comps/Timeline/RowHeaders/RowHeaders.tsx
+++ b/app/pages/PageEnigma/comps/Timeline/RowHeaders/RowHeaders.tsx
@@ -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 (
+ className="mb-4 w-full rounded-l-lg bg-character-groupBg pb-2"
+ // style={{
+ // height: environmentVariables.value.EXPRESSIONS ? 247 : 199,
+ // }}
+ >
{
Expression
)}
-
-
- Lip Sync
-
-
-
+
);
})}
diff --git a/app/pages/PageEnigma/js/editor.ts b/app/pages/PageEnigma/js/editor.ts
index 2274e10819..69b21c44e0 100644
--- a/app/pages/PageEnigma/js/editor.ts
+++ b/app/pages/PageEnigma/js/editor.ts
@@ -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){