This commit is contained in:
18142669586
2024-02-23 16:07:50 +08:00
commit a02f7b2e22
5737 changed files with 438436 additions and 0 deletions

View File

@@ -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;
/**
* DESCAnimoji业务工厂
* 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);
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}

View File

@@ -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<>();
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}
}

View File

@@ -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;
/*当前道具的类型 普通单bundleavatar 默认为普通单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;
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);
}
}

View File

@@ -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);
}
}
}