Playcanvas动画格式解析

Playcanvas是一款开源的3d引擎,底层格式是自家定义的json格式,其文档说明如下:

https://developer.playcanvas.com/en/user-manual/graphics/file-format/

但是在官网翻不到其动画文件的解析代码,这里根据其引擎源码的解析,对其源码文件格式解析如下记录

{
    "animation":{
        // 动画时长
        "duration": 0.2,
        "nodes":[
            {
                // key.t 动画对应的时间节点
                // key.p 该时间节点对应的translations
                // key.r 该时间节点对应的rotations
                // key.s 该时间节点对应的scale
                "keys":[
                    {"p":[0,0,0],"s":[1,1,1],"r":[0,0,0],"t":0}
                ],
                //节点名称
                "name": "RootNode",
                // 一般为空,当keys为null时,取default作为keys的值
                "default": {}
            },
            {
                "keys":[
                    {"p":[0,0,0],"s":[1,1,1],"r":[0,0,0],"t":0},
                    {"p":[0.1,0,0],"s":[1,1,1],"r":[0,0,0],"t":0.1},
                    {"p":[0.1,0,0.1],"s":[1,1,1],"r":[0,0,0],"t":0.2}
                ],
                "name": "Node1",
                // 一般为空,当keys为null时,取default作为keys的值
                "default": {}
            }          
        ]
    }
}

实现playcanvas动画到gltf动画的转换(python代码示例)

animation_nodes = animation_data['nodes']
# 一般animation_nodes第一个节点为root,无需转换
animation_nodes.pop(0)
animations = []
channels = []
samplers = []
for animation_node in animation_nodes:
    # 查找node name 对应 gltf node 的 index
    node_index = self.search_node_index(animation_node['name'])
    if node_index == -1:
        continue
    current_times = []
    translations = []
    rotations = []
    scales = []
    for key in animation_node['keys']:
        current_times.append(key['t'])
 
        translations.extend(key['p'])
        rotations.extend(math_util.euler_to_quaternion(key['r']))
        scales.extend(key['s'])
     
    input_accessor = gltf_accessor_util.create_gltf_accessors(
                current_times, AccessorComponentType.FLOAT, 'SCALAR', 0
    )
 
    output_t_accessor = gltf_accessor_util.create_gltf_accessors(
                translations, AccessorComponentType.FLOAT, 'VEC3', 0
    )
    output_r_accessor = gltf_accessor_util.create_gltf_accessors(
                rotations, AccessorComponentType.FLOAT, 'VEC4', 0
    )
    output_s_accessor = gltf_accessor_util.create_gltf_accessors(
                scales, AccessorComponentType.FLOAT, 'VEC3', 0
    )
    # playcanvas每个node的p、r、s 对应 gltf三个sampler和channel
    path_accessor_relatives = dict(
        translation=output_t_accessor,
        rotation=output_r_accessor,
        scale=output_s_accessor,
    )
  
    for path, accessor in path_accessor_relatives.items():
        samplers.append(
            dict(
                input=input_accessor,
                interpolation='LINEAR',  # 默认
                output=accessor,
            )
        )
        channels.append(
            dict(
                target=dict(node=node_index, path=path),
                sampler=len(samplers) - 1,
            )
        )
if len(channels) > 0 and len(samplers) > 0:
    animation_dict['channels'] = channels
    animation_dict['samplers'] = samplers
    # 当有多段动画(多个json)时,可以在最外层添加for循环,并添加到animations
    animations.append(animation_dict)
     
if len(animations) > 0:
    self.gltf_json['animations'] = animations  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值