补充美颜模型和美颜配置
This commit is contained in:
@@ -0,0 +1,166 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.animationFilter.AnimationFilter;
|
||||
import com.faceunity.core.model.antialiasing.Antialiasing;
|
||||
import com.faceunity.core.model.prop.Prop;
|
||||
import com.faceunity.core.model.prop.PropContainer;
|
||||
import com.faceunity.core.model.prop.animoji.Animoji;
|
||||
import com.yunbao.faceunity.entity.AnimationFilterBean;
|
||||
import com.yunbao.faceunity.entity.AnimojiBean;
|
||||
import com.yunbao.faceunity.infe.AbstractAnimojiDataFactory;
|
||||
import com.yunbao.faceunity.repo.AnimojiSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:Animoji业务工厂
|
||||
* Created on 2021/3/3
|
||||
*/
|
||||
public class AnimojiDataFactory extends AbstractAnimojiDataFactory {
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
/*3D抗锯齿*/
|
||||
public final Antialiasing antialiasing;
|
||||
/*动漫滤镜模型*/
|
||||
public final AnimationFilter animationFilter;
|
||||
/*当前选中贴图模型*/
|
||||
private Prop currentAnimoji;
|
||||
/*当前选中下标*/
|
||||
private int currentAnimojiIndex;
|
||||
/*当前滤镜下标*/
|
||||
private int currentFilterIndex;
|
||||
/*Animoji数据*/
|
||||
private ArrayList<AnimojiBean> animojiBeans;
|
||||
/*Animoji滤镜数据*/
|
||||
private ArrayList<AnimationFilterBean> animationFilterBeans;
|
||||
|
||||
/**
|
||||
* 构造 AnimojiDataFactory
|
||||
*
|
||||
* @param animojiIndex 贴图下标
|
||||
* @param filterIndex 滤镜下标
|
||||
*/
|
||||
public AnimojiDataFactory(int animojiIndex, int filterIndex) {
|
||||
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
|
||||
animationFilter = new AnimationFilter(new FUBundleData(FaceUnityConfig.BUNDLE_ANIMATION_FILTER));
|
||||
currentAnimojiIndex = animojiIndex;
|
||||
currentFilterIndex = filterIndex;
|
||||
animojiBeans = AnimojiSource.buildAnimojis();
|
||||
animationFilterBeans = AnimojiSource.buildFilters();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动漫贴图列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<AnimojiBean> getAnimojis() {
|
||||
return animojiBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 动漫滤镜列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<AnimationFilterBean> getFilters() {
|
||||
return animationFilterBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前选中动漫贴图下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentAnimojiIndex() {
|
||||
return currentAnimojiIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中动漫贴图下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentAnimojiIndex(int currentAnimojiIndex) {
|
||||
this.currentAnimojiIndex = currentAnimojiIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前选中滤镜下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentFilterIndex() {
|
||||
return currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中动漫贴图下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentFilterIndex(int currentFilterIndex) {
|
||||
this.currentFilterIndex = currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中贴图
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onAnimojiSelected(AnimojiBean bean) {
|
||||
PropContainer propContainer = mFURenderKit.getPropContainer();
|
||||
String path = bean.getPath();
|
||||
Prop prop = null;
|
||||
if (path != null && path.trim().length() > 0) {
|
||||
prop = new Animoji(new FUBundleData(path));
|
||||
}
|
||||
propContainer.replaceProp(currentAnimoji, prop);
|
||||
currentAnimoji = prop;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置选中滤镜
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
@Override
|
||||
public void onFilterSelected(AnimationFilterBean data) {
|
||||
animationFilter.setStyle(data.getStyle());
|
||||
}
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.BUNDLE_AI_TONGUE, FUAITypeEnum.FUAITYPE_TONGUETRACKING);
|
||||
mFUAIKit.setMaxFaces(4);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFURenderKit.setAntialiasing(antialiasing);
|
||||
mFURenderKit.setAnimationFilter(animationFilter);
|
||||
animationFilter.setStyle(animationFilterBeans.get(currentFilterIndex).getStyle());
|
||||
onAnimojiSelected(animojiBeans.get(currentAnimojiIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_TONGUETRACKING);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.avatar.model.Avatar;
|
||||
import com.faceunity.core.avatar.model.Scene;
|
||||
import com.faceunity.core.avatar.scene.ProcessorConfig;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUCoordinate3DData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.faceunity.FUSceneKit;
|
||||
import com.faceunity.core.model.antialiasing.Antialiasing;
|
||||
import com.yunbao.faceunity.entity.AvatarBean;
|
||||
import com.yunbao.faceunity.infe.AbstractAvatarDataFactory;
|
||||
import com.yunbao.faceunity.repo.AvatarSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:
|
||||
* Created on 2021/3/30
|
||||
*/
|
||||
public class AvatarDataFactory extends AbstractAvatarDataFactory {
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
/*3D抗锯齿*/
|
||||
public final Antialiasing antialiasing;
|
||||
|
||||
/* 人物队列 */
|
||||
private ArrayList<AvatarBean> members;
|
||||
/* 当前选中人物下标 */
|
||||
private int currentMemberIndex;
|
||||
/* 驱动类型是否为全身 */
|
||||
private Boolean isHumanTrackSceneFull;
|
||||
|
||||
/* 场景 */
|
||||
private Scene sceneModel;
|
||||
/* 男孩对象 */
|
||||
private Avatar boyAvatarModel;
|
||||
/* 女孩对象 */
|
||||
private Avatar girlAvatarModel;
|
||||
/*当前对象*/
|
||||
private Avatar currentAvatarModel;
|
||||
|
||||
|
||||
public AvatarDataFactory(int index, boolean isFull) {
|
||||
isHumanTrackSceneFull = isFull;
|
||||
currentMemberIndex = index;
|
||||
members = AvatarSource.buildMembers();
|
||||
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
|
||||
boyAvatarModel = AvatarSource.buildBoyData(isFull);
|
||||
girlAvatarModel = AvatarSource.buildGirlData(isFull);
|
||||
|
||||
if (index == 0) {
|
||||
currentAvatarModel = girlAvatarModel;
|
||||
} else if (index == 1) {
|
||||
currentAvatarModel = boyAvatarModel;
|
||||
}
|
||||
|
||||
sceneModel = AvatarSource.buildSceneModel(currentAvatarModel);
|
||||
AvatarSource.setSceneBackGround(sceneModel, true);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取人物队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<AvatarBean> getMembers() {
|
||||
return members;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前选中人物下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentMemberIndex() {
|
||||
return currentMemberIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前人物选中下标
|
||||
*
|
||||
* @param index
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentMemberIndex(int index) {
|
||||
currentMemberIndex = index;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前驱动类型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public boolean isHumanTrackSceneFull() {
|
||||
return isHumanTrackSceneFull;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前驱动类型
|
||||
*
|
||||
* @param isFull
|
||||
*/
|
||||
@Override
|
||||
public void setHumanTrackSceneFull(boolean isFull) {
|
||||
isHumanTrackSceneFull = isFull;
|
||||
sceneModel.processorConfig.setTrackScene(isFull ? ProcessorConfig.TrackScene.SceneFull : ProcessorConfig.TrackScene.SceneHalf);
|
||||
if (isFull) {
|
||||
boyAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 58.14, -618.94));
|
||||
girlAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 58.14, -618.94));
|
||||
} else {
|
||||
boyAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 11.76, -183.89));
|
||||
girlAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 11.76, -183.89));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 人物切换
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onMemberSelected(AvatarBean bean) {
|
||||
if (mAvatarChoiceListener != null)
|
||||
mAvatarChoiceListener.choiceAvatar(bean);
|
||||
|
||||
sceneModel.replaceAvatar(currentAvatarModel, bean.getDes().equals(AvatarSource.GIRL) ? girlAvatarModel : boyAvatarModel);
|
||||
currentAvatarModel = bean.getDes().equals(AvatarSource.GIRL) ? girlAvatarModel : boyAvatarModel;
|
||||
}
|
||||
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
mFURenderKit.setAntialiasing(antialiasing);
|
||||
FUSceneKit.getInstance().addSceneGL(sceneModel);
|
||||
FUSceneKit.getInstance().setCurrentSceneGL(sceneModel);
|
||||
setHumanTrackSceneFull(isHumanTrackSceneFull);
|
||||
}
|
||||
|
||||
public AvatarChoiceListener mAvatarChoiceListener;
|
||||
|
||||
public interface AvatarChoiceListener {
|
||||
void choiceAvatar(AvatarBean avatarBean);
|
||||
}
|
||||
|
||||
public void setAvatarChoiceListener(AvatarChoiceListener avatarChoiceListener) {
|
||||
this.mAvatarChoiceListener = avatarChoiceListener;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.controller.bgSegGreen.BgSegGreenParam;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.bgSegGreen.BgSegGreen;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBackgroundBean;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenBean;
|
||||
import com.yunbao.faceunity.entity.BgSegGreenSafeAreaBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.infe.AbstractBgSegGreenDataFactory;
|
||||
import com.yunbao.faceunity.repo.BgSegGreenSource;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* DESC:绿幕抠像业务工厂
|
||||
* Created on 2021/3/4
|
||||
*/
|
||||
public class BgSegGreenDataFactory extends AbstractBgSegGreenDataFactory {
|
||||
public interface BgSegGreenListener {
|
||||
/**
|
||||
* 取色状态回调
|
||||
*
|
||||
* @param isSelected 是否选中
|
||||
* @param color 默认颜色
|
||||
*/
|
||||
void onColorPickerStateChanged(boolean isSelected, int color);
|
||||
|
||||
/**
|
||||
* 切换背景道具
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
void onBackgroundSelected(BgSegGreenBackgroundBean bean);
|
||||
|
||||
/**
|
||||
* 添加自定义安全区域图片
|
||||
*/
|
||||
void onSafeAreaAdd();
|
||||
|
||||
/**
|
||||
* 切换安全区域图片
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
void onSafeAreaSelected(BgSegGreenSafeAreaBean bean);
|
||||
}
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*绿幕抠像特效模型*/
|
||||
private final BgSegGreen mBgSegGreen;
|
||||
|
||||
/*绿幕抠像背景列表*/
|
||||
private final ArrayList<BgSegGreenBackgroundBean> mBgSegGreenBackgroundBeans;
|
||||
/* 绿幕抠像当前背景下标 */
|
||||
private int mCurrentBackgroundIndex;
|
||||
|
||||
/*绿幕抠像安全区域列表*/
|
||||
private ArrayList<BgSegGreenSafeAreaBean> mBgSegGreenSafeAreaBeans;
|
||||
/* 绿幕抠像当前安全区域下标 */
|
||||
private int mCurrentSafeAreaIndex;
|
||||
|
||||
/* 回调 */
|
||||
private final BgSegGreenListener mBgSegGreenListener;
|
||||
|
||||
|
||||
/**
|
||||
* 构造绿幕抠像
|
||||
*
|
||||
* @param listener 回调
|
||||
* @param index 背景下标
|
||||
*/
|
||||
public BgSegGreenDataFactory(BgSegGreenListener listener, int index) {
|
||||
mBgSegGreenListener = listener;
|
||||
mBgSegGreen = BgSegGreenSource.buildBgSegGreen();
|
||||
mBgSegGreenBackgroundBeans = BgSegGreenSource.buildBgSegGreenBackground();
|
||||
mBgSegGreenSafeAreaBeans = BgSegGreenSource.buildBgSegGreenSafeArea();
|
||||
mCurrentBackgroundIndex = index;
|
||||
mCurrentSafeAreaIndex = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像当前背景下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
|
||||
public int getBackgroundIndex() {
|
||||
return mCurrentBackgroundIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置绿幕抠像当前背景下标
|
||||
*
|
||||
* @param backgroundIndex
|
||||
*/
|
||||
@Override
|
||||
public void setBackgroundIndex(int backgroundIndex) {
|
||||
this.mCurrentBackgroundIndex = backgroundIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像当前安全区域下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getBgSafeAreaIndex() {
|
||||
return mCurrentSafeAreaIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置绿幕抠像安全区域下标
|
||||
*
|
||||
* @param currentSafeAreaIndex
|
||||
*/
|
||||
@Override
|
||||
public void setBgSafeAreaIndex(int currentSafeAreaIndex) {
|
||||
this.mCurrentSafeAreaIndex = currentSafeAreaIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新安全区UI
|
||||
*/
|
||||
public boolean updateSafeAreaBeansAndIndex() {
|
||||
ArrayList<BgSegGreenSafeAreaBean> bgSegGreenSafeAreaBeans = BgSegGreenSource.buildBgSegGreenSafeArea();
|
||||
if (!bgSegGreenSafeAreaBeans.equals(mBgSegGreenSafeAreaBeans)) {
|
||||
//需要刷新数据
|
||||
//比对数据 1、数据增加 or 自定义数据修改 -> 当前应该选中的角标
|
||||
if (bgSegGreenSafeAreaBeans.size() > mBgSegGreenSafeAreaBeans.size()) {
|
||||
//数据增加
|
||||
if (mCurrentSafeAreaIndex > 2) {
|
||||
mCurrentSafeAreaIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
mBgSegGreenSafeAreaBeans = bgSegGreenSafeAreaBeans;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像项目数据扩展模型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
|
||||
return BgSegGreenSource.buildModelAttributeRange();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像功能列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BgSegGreenBean> getBgSegGreenActions() {
|
||||
return BgSegGreenSource.buildBgSegGreenAction();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像安全区域功能列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BgSegGreenSafeAreaBean> getBgSegGreenSafeAreas() {
|
||||
return mBgSegGreenSafeAreaBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取绿幕抠像背景列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BgSegGreenBackgroundBean> getBgSegGreenBackgrounds() {
|
||||
return mBgSegGreenBackgroundBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 背景图片变更
|
||||
*
|
||||
* @param data BgSegGreenBackgroundBean
|
||||
*/
|
||||
@Override
|
||||
public void onBackgroundSelected(BgSegGreenBackgroundBean data) {
|
||||
mBgSegGreenListener.onBackgroundSelected(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义安全区域
|
||||
*/
|
||||
@Override
|
||||
public void onSafeAreaAdd() {
|
||||
mBgSegGreenListener.onSafeAreaAdd();
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全区域变更
|
||||
*
|
||||
* @param data BgSegGreenBackgroundBean
|
||||
*/
|
||||
@Override
|
||||
public void onSafeAreaSelected(BgSegGreenSafeAreaBean data) {
|
||||
mBgSegGreenListener.onSafeAreaSelected(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUseTemplate() {
|
||||
return getCurrentBgSegGreenModel().isUseTemplate() == 1.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 取色锚点颜色变更
|
||||
*
|
||||
* @param array DoubleArray
|
||||
*/
|
||||
@Override
|
||||
public void onColorRGBChanged(double[] array) {
|
||||
mBgSegGreen.setColorRGB(new FUColorRGBData(array[0], array[1], array[2]));
|
||||
mBgSegGreen.setEnable(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿幕开关
|
||||
*
|
||||
* @param enable Boolean
|
||||
*/
|
||||
@Override
|
||||
public void onBgSegGreenEnableChanged(boolean enable) {
|
||||
mBgSegGreen.setEnable(enable);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据名称标识获取对应的值
|
||||
*
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
@Override
|
||||
public double getParamIntensity(@NonNull String key) {
|
||||
if (bgSegGreenGetMapping.containsKey(key)) {
|
||||
return bgSegGreenGetMapping.get(key).getValue();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据名称标识更新对应的值
|
||||
*
|
||||
* @param key String 标识
|
||||
* @return Double 值
|
||||
*/
|
||||
@Override
|
||||
public void updateParamIntensity(@NonNull String key, double value) {
|
||||
if (bgSegGreenSetMapping.containsKey(key)) {
|
||||
Objects.requireNonNull(bgSegGreenSetMapping.get(key)).setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 调用取色器功能状态变更
|
||||
*
|
||||
* @param selected
|
||||
* @param color
|
||||
*/
|
||||
@Override
|
||||
public void onColorPickerStateChanged(boolean selected, int color) {
|
||||
mBgSegGreenListener.onColorPickerStateChanged(selected, color);
|
||||
}
|
||||
|
||||
//region 业务映射
|
||||
|
||||
/**
|
||||
* 参数设置
|
||||
*/
|
||||
interface BgSegGreenSetParam {
|
||||
void setValue(double value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 模型参数获取
|
||||
*/
|
||||
interface BgSegGreenGetParam {
|
||||
double getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前绿幕对象
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private BgSegGreen getCurrentBgSegGreenModel() {
|
||||
return mBgSegGreen;
|
||||
}
|
||||
|
||||
|
||||
/* 模型映射 */
|
||||
private final HashMap<String, BgSegGreenSetParam> bgSegGreenSetMapping = new HashMap<String, BgSegGreenSetParam>() {
|
||||
{
|
||||
put(BgSegGreenParam.SIMILARITY, value -> getCurrentBgSegGreenModel().setSimilarity(value));
|
||||
put(BgSegGreenParam.SMOOTHNESS, value -> getCurrentBgSegGreenModel().setSmoothness(value));
|
||||
put(BgSegGreenParam.TRANSPARENCY, value -> getCurrentBgSegGreenModel().setTransparency(value));
|
||||
}
|
||||
};
|
||||
|
||||
/*模型映射获取模型值*/
|
||||
private final HashMap<String, BgSegGreenGetParam> bgSegGreenGetMapping = new HashMap<String, BgSegGreenGetParam>() {
|
||||
{
|
||||
put(BgSegGreenParam.SIMILARITY, () -> getCurrentBgSegGreenModel().getSimilarity());
|
||||
put(BgSegGreenParam.SMOOTHNESS, () -> getCurrentBgSegGreenModel().getSmoothness());
|
||||
put(BgSegGreenParam.TRANSPARENCY, () -> getCurrentBgSegGreenModel().getTransparency());
|
||||
}
|
||||
};
|
||||
|
||||
//endregion 业务映射
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
FUAIKit.getInstance().setMaxFaces(1);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFURenderKit.setBgSegGreen(mBgSegGreen);
|
||||
mBgSegGreenListener.onBackgroundSelected(mBgSegGreenBackgroundBeans.get(mCurrentBackgroundIndex));
|
||||
mBgSegGreenListener.onSafeAreaSelected(mBgSegGreenSafeAreaBeans.get(mCurrentSafeAreaIndex));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyBlurTypeEnum;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
|
||||
/**
|
||||
* 保存到磁盘的对象
|
||||
* 该例只保存特效demo展示出来的美颜功能
|
||||
*/
|
||||
public class FaceBeautyData implements Serializable {
|
||||
/* 美肤 */
|
||||
/* 磨皮类型 */
|
||||
public int blurType = FaceBeautyBlurTypeEnum.FineSkin;
|
||||
/* 磨皮程度 */
|
||||
public double blurIntensity = 0.0;
|
||||
/* 美白程度 */
|
||||
public double colorIntensity = 0.0;
|
||||
/* 红润程度 */
|
||||
public double redIntensity = 0.0;
|
||||
/* 锐化程度 */
|
||||
public double sharpenIntensity = 0.0;
|
||||
/* 亮眼程度 */
|
||||
public double eyeBrightIntensity = 0.0;
|
||||
/* 美牙程度 */
|
||||
public double toothIntensity = 0.0;
|
||||
/* 去黑眼圈强度*/
|
||||
public double removePouchIntensity = 0.0;
|
||||
/* 去法令纹强度*/
|
||||
public double removeLawPatternIntensity = 0.0;
|
||||
|
||||
/*美型*/
|
||||
/* 瘦脸程度 */
|
||||
public double cheekThinningIntensity = 0.0;
|
||||
/* V脸程度 */
|
||||
public double cheekVIntensity = 0.0;
|
||||
/* 窄脸程度 */
|
||||
public double cheekNarrowIntensity = 0.0;
|
||||
/* 短脸程度 */
|
||||
public double cheekShortIntensity = 0.0;
|
||||
/* 小脸程度 */
|
||||
public double cheekSmallIntensity = 0.0;
|
||||
/* 瘦颧骨 */
|
||||
public double cheekBonesIntensity = 0.0;
|
||||
/* 瘦下颌骨 */
|
||||
public double lowerJawIntensity = 0.0;
|
||||
/* 大眼程度 */
|
||||
public double eyeEnlargingIntensity = 0.0;
|
||||
/* 圆眼程度 */
|
||||
public double eyeCircleIntensity = 0.0;
|
||||
/* 下巴调整程度 */
|
||||
public double chinIntensity = 0.5;
|
||||
/* 额头调整程度 */
|
||||
public double forHeadIntensity = 0.5;
|
||||
/* 瘦鼻程度 */
|
||||
public double noseIntensity = 0.0;
|
||||
/* 嘴巴调整程度 */
|
||||
public double mouthIntensity = 0.5;
|
||||
/* 开眼角强度 */
|
||||
public double canthusIntensity = 0.0;
|
||||
/* 眼睛间距 */
|
||||
public double eyeSpaceIntensity = 0.5;
|
||||
/* 眼睛角度 */
|
||||
public double eyeRotateIntensity = 0.5;
|
||||
/* 鼻子长度 */
|
||||
public double longNoseIntensity = 0.5;
|
||||
/* 调节人中 */
|
||||
public double philtrumIntensity = 0.5;
|
||||
/* 微笑嘴角强度 */
|
||||
public double smileIntensity = 0.0;
|
||||
/* 眉毛上下 */
|
||||
public double browHeightIntensity = 0.5;
|
||||
/* 眉毛间距 */
|
||||
public double browSpaceIntensity = 0.5;
|
||||
/* 眼睑 */
|
||||
public double eyeLidIntensity = 0.0;
|
||||
/* 眼睛高度 */
|
||||
public double eyeHeightIntensity = 0.5;
|
||||
/* 眉毛粗细 */
|
||||
public double browThickIntensity = 0.5;
|
||||
/* 嘴巴厚度 */
|
||||
public double lipThickIntensity = 0.5;
|
||||
/* 五官立体 */
|
||||
public double faceThreeIntensity = 0.5;
|
||||
|
||||
/* 风格推荐 */
|
||||
/* 是否开启风格推荐 */
|
||||
/* 风格推荐类型 */
|
||||
public int styleTypeIndex = -1;
|
||||
|
||||
//所有滤镜
|
||||
public HashMap<String,Double> filterMap = new HashMap<>();
|
||||
|
||||
/* 滤镜相关 */
|
||||
/* 滤镜名称 */
|
||||
public String filterName = FaceBeautyFilterEnum.ORIGIN;
|
||||
/* 滤镜程度 */
|
||||
public double filterIntensity = 0.0f;
|
||||
}
|
||||
@@ -4,13 +4,20 @@ package com.yunbao.faceunity.data;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.controller.facebeauty.FaceBeautyParam;
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeauty;
|
||||
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
|
||||
import com.yunbao.faceunity.entity.FaceBeautyStyleBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.infe.AbstractFaceBeautyDataFactory;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
@@ -22,6 +29,21 @@ import java.util.HashMap;
|
||||
*/
|
||||
public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
|
||||
public interface FaceBeautyListener {
|
||||
/**
|
||||
* 风格切换
|
||||
*
|
||||
* @param res
|
||||
*/
|
||||
void onFilterSelected(int res);
|
||||
|
||||
/**
|
||||
* 美颜开关
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
void onFaceBeautyEnable(boolean enable);
|
||||
}
|
||||
|
||||
interface FaceBeautySetParamInterface {
|
||||
/**
|
||||
@@ -44,11 +66,26 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*当前生效美颜数据模型*/
|
||||
public FaceBeauty defaultFaceBeauty = FaceBeautySource.getDefaultFaceBeauty();
|
||||
/*推荐风格标识*/
|
||||
private static int currentStyleIndex = -1;
|
||||
|
||||
/*美颜缓存数据模型 用于普通美颜*/
|
||||
public static final FaceBeauty defaultFaceBeauty = FaceBeautySource.getDefaultFaceBeauty();
|
||||
|
||||
/*当前生效美颜数据模型 普通 or 风格的*/
|
||||
public static FaceBeauty faceBeauty = defaultFaceBeauty;
|
||||
|
||||
|
||||
/*默认滤镜选中下标*/
|
||||
private int currentFilterIndex = 0;
|
||||
/*业务回调*/
|
||||
private final FaceBeautyListener mFaceBeautyListener;
|
||||
|
||||
|
||||
public FaceBeautyDataFactory(FaceBeautyListener listener) {
|
||||
mFaceBeautyListener = listener;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美肤参数列表
|
||||
@@ -72,6 +109,17 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
return FaceBeautySource.buildShapeParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美型参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getShapeBeautySubItem() {
|
||||
return FaceBeautySource.buildFaceShapeSubItemParams();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美肤、美型扩展参数
|
||||
@@ -99,7 +147,6 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
filterBeans.get(i).setIntensity(defaultFaceBeauty.getFilterIntensity());
|
||||
currentFilterIndex = i;
|
||||
}
|
||||
|
||||
}
|
||||
return filterBeans;
|
||||
}
|
||||
@@ -124,6 +171,46 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
this.currentFilterIndex = currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取推荐风格列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyStyleBean> getBeautyStyles() {
|
||||
return FaceBeautySource.buildStylesParams();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前风格推荐标识
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentStyleIndex() {
|
||||
return currentStyleIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置风格推荐标识
|
||||
*
|
||||
* @param styleIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentStyleIndex(int styleIndex) {
|
||||
currentStyleIndex = styleIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置风格推荐标识 来自于硬盘
|
||||
*
|
||||
* @param styleIndex
|
||||
*/
|
||||
public static void setDiskCurrentStyleIndex(int styleIndex) {
|
||||
currentStyleIndex = styleIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 美颜开关设置
|
||||
@@ -132,9 +219,7 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
*/
|
||||
@Override
|
||||
public void enableFaceBeauty(boolean enable) {
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setEnable(enable);
|
||||
}
|
||||
mFaceBeautyListener.onFaceBeautyEnable(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -164,6 +249,69 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有效果制空
|
||||
*/
|
||||
@Override
|
||||
public void resetParamIntensity() {
|
||||
if (faceBeauty != defaultFaceBeauty) {
|
||||
faceBeauty = defaultFaceBeauty;
|
||||
FURenderKit.getInstance().setFaceBeauty(faceBeauty);
|
||||
}
|
||||
|
||||
ArrayList<FaceBeautyBean> skinBeauty = getSkinBeauty();
|
||||
ArrayList<FaceBeautyBean> shapeBeauty = getShapeBeauty();
|
||||
HashMap<String, ModelAttributeData> modelAttributeRange = getModelAttributeRange();
|
||||
|
||||
//还原美肤
|
||||
for (FaceBeautyBean faceBeautyBean : skinBeauty) {
|
||||
String key = faceBeautyBean.getKey();
|
||||
ModelAttributeData modelAttributeData = modelAttributeRange.get(key);
|
||||
updateParamIntensity(key, modelAttributeData.getStand());
|
||||
}
|
||||
|
||||
//还原美型
|
||||
for (FaceBeautyBean faceBeautyBean : shapeBeauty) {
|
||||
String key = faceBeautyBean.getKey();
|
||||
ModelAttributeData modelAttributeData = modelAttributeRange.get(key);
|
||||
updateParamIntensity(key, modelAttributeData.getStand());
|
||||
}
|
||||
|
||||
//还原滤镜
|
||||
defaultFaceBeauty.setFilterName(FaceBeautyFilterEnum.ORIGIN);
|
||||
defaultFaceBeauty.setFilterIntensity(0.0);
|
||||
setCurrentFilterIndex(0);
|
||||
|
||||
//设置风格角标
|
||||
setCurrentStyleIndex(-1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCurrentOneHotFaceShape() {
|
||||
return CurrentFaceShapeUIValue.currentFaceShape == null ? FaceBeautyParam.CHEEK_V_INTENSITY : CurrentFaceShapeUIValue.currentFaceShape;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCurrentOneHotFaceShape(String faceShape) {
|
||||
CurrentFaceShapeUIValue.currentFaceShape = faceShape;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置当前脸型的UI值
|
||||
*/
|
||||
public void setCurrentFaceShapeUIValue(HashMap<String, Double> hashMap) {
|
||||
CurrentFaceShapeUIValue.currentFaceShapeValue.clear();
|
||||
CurrentFaceShapeUIValue.currentFaceShapeValue.putAll(hashMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前脸型的UI值
|
||||
*/
|
||||
public HashMap<String, Double> getCurrentFaceShapeUIValue() {
|
||||
return CurrentFaceShapeUIValue.currentFaceShapeValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换滤镜
|
||||
*
|
||||
@@ -175,6 +323,7 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
public void onFilterSelected(@NonNull String name, double intensity, int resID) {
|
||||
defaultFaceBeauty.setFilterName(name);
|
||||
defaultFaceBeauty.setFilterIntensity(intensity);
|
||||
mFaceBeautyListener.onFilterSelected(resID);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,6 +336,23 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
defaultFaceBeauty.setFilterIntensity(intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置推荐风格
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
@Override
|
||||
public void onStyleSelected(String name) {
|
||||
if (name == null) {
|
||||
faceBeauty = defaultFaceBeauty;
|
||||
FURenderKit.getInstance().setFaceBeauty(faceBeauty);
|
||||
} else {
|
||||
Runnable runnable = FaceBeautySource.styleParams.get(name);
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*模型映射设置模型值*/
|
||||
private final HashMap<String, FaceBeautySetParamInterface> faceBeautySetMapping = new HashMap<String, FaceBeautySetParamInterface>() {{
|
||||
@@ -270,6 +436,22 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFURenderKit.setFaceBeauty(defaultFaceBeauty);
|
||||
mFURenderKit.setFaceBeauty(faceBeauty);
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
|
||||
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
|
||||
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
|
||||
mFURenderKit.getPropContainer().addProp(expressionRecognition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于记录当前脸型的UI值 -> 用于用户下次点入的时候恢复
|
||||
*/
|
||||
static class CurrentFaceShapeUIValue {
|
||||
/* 当前生效的脸型 */
|
||||
public static String currentFaceShape = FaceBeautyParam.CHEEK_V_INTENSITY;
|
||||
/* 当前脸型的UI值 */
|
||||
public static HashMap<String, Double> currentFaceShapeValue = new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.enumeration.FUAIProcessorEnum;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
import com.yunbao.faceunity.utils.FURenderer;
|
||||
|
||||
/**
|
||||
@@ -50,10 +51,25 @@ public class FaceUnityDataFactory {
|
||||
|
||||
public FaceUnityDataFactory(int index) {
|
||||
currentFunctionIndex = index;
|
||||
mFaceBeautyDataFactory = new FaceBeautyDataFactory();
|
||||
mFaceBeautyDataFactory = new FaceBeautyDataFactory(new FaceBeautyDataFactory.FaceBeautyListener() {
|
||||
@Override
|
||||
public void onFilterSelected(int res) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFaceBeautyEnable(boolean enable) {
|
||||
|
||||
}
|
||||
});
|
||||
mBodyBeautyDataFactory = new BodyBeautyDataFactory();
|
||||
mMakeupDataFactory = new MakeupDataFactory(0);
|
||||
mPropDataFactory = new PropDataFactory(0);
|
||||
mPropDataFactory = new PropDataFactory(new PropDataFactory.PropListener() {
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
|
||||
}
|
||||
},0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.yunbao.faceunity.entity.LightMakeupBean;
|
||||
import com.yunbao.faceunity.infe.AbstractLightMakeupDataFactory;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.repo.LightMakeupSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:轻美妆业务工厂
|
||||
* Created on 2021/3/3
|
||||
*/
|
||||
public class LightMakeupDataFactory extends AbstractLightMakeupDataFactory {
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
|
||||
/* 轻美妆队列 */
|
||||
private ArrayList<LightMakeupBean> lightMakeupBeans;
|
||||
/* 当前轻美妆选中下标 */
|
||||
private int currentLightMakeupIndex;
|
||||
|
||||
|
||||
public LightMakeupDataFactory(int index) {
|
||||
currentLightMakeupIndex = index;
|
||||
lightMakeupBeans = LightMakeupSource.buildLightMakeup();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轻美妆队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<LightMakeupBean> getLightMakeUpBeans() {
|
||||
return lightMakeupBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取轻美妆下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentLightMakeupIndex() {
|
||||
return currentLightMakeupIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置轻美妆下标
|
||||
*
|
||||
* @param currentLightMakeupIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentLightMakeupIndex(int currentLightMakeupIndex) {
|
||||
this.currentLightMakeupIndex = currentLightMakeupIndex;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 切换轻美妆
|
||||
*
|
||||
* @param data
|
||||
*/
|
||||
@Override
|
||||
public void onLightMakeupSelected(LightMakeupBean data) {
|
||||
if (data.getKey() == null) {
|
||||
mFURenderKit.setLightMakeup(null);
|
||||
} else {
|
||||
Runnable runnable = LightMakeupSource.LightMakeupParams.get(data.getKey());
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
onLightMakeupIntensityChanged(data.getIntensity());
|
||||
}
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterName(data.getFilterName());
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(data.getFilterIntensity());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 修改强度
|
||||
*
|
||||
* @param intensity
|
||||
*/
|
||||
@Override
|
||||
public void onLightMakeupIntensityChanged(double intensity) {
|
||||
if (mFURenderKit.getLightMakeup() != null) {
|
||||
mFURenderKit.getLightMakeup().setMakeupIntensity(intensity);
|
||||
}
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(intensity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFURenderKit.setFaceBeauty(FaceBeautySource.clone(FaceBeautyDataFactory.faceBeauty));
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
LightMakeupBean lightMakeupBean = lightMakeupBeans.get(currentLightMakeupIndex);
|
||||
onLightMakeupSelected(lightMakeupBean);
|
||||
|
||||
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
|
||||
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
|
||||
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
|
||||
mFURenderKit.getPropContainer().addProp(expressionRecognition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,38 +1,59 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.prop.Prop;
|
||||
import com.faceunity.core.model.prop.arMask.ARMask;
|
||||
import com.faceunity.core.model.prop.bigHead.BigHead;
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.faceunity.core.model.prop.faceWarp.FaceWarp;
|
||||
import com.faceunity.core.model.prop.gesture.GestureRecognition;
|
||||
import com.faceunity.core.model.prop.sticker.Sticker;
|
||||
|
||||
import com.yunbao.faceunity.entity.FunctionEnum;
|
||||
import com.yunbao.faceunity.entity.PropBean;
|
||||
import com.yunbao.faceunity.infe.AbstractPropDataFactory;
|
||||
import com.yunbao.faceunity.repo.PropSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* DESC:道具业务工厂
|
||||
* DESC:道具业务工厂:道具贴图、AR面具、搞笑大头、表情识别、哈哈镜、手势识别
|
||||
* Created on 2021/3/2
|
||||
*/
|
||||
public class PropDataFactory extends AbstractPropDataFactory {
|
||||
|
||||
public interface PropListener {
|
||||
|
||||
void onItemSelected(PropBean bean);
|
||||
|
||||
}
|
||||
|
||||
/*渲染控制器*/
|
||||
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
/*道具列表*/
|
||||
private final ArrayList<PropBean> propBeans;
|
||||
|
||||
/*默认选中下标*/
|
||||
private int currentPropIndex;
|
||||
/*当前道具*/
|
||||
public Prop currentProp;
|
||||
/*回调接口*/
|
||||
private final PropListener mPropListener;
|
||||
/*道具类型*/
|
||||
private final int propType;
|
||||
|
||||
public PropDataFactory(int index) {
|
||||
|
||||
public PropDataFactory(PropListener listener, int type, int index) {
|
||||
mPropListener = listener;
|
||||
propType = type;
|
||||
currentPropIndex = index;
|
||||
propBeans = PropSource.buildPropBeans();
|
||||
propBeans = PropSource.buildPropBeans(type);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,20 +88,47 @@ public class PropDataFactory extends AbstractPropDataFactory {
|
||||
return propBeans;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
onPropSelected(bean);
|
||||
mPropListener.onItemSelected(bean);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 道具选中
|
||||
* 其他道具
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
private void onPropSelected(PropBean bean) {
|
||||
String path = bean.getPath();
|
||||
if (path == null || path.trim().length() == 0) {
|
||||
mFURenderKit.getPropContainer().removeAllProp();
|
||||
currentProp = null;
|
||||
return;
|
||||
}
|
||||
Prop prop = new Sticker(new FUBundleData(path));
|
||||
Prop prop = null;
|
||||
switch (propType) {
|
||||
case FunctionEnum.STICKER:
|
||||
prop = new Sticker(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.AR_MASK:
|
||||
prop = new ARMask(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.BIG_HEAD:
|
||||
prop = new BigHead(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.EXPRESSION_RECOGNITION:
|
||||
prop = new ExpressionRecognition(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.FACE_WARP:
|
||||
prop = new FaceWarp(new FUBundleData(path));
|
||||
break;
|
||||
case FunctionEnum.GESTURE_RECOGNITION:
|
||||
prop = new GestureRecognition(new FUBundleData(path));
|
||||
break;
|
||||
}
|
||||
mFURenderKit.getPropContainer().replaceProp(currentProp, prop);
|
||||
currentProp = prop;
|
||||
}
|
||||
@@ -90,7 +138,25 @@ public class PropDataFactory extends AbstractPropDataFactory {
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
if (propType == FunctionEnum.GESTURE_RECOGNITION) {
|
||||
FUAIKit.getInstance().loadAIProcessor(FaceUnityConfig.BUNDLE_AI_HAND, FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
}
|
||||
if (propType == FunctionEnum.BIG_HEAD) {
|
||||
FUAIKit.getInstance().setMaxFaces(1);
|
||||
} else {
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
}
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
PropBean propBean = propBeans.get(currentPropIndex);
|
||||
onItemSelected(propBean);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
if (propType == FunctionEnum.GESTURE_RECOGNITION) {
|
||||
FUAIKit.getInstance().releaseAIProcessor(FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user