1
This commit is contained in:
@@ -0,0 +1,168 @@
|
||||
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();
|
||||
bindCurrentRenderer();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 动漫贴图列表
|
||||
*
|
||||
* @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,160 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import com.faceunity.core.controller.bodyBeauty.BodyBeautyParam;
|
||||
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.bodyBeauty.BodyBeauty;
|
||||
|
||||
import com.yunbao.faceunity.entity.BodyBeautyBean;
|
||||
import com.yunbao.faceunity.entity.ModelAttributeData;
|
||||
import com.yunbao.faceunity.infe.AbstractBodyBeautyDataFactory;
|
||||
import com.yunbao.faceunity.repo.BodyBeautySource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:美体业务工厂
|
||||
* Created on 2021/3/2
|
||||
*/
|
||||
public class BodyBeautyDataFactory extends AbstractBodyBeautyDataFactory {
|
||||
|
||||
|
||||
interface BodyBeautySetParamInterface {
|
||||
void setValue(double value);
|
||||
}
|
||||
|
||||
interface BodyBeautyGetParamInterface {
|
||||
double getValue();
|
||||
}
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
|
||||
/*美体数据模型*/
|
||||
public final BodyBeauty bodyBeauty;
|
||||
|
||||
public BodyBeautyDataFactory() {
|
||||
bodyBeauty = new BodyBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_BODY_BEAUTY));
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美体属性列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<BodyBeautyBean> getBodyBeautyParam() {
|
||||
return BodyBeautySource.buildBodyBeauty();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美体扩展参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
|
||||
return BodyBeautySource.buildModelAttributeRange();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取模型参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double getParamIntensity(String key) {
|
||||
if (bodyBeautyGetMapping.containsKey(key)) {
|
||||
return bodyBeautyGetMapping.get(key).getValue();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置属性参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @param value 结果值
|
||||
*/
|
||||
@Override
|
||||
public void updateParamIntensity(String key, double value) {
|
||||
if (bodyBeautySetMapping.containsKey(key)) {
|
||||
bodyBeautySetMapping.get(key).setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableBodyBeauty(boolean enable) {
|
||||
if (mFURenderKit.getBodyBeauty() != null) {
|
||||
mFURenderKit.getBodyBeauty().setEnable(enable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前模型
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private BodyBeauty getCurrentBodyBeautyModel() {
|
||||
return bodyBeauty;
|
||||
}
|
||||
|
||||
|
||||
/*模型映射设置模型值*/
|
||||
private final HashMap<String, BodyBeautySetParamInterface> bodyBeautySetMapping = new HashMap<String, BodyBeautySetParamInterface>() {
|
||||
{
|
||||
put(BodyBeautyParam.BODY_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setBodySlimIntensity(value));
|
||||
put(BodyBeautyParam.LEG_STRETCH_INTENSITY, value -> getCurrentBodyBeautyModel().setLegStretchIntensity(value));
|
||||
put(BodyBeautyParam.WAIST_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setWaistSlimIntensity(value));
|
||||
put(BodyBeautyParam.SHOULDER_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setShoulderSlimIntensity(value));
|
||||
put(BodyBeautyParam.HIP_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setHipSlimIntensity(value));
|
||||
put(BodyBeautyParam.HEAD_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setHeadSlimIntensity(value));
|
||||
put(BodyBeautyParam.LEG_SLIM_INTENSITY, value -> getCurrentBodyBeautyModel().setLegSlimIntensity(value));
|
||||
}
|
||||
};
|
||||
|
||||
/*模型映射获取模型值*/
|
||||
HashMap<String, BodyBeautyGetParamInterface> bodyBeautyGetMapping = new HashMap<String, BodyBeautyGetParamInterface>() {
|
||||
{
|
||||
put(BodyBeautyParam.BODY_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getBodySlimIntensity());
|
||||
put(BodyBeautyParam.LEG_STRETCH_INTENSITY, ()->getCurrentBodyBeautyModel().getLegStretchIntensity());
|
||||
put(BodyBeautyParam.WAIST_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getWaistSlimIntensity());
|
||||
put(BodyBeautyParam.SHOULDER_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getShoulderSlimIntensity());
|
||||
put(BodyBeautyParam.HIP_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getHipSlimIntensity());
|
||||
put(BodyBeautyParam.HEAD_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getHeadSlimIntensity());
|
||||
put(BodyBeautyParam.LEG_SLIM_INTENSITY, ()->getCurrentBodyBeautyModel().getLegSlimIntensity());
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFURenderKit.setBodyBeauty(bodyBeauty);
|
||||
}
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,470 @@
|
||||
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;
|
||||
|
||||
|
||||
/**
|
||||
* DESC:美颜业务工厂
|
||||
* Created on 2021/3/1
|
||||
*/
|
||||
public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
|
||||
|
||||
public interface FaceBeautyListener {
|
||||
/**
|
||||
* 风格切换
|
||||
*
|
||||
* @param res
|
||||
*/
|
||||
void onFilterSelected(int res);
|
||||
|
||||
/**
|
||||
* 美颜开关
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
void onFaceBeautyEnable(boolean enable);
|
||||
}
|
||||
|
||||
interface FaceBeautySetParamInterface {
|
||||
/**
|
||||
* 设置属性值
|
||||
*
|
||||
* @param value
|
||||
*/
|
||||
void setValue(double value);
|
||||
}
|
||||
|
||||
interface FaceBeautyGetParamInterface {
|
||||
/**
|
||||
* 获取属性值
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
double getValue();
|
||||
}
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*推荐风格标识*/
|
||||
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;
|
||||
}
|
||||
public FaceBeautyDataFactory(){
|
||||
mFaceBeautyListener=new FaceBeautyListener() {
|
||||
@Override
|
||||
public void onFilterSelected(int res) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFaceBeautyEnable(boolean enable) {
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美肤参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getSkinBeauty() {
|
||||
return FaceBeautySource.buildSkinParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美型参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getShapeBeauty() {
|
||||
return FaceBeautySource.buildShapeParams();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取美型参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyBean> getShapeBeautySubItem() {
|
||||
return FaceBeautySource.buildFaceShapeSubItemParams();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取美肤、美型扩展参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
|
||||
return FaceBeautySource.buildModelAttributeRange();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取滤镜参数列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NonNull
|
||||
@Override
|
||||
public ArrayList<FaceBeautyFilterBean> getBeautyFilters() {
|
||||
ArrayList<FaceBeautyFilterBean> filterBeans = FaceBeautySource.buildFilters();
|
||||
for (int i = 0; i < filterBeans.size(); i++) {
|
||||
if (filterBeans.get(i).getKey().equals(defaultFaceBeauty.getFilterName())) {
|
||||
filterBeans.get(i).setIntensity(defaultFaceBeauty.getFilterIntensity());
|
||||
currentFilterIndex = i;
|
||||
}
|
||||
}
|
||||
return filterBeans;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前滤镜下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentFilterIndex() {
|
||||
return currentFilterIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前滤镜下标
|
||||
*
|
||||
* @param currentFilterIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentFilterIndex(int currentFilterIndex) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 美颜开关设置
|
||||
*
|
||||
* @param enable
|
||||
*/
|
||||
@Override
|
||||
public void enableFaceBeauty(boolean enable) {
|
||||
mFaceBeautyListener.onFaceBeautyEnable(enable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模型参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @return 属性值
|
||||
*/
|
||||
@Override
|
||||
public double getParamIntensity(@NonNull String key) {
|
||||
if (faceBeautyGetMapping.containsKey(key)) {
|
||||
return faceBeautyGetMapping.get(key).getValue();
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模型参数
|
||||
*
|
||||
* @param key 名称标识
|
||||
* @param value 属性值
|
||||
*/
|
||||
@Override
|
||||
public void updateParamIntensity(@NonNull String key, double value) {
|
||||
if (faceBeautySetMapping.containsKey(key)) {
|
||||
faceBeautySetMapping.get(key).setValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 将所有效果制空
|
||||
*/
|
||||
@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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换滤镜
|
||||
*
|
||||
* @param name 滤镜名称标识
|
||||
* @param intensity 滤镜强度
|
||||
* @param resID 滤镜名称
|
||||
*/
|
||||
@Override
|
||||
public void onFilterSelected(@NonNull String name, double intensity, int resID) {
|
||||
defaultFaceBeauty.setFilterName(name);
|
||||
defaultFaceBeauty.setFilterIntensity(intensity);
|
||||
mFaceBeautyListener.onFilterSelected(resID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更换滤镜强度
|
||||
*
|
||||
* @param intensity 滤镜强度
|
||||
*/
|
||||
@Override
|
||||
public void updateFilterIntensity(double intensity) {
|
||||
defaultFaceBeauty.setFilterIntensity(intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置推荐风格
|
||||
*
|
||||
* @param name 风格key
|
||||
*/
|
||||
@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>() {{
|
||||
put(FaceBeautyParam.COLOR_INTENSITY, defaultFaceBeauty::setColorIntensity);
|
||||
put(FaceBeautyParam.BLUR_INTENSITY, defaultFaceBeauty::setBlurIntensity);
|
||||
put(FaceBeautyParam.RED_INTENSITY, defaultFaceBeauty::setRedIntensity);
|
||||
put(FaceBeautyParam.SHARPEN_INTENSITY, defaultFaceBeauty::setSharpenIntensity);
|
||||
put(FaceBeautyParam.EYE_BRIGHT_INTENSITY, defaultFaceBeauty::setEyeBrightIntensity);
|
||||
put(FaceBeautyParam.TOOTH_WHITEN_INTENSITY, defaultFaceBeauty::setToothIntensity);
|
||||
put(FaceBeautyParam.REMOVE_POUCH_INTENSITY, defaultFaceBeauty::setRemovePouchIntensity);
|
||||
put(FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, defaultFaceBeauty::setRemoveLawPatternIntensity);
|
||||
/*美型*/
|
||||
put(FaceBeautyParam.FACE_SHAPE_INTENSITY, defaultFaceBeauty::setSharpenIntensity);
|
||||
put(FaceBeautyParam.CHEEK_THINNING_INTENSITY, defaultFaceBeauty::setCheekThinningIntensity);
|
||||
put(FaceBeautyParam.CHEEK_V_INTENSITY, defaultFaceBeauty::setCheekVIntensity);
|
||||
put(FaceBeautyParam.CHEEK_LONG_INTENSITY, defaultFaceBeauty::setCheekLongIntensity);
|
||||
put(FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, defaultFaceBeauty::setCheekCircleIntensity);
|
||||
put(FaceBeautyParam.CHEEK_NARROW_INTENSITY, defaultFaceBeauty::setCheekNarrowIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SHORT_INTENSITY, defaultFaceBeauty::setCheekShortIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SMALL_INTENSITY, defaultFaceBeauty::setCheekSmallIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_CHEEKBONES_INTENSITY, defaultFaceBeauty::setCheekBonesIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_LOW_JAW_INTENSITY, defaultFaceBeauty::setLowerJawIntensity);
|
||||
put(FaceBeautyParam.EYE_ENLARGING_INTENSITY, defaultFaceBeauty::setEyeEnlargingIntensity);
|
||||
put(FaceBeautyParam.EYE_CIRCLE_INTENSITY, defaultFaceBeauty::setEyeCircleIntensity);
|
||||
put(FaceBeautyParam.BROW_HEIGHT_INTENSITY, defaultFaceBeauty::setBrowHeightIntensity);
|
||||
put(FaceBeautyParam.BROW_SPACE_INTENSITY, defaultFaceBeauty::setBrowSpaceIntensity);
|
||||
put(FaceBeautyParam.CHIN_INTENSITY, defaultFaceBeauty::setChinIntensity);
|
||||
put(FaceBeautyParam.FOREHEAD_INTENSITY, defaultFaceBeauty::setForHeadIntensity);
|
||||
put(FaceBeautyParam.NOSE_INTENSITY, defaultFaceBeauty::setNoseIntensity);
|
||||
put(FaceBeautyParam.MOUTH_INTENSITY, defaultFaceBeauty::setMouthIntensity);
|
||||
put(FaceBeautyParam.CANTHUS_INTENSITY, defaultFaceBeauty::setCanthusIntensity);
|
||||
put(FaceBeautyParam.EYE_SPACE_INTENSITY, defaultFaceBeauty::setEyeSpaceIntensity);
|
||||
put(FaceBeautyParam.EYE_ROTATE_INTENSITY, defaultFaceBeauty::setEyeRotateIntensity);
|
||||
put(FaceBeautyParam.LONG_NOSE_INTENSITY, defaultFaceBeauty::setLongNoseIntensity);
|
||||
put(FaceBeautyParam.PHILTRUM_INTENSITY, defaultFaceBeauty::setPhiltrumIntensity);
|
||||
put(FaceBeautyParam.SMILE_INTENSITY, defaultFaceBeauty::setSmileIntensity);
|
||||
}};
|
||||
|
||||
/*模型映射获取模型值*/
|
||||
HashMap<String, FaceBeautyGetParamInterface> faceBeautyGetMapping = new HashMap<String, FaceBeautyGetParamInterface>() {
|
||||
{
|
||||
put(FaceBeautyParam.COLOR_INTENSITY, defaultFaceBeauty::getColorIntensity);
|
||||
put(FaceBeautyParam.BLUR_INTENSITY, defaultFaceBeauty::getBlurIntensity);
|
||||
put(FaceBeautyParam.RED_INTENSITY, defaultFaceBeauty::getRedIntensity);
|
||||
put(FaceBeautyParam.SHARPEN_INTENSITY, defaultFaceBeauty::getSharpenIntensity);
|
||||
put(FaceBeautyParam.EYE_BRIGHT_INTENSITY, defaultFaceBeauty::getEyeBrightIntensity);
|
||||
put(FaceBeautyParam.TOOTH_WHITEN_INTENSITY, defaultFaceBeauty::getToothIntensity);
|
||||
put(FaceBeautyParam.REMOVE_POUCH_INTENSITY, defaultFaceBeauty::getRemovePouchIntensity);
|
||||
put(FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, defaultFaceBeauty::getRemoveLawPatternIntensity);
|
||||
/*美型*/
|
||||
put(FaceBeautyParam.FACE_SHAPE_INTENSITY, defaultFaceBeauty::getSharpenIntensity);
|
||||
put(FaceBeautyParam.CHEEK_THINNING_INTENSITY, defaultFaceBeauty::getCheekThinningIntensity);
|
||||
put(FaceBeautyParam.CHEEK_V_INTENSITY, defaultFaceBeauty::getCheekVIntensity);
|
||||
put(FaceBeautyParam.CHEEK_LONG_INTENSITY, defaultFaceBeauty::getCheekLongIntensity);
|
||||
put(FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, defaultFaceBeauty::getCheekCircleIntensity);
|
||||
put(FaceBeautyParam.CHEEK_NARROW_INTENSITY, defaultFaceBeauty::getCheekNarrowIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SHORT_INTENSITY, defaultFaceBeauty::getCheekShortIntensity);
|
||||
put(FaceBeautyParam.CHEEK_SMALL_INTENSITY, defaultFaceBeauty::getCheekSmallIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_CHEEKBONES_INTENSITY, defaultFaceBeauty::getCheekBonesIntensity);
|
||||
put(FaceBeautyParam.INTENSITY_LOW_JAW_INTENSITY, defaultFaceBeauty::getLowerJawIntensity);
|
||||
put(FaceBeautyParam.EYE_ENLARGING_INTENSITY, defaultFaceBeauty::getEyeEnlargingIntensity);
|
||||
put(FaceBeautyParam.EYE_CIRCLE_INTENSITY, defaultFaceBeauty::getEyeCircleIntensity);
|
||||
put(FaceBeautyParam.BROW_HEIGHT_INTENSITY, defaultFaceBeauty::getBrowHeightIntensity);
|
||||
put(FaceBeautyParam.BROW_SPACE_INTENSITY, defaultFaceBeauty::getBrowSpaceIntensity);
|
||||
put(FaceBeautyParam.CHIN_INTENSITY, defaultFaceBeauty::getChinIntensity);
|
||||
put(FaceBeautyParam.FOREHEAD_INTENSITY, defaultFaceBeauty::getForHeadIntensity);
|
||||
put(FaceBeautyParam.NOSE_INTENSITY, defaultFaceBeauty::getNoseIntensity);
|
||||
put(FaceBeautyParam.MOUTH_INTENSITY, defaultFaceBeauty::getMouthIntensity);
|
||||
put(FaceBeautyParam.CANTHUS_INTENSITY, defaultFaceBeauty::getCanthusIntensity);
|
||||
put(FaceBeautyParam.EYE_SPACE_INTENSITY, defaultFaceBeauty::getEyeSpaceIntensity);
|
||||
put(FaceBeautyParam.EYE_ROTATE_INTENSITY, defaultFaceBeauty::getEyeRotateIntensity);
|
||||
put(FaceBeautyParam.LONG_NOSE_INTENSITY, defaultFaceBeauty::getLongNoseIntensity);
|
||||
put(FaceBeautyParam.PHILTRUM_INTENSITY, defaultFaceBeauty::getPhiltrumIntensity);
|
||||
put(FaceBeautyParam.SMILE_INTENSITY, defaultFaceBeauty::getSmileIntensity);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
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<>();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
public class FaceParam {
|
||||
public static final int FACE_BEAUTY=100;//美颜
|
||||
public static final int FACE_BEAUTY_SKIN=101;//美肤
|
||||
public static final int FACE_BEAUTY_SHAPE=102;//美型
|
||||
public static final int FACE_BEAUTY_FILTER=103;//滤镜
|
||||
public static final int FACE_BEAUTY_STYLE=104;//风格推荐
|
||||
public static final int FACE_MAKEUP=200;//美妆
|
||||
public static final int FACE_MAKEUP_TYPE_FOUNDATION=201;//粉底
|
||||
public static final int FACE_MAKEUP_TYPE_LIP_STICK=202;//口红
|
||||
public static final int FACE_MAKEUP_TYPE_BLUSHER=203;//腮红
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_BROW=204;//眉毛
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_SHADOW=205;//眼影
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_LINER=206;//眼线
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_LASH=207;//睫毛
|
||||
public static final int FACE_MAKEUP_TYPE_HIGH_LIGHT=208;//高光
|
||||
public static final int FACE_MAKEUP_TYPE_SHADOW=209;//阴影
|
||||
public static final int FACE_MAKEUP_TYPE_EYE_PUPIL=210;//美瞳
|
||||
public static final int FACE_BEAUTY_BODY=300;//美体
|
||||
public static final int FACE_BIG_HEAD=400;//大头
|
||||
public static final int FACE_ANIMOJI=500;//Animoji
|
||||
public static final int FACE_STICKER=600;//贴纸
|
||||
public static final int FACE_FINE_STICKER=700;//精品贴纸
|
||||
public static final int FACE_FINE_STICKER_MIDDLE=701;//中级道具
|
||||
public static final int FACE_FINE_STICKER_HIGH=702;//高级道具
|
||||
public static final int FACE_FINE_STICKER_GAME=703;//游戏道具
|
||||
public static final int FACE_ANIM=800;//动漫滤镜
|
||||
// 占位符,以下均未使用
|
||||
public static final int FACE_ANIM_AR_MASK=900;
|
||||
public static final int FACE_EXPRESSION_RECOGNITION=1000;
|
||||
public static final int FACE_FACE_WARP=1100;
|
||||
public static final int FACE_GESTURE_RECOGNITION=1200;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* DESC:
|
||||
* Created on 2021/4/25
|
||||
*/
|
||||
public class FaceUnityDataFactory {
|
||||
|
||||
/**
|
||||
* 道具数据工厂
|
||||
*/
|
||||
public FaceBeautyDataFactory mFaceBeautyDataFactory;
|
||||
public BodyBeautyDataFactory mBodyBeautyDataFactory;
|
||||
public MakeupDataFactory mMakeupDataFactory;
|
||||
public PropDataFactory mPropDataFactory;
|
||||
|
||||
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FURenderer mFURenderer = FURenderer.getInstance();
|
||||
|
||||
private static FaceUnityDataFactory sInstance;
|
||||
public static FaceUnityDataFactory getInstance() {
|
||||
if (sInstance == null) {
|
||||
synchronized (FaceUnityDataFactory.class) {
|
||||
if (sInstance == null) {
|
||||
sInstance = new FaceUnityDataFactory(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
public static void release() {
|
||||
sInstance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 道具加载标识
|
||||
*/
|
||||
public int currentFunctionIndex;
|
||||
private boolean hasFaceBeautyLoaded = false;
|
||||
private boolean hasBodyBeautyLoaded = false;
|
||||
private boolean hasMakeupLoaded = false;
|
||||
private boolean hasPropLoaded = false;
|
||||
|
||||
|
||||
public FaceUnityDataFactory(int index) {
|
||||
currentFunctionIndex = index;
|
||||
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(new PropDataFactory.PropListener() {
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
|
||||
}
|
||||
},0,0);
|
||||
}
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
switch (currentFunctionIndex) {
|
||||
case 0:
|
||||
mFaceBeautyDataFactory.bindCurrentRenderer();
|
||||
hasFaceBeautyLoaded = true;
|
||||
break;
|
||||
case 1:
|
||||
mPropDataFactory.bindCurrentRenderer();
|
||||
hasPropLoaded = true;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
mMakeupDataFactory.bindCurrentRenderer();
|
||||
hasMakeupLoaded = true;
|
||||
break;
|
||||
case 3:
|
||||
mBodyBeautyDataFactory.bindCurrentRenderer();
|
||||
hasBodyBeautyLoaded = true;
|
||||
break;
|
||||
}
|
||||
if (hasFaceBeautyLoaded && currentFunctionIndex != 0) {
|
||||
mFaceBeautyDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (hasPropLoaded && currentFunctionIndex != 1) {
|
||||
mPropDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (hasMakeupLoaded && currentFunctionIndex != 2) {
|
||||
mMakeupDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (hasBodyBeautyLoaded && currentFunctionIndex != 3) {
|
||||
mBodyBeautyDataFactory.bindCurrentRenderer();
|
||||
}
|
||||
if (currentFunctionIndex == 3) {
|
||||
mFURenderKit.getFUAIController().setMaxFaces(1);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.HUMAN_PROCESSOR);
|
||||
} else {
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 道具功能切换
|
||||
*/
|
||||
public void onFunctionSelected(int index) {
|
||||
currentFunctionIndex = index;
|
||||
switch (index) {
|
||||
case 0:
|
||||
if (!hasFaceBeautyLoaded) {
|
||||
mFaceBeautyDataFactory.bindCurrentRenderer();
|
||||
hasFaceBeautyLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
break;
|
||||
case 1:
|
||||
if (!hasPropLoaded) {
|
||||
mPropDataFactory.bindCurrentRenderer();
|
||||
hasPropLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
break;
|
||||
case 2:
|
||||
if (!hasMakeupLoaded) {
|
||||
mMakeupDataFactory.bindCurrentRenderer();
|
||||
hasMakeupLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(4);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.FACE_PROCESSOR);
|
||||
break;
|
||||
case 3:
|
||||
if (!hasBodyBeautyLoaded) {
|
||||
mBodyBeautyDataFactory.bindCurrentRenderer();
|
||||
hasBodyBeautyLoaded = true;
|
||||
}
|
||||
mFURenderKit.getFUAIController().setMaxFaces(1);
|
||||
mFURenderer.setAIProcessTrackType(FUAIProcessorEnum.HUMAN_PROCESSOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,405 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
|
||||
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.FUTranslationScale;
|
||||
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.faceunity.core.model.prop.sticker.FineSticker;
|
||||
import com.faceunity.core.utils.FileUtils;
|
||||
|
||||
import com.yunbao.faceunity.entity.net.FineStickerEntity;
|
||||
import com.yunbao.faceunity.entity.net.FineStickerTagEntity;
|
||||
import com.yunbao.faceunity.infe.AbstractFineStickerDataFactory;
|
||||
import com.yunbao.faceunity.repo.AvatarSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
import com.yunbao.faceunity.utils.net.StickerDownloadHelper;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created on 2021/3/31 0031 15:28.
|
||||
* Author: xloger
|
||||
* Email:phoenix@xloger.com
|
||||
*/
|
||||
public class FineStickerDataFactory extends AbstractFineStickerDataFactory {
|
||||
private static final String TAG = "FineStickerDataFactory";
|
||||
private static FineStickerDataFactory factory;
|
||||
public static FineStickerDataFactory getInstance(){
|
||||
if(factory==null){
|
||||
factory=new FineStickerDataFactory();
|
||||
}
|
||||
return factory;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
private FUAIKit mFUAIKit = FUAIKit.getInstance();
|
||||
/*当前选中道具模型*/
|
||||
private FineSticker currentProp;
|
||||
/*菜单视图*/
|
||||
/*当前选中道具*/
|
||||
private FineStickerEntity.DocsBean currentSticker;
|
||||
/*当前道具的类型 普通单bundle,avatar 默认为普通单bundle*/
|
||||
private BundleType mCurrentBundleType = BundleType.NORMAL_SINGLE_BUNDLE;
|
||||
|
||||
//avatar相关
|
||||
/* 场景 */
|
||||
private Scene mSceneModel;
|
||||
/* 对象 */
|
||||
private Avatar mCurrentAvatarModel;
|
||||
/*3D抗锯齿*/
|
||||
public Antialiasing antialiasing;
|
||||
|
||||
//回调
|
||||
private List<StickerDownloadHelper.Callback> callbacks;
|
||||
|
||||
//avatar用于区分bundle类型的关键字
|
||||
private final String COMPONENTS_STR = "components";
|
||||
private final String ANIM_STR = "anim";
|
||||
private final String INFO = "info.json";
|
||||
private final String ZIP = ".zip";
|
||||
private final String AVATAR = "avatar";
|
||||
|
||||
private FineStickerDataFactory() {
|
||||
callbacks=new ArrayList<>();
|
||||
StickerDownloadHelper.getInstance().setCallback(downloadHelper);
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定菜单视图
|
||||
*
|
||||
*/
|
||||
public void bindView() {
|
||||
|
||||
}
|
||||
|
||||
public void addCallback(StickerDownloadHelper.Callback downloadHelper) {
|
||||
callbacks.add(downloadHelper);
|
||||
}
|
||||
public void removeCallback(StickerDownloadHelper.Callback downloadHelper){
|
||||
callbacks.remove(downloadHelper);
|
||||
}
|
||||
private void removeAllCallback(){
|
||||
callbacks.clear();
|
||||
}
|
||||
|
||||
public void refuseEvent() {
|
||||
StickerDownloadHelper.getInstance().setCallback(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换道具
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(FineStickerEntity.DocsBean bean) {
|
||||
currentSticker = bean;
|
||||
if (bean != null && bean.getTool().getBundle().getUid().endsWith(ZIP)) {
|
||||
//复合道具
|
||||
if (AVATAR.equals(bean.getTool().getCategory())) {
|
||||
//avatar道具
|
||||
if (mCurrentBundleType == BundleType.NORMAL_SINGLE_BUNDLE) {
|
||||
//移除旧的道具
|
||||
mFURenderKit.getPropContainer().removeAllProp();
|
||||
currentProp = null;
|
||||
adapterMaxFace();
|
||||
}
|
||||
if (bean.getUnZipFilePaths() != null) {
|
||||
buildAvatarModel(bean);
|
||||
//当前为 avatar bundle
|
||||
mCurrentBundleType = BundleType.AVATAR_BUNDLE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//普通道具
|
||||
if (mCurrentBundleType == BundleType.NORMAL_SINGLE_BUNDLE) {
|
||||
mFURenderKit.getPropContainer().removeAllProp();
|
||||
currentProp = null;
|
||||
if (bean != null && bean.getFilePath() != null && bean.getFilePath().trim().length() > 0) {
|
||||
adapterMaxFace();
|
||||
FineSticker prop = adapterBean(bean.getFilePath());
|
||||
mFURenderKit.getPropContainer().addProp(prop);
|
||||
currentProp = prop;
|
||||
}
|
||||
} else if (mCurrentBundleType == BundleType.AVATAR_BUNDLE) {
|
||||
//关闭avatar 相关的东西
|
||||
if (mSceneModel != null && mCurrentAvatarModel != null) {
|
||||
mSceneModel.removeAvatar(mCurrentAvatarModel);
|
||||
FUSceneKit.getInstance().removeScene(mSceneModel);
|
||||
mSceneModel = null;
|
||||
mCurrentAvatarModel = null;
|
||||
}
|
||||
|
||||
//设置道具
|
||||
if (bean != null && bean.getFilePath() != null && bean.getFilePath().trim().length() > 0) {
|
||||
adapterMaxFace();
|
||||
FineSticker prop = adapterBean(bean.getFilePath());
|
||||
mFURenderKit.getPropContainer().addProp(prop);
|
||||
currentProp = prop;
|
||||
}
|
||||
}
|
||||
|
||||
//当前为普通bundle
|
||||
mCurrentBundleType = BundleType.NORMAL_SINGLE_BUNDLE;
|
||||
}
|
||||
|
||||
if (mBundleTypeListener != null) {
|
||||
mBundleTypeListener.bundleType(mCurrentBundleType);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建avatar -> scene
|
||||
* @param bean
|
||||
*/
|
||||
private void buildAvatarModel(FineStickerEntity.DocsBean bean) {
|
||||
//启动avatar基本逻辑
|
||||
if (antialiasing == null)
|
||||
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
|
||||
//3d抗锯齿
|
||||
mFURenderKit.setAntialiasing(antialiasing);
|
||||
//判断是avatar 控件 -> 查看是否有json文件
|
||||
ArrayList<String> unZipFilePaths = bean.getUnZipFilePaths();
|
||||
int hasJson = unZipFilePaths.indexOf(INFO);
|
||||
|
||||
ArrayList<String> strComponents = new ArrayList<>();//组件Bundle
|
||||
ArrayList<String> strAnimations = new ArrayList<>();//动画Bundle
|
||||
if (hasJson >= 0) {
|
||||
//用json的描述赋予每一个bundle自己的职责,还可以赋予其他参数
|
||||
String jsonPath = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + unZipFilePaths.get(hasJson);
|
||||
//解析json文件 ->
|
||||
String json = FileUtils.loadStringFromExternal(jsonPath);
|
||||
//解析avatar的json文件
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(json);
|
||||
JSONArray components = jsonObject.getJSONArray("components");
|
||||
for(int i =0 ;i < components.length();i++) {
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + components.get(i);
|
||||
strComponents.add(path);
|
||||
}
|
||||
|
||||
JSONArray anims = jsonObject.getJSONArray("anims");
|
||||
for(int i =0 ;i < anims.length();i++) {
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + anims.get(i);
|
||||
strAnimations.add(path);
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
//根据bundle的命名赋予每一个bundle自己的职责
|
||||
for (String str:unZipFilePaths) {
|
||||
if (str.startsWith(COMPONENTS_STR)) {
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + str;
|
||||
strComponents.add(path);
|
||||
} else if (str.startsWith(ANIM_STR)){
|
||||
String path = bean.getFilePath().substring(0,bean.getFilePath().lastIndexOf(".")) + "/" + str;
|
||||
strAnimations.add(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mSceneModel == null) {
|
||||
mCurrentAvatarModel = AvatarSource.buildAvatarData(strComponents,strAnimations);
|
||||
mSceneModel = AvatarSource.buildSceneModel(mCurrentAvatarModel);
|
||||
mSceneModel.processorConfig.setTrackScene(ProcessorConfig.TrackScene.SceneFull);
|
||||
mCurrentAvatarModel.transForm.setTranslationScale(new FUTranslationScale(0.5f, 0f, 0.1f));
|
||||
} else {
|
||||
if (mCurrentAvatarModel != null)
|
||||
mSceneModel.removeAvatar(mCurrentAvatarModel);
|
||||
mCurrentAvatarModel = AvatarSource.buildAvatarData(strComponents,strAnimations);
|
||||
mSceneModel.addAvatar(mCurrentAvatarModel);
|
||||
}
|
||||
FUSceneKit.getInstance().addScene(mSceneModel);
|
||||
FUSceneKit.getInstance().setCurrentScene(mSceneModel);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 根据adpater 调整业务模型
|
||||
* 0:维持竖屏
|
||||
* 1:仅限一人
|
||||
* 2:美妆道具
|
||||
* 3:点击事件
|
||||
* 4:翻转
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private FineSticker adapterBean(String path) {
|
||||
String adapter = currentSticker.getTool().getAdapter();
|
||||
if (adapter == null || !adapter.contains("1")) {
|
||||
mFUAIKit.setMaxFaces(4);
|
||||
} else {
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
}
|
||||
if (adapter != null && adapter.trim().length() > 0) {
|
||||
boolean isFlipPoints = adapter.contains("2");
|
||||
boolean is3DFlipH = adapter.contains("4");
|
||||
boolean isClick = adapter.contains("3");
|
||||
return new FineSticker(new FUBundleData(path), isFlipPoints, is3DFlipH, isClick);
|
||||
} else {
|
||||
return new FineSticker(new FUBundleData(path));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 网络回调
|
||||
*/
|
||||
private StickerDownloadHelper.Callback downloadHelper = new StickerDownloadHelper.Callback() {
|
||||
@Override
|
||||
public void onGetTags(String[] tags) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onGetTags(tags);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetList(String tag, FineStickerEntity fineSticker) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onGetList(tag, fineSticker);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownload(FineStickerEntity.DocsBean entity) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onDownload(entity);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownloadError(FineStickerEntity.DocsBean entity, String msg) {
|
||||
for (StickerDownloadHelper.Callback callback : callbacks) {
|
||||
callback.onDownloadError(entity, msg);
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 获取标签列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public List<FineStickerTagEntity> loadTagList() {
|
||||
String[] tags = StickerDownloadHelper.getInstance().tags();
|
||||
return formatTag(tags);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取标签对应道具列表
|
||||
*
|
||||
* @param tag
|
||||
* @return
|
||||
*/
|
||||
@NotNull
|
||||
@Override
|
||||
public FineStickerEntity loadStickerList(@NotNull FineStickerTagEntity tag) {
|
||||
return StickerDownloadHelper.getInstance().tools(tag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载道具
|
||||
*
|
||||
* @param docsBean
|
||||
*/
|
||||
@Override
|
||||
public void downloadSticker(@NotNull FineStickerEntity.DocsBean docsBean) {
|
||||
try{
|
||||
StickerDownloadHelper.getInstance().download(docsBean);
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG,"downloadSticker",e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 数据转换
|
||||
*
|
||||
* @param tags
|
||||
* @return
|
||||
*/
|
||||
public static List<FineStickerTagEntity> formatTag(String[] tags) {
|
||||
List<FineStickerTagEntity> tagEntityList = new ArrayList<>(tags.length);
|
||||
for (int i = 0; i < tags.length; i++) {
|
||||
tagEntityList.add(new FineStickerTagEntity(tags[i]));
|
||||
}
|
||||
return tagEntityList;
|
||||
}
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.loadAIProcessor(FaceUnityConfig.BUNDLE_AI_HAND, FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
onItemSelected(currentSticker);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 结束需要释放AI驱动
|
||||
*/
|
||||
public void releaseAIProcessor() {
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
|
||||
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_HANDGESTURE);
|
||||
}
|
||||
|
||||
|
||||
private void adapterMaxFace() {
|
||||
if (currentSticker == null) return;
|
||||
String adapter = currentSticker.getTool().getAdapter();
|
||||
if (adapter == null || !adapter.contains("1")) {
|
||||
mFUAIKit.setMaxFaces(4);
|
||||
} else {
|
||||
mFUAIKit.setMaxFaces(1);
|
||||
}
|
||||
}
|
||||
|
||||
public void onTouchEvent(MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_UP && currentProp != null && currentProp.isClick()) {
|
||||
currentProp.onClick();
|
||||
}
|
||||
}
|
||||
|
||||
//通过枚举记录每一个bundle的类型
|
||||
public enum BundleType {
|
||||
NORMAL_SINGLE_BUNDLE,//普通的单bundle道具
|
||||
AVATAR_BUNDLE//avatar bundle 一般为多bundle
|
||||
}
|
||||
|
||||
private BundleTypeListener mBundleTypeListener;
|
||||
public interface BundleTypeListener {
|
||||
void bundleType(BundleType bundleType);
|
||||
}
|
||||
public void setBundleTypeListener (BundleTypeListener bundleTypeListener){
|
||||
mBundleTypeListener = bundleTypeListener;
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,853 @@
|
||||
package com.yunbao.faceunity.data;
|
||||
|
||||
|
||||
import static com.yunbao.faceunity.repo.MakeupSource.*;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.faceunity.core.entity.FUBundleData;
|
||||
import com.faceunity.core.entity.FUColorRGBData;
|
||||
import com.faceunity.core.enumeration.FUAITypeEnum;
|
||||
import com.faceunity.core.faceunity.FUAIKit;
|
||||
import com.faceunity.core.faceunity.FURenderKit;
|
||||
import com.faceunity.core.model.makeup.Makeup;
|
||||
import com.faceunity.core.model.makeup.MakeupLipEnum;
|
||||
|
||||
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
|
||||
import com.faceunity.core.utils.DecimalUtils;
|
||||
import com.yunbao.faceunity.entity.MakeupCombinationBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomBean;
|
||||
import com.yunbao.faceunity.entity.MakeupCustomClassBean;
|
||||
import com.yunbao.faceunity.infe.AbstractMakeupDataFactory;
|
||||
import com.yunbao.faceunity.repo.FaceBeautySource;
|
||||
import com.yunbao.faceunity.repo.MakeupSource;
|
||||
import com.yunbao.faceunity.utils.FaceUnityConfig;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
/**
|
||||
* DESC:美妆业务工厂
|
||||
* Created on 2021/3/1
|
||||
*/
|
||||
public class MakeupDataFactory extends AbstractMakeupDataFactory {
|
||||
|
||||
|
||||
/*渲染控制器*/
|
||||
private FURenderKit mFURenderKit = FURenderKit.getInstance();
|
||||
|
||||
/*组合妆容列表*/
|
||||
private ArrayList<MakeupCombinationBean> makeupCombinations;
|
||||
/*组合妆容当前下标*/
|
||||
private int currentCombinationIndex;//-1:自定义
|
||||
/*美妆数据模型*/
|
||||
private Makeup currentMakeup;
|
||||
/*当前滤镜*/
|
||||
private String currentFilterName;
|
||||
/*当前滤镜*/
|
||||
private Double currentFilterIntensity;
|
||||
|
||||
|
||||
private LinkedHashMap<String, ArrayList<double[]>> mMakeUpColorMap;//美妆颜色表
|
||||
|
||||
private HashMap<String, Integer> mCustomIndexMap = new HashMap<>();//key:美妆类别 value:当前美妆子项选中下标 默认0
|
||||
private HashMap<String, Double> mCustomIntensityMap = new HashMap<>();//key:美妆类别_子项下标 value:当前美妆选中子项的妆容强度 默认1.0
|
||||
private HashMap<String, Integer> mCustomColorIndexMap = new HashMap<>();//key:美妆类别_子项下标 value:当前美妆选中子项的颜色下标 默认3
|
||||
|
||||
|
||||
public MakeupDataFactory(int index) {
|
||||
makeupCombinations = MakeupSource.buildCombinations();
|
||||
mMakeUpColorMap = MakeupSource.buildMakeUpColorMap();
|
||||
currentCombinationIndex = index;
|
||||
currentFilterName = makeupCombinations.get(index).getFilterName();
|
||||
currentFilterIntensity = makeupCombinations.get(index).getFilterIntensity();
|
||||
currentMakeup = MakeupSource.getMakeupModel(makeupCombinations.get(currentCombinationIndex)); // 当前生效模型
|
||||
}
|
||||
|
||||
//region 组合妆
|
||||
|
||||
/**
|
||||
* 获取当前组合妆容列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@NonNull
|
||||
public ArrayList<MakeupCombinationBean> getMakeupCombinations() {
|
||||
return makeupCombinations;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前组合妆容下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentCombinationIndex() {
|
||||
return currentCombinationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置组合妆容下标
|
||||
*
|
||||
* @param currentCombinationIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentCombinationIndex(int currentCombinationIndex) {
|
||||
this.currentCombinationIndex = currentCombinationIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换组合妆容
|
||||
*
|
||||
* @param bean
|
||||
*/
|
||||
@Override
|
||||
public void onMakeupCombinationSelected(MakeupCombinationBean bean) {
|
||||
currentFilterName = bean.getFilterName();
|
||||
currentFilterIntensity = bean.getFilterIntensity();
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterName(currentFilterName);
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
currentMakeup = MakeupSource.getMakeupModel(bean);
|
||||
mFURenderKit.setMakeup(currentMakeup);
|
||||
if (!currentMakeup.getControlBundle().getPath().equals(FaceUnityConfig.BUNDLE_FACE_MAKEUP))
|
||||
currentMakeup.setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换美妆模型整体强度
|
||||
*
|
||||
* @param intensity
|
||||
*/
|
||||
@Override
|
||||
public void updateCombinationIntensity(double intensity) {
|
||||
currentMakeup.setMakeupIntensity(intensity);
|
||||
currentFilterIntensity = intensity;
|
||||
if (mFURenderKit.getFaceBeauty() != null) {
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
|
||||
if (!currentMakeup.getControlBundle().getPath().equals(FaceUnityConfig.BUNDLE_FACE_MAKEUP))
|
||||
currentMakeup.setFilterIntensity(currentFilterIntensity);
|
||||
}
|
||||
|
||||
|
||||
//endregion 组合妆
|
||||
|
||||
//region 子美妆
|
||||
|
||||
|
||||
/**
|
||||
* 获取子妆类别列表
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public ArrayList<MakeupCustomClassBean> getMakeupCustomClass() {
|
||||
return MakeupSource.buildCustomClasses();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取子妆列表参数
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public LinkedHashMap<String, ArrayList<MakeupCustomBean>> getMakeupCustomItemParams() {
|
||||
return MakeupSource.buildCustomItemParams(mMakeUpColorMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置子妆强度
|
||||
*
|
||||
* @param key
|
||||
* @param current
|
||||
* @param intensity
|
||||
*/
|
||||
@Override
|
||||
public void updateCustomItemIntensity(String key, int current, double intensity) {
|
||||
if (key.equals(FACE_MAKEUP_TYPE_FOUNDATION)) {
|
||||
currentMakeup.setFoundationIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_LIP_STICK)) {
|
||||
currentMakeup.setLipIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_BLUSHER)) {
|
||||
currentMakeup.setBlusherIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_BROW)) {
|
||||
currentMakeup.setEyeBrowIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_SHADOW)) {
|
||||
currentMakeup.setEyeShadowIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LINER)) {
|
||||
currentMakeup.setEyeLineIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LASH)) {
|
||||
currentMakeup.setEyeLashIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_HIGH_LIGHT)) {
|
||||
currentMakeup.setHeightLightIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_SHADOW)) {
|
||||
currentMakeup.setShadowIntensity(intensity);
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_PUPIL)) {
|
||||
currentMakeup.setPupilIntensity(intensity);
|
||||
}
|
||||
mCustomIntensityMap.put(key + "_" + current, intensity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换子妆单项
|
||||
*
|
||||
* @param key 子妆类别
|
||||
* @param index 选中下标
|
||||
*/
|
||||
@Override
|
||||
public void onCustomBeanSelected(String key, int index) {
|
||||
String itemDir = FaceUnityConfig.MAKEUP_RESOURCE_ITEM_BUNDLE_DIR;
|
||||
mCustomIndexMap.put(key, index);
|
||||
if (key.equals(FACE_MAKEUP_TYPE_FOUNDATION)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setFoundationIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setFoundationBundle(new FUBundleData(itemDir + "mu_style_foundation_01.bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_FOUNDATION + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_FOUNDATION + "_" + index);
|
||||
}
|
||||
currentMakeup.setFoundationIntensity((intensity));
|
||||
updateCustomColor(key, index + 2);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_foundation_01").get(index + 2);
|
||||
currentMakeup.setFoundationColor(buildFUColorRGBData(color));
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_LIP_STICK)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setLipIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setLipBundle(new FUBundleData(itemDir + "mu_style_lip_0" + index + ".bundle"));
|
||||
switch (index) {
|
||||
case 1:
|
||||
currentMakeup.setLipType(MakeupLipEnum.FOG);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
break;
|
||||
case 2:
|
||||
currentMakeup.setLipType(MakeupLipEnum.MOIST);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
break;
|
||||
case 3:
|
||||
currentMakeup.setLipType(MakeupLipEnum.WATER);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(true);
|
||||
currentMakeup.setLipHighLightStrength(0.8);
|
||||
break;
|
||||
case 4:
|
||||
currentMakeup.setLipType(MakeupLipEnum.PEARL);
|
||||
currentMakeup.setEnableTwoLipColor(false);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
break;
|
||||
case 5:
|
||||
currentMakeup.setLipType(MakeupLipEnum.FOG);
|
||||
currentMakeup.setEnableTwoLipColor(true);
|
||||
currentMakeup.setLipHighLightEnable(false);
|
||||
currentMakeup.setLipHighLightStrength(0.0);
|
||||
currentMakeup.setLipColor2(new FUColorRGBData(0.0, 0.0, 0.0, 0.0));
|
||||
break;
|
||||
}
|
||||
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index);
|
||||
}
|
||||
currentMakeup.setLipIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_LIP_STICK + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_BLUSHER)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setBlusherIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setBlusherBundle(new FUBundleData(itemDir + "mu_style_blush_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_BLUSHER + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_BLUSHER + "_" + index);
|
||||
}
|
||||
currentMakeup.setBlusherIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_BLUSHER + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_BLUSHER + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_BROW)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeBrowIntensity(0.0);
|
||||
currentMakeup.setEnableBrowWarp(false);
|
||||
} else {
|
||||
currentMakeup.setEnableBrowWarp(false);
|
||||
currentMakeup.setEyeBrowBundle(new FUBundleData(itemDir + "mu_style_eyebrow_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeBrowIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_BROW + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_SHADOW)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeShadowIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setEyeShadowBundle(new FUBundleData(itemDir + "mu_style_eyeshadow_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeShadowIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LINER)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeLineIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setEyeLinerBundle(new FUBundleData(itemDir + "mu_style_eyeliner_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeLineIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_LINER + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LASH)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setEyeLashIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setEyeLashBundle(new FUBundleData(itemDir + "mu_style_eyelash_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index);
|
||||
}
|
||||
currentMakeup.setEyeLashIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_LASH + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_HIGH_LIGHT)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setHeightLightIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setHighLightBundle(new FUBundleData(itemDir + "mu_style_highlight_0" + index + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index);
|
||||
}
|
||||
currentMakeup.setHeightLightIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_SHADOW)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setShadowIntensity(0.0);
|
||||
} else {
|
||||
currentMakeup.setShadowBundle(new FUBundleData(itemDir + "mu_style_contour_01.bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_SHADOW + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_SHADOW + "_" + index);
|
||||
}
|
||||
currentMakeup.setShadowIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_SHADOW + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_SHADOW + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
}
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_PUPIL)) {
|
||||
if (index == 0) {
|
||||
currentMakeup.setPupilIntensity(0.0);
|
||||
} else {
|
||||
if (index == 1) {
|
||||
currentMakeup.setPupilBundle(new FUBundleData(itemDir + "mu_style_eyepupil_01.bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index);
|
||||
}
|
||||
currentMakeup.setPupilIntensity((intensity));
|
||||
int colorIndex = 3;
|
||||
if (mCustomColorIndexMap.containsKey(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index)) {
|
||||
colorIndex = mCustomColorIndexMap.get(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index);
|
||||
}
|
||||
updateCustomColor(key, colorIndex);
|
||||
} else {
|
||||
currentMakeup.setPupilBundle(new FUBundleData(itemDir + "mu_style_eyepupil_0" + (index + 1) + ".bundle"));
|
||||
double intensity = 1.0;
|
||||
if (mCustomIntensityMap.containsKey(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index)) {
|
||||
intensity = mCustomIntensityMap.get(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + index);
|
||||
}
|
||||
currentMakeup.setPupilIntensity((intensity));
|
||||
currentMakeup.setPupilColor(buildFUColorRGBData(new double[]{0.0, 0.0, 0.0, 0.0}));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置子妆颜色值
|
||||
*
|
||||
* @param key 类别关键字
|
||||
* @param index 颜色下标
|
||||
*/
|
||||
@Override
|
||||
public void updateCustomColor(String key, int index) {
|
||||
int current = mCustomIndexMap.containsKey(key) ? mCustomIndexMap.get(key) : 0;
|
||||
if (key.equals(FACE_MAKEUP_TYPE_LIP_STICK)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_LIP_STICK + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_lip_01").get(index);
|
||||
if (current == 3)
|
||||
currentMakeup.setLipColorV2(buildFUColorRGBData(color));
|
||||
else
|
||||
currentMakeup.setLipColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_BLUSHER)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_BLUSHER + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_blush_0" + current).get(index);
|
||||
currentMakeup.setBlusherColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_BROW)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_BROW + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyebrow_01").get(index);
|
||||
currentMakeup.setEyeBrowColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_SHADOW)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyeshadow_0" + current).get(index);
|
||||
currentMakeup.setEyeShadowColor(new FUColorRGBData(color[0] * 255, color[1] * 255, color[2] * 255, color[3] * 255));
|
||||
currentMakeup.setEyeShadowColor2(new FUColorRGBData(color[4] * 255, color[5] * 255, color[6] * 255, color[7] * 255));
|
||||
currentMakeup.setEyeShadowColor3(new FUColorRGBData(color[8] * 255, color[9] * 255, color[10] * 255, color[11] * 255));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LINER)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LINER + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyeliner_0" + current).get(index);
|
||||
currentMakeup.setEyeLinerColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_LASH)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LASH + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyelash_0" + current).get(index);
|
||||
currentMakeup.setEyeLashColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_HIGH_LIGHT)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_highlight_0" + current).get(index);
|
||||
currentMakeup.setHighLightColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_SHADOW)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_SHADOW + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_contour_01").get(index);
|
||||
currentMakeup.setShadowColor(buildFUColorRGBData(color));
|
||||
} else if (key.equals(FACE_MAKEUP_TYPE_EYE_PUPIL)) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + current, index);
|
||||
double[] color = mMakeUpColorMap.get("color_mu_style_eyepupil_01").get(index);
|
||||
currentMakeup.setPupilColor(buildFUColorRGBData(color));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//endregion 子美妆
|
||||
|
||||
//region 其他
|
||||
|
||||
/**
|
||||
* 进入自定义美妆,模型分析
|
||||
*/
|
||||
@Override
|
||||
public void enterCustomMakeup() {
|
||||
mCustomIndexMap.clear();
|
||||
mCustomColorIndexMap.clear();
|
||||
mCustomIntensityMap.clear();
|
||||
double makeupIntensity = currentMakeup.getMakeupIntensity();
|
||||
/*粉底*/
|
||||
if (currentMakeup.getFoundationIntensity() != 0.0) {
|
||||
double intensity = currentMakeup.getFoundationIntensity() * makeupIntensity;
|
||||
currentMakeup.setFoundationIntensity(intensity);
|
||||
double[] array = currentMakeup.getFoundationColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_foundation_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(array, list.get(i))) {
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_FOUNDATION, i - 2);
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_FOUNDATION + "_" + (i - 2), intensity);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
/*口红*/
|
||||
if (currentMakeup.getLipIntensity() != 0.0) {
|
||||
double intensity = currentMakeup.getLipIntensity() * makeupIntensity;
|
||||
currentMakeup.setLipIntensity(intensity);
|
||||
int current = 0;
|
||||
switch (currentMakeup.getLipType()) {
|
||||
case MakeupLipEnum.FOG:
|
||||
if (currentMakeup.getEnableTwoLipColor()) {
|
||||
current = 5;
|
||||
} else {
|
||||
current = 1;
|
||||
}
|
||||
break;
|
||||
case MakeupLipEnum.MOIST:
|
||||
current = 3;
|
||||
break;
|
||||
case MakeupLipEnum.PEARL:
|
||||
current = 4;
|
||||
break;
|
||||
case MakeupLipEnum.WATER:
|
||||
current = 2;
|
||||
break;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_LIP_STICK, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray;
|
||||
if (currentMakeup.getLipType() == MakeupLipEnum.WATER) {
|
||||
colorArray = currentMakeup.getLipColorV2().toScaleColorArray();
|
||||
} else {
|
||||
colorArray = currentMakeup.getLipColor().toScaleColorArray();
|
||||
}
|
||||
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_lip_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_LIP_STICK + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_LIP_STICK + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*腮红*/
|
||||
if (currentMakeup.getBlusherIntensity() != 0.0 && currentMakeup.getBlusherBundle() != null) {
|
||||
double intensity = currentMakeup.getBlusherIntensity() * makeupIntensity;
|
||||
currentMakeup.setBlusherIntensity(intensity);
|
||||
String path = currentMakeup.getBlusherBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_blush_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_blush_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_blush_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_blush_04.bundle")) {
|
||||
current = 4;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_BLUSHER, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getBlusherColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_blush_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_BLUSHER + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_BLUSHER + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*眉毛*/
|
||||
if (currentMakeup.getEyeBrowIntensity() != 0.0) {
|
||||
double intensity = currentMakeup.getEyeBrowIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeBrowIntensity(intensity);
|
||||
int current = 0;
|
||||
if (currentMakeup.getEyeBrowBundle() != null && currentMakeup.getEyeBrowBundle().getPath() != null) {
|
||||
String bundlePath = currentMakeup.getEyeBrowBundle().getPath();
|
||||
int spotIndex = bundlePath.lastIndexOf(".");
|
||||
String index = bundlePath.substring(spotIndex - 1, spotIndex);
|
||||
current = Integer.valueOf(index);
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_BROW, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getEyeBrowColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyebrow_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_BROW + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_BROW + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*眼影*/
|
||||
if (currentMakeup.getEyeShadowIntensity() != 0.0 && currentMakeup.getEyeShadowBundle() != null) {
|
||||
double intensity = currentMakeup.getEyeShadowIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeShadowIntensity(intensity);
|
||||
String path = currentMakeup.getEyeShadowBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyeshadow_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_04.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_05.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyeshadow_06.bundle")) {
|
||||
current = 6;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW, current);
|
||||
if (current != 0) {
|
||||
double[] array = new double[12];
|
||||
double[] color1 = currentMakeup.getEyeShadowColor().toScaleColorArray();
|
||||
double[] color2 = currentMakeup.getEyeShadowColor2().toScaleColorArray();
|
||||
double[] color3 = currentMakeup.getEyeShadowColor3().toScaleColorArray();
|
||||
System.arraycopy(color1, 0, array, 0, color1.length);
|
||||
System.arraycopy(color2, 0, array, 4, color2.length);
|
||||
System.arraycopy(color3, 0, array, 8, color3.length);
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyeshadow_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(array, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_SHADOW + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/*眼线*/
|
||||
if (currentMakeup.getEyeLineIntensity() != 0.0 && currentMakeup.getEyeLinerBundle() != null) {
|
||||
double intensity = currentMakeup.getEyeLineIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeLineIntensity(intensity);
|
||||
String path = currentMakeup.getEyeLinerBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyeliner_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyeliner_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyeliner_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyeliner_04.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyeliner_05.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyeliner_06.bundle")) {
|
||||
current = 6;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_LINER, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getEyeLinerColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyeliner_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LINER + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_LINER + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 睫毛*/
|
||||
if (currentMakeup.getEyeLashIntensity() != 0.0 && currentMakeup.getEyeLashBundle() != null) {
|
||||
double intensity = currentMakeup.getEyeLashIntensity() * makeupIntensity;
|
||||
currentMakeup.setEyeLashIntensity(intensity);
|
||||
String path = currentMakeup.getEyeLashBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyelash_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyelash_02.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyelash_03.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyelash_04.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyelash_05.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyelash_06.bundle")) {
|
||||
current = 6;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_LASH, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getEyeLashColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyelash_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_LASH + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_LASH + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 高光*/
|
||||
if (currentMakeup.getHeightLightIntensity() != 0.0 && currentMakeup.getHighLightBundle() != null) {
|
||||
double intensity = currentMakeup.getHeightLightIntensity() * makeupIntensity;
|
||||
currentMakeup.setHeightLightIntensity(intensity);
|
||||
String path = currentMakeup.getHighLightBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_highlight_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_highlight_02.bundle")) {
|
||||
current = 2;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getHighLightColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_highlight_0" + current);
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_HIGH_LIGHT + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 阴影*/
|
||||
if (currentMakeup.getShadowIntensity() != 0.0 && currentMakeup.getShadowBundle() != null) {
|
||||
double intensity = currentMakeup.getShadowIntensity() * makeupIntensity;
|
||||
currentMakeup.setShadowIntensity(intensity);
|
||||
String path = currentMakeup.getShadowBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_contour_01.bundle")) {
|
||||
current = 1;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_SHADOW, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getShadowColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_contour_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_SHADOW + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_SHADOW + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
/* 美瞳*/
|
||||
if (currentMakeup.getPupilIntensity() != 0.0 && currentMakeup.getPupilBundle() != null) {
|
||||
double intensity = currentMakeup.getPupilIntensity() * makeupIntensity;
|
||||
currentMakeup.setPupilIntensity(intensity);
|
||||
String path = currentMakeup.getPupilBundle().getPath();
|
||||
int current = 0;
|
||||
if (path.endsWith("mu_style_eyepupil_01.bundle")) {
|
||||
current = 1;
|
||||
} else if (path.endsWith("mu_style_eyepupil_03.bundle")) {
|
||||
current = 2;
|
||||
} else if (path.endsWith("mu_style_eyepupil_04.bundle")) {
|
||||
current = 3;
|
||||
} else if (path.endsWith("mu_style_eyepupil_05.bundle")) {
|
||||
current = 4;
|
||||
} else if (path.endsWith("mu_style_eyepupil_06.bundle")) {
|
||||
current = 5;
|
||||
} else if (path.endsWith("mu_style_eyepupil_07.bundle")) {
|
||||
current = 6;
|
||||
} else if (path.endsWith("mu_style_eyepupil_08.bundle")) {
|
||||
current = 7;
|
||||
} else if (path.endsWith("mu_style_eyepupil_09.bundle")) {
|
||||
current = 8;
|
||||
}
|
||||
mCustomIndexMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL, current);
|
||||
if (current != 0) {
|
||||
double[] colorArray = currentMakeup.getPupilColor().toScaleColorArray();
|
||||
ArrayList<double[]> list = mMakeUpColorMap.get("color_mu_style_eyepupil_01");
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
if (DecimalUtils.doubleArrayEquals(colorArray, list.get(i))) {
|
||||
mCustomColorIndexMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + current, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mCustomIntensityMap.put(FACE_MAKEUP_TYPE_EYE_PUPIL + "_" + current, intensity);
|
||||
}
|
||||
}
|
||||
currentMakeup.setMakeupIntensity(1.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 或当单项列表当前下标
|
||||
*
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentCustomItemIndex(String key) {
|
||||
if (mCustomIndexMap.containsKey(key)) {
|
||||
return mCustomIndexMap.get(key);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前单项颜色下标
|
||||
*
|
||||
* @param key
|
||||
* @param current
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentCustomColorIndex(String key, int current) {
|
||||
if (mCustomColorIndexMap.containsKey(key + "_" + current)) {
|
||||
return mCustomColorIndexMap.get(key + "_" + current);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前单项强度
|
||||
*
|
||||
* @param key
|
||||
* @param current
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public double getCurrentCustomIntensity(String key, int current) {
|
||||
if (mCustomIntensityMap.containsKey(key + "_" + current)) {
|
||||
return mCustomIntensityMap.get(key + "_" + current);
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
||||
/**
|
||||
* FURenderKit加载当前特效
|
||||
*/
|
||||
public void bindCurrentRenderer() {
|
||||
mFURenderKit.setFaceBeauty(FaceBeautySource.clone(FaceBeautyDataFactory.faceBeauty));
|
||||
mFURenderKit.getFaceBeauty().setFilterName(currentFilterName);
|
||||
mFURenderKit.getFaceBeauty().setFilterIntensity(currentFilterIntensity);
|
||||
if (!currentMakeup.getControlBundle().getPath().equals(FaceUnityConfig.BUNDLE_FACE_MAKEUP))
|
||||
currentMakeup.setFilterIntensity(currentFilterIntensity);
|
||||
FUAIKit.getInstance().setMaxFaces(4);
|
||||
mFURenderKit.setMakeup(currentMakeup);
|
||||
|
||||
//特殊有一些需要设置图层混合模式的 04双色眼影3(第2层眼影的混合模式 == 1) 06三色眼影2(第3层眼影的混合模式 == 1)
|
||||
if (currentMakeup.getEyeShadowBundle() != null && ("mu_style_eyeshadow_0" + 4).equals(currentMakeup.getEyeShadowBundle().getName()))
|
||||
currentMakeup.setEyeShadowTexBlend2(1);
|
||||
else if (currentMakeup.getEyeShadowBundle() != null && ("mu_style_eyeshadow_0" + 6).equals(currentMakeup.getEyeShadowBundle().getName()))
|
||||
currentMakeup.setEyeShadowTexBlend3(1);
|
||||
|
||||
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
|
||||
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
|
||||
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
|
||||
mFURenderKit.getPropContainer().addProp(expressionRecognition);
|
||||
}
|
||||
}
|
||||
public void clearAll(){
|
||||
currentMakeup = new Makeup(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_MAKEUP));
|
||||
mFURenderKit.setMakeup(currentMakeup);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
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:道具业务工厂:道具贴图、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 int propType;
|
||||
|
||||
|
||||
/**
|
||||
* @param listener 回调接口
|
||||
* @param type 道具类型
|
||||
* @param index 默认选中下标
|
||||
*/
|
||||
public PropDataFactory(PropListener listener, int type, int index) {
|
||||
mPropListener = listener;
|
||||
propType = type;
|
||||
currentPropIndex = index;
|
||||
propBeans = PropSource.buildPropBeans(type);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前选中下标
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public int getCurrentPropIndex() {
|
||||
return currentPropIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前选中下标
|
||||
*
|
||||
* @param currentPropIndex
|
||||
*/
|
||||
@Override
|
||||
public void setCurrentPropIndex(int currentPropIndex) {
|
||||
this.currentPropIndex = currentPropIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取道具队列
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@NonNull
|
||||
public ArrayList<PropBean> getPropBeans() {
|
||||
return propBeans;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 设置效果
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(PropBean bean) {
|
||||
onPropSelected(bean);
|
||||
mPropListener.onItemSelected(bean);
|
||||
}
|
||||
|
||||
public void setPropType(int propType) {
|
||||
this.propType = propType;
|
||||
}
|
||||
|
||||
/**
|
||||
* 其他道具
|
||||
*
|
||||
* @param 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 = 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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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