debug_fix_screen_change #2
@@ -165,7 +165,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
void CppCallback(const string& motion_type)
|
||||
void CppCallback()
|
||||
{
|
||||
JNIEnv* env = nullptr;
|
||||
bool needDetach = false;
|
||||
@@ -205,7 +205,7 @@ void CppCallback(const string& motion_type)
|
||||
}
|
||||
|
||||
// 3. 构造 jstring 参数
|
||||
jstring jResult = env->NewStringUTF(motion_type.c_str());
|
||||
jstring jResult = env->NewStringUTF("ok");
|
||||
|
||||
// 4. 调用 Java 回调
|
||||
env->CallVoidMethod(g_callback, methodId, jResult);
|
||||
@@ -309,7 +309,7 @@ Java_com_hmwl_face_1sdk_FaceActivity_PreReadAction(JNIEnv *env, jobject thiz, js
|
||||
aout << "ArgLen to long:" << len << std::endl;
|
||||
}
|
||||
|
||||
std::string ret = g_Application->preReadyMotion(nativeString, CppCallback);
|
||||
std::string ret = g_Application->preLoadMotionList(nativeString, CppCallback);
|
||||
return env->NewStringUTF(ret.c_str());
|
||||
}
|
||||
|
||||
@@ -336,6 +336,6 @@ Java_com_hmwl_face_1sdk_FaceActivity_ChangeMotionCpp(JNIEnv *env, jobject thiz,
|
||||
|
||||
if(g_Application->isInited())
|
||||
{
|
||||
g_Application->changeMotion(nativeString, CppAnimationFinishedCallback, loop);
|
||||
g_Application->changeMotionList(CppAnimationFinishedCallback, loop);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.hmwl.face_sdk;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Frame {
|
||||
public String name;
|
||||
public float x;
|
||||
public float y;
|
||||
public Frame(String name, float x, float y)
|
||||
{
|
||||
this.name = name;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
public JSONObject toJsonObject(){
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("name", name);
|
||||
jsonObject.put("x", x);
|
||||
jsonObject.put("y", y);
|
||||
return jsonObject;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,32 +5,29 @@ import org.json.JSONObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
public class Motion {
|
||||
public String type = "no";
|
||||
public List<String> png_names = new ArrayList<>();
|
||||
public String name = "no";
|
||||
public List<Frame> frames = new ArrayList<>();
|
||||
public Motion(String name, List<Frame> frames)
|
||||
{
|
||||
this.name = name;
|
||||
this.frames = frames;
|
||||
}
|
||||
|
||||
public JSONObject toJsonObject() {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
jsonObject.put("type", type);
|
||||
JSONArray ja = new JSONArray();
|
||||
for(int i = 0; i < png_names.size(); ++i){
|
||||
ja.put(png_names.get(i));
|
||||
jsonObject.put("name", name);
|
||||
JSONObject jframes = new JSONObject();
|
||||
for(int i = 0; i < frames.size(); ++i){
|
||||
jframes.put(frames.get(i).name, frames.get(i).toJsonObject());
|
||||
}
|
||||
jsonObject.put("png_names", ja);
|
||||
jsonObject.put("frames", jframes);
|
||||
return jsonObject;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String toJson() {
|
||||
try {
|
||||
return toJsonObject().toString();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.hmwl.face_sdk;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MotionList {
|
||||
public List<Motion> motions = new ArrayList<>();
|
||||
public JSONObject toJsonObject() {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
JSONArray jMotions = new JSONArray();
|
||||
for(int i = 0; i < motions.size(); ++i){
|
||||
jMotions.put(motions.get(i).toJsonObject());
|
||||
}
|
||||
jsonObject.put("motions", jMotions);
|
||||
return jsonObject;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return new JSONObject();
|
||||
}
|
||||
}
|
||||
public String toJsonString(){
|
||||
return toJsonObject().toString();
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,10 @@ import android.view.KeyEvent.KEYCODE_BACK
|
||||
import android.view.MotionEvent
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.hmwl.face_sdk.FaceActivity
|
||||
import com.hmwl.face_sdk.Frame
|
||||
import com.hmwl.face_sdk.InitArg
|
||||
import com.hmwl.face_sdk.Motion
|
||||
import com.hmwl.face_sdk.MotionList
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -21,18 +23,13 @@ import java.io.InputStreamReader
|
||||
|
||||
class MakeupActivity : FaceActivity()
|
||||
{
|
||||
var isLoadFinished: Boolean = false;
|
||||
var isMotionFinished: Boolean = true;
|
||||
var _motionIndex : Int = 0
|
||||
|
||||
|
||||
var animationFinishedFun = object : AnimationFinishedCallbackInterface {
|
||||
override fun OnAnimationFinished() {
|
||||
isMotionFinished = true;
|
||||
Log.i("MakeupActivity", "OnAnimationFinished: ")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var isLoadFinished : Boolean = false
|
||||
var loadFinishedFun = object : CallbackInterface {
|
||||
override fun OnLoadActionFinished(motion_type: String) {
|
||||
isLoadFinished = true;
|
||||
@@ -40,28 +37,13 @@ class MakeupActivity : FaceActivity()
|
||||
}
|
||||
|
||||
|
||||
|
||||
private val motionQueue: MutableList<String> = mutableListOf()
|
||||
fun PlayMotionQueue(motions: List<String>)
|
||||
{
|
||||
for (m in motions) {
|
||||
var motion = getMotionByName(m);
|
||||
var motionJsonString = motion.toJson();
|
||||
motionQueue.add(motionJsonString)
|
||||
}
|
||||
//开始播放动画的时候需要先加载第一个动画
|
||||
isLoadFinished = false;
|
||||
_motionIndex = 0;
|
||||
PreLoadAction(motionQueue[_motionIndex], loadFinishedFun)
|
||||
}
|
||||
|
||||
private var updateJob: Job? = null
|
||||
|
||||
|
||||
|
||||
private var existMotions: Map<String, Motion>? = null
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
|
||||
FaceInit(this)
|
||||
existMotions = readMotionsFromAssets(this, "pic/motion_data_ex.json")
|
||||
|
||||
val initArg = InitArg().apply {
|
||||
action_fps = 10
|
||||
@@ -81,27 +63,32 @@ class MakeupActivity : FaceActivity()
|
||||
}
|
||||
}
|
||||
|
||||
val mlist = MotionList();
|
||||
getMotionByName("4")?.let { mlist.motions.add(it) }
|
||||
//getMotionByName("11")?.let { mlist.motions.add(it) }
|
||||
//getMotionByName("13")?.let { mlist.motions.add(it) }
|
||||
PreLoadAction(mlist.toJsonString(), loadFinishedFun)
|
||||
}
|
||||
|
||||
private fun update()
|
||||
{
|
||||
//下一个动画加载完成,并且当前动画已经播放完了 (刚开始的时候当前动画初始化为播放完成)
|
||||
if(isLoadFinished && isMotionFinished)
|
||||
{
|
||||
//切换到加载完成的动画
|
||||
isMotionFinished = false
|
||||
ChangeMotion(motionQueue[_motionIndex], animationFinishedFun, false)
|
||||
|
||||
isLoadFinished = false
|
||||
|
||||
//如果还有动画,则开始预先加载
|
||||
if(_motionIndex + 1 < motionQueue.size)
|
||||
{
|
||||
_motionIndex += 1
|
||||
PreLoadAction(motionQueue[_motionIndex], loadFinishedFun)
|
||||
}
|
||||
|
||||
}
|
||||
// //下一个动画加载完成,并且当前动画已经播放完了 (刚开始的时候当前动画初始化为播放完成)
|
||||
// if(isLoadFinished && isMotionFinished)
|
||||
// {
|
||||
// //切换到加载完成的动画
|
||||
// isMotionFinished = false
|
||||
// ChangeMotion(motionQueue[_motionIndex], animationFinishedFun, false)
|
||||
//
|
||||
// isLoadFinished = false
|
||||
//
|
||||
// //如果还有动画,则开始预先加载
|
||||
// if(_motionIndex + 1 < motionQueue.size)
|
||||
// {
|
||||
// _motionIndex += 1
|
||||
// PreLoadAction(motionQueue[_motionIndex], loadFinishedFun)
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -120,12 +107,8 @@ class MakeupActivity : FaceActivity()
|
||||
}
|
||||
|
||||
|
||||
private fun getMotionByName(m: String): Motion {
|
||||
val motion = Motion().apply {
|
||||
type = m
|
||||
png_names = pngFilesByFolder?.get(m)?.fileList
|
||||
}
|
||||
return motion
|
||||
private fun getMotionByName(m: String): Motion? {
|
||||
return existMotions?.get(m);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,20 +116,14 @@ class MakeupActivity : FaceActivity()
|
||||
override fun onTouchEvent(event: MotionEvent): Boolean {
|
||||
when (event.action) {
|
||||
MotionEvent.ACTION_UP -> {
|
||||
val motions: List<String> = listOf("4", "11", "13")
|
||||
PlayMotionQueue(motions)
|
||||
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
private inner class FolderInfo(
|
||||
val folderName: String,
|
||||
val fileList: List<String>
|
||||
)
|
||||
|
||||
private fun readPngFilenamesFromAssets(context: Context, filename: String): Map<String,FolderInfo> {
|
||||
val folderMap = mutableMapOf<String, FolderInfo>()
|
||||
private fun readMotionsFromAssets(context: Context, filename: String): Map<String,Motion> {
|
||||
val motionMap = mutableMapOf<String, Motion>()
|
||||
|
||||
try {
|
||||
context.assets.open(filename).use { inputStream ->
|
||||
@@ -158,30 +135,32 @@ class MakeupActivity : FaceActivity()
|
||||
}
|
||||
|
||||
val jsonObject = JSONObject(stringBuilder.toString())
|
||||
val folderIterator = jsonObject.keys()
|
||||
// 遍历JSON对象
|
||||
val keys = jsonObject.keys()
|
||||
while (keys.hasNext()) {
|
||||
val key = keys.next() // 获取键,即"Motion"的名字
|
||||
val motionObject = jsonObject.getJSONObject(key)
|
||||
|
||||
while (folderIterator.hasNext()) {
|
||||
val folderName = folderIterator.next()
|
||||
val fileArray = jsonObject.getJSONArray(folderName)
|
||||
val filesInFolder = mutableListOf<String>()
|
||||
|
||||
for (i in 0 until fileArray.length()) {
|
||||
filesInFolder.add(fileArray.getString(i))
|
||||
val frameList = mutableListOf<Frame>()
|
||||
val fileKeys = motionObject.keys()
|
||||
while (fileKeys.hasNext()) {
|
||||
val fileKey = fileKeys.next() // 获取每个文件名
|
||||
val fileObject = motionObject.getJSONObject(fileKey)
|
||||
val x = fileObject.getDouble("x").toFloat()
|
||||
val y = fileObject.getDouble("y").toFloat()
|
||||
frameList.add(Frame(fileKey, x, y))
|
||||
}
|
||||
|
||||
folderMap[folderName] = (FolderInfo(folderName, filesInFolder))
|
||||
motionMap[key] = Motion(key, frameList)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
return folderMap
|
||||
return motionMap
|
||||
}
|
||||
|
||||
private var pngFilesByFolder: Map<String, FolderInfo>? = null
|
||||
private fun FaceInit(context: Context) {
|
||||
pngFilesByFolder = readPngFilenamesFromAssets(context, "pic/motion_data.json")
|
||||
}
|
||||
}
|
||||
+4
-7
@@ -1370,7 +1370,7 @@ void FaceApp::drawFrame(long long frameTime)
|
||||
// changeMotion(motion);
|
||||
//}
|
||||
|
||||
string FaceApp::preLoadMotionList(const vector<string>& motions, Callback callback)
|
||||
string FaceApp::preLoadMotionList(string motion_list_str, Callback callback)
|
||||
{
|
||||
if (_isLoadMotion)
|
||||
{
|
||||
@@ -1379,12 +1379,9 @@ string FaceApp::preLoadMotionList(const vector<string>& motions, Callback callba
|
||||
_isLoadMotion = true;
|
||||
_callback_loadfinish = callback;
|
||||
_preLoadMotions.clear();
|
||||
for (auto s : motions)
|
||||
{
|
||||
json j = json::parse(s);
|
||||
Motion motion = j.get<Motion>();
|
||||
_preLoadMotions.push_back(motion);
|
||||
}
|
||||
json j = json::parse(motion_list_str);
|
||||
MotionList motion_list = j.get<MotionList>();
|
||||
_preLoadMotions = motion_list.motions;
|
||||
worker_ = std::thread(&FaceApp::loadMotionThread, this);
|
||||
return "ok";
|
||||
}
|
||||
|
||||
+7
-1
@@ -28,6 +28,12 @@ struct Motion {
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, name, frames)
|
||||
};
|
||||
|
||||
struct MotionList
|
||||
{
|
||||
vector<Motion> motions;
|
||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(MotionList, motions)
|
||||
};
|
||||
|
||||
struct InitArg
|
||||
{
|
||||
int action_fps;
|
||||
@@ -152,7 +158,7 @@ public:
|
||||
Callback _callback_loadfinish;
|
||||
AnimationFinishedCallback _animationFinishedCallback;
|
||||
bool _animationLoop = true;
|
||||
string preLoadMotionList(const vector<string>& motions, Callback callback);
|
||||
string preLoadMotionList(string motion_list_str, Callback callback);
|
||||
vector<Motion>_preLoadMotions;
|
||||
vector<Motion>_curMotions;
|
||||
void changeMotionList(AnimationFinishedCallback callback, bool loop);
|
||||
|
||||
+5
-4
@@ -140,11 +140,12 @@ int main() {
|
||||
std::cout << "Warning: Empty motion string" << std::endl;
|
||||
}
|
||||
|
||||
vector<string> s_motions;
|
||||
json j = motions["4"];
|
||||
s_motions.push_back(j.dump());
|
||||
MotionList s_motions;
|
||||
s_motions.motions.push_back(motions["4"]);
|
||||
json j = s_motions;
|
||||
auto s = j.dump();
|
||||
|
||||
app.preLoadMotionList(s_motions, CppCallback);
|
||||
app.preLoadMotionList(s, CppCallback);
|
||||
app.mainLoop();
|
||||
//try {
|
||||
// app.mainLoop();
|
||||
|
||||
Reference in New Issue
Block a user