Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat totem layout #26

Closed
wants to merge 27 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
890eb9d
feat: added idle random after every animation except for Loading
andrepat0 Nov 4, 2024
fd169f0
refactor: fine tuned lip sync constant values
andrepat0 Nov 4, 2024
1ee84d5
fix: condition to avoid repeating the same idle animation twice
andrepat0 Nov 4, 2024
8e17353
refactor: handle full body avatar animation and morph target in separ…
andrepat0 Nov 5, 2024
3c2a22b
refactor: removed logs and set max idle count
andrepat0 Nov 6, 2024
52a0720
feat: added new slider component
andrepat0 Nov 7, 2024
3e19e5e
lang: updated translations for settings drawer
andrepat0 Nov 7, 2024
0cb2f33
feat: settings drawer added enable controls checkbox
andrepat0 Nov 7, 2024
3d11892
feat: added position controller to handle height and camera depth of …
andrepat0 Nov 7, 2024
63cff2c
feat: passed enablePositionControl to avatar component
andrepat0 Nov 7, 2024
43dd930
refactor: replaced constants and morp target controller to the parent…
andrepat0 Nov 7, 2024
c324473
feat: added position controls for height and depth
andrepat0 Nov 7, 2024
2b0c360
feat: updated slider component, now the label can be a ReactNode
andrepat0 Nov 7, 2024
d36b0de
feat: added isAvatar3D flag for making the Avatar Controls visible
andrepat0 Nov 7, 2024
05c0c4e
feat: half body and full body dynamic position update
andrepat0 Nov 7, 2024
fed9a55
fix: removed style that was cropping the half body avatar
andrepat0 Nov 7, 2024
0b089a9
feat: for slider component improved compatibility for mobile and anim…
andrepat0 Nov 8, 2024
9bbf5dc
fix: removed hands for half body avatar
andrepat0 Nov 8, 2024
d173643
feat: adjusted fixed positions for totem
andrepat0 Nov 8, 2024
e2d5732
feat: for TOTEM layout get the position values from the local storage…
andrepat0 Nov 8, 2024
c00d2c8
feat: added isactive flag for reusable button component
andrepat0 Nov 8, 2024
bb7a0e0
fix: update slider state and fixed depth buttons
andrepat0 Nov 8, 2024
f80602d
feat(lang): updated lang
andrepat0 Nov 8, 2024
0900f1a
feat(lang): updated translations
andrepat0 Nov 11, 2024
9d171dc
feat: added isTotem prop in Avatar Component for managing default ava…
andrepat0 Nov 11, 2024
3332a93
fix: updated flag isChatAlreadyStarted as soon as the avatar isLoading
andrepat0 Nov 11, 2024
97158f4
fix: lint css
andrepat0 Nov 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/components/Avatar/Avatar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ it('renders defualt Avatar (blob) unchanged', () => {
<Avatar
memori={memori}
tenant={tenant}
isTotem={false}
setEnablePositionControls={() => {}}
instruct={false}
avatar3dVisible={true}
setAvatar3dVisible={() => {}}
Expand All @@ -34,6 +36,8 @@ it('renders Avatar with blob and avatar in blob unchanged', () => {
}}
tenant={tenant}
instruct={false}
isTotem={false}
setEnablePositionControls={() => {}}
avatar3dVisible={true}
setAvatar3dVisible={() => {}}
hasUserActivatedSpeak={false}
Expand All @@ -50,6 +54,8 @@ it('renders Avatar with custom glb model unchanged', () => {
<Avatar
memori={memori}
integration={integration}
isTotem={false}
setEnablePositionControls={() => {}}
integrationConfig={{
...integrationConfig,
avatar: 'customglb',
Expand All @@ -74,6 +80,8 @@ it('renders Avatar with rpm 3d avatar unchanged', () => {
<Avatar
memori={memori}
integration={integration}
isTotem={false}
setEnablePositionControls={() => {}}
integrationConfig={{
...integrationConfig,
avatar: 'readyplayerme',
Expand Down
30 changes: 21 additions & 9 deletions src/components/Avatar/Avatar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import Edit from '../icons/Edit';
import cx from 'classnames';
import ContainerAvatarView from './AvatarView';
import { useViseme } from '../../context/visemeContext';
import PositionControls from './AvatarView/AvatarComponent/positionControls/positionControls';
import { getLocalConfig } from '../../helpers/configuration';

export interface Props {
memori: Memori;
Expand All @@ -34,6 +36,10 @@ export interface Props {
animation?: string;
isZoomed?: boolean;
chatProps?: any;
enablePositionControls?: boolean;
setEnablePositionControls: (value: boolean) => void;
avatarType?: 'blob' | 'avatar3d' | undefined;
isTotem?: boolean;
}

const Avatar: React.FC<Props> = ({
Expand All @@ -52,8 +58,11 @@ const Avatar: React.FC<Props> = ({
animation,
isZoomed = false,
chatProps,
avatarType,
enablePositionControls,
setEnablePositionControls,
isTotem = false,
}) => {

const { t } = useTranslation();
const [isClient, setIsClient] = useState(false);

Expand Down Expand Up @@ -87,7 +96,8 @@ const Avatar: React.FC<Props> = ({
integrationConfig?.avatar === 'readyplayerme-full' ||
integrationConfig?.avatar === 'customglb' ||
integrationConfig?.avatar === 'customrpm') &&
integrationConfig?.avatarURL
integrationConfig?.avatarURL &&
(avatarType && avatarType !== 'blob')
) {
return (
<>
Expand Down Expand Up @@ -115,11 +125,10 @@ const Avatar: React.FC<Props> = ({

const renderAvatarContent = () => {
if (!isClient) return null;

if (
integrationConfig?.avatar === 'readyplayerme' ||
integrationConfig?.avatar === 'readyplayerme-full' ||
integrationConfig?.avatar === 'customrpm'
integrationConfig?.avatar === 'readyplayerme-full' ||
integrationConfig?.avatar === 'customrpm'
) {
return (
<ErrorBoundary
Expand All @@ -132,6 +141,7 @@ const Avatar: React.FC<Props> = ({
}
>
<ContainerAvatarView
enablePositionControls={enablePositionControls}
updateCurrentViseme={updateCurrentViseme}
url={integrationConfig.avatarURL}
sex={memori.voiceType === 'FEMALE' ? 'FEMALE' : 'MALE'}
Expand All @@ -145,8 +155,10 @@ const Avatar: React.FC<Props> = ({
style={getAvatarStyle()}
stopProcessing={stopProcessing}
resetVisemeQueue={resetVisemeQueue}
isZoomed={isZoomed}
isZoomed={isZoomed}
isTotem={isTotem}
chatEmission={chatProps?.dialogState?.emission}
setEnablePositionControls={setEnablePositionControls}
/>
</ErrorBoundary>
);
Expand Down Expand Up @@ -183,10 +195,10 @@ const Avatar: React.FC<Props> = ({
const getAvatarStyle = () => {
if (integrationConfig?.avatar === 'readyplayerme') {
return {
width: '300px',
height: '300px',
width: '100%',
height: '100%',
backgroundColor: 'none',
borderRadius: '100%',
// borderRadius: '100%',
boxShadow: 'none',
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import React, { useState, useEffect, useCallback } from 'react';
import AnimationControlPanel from './components/controls';
import FullbodyAvatar from './components/fullbodyAvatar';
import { FullbodyAvatar } from './components/FullbodyAvatar/FullbodyAvatar';
import HalfBodyAvatar from './components/halfbodyAvatar';
import PositionControls from './positionControls/positionControls';
import { PerspectiveCamera, Vector3 } from 'three';
import { getLocalConfig } from '../../../../helpers/configuration';

interface Props {
showControls: boolean;
Expand All @@ -14,11 +17,14 @@ interface Props {
speaking: boolean;
isZoomed: boolean;
chatEmission: any;
avatarHeight?: number;
avatarDepth?: number;
stopProcessing: () => void;
resetVisemeQueue: () => void;
updateCurrentViseme: (
currentTime: number
) => { name: string; weight: number } | null;
setCameraZ: (value: number) => void;
}

interface BaseAction {
Expand Down Expand Up @@ -65,8 +71,11 @@ export const AvatarView: React.FC<Props & { halfBody: boolean }> = ({
halfBody,
loading,
isZoomed,
avatarHeight,
avatarDepth,
updateCurrentViseme,
resetVisemeQueue,
setCameraZ,
}) => {
const [currentBaseAction, setCurrentBaseAction] = useState({
action: animation || 'Idle1',
Expand All @@ -87,8 +96,11 @@ export const AvatarView: React.FC<Props & { halfBody: boolean }> = ({

// Set the morph target influences for the given emotions
const setEmotionMorphTargetInfluences = useCallback((action: string) => {

if(action === 'Loading1' || action === 'Loading2' || action === 'Loading3') {
if (
action === 'Loading1' ||
action === 'Loading2' ||
action === 'Loading3'
) {
return;
}

Expand All @@ -99,9 +111,6 @@ export const AvatarView: React.FC<Props & { halfBody: boolean }> = ({
Tristezza: { Tristezza: 1 },
Timore: { Timore: 1 },
};




// Set all emotions to 0
const defaultEmotions = Object.keys(emotionMap).reduce((acc, key) => {
Expand Down Expand Up @@ -190,13 +199,6 @@ export const AvatarView: React.FC<Props & { halfBody: boolean }> = ({
}
}, [loading]);

// useEffect(() => {
// if (speaking && currentBaseAction.action !== 'Idle1') {
// const animation = `Idle1`;
// onBaseActionChange(animation);
// }
// }, [speaking]);

return (
<>
{showControls && (
Expand All @@ -214,13 +216,12 @@ export const AvatarView: React.FC<Props & { halfBody: boolean }> = ({
{halfBody ? (
<HalfBodyAvatar
url={url}
headMovement={headMovement}
speaking={speaking}
eyeBlink={eyeBlink}
morphTargetInfluences={morphTargetInfluences}
onCameraZChange={setCameraZ}
setMorphTargetInfluences={setMorphTargetInfluences}
setMorphTargetDictionary={setMorphTargetDictionary}
updateCurrentViseme={updateCurrentViseme}
avatarHeight={avatarHeight || 50}
avatarDepth={avatarDepth || -50}
/>
) : (
<FullbodyAvatar
Expand All @@ -237,6 +238,10 @@ export const AvatarView: React.FC<Props & { halfBody: boolean }> = ({
setMorphTargetDictionary={setMorphTargetDictionary}
setMorphTargetInfluences={setMorphTargetInfluences}
emotionMorphTargets={emotionMorphTargets}
halfBody={halfBody}
onCameraZChange={setCameraZ}
avatarHeight={avatarHeight || 50}
avatarDepth={avatarDepth || -50}
/>
)}
</>
Expand Down
Loading
Loading