# Copyright 2020 The dm_control Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ============================================================================ """Utilities for parsing and writing MuJoCo skin files. The file format is described at http://mujoco.org/book/XMLreference.html#skin. """ import collections import io import struct import numpy as np MAX_BODY_NAME_LENGTH = 40 Skin = collections.namedtuple( 'Skin', ('vertices', 'texcoords', 'faces', 'bones')) Bone = collections.namedtuple( 'Bone', ('body', 'bindpos', 'bindquat', 'vertex_ids', 'vertex_weights')) def parse(contents, body_getter): """Parses the contents of a MuJoCo skin file. Args: contents: a bytes-like object containing the contents of a skin file. body_getter: a callable that takes a string and returns the `mjcf.Element` instance of a MuJoCo body of the specified name. Returns: A `Skin` named tuple. """ f = io.BytesIO(contents) nvertex, ntexcoord, nface, nbone = struct.unpack(' MAX_BODY_NAME_LENGTH: raise ValueError( 'body name is longer than permitted by the skin file format ' '(maximum 40): {:r}'.format(body_bytes)) out.write(body_bytes) out.write(b'\0'*(MAX_BODY_NAME_LENGTH - len(body_bytes))) out.write(bone.bindpos.astype('