save code

This commit is contained in:
xsl
2025-12-19 13:47:16 +08:00
parent e38da96e37
commit 6bbbb3c3ef
8 changed files with 137 additions and 102 deletions
+4 -4
View File
@@ -165,7 +165,7 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
return JNI_VERSION_1_6; return JNI_VERSION_1_6;
} }
void CppCallback(const string& motion_type) void CppCallback()
{ {
JNIEnv* env = nullptr; JNIEnv* env = nullptr;
bool needDetach = false; bool needDetach = false;
@@ -205,7 +205,7 @@ void CppCallback(const string& motion_type)
} }
// 3. 构造 jstring 参数 // 3. 构造 jstring 参数
jstring jResult = env->NewStringUTF(motion_type.c_str()); jstring jResult = env->NewStringUTF("ok");
// 4. 调用 Java 回调 // 4. 调用 Java 回调
env->CallVoidMethod(g_callback, methodId, jResult); 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; 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()); 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()) 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;
}
}
}
+13 -16
View File
@@ -5,32 +5,29 @@ import org.json.JSONObject;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
public class Motion { public class Motion {
public String type = "no"; public String name = "no";
public List<String> png_names = new ArrayList<>(); public List<Frame> frames = new ArrayList<>();
public Motion(String name, List<Frame> frames)
{
this.name = name;
this.frames = frames;
}
public JSONObject toJsonObject() { public JSONObject toJsonObject() {
try { try {
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("type", type); jsonObject.put("name", name);
JSONArray ja = new JSONArray(); JSONObject jframes = new JSONObject();
for(int i = 0; i < png_names.size(); ++i){ for(int i = 0; i < frames.size(); ++i){
ja.put(png_names.get(i)); jframes.put(frames.get(i).name, frames.get(i).toJsonObject());
} }
jsonObject.put("png_names", ja); jsonObject.put("frames", jframes);
return jsonObject; return jsonObject;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
return null; 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 android.view.MotionEvent
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import com.hmwl.face_sdk.FaceActivity import com.hmwl.face_sdk.FaceActivity
import com.hmwl.face_sdk.Frame
import com.hmwl.face_sdk.InitArg import com.hmwl.face_sdk.InitArg
import com.hmwl.face_sdk.Motion import com.hmwl.face_sdk.Motion
import com.hmwl.face_sdk.MotionList
import kotlinx.coroutines.Job import kotlinx.coroutines.Job
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
@@ -21,18 +23,13 @@ import java.io.InputStreamReader
class MakeupActivity : FaceActivity() class MakeupActivity : FaceActivity()
{ {
var isLoadFinished: Boolean = false;
var isMotionFinished: Boolean = true;
var _motionIndex : Int = 0
var animationFinishedFun = object : AnimationFinishedCallbackInterface { var animationFinishedFun = object : AnimationFinishedCallbackInterface {
override fun OnAnimationFinished() { override fun OnAnimationFinished() {
isMotionFinished = true; Log.i("MakeupActivity", "OnAnimationFinished: ")
} }
} }
var isLoadFinished : Boolean = false
var loadFinishedFun = object : CallbackInterface { var loadFinishedFun = object : CallbackInterface {
override fun OnLoadActionFinished(motion_type: String) { override fun OnLoadActionFinished(motion_type: String) {
isLoadFinished = true; 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 updateJob: Job? = null
private var existMotions: Map<String, Motion>? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
FaceInit(this) existMotions = readMotionsFromAssets(this, "pic/motion_data_ex.json")
val initArg = InitArg().apply { val initArg = InitArg().apply {
action_fps = 10 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() private fun update()
{ {
//下一个动画加载完成,并且当前动画已经播放完了 (刚开始的时候当前动画初始化为播放完成) // //下一个动画加载完成,并且当前动画已经播放完了 (刚开始的时候当前动画初始化为播放完成)
if(isLoadFinished && isMotionFinished) // if(isLoadFinished && isMotionFinished)
{ // {
//切换到加载完成的动画 // //切换到加载完成的动画
isMotionFinished = false // isMotionFinished = false
ChangeMotion(motionQueue[_motionIndex], animationFinishedFun, false) // ChangeMotion(motionQueue[_motionIndex], animationFinishedFun, false)
//
isLoadFinished = false // isLoadFinished = false
//
//如果还有动画,则开始预先加载 // //如果还有动画,则开始预先加载
if(_motionIndex + 1 < motionQueue.size) // if(_motionIndex + 1 < motionQueue.size)
{ // {
_motionIndex += 1 // _motionIndex += 1
PreLoadAction(motionQueue[_motionIndex], loadFinishedFun) // PreLoadAction(motionQueue[_motionIndex], loadFinishedFun)
} // }
//
} // }
} }
@@ -120,12 +107,8 @@ class MakeupActivity : FaceActivity()
} }
private fun getMotionByName(m: String): Motion { private fun getMotionByName(m: String): Motion? {
val motion = Motion().apply { return existMotions?.get(m);
type = m
png_names = pngFilesByFolder?.get(m)?.fileList
}
return motion
} }
@@ -133,20 +116,14 @@ class MakeupActivity : FaceActivity()
override fun onTouchEvent(event: MotionEvent): Boolean { override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) { when (event.action) {
MotionEvent.ACTION_UP -> { MotionEvent.ACTION_UP -> {
val motions: List<String> = listOf("4", "11", "13")
PlayMotionQueue(motions)
} }
} }
return true return true
} }
private inner class FolderInfo( private fun readMotionsFromAssets(context: Context, filename: String): Map<String,Motion> {
val folderName: String, val motionMap = mutableMapOf<String, Motion>()
val fileList: List<String>
)
private fun readPngFilenamesFromAssets(context: Context, filename: String): Map<String,FolderInfo> {
val folderMap = mutableMapOf<String, FolderInfo>()
try { try {
context.assets.open(filename).use { inputStream -> context.assets.open(filename).use { inputStream ->
@@ -158,30 +135,32 @@ class MakeupActivity : FaceActivity()
} }
val jsonObject = JSONObject(stringBuilder.toString()) 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 frameList = mutableListOf<Frame>()
val folderName = folderIterator.next() val fileKeys = motionObject.keys()
val fileArray = jsonObject.getJSONArray(folderName) while (fileKeys.hasNext()) {
val filesInFolder = mutableListOf<String>() val fileKey = fileKeys.next() // 获取每个文件名
val fileObject = motionObject.getJSONObject(fileKey)
for (i in 0 until fileArray.length()) { val x = fileObject.getDouble("x").toFloat()
filesInFolder.add(fileArray.getString(i)) 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) { } catch (e: Exception) {
e.printStackTrace() 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
View File
@@ -1370,7 +1370,7 @@ void FaceApp::drawFrame(long long frameTime)
// changeMotion(motion); // changeMotion(motion);
//} //}
string FaceApp::preLoadMotionList(const vector<string>& motions, Callback callback) string FaceApp::preLoadMotionList(string motion_list_str, Callback callback)
{ {
if (_isLoadMotion) if (_isLoadMotion)
{ {
@@ -1379,12 +1379,9 @@ string FaceApp::preLoadMotionList(const vector<string>& motions, Callback callba
_isLoadMotion = true; _isLoadMotion = true;
_callback_loadfinish = callback; _callback_loadfinish = callback;
_preLoadMotions.clear(); _preLoadMotions.clear();
for (auto s : motions) json j = json::parse(motion_list_str);
{ MotionList motion_list = j.get<MotionList>();
json j = json::parse(s); _preLoadMotions = motion_list.motions;
Motion motion = j.get<Motion>();
_preLoadMotions.push_back(motion);
}
worker_ = std::thread(&FaceApp::loadMotionThread, this); worker_ = std::thread(&FaceApp::loadMotionThread, this);
return "ok"; return "ok";
} }
+7 -1
View File
@@ -28,6 +28,12 @@ struct Motion {
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, name, frames) NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, name, frames)
}; };
struct MotionList
{
vector<Motion> motions;
NLOHMANN_DEFINE_TYPE_INTRUSIVE(MotionList, motions)
};
struct InitArg struct InitArg
{ {
int action_fps; int action_fps;
@@ -152,7 +158,7 @@ public:
Callback _callback_loadfinish; Callback _callback_loadfinish;
AnimationFinishedCallback _animationFinishedCallback; AnimationFinishedCallback _animationFinishedCallback;
bool _animationLoop = true; bool _animationLoop = true;
string preLoadMotionList(const vector<string>& motions, Callback callback); string preLoadMotionList(string motion_list_str, Callback callback);
vector<Motion>_preLoadMotions; vector<Motion>_preLoadMotions;
vector<Motion>_curMotions; vector<Motion>_curMotions;
void changeMotionList(AnimationFinishedCallback callback, bool loop); void changeMotionList(AnimationFinishedCallback callback, bool loop);
+5 -4
View File
@@ -140,11 +140,12 @@ int main() {
std::cout << "Warning: Empty motion string" << std::endl; std::cout << "Warning: Empty motion string" << std::endl;
} }
vector<string> s_motions; MotionList s_motions;
json j = motions["4"]; s_motions.motions.push_back(motions["4"]);
s_motions.push_back(j.dump()); json j = s_motions;
auto s = j.dump();
app.preLoadMotionList(s_motions, CppCallback); app.preLoadMotionList(s, CppCallback);
app.mainLoop(); app.mainLoop();
//try { //try {
// app.mainLoop(); // app.mainLoop();