Java动态递归解析任意层复杂Json,并编写BVH文件

tech2026-06-19  7

Java动态递归解析复杂Json,并编写BVH文件

前言代码部分运行结果 完结

前言

遇到一个需求,我们公司目前在做动作捕捉的项目,动作捕捉有个功能要输出一个BVH类型的文件(至于是什么类型文件我就不多解释了,有兴趣的可以查一下),因为没有生成BVH文件相关的库,所以我用Java语言写了一个(代码写的垃圾,我就提个思路,轻点喷我=.=)。

代码部分

我用的是fastjson

import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject;

json的字符串是复杂的多层嵌套json,json嵌套json对象/json数组多层嵌套。撇去写入buffer的部分,可以用来解析复杂多层json。

private static StringBuffer buf;//全局buffer字符缓存 private static int num = 0;//计数 public static void main(String[] args) { String str = "{\"control\":\"BVHControl\",\"type\":\"1\",\"action\":\"start\",\"children\":{\"name\":\"crotch\",\"offset\":[0,0,0],\"children\":[{\"name\":\"back\",\"offset\":[0,2,0],\"children\":[{\"name\":\"head\",\"offset\":[0,1,0]},{\"name\":\"leftShoulder\",\"offset\":[-1,1,0],\"children\":[{\"name\":\"leftUpperArm\",\"offset\":[-1,0,0],\"children\":[{\"name\":\"leftLowerArm\",\"offset\":[-1,0,0],\"children\":[{\"name\":\"leftHand\",\"offset\":[-1,0,0]}]}]}]},{\"name\":\"rightShoulder\",\"offset\":[1,1,0],\"children\":[{\"name\":\"rightUpperArm\",\"offset\":[1,0,0],\"children\":[{\"name\":\"rightLowerArm\",\"offset\":[1,0,0],\"children\":[{\"name\":\"rightHand\",\"offset\":[1,0,0]}]}]}]}]},{\"name\":\"leftUpperLeg\",\"offset\":[-1,-1.5,0],\"children\":[{\"name\":\"leftLowerLeg\",\"offset\":[0,-1.2,0],\"children\":[{\"name\":\"leftFoot\",\"offset\":[0,0,0.3]}]}]},{\"name\":\"rightUpperLeg\",\"offset\":[1,-1.5,0],\"children\":[{\"name\":\"rightLowerLeg\",\"offset\":[0,-1.2,0],\"children\":[{\"name\":\"rightFoot\",\"offset\":[0,0,0.3]}]}]}]}}"; buf = new StringBuffer();//初始化buffer buf.append("HIERARCHY\n");//写文件头 JSONObject jsonObject = JSONObject.parseObject(str);//转换json字符串 jsonJX(jsonObject);//调用json解析方法 System.out.println(buf); } //解析json并写入buffer缓冲的核心方法 public static void jsonJX(JSONObject jsonObject) { String children = jsonObject.getString("children");//获取节点数据 num++;//统计方法调用次数,为了算缩进距离和{}位置 if (children.substring(0,1).equals("{") && children.substring(children.length()-1).equals("}")){//通过判断字符串的括号,转jsonObject JSONObject json = JSON.parseObject(children);//获取子节点数据 buf.append("ROOT ").append(json.getString("name")).append("\n");//拼接根节点名称 buf.append("{\n"); buf.append(strPloidy(num)).append("OFFSET").append(strAddTab(json.getJSONArray("offset"))).append("\n");//拼接offset偏移量 buf.append(strPloidy(num)).append("CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation\n"); if (json.containsKey("children")){//判断是否还有子节点 jsonJX(json);//有子节点,递归调用方法继续解析 } buf.append(strPloidy(num)).append("}\n"); }else if (children.substring(0,1).equals("[") && children.substring(children.length()-1).equals("]")){//通过判断字符串的括号,转jsonArray JSONArray arrJson = JSON.parseArray(children);//获取子节点array数据 for (int i=0;i<arrJson.size();i++) {//循环节点数组 JSONObject newJson = JSON.parseObject(arrJson.get(i).toString());//将节点数据转成json对象 buf.append(strPloidy(num-1)).append("JOINT ").append(newJson.getString("name")).append("\n");//拼接子节点名称 buf.append(strPloidy(num)).append("{\n"); buf.append(strPloidy(num)).append("OFFSET").append(strAddTab(newJson.getJSONArray("offset"))).append("\n");//拼接子节点offset偏移量 buf.append(strPloidy(num)).append("CHANNELS 3 Zrotation Yrotation Xrotation\n"); if (newJson.containsKey("children")){//判断是否还有子节点 jsonJX(newJson);//有子节点,递归调用方法继续解析 } buf.append(strPloidy(num)).append("}\n"); } } num=num-1;//计算}缩进位置 } //添加缩进方法,参数num:缩进次数 private static String strPloidy(int num) { String str = " "; for (int i = 1; i < num; i++) { str += " "; } return str; } //解析offset偏移量数组方法,在每个元素中间添加空格 private static String strAddTab(JSONArray json) { String str = ""; for (int i = 0; i < json.size(); i++) { str += " " + json.get(i); } return str; }

运行结果

这是运行后的打印结果:

HIERARCHY ROOT crotch { OFFSET 0 0 0 CHANNELS 6 Xposition Yposition Zposition Zrotation Yrotation Xrotation JOINT back { OFFSET 0 2 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT head { OFFSET 0 1 0 CHANNELS 3 Zrotation Yrotation Xrotation } JOINT leftShoulder { OFFSET -1 1 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT leftUpperArm { OFFSET -1 0 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT leftLowerArm { OFFSET -1 0 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT leftHand { OFFSET -1 0 0 CHANNELS 3 Zrotation Yrotation Xrotation } } } } JOINT rightShoulder { OFFSET 1 1 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT rightUpperArm { OFFSET 1 0 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT rightLowerArm { OFFSET 1 0 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT rightHand { OFFSET 1 0 0 CHANNELS 3 Zrotation Yrotation Xrotation } } } } } JOINT leftUpperLeg { OFFSET -1 -1.5 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT leftLowerLeg { OFFSET 0 -1.2 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT leftFoot { OFFSET 0 0 0.3 CHANNELS 3 Zrotation Yrotation Xrotation } } } JOINT rightUpperLeg { OFFSET 1 -1.5 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT rightLowerLeg { OFFSET 0 -1.2 0 CHANNELS 3 Zrotation Yrotation Xrotation JOINT rightFoot { OFFSET 0 0 0.3 CHANNELS 3 Zrotation Yrotation Xrotation } } } }

完结

我只贴出了核心部分,编写BVH文件有骨骼数据的部分,添加动作数据这个方法中没有,也就给大家个思路,希望有用。

代码写的烂,别喷我[狗头]。我果然是个辣鸡,哈哈哈哈。

最新回复(0)