/* ----------------------------------------------------------------------------- This source file is part of OpenSpace3D For the latest info, see http://www.openspace3d.com Copyright (c) 2012 I-maginer This program is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA, or go to http://www.gnu.org/copyleft/lesser.txt ----------------------------------------------------------------------------- */ struct PlugLipSync = [ PLIPSYNC_inst : PInstance, PLIPSYNC_animList : [[S V3Danim] r1], PLIPSYNC_currentAnim : V3Danim, PLIPSYNC_prevAnim : V3Danim, PLIPSYNC_bFadeCurrent : I, PLIPSYNC_bFadePrev : I, PLIPSYNC_fDefSpeed : F, PLIPSYNC_fSpeed : F, PLIPSYNC_fDuration : F, PLIPSYNC_iTick : I, PLIPSYNC_iDurationTick : I ]mkPlugLipSync;; fun deleteOb(inst, obstr)= V3DstopAnimation obstr.PLIPSYNC_currentAnim; V3DenableAnimation obstr.PLIPSYNC_currentAnim 0; V3DstopAnimation obstr.PLIPSYNC_prevAnim; V3DenableAnimation obstr.PLIPSYNC_prevAnim 0; setPluginInstanceCbScenePreRender2 inst nil; 0;; fun cbAnimVisems(inst, sessionstr, etime, obstr)= let V3DgetAnimationWeight obstr.PLIPSYNC_currentAnim -> weight1 in let V3DgetAnimationWeight obstr.PLIPSYNC_prevAnim -> weight2 in let itof obstr.PLIPSYNC_iTick -> deltatime in let maxf obstr.PLIPSYNC_fSpeed 1.0 -> speed in ( //fade in if !obstr.PLIPSYNC_bFadeCurrent then nil else let weight1 +. (deltatime /. speed) -> nweight in ( V3DsetAnimationWeight obstr.PLIPSYNC_currentAnim (SO3MathsClampValue nweight 0.0 1.0); if (V3DgetAnimationState obstr.PLIPSYNC_currentAnim) then nil else V3DplayAnimation obstr.PLIPSYNC_currentAnim; if (nweight >=. 1.0) || (!V3DgetAnimationState obstr.PLIPSYNC_currentAnim) then ( if (V3DgetAnimationLoop obstr.PLIPSYNC_currentAnim) then nil else V3DpauseAnimation obstr.PLIPSYNC_currentAnim; set obstr.PLIPSYNC_bFadeCurrent = 0; ) else nil; ); //fade out if !obstr.PLIPSYNC_bFadePrev then nil else let weight2 -. (deltatime /. speed) -> nweight in ( V3DsetAnimationWeight obstr.PLIPSYNC_prevAnim (SO3MathsClampValue nweight 0.0 1.0); if (V3DgetAnimationState obstr.PLIPSYNC_prevAnim) || (nweight <=. 0.0) then nil else V3DplayAnimation obstr.PLIPSYNC_prevAnim; if (nweight <=. 0.0) || (!V3DgetAnimationState obstr.PLIPSYNC_prevAnim) then ( if (V3DgetAnimationLoop obstr.PLIPSYNC_prevAnim) then nil else V3DpauseAnimation obstr.PLIPSYNC_prevAnim; set obstr.PLIPSYNC_bFadePrev = 0; ) else nil; ); if obstr.PLIPSYNC_bFadeCurrent || obstr.PLIPSYNC_bFadePrev then nil else ( //switch when duration is completed if (obstr.PLIPSYNC_iTick < obstr.PLIPSYNC_iDurationTick) then nil else let switchstr obstr.PLIPSYNC_animList "rest" -> defanim in if (obstr.PLIPSYNC_currentAnim != defanim) then ( set obstr.PLIPSYNC_iTick = 0; set obstr.PLIPSYNC_iDurationTick = 0; set obstr.PLIPSYNC_fSpeed = if (obstr.PLIPSYNC_fDuration == 0.0) then obstr.PLIPSYNC_fDefSpeed else obstr.PLIPSYNC_fDuration *. 2.0; set obstr.PLIPSYNC_fDuration = 0.0; set obstr.PLIPSYNC_bFadeCurrent = 1; set obstr.PLIPSYNC_bFadePrev = 1; V3DsetAnimationWeight obstr.PLIPSYNC_prevAnim 0.0; set obstr.PLIPSYNC_prevAnim = obstr.PLIPSYNC_currentAnim; set obstr.PLIPSYNC_currentAnim = defanim; V3DsetAnimationWeight obstr.PLIPSYNC_currentAnim 0.0; 0; ) else ( setPluginInstanceCbScenePreRender2 inst nil; 0; ); ); set obstr.PLIPSYNC_iTick = obstr.PLIPSYNC_iTick + (etime / 1000); ); 0;; fun cbInjectViseme(inst, from, action, param, rep, obstr) = if (param == nil) then nil else let hd strextr param -> lp in let (nth_list lp 0) -> viseme in let atof (nth_list lp 1) -> duration in let if duration == nil then 0.0 else duration -> duration in let switchstr obstr.PLIPSYNC_animList viseme -> animation in let if animation == nil then (switchstr obstr.PLIPSYNC_animList "rest") else animation -> animation in if (animation == obstr.PLIPSYNC_currentAnim) then ( //set obstr.PLIPSYNC_iTick = 0; set obstr.PLIPSYNC_iDurationTick = (ftoi duration); set obstr.PLIPSYNC_fSpeed = if (obstr.PLIPSYNC_fDuration == 0.0) then obstr.PLIPSYNC_fDefSpeed else obstr.PLIPSYNC_fDuration *. 2.0; set obstr.PLIPSYNC_fDuration = duration; setPluginInstanceCbScenePreRender2 inst mkfun4 @cbAnimVisems obstr; ) else ( set obstr.PLIPSYNC_iTick = 0; set obstr.PLIPSYNC_iDurationTick = (ftoi duration); set obstr.PLIPSYNC_fSpeed = if (obstr.PLIPSYNC_fDuration == 0.0) then obstr.PLIPSYNC_fDefSpeed else obstr.PLIPSYNC_fDuration *. 2.0; set obstr.PLIPSYNC_fDuration = duration; set obstr.PLIPSYNC_bFadeCurrent = 1; set obstr.PLIPSYNC_bFadePrev = 1; V3DsetAnimationWeight obstr.PLIPSYNC_prevAnim 0.0; set obstr.PLIPSYNC_prevAnim = obstr.PLIPSYNC_currentAnim; set obstr.PLIPSYNC_currentAnim = animation; V3DsetAnimationWeight obstr.PLIPSYNC_currentAnim 0.0; setPluginInstanceCbScenePreRender2 inst mkfun4 @cbAnimVisems obstr; ); 0;; fun newOb(inst)= let atof (getPluginInstanceParam inst "visemeRaiseSpeed") -> lipsyncvisemeraisespeed in let if lipsyncvisemeraisespeed == nil then 200.0 else lipsyncvisemeraisespeed -> lipsyncvisemeraisespeed in let nil -> lipsyncvisemesanims in ( let "rest"::"AI"::"E"::"etc"::"FV"::"L"::"MBP"::"O"::"U"::"WQ"::nil -> lipsyncvisemes in let sizelist lipsyncvisemes -> size in ( let 0 -> i in while (i < size) do ( let nth_list lipsyncvisemes i -> lipsyncvisem in let (getPluginInstanceParam inst lipsyncvisem) -> lipsyncvisemanimname in let V3DgetAnimationByName c3dXsession lipsyncvisemanimname -> lipsyncvisemanim in ( set lipsyncvisemesanims = [lipsyncvisem lipsyncvisemanim]::lipsyncvisemesanims; set i = i + 1; ); ); let mkPlugLipSync [inst nil nil nil nil nil nil nil nil nil nil] -> obstr in ( set obstr.PLIPSYNC_animList = lipsyncvisemesanims; set obstr.PLIPSYNC_currentAnim = switchstr lipsyncvisemesanims "rest"; V3DsetAnimationWeight obstr.PLIPSYNC_currentAnim 1.0; set obstr.PLIPSYNC_prevAnim = nil; set obstr.PLIPSYNC_bFadeCurrent = 0; set obstr.PLIPSYNC_bFadePrev = 0; set obstr.PLIPSYNC_fDefSpeed = lipsyncvisemeraisespeed; set obstr.PLIPSYNC_fSpeed = lipsyncvisemeraisespeed; set obstr.PLIPSYNC_fDuration = lipsyncvisemeraisespeed; set obstr.PLIPSYNC_iTick = 0; set obstr.PLIPSYNC_iDurationTick = 0; PluginRegisterAction inst "Inject viseme" mkfun6 @cbInjectViseme obstr; setPluginInstanceCbDel inst mkfun2 @deleteOb obstr; ); ); ); 0;; fun IniPlug(file)= PlugRegister @newOb nil; setPluginEditor @dynamicedit; 0;;