Search in sources :

Example 1 with MeshAnimationData

use of org.terasology.engine.rendering.assets.animation.MeshAnimationData in project Terasology by MovingBlocks.

the class GLTFAnimationFormat method load.

@Override
public MeshAnimationBundleData load(ResourceUrn urn, List<AssetDataFile> inputs) throws IOException {
    try (Reader in = new InputStreamReader(inputs.get(0).openStream())) {
        GLTF gltf = gson.fromJson(in, GLTF.class);
        checkVersionSupported(urn, gltf);
        List<byte[]> loadedBuffers = loadBinaryBuffers(urn, gltf);
        if (gltf.getSkins().isEmpty()) {
            throw new IOException("Skeletal mesh '" + urn + "' missing skin");
        }
        GLTFSkin skin = gltf.getSkins().get(0);
        List<String> boneNames = Lists.newArrayList();
        TIntList boneParents = new TIntArrayList();
        TIntIntMap nodeToJoint = new TIntIntHashMap();
        for (int i = 0; i < skin.getJoints().size(); i++) {
            nodeToJoint.put(skin.getJoints().get(i), i);
        }
        List<Bone> bones = loadBones(gltf, skin, loadedBuffers);
        bones.forEach(x -> boneNames.add(x.getName()));
        bones.forEach(x -> {
            if (x.getParentIndex() != -1) {
                boneParents.add(x.getParentIndex());
            } else {
                boneParents.add(MeshAnimationData.NO_PARENT);
            }
        });
        Map<ResourceUrn, MeshAnimationData> animations = new HashMap<>();
        for (int index = 0; index < gltf.getAnimations().size(); ++index) {
            GLTFAnimation gltfAnimation = gltf.getAnimations().get(index);
            String name = gltfAnimation.getName();
            if (Strings.isNullOrEmpty(name)) {
                name = "anim_" + index;
            }
            animations.put(new ResourceUrn(urn, name), loadAnimation(gltf, gltfAnimation, loadedBuffers, nodeToJoint, boneNames, boneParents, bones));
        }
        return new MeshAnimationBundleData(animations);
    }
}
Also used : InputStreamReader(java.io.InputStreamReader) HashMap(java.util.HashMap) TIntIntHashMap(gnu.trove.map.hash.TIntIntHashMap) Reader(java.io.Reader) InputStreamReader(java.io.InputStreamReader) MeshAnimationBundleData(org.terasology.engine.rendering.assets.animation.MeshAnimationBundleData) IOException(java.io.IOException) TIntArrayList(gnu.trove.list.array.TIntArrayList) TIntIntMap(gnu.trove.map.TIntIntMap) GLTFSkin(org.terasology.engine.rendering.gltf.model.GLTFSkin) GLTF(org.terasology.engine.rendering.gltf.model.GLTF) MeshAnimationData(org.terasology.engine.rendering.assets.animation.MeshAnimationData) Bone(org.terasology.engine.rendering.assets.skeletalmesh.Bone) TIntList(gnu.trove.list.TIntList) TIntIntHashMap(gnu.trove.map.hash.TIntIntHashMap) ResourceUrn(org.terasology.gestalt.assets.ResourceUrn) GLTFAnimation(org.terasology.engine.rendering.gltf.model.GLTFAnimation)

Example 2 with MeshAnimationData

use of org.terasology.engine.rendering.assets.animation.MeshAnimationData in project Terasology by MovingBlocks.

the class GLTFAnimationFormat method loadAnimation.

private MeshAnimationData loadAnimation(GLTF gltf, GLTFAnimation animation, List<byte[]> loadedBuffers, TIntIntMap boneIndexMapping, List<String> boneNames, TIntList boneParents, List<Bone> bones) throws IOException {
    List<ChannelReader> channelReaders = new ArrayList<>();
    for (GLTFChannel channel : animation.getChannels()) {
        GLTFAnimationSampler sampler = animation.getSamplers().get(channel.getSampler());
        TFloatList times = getFloats(gltf, loadedBuffers, sampler.getInput());
        int bone = boneIndexMapping.get(channel.getTarget().getNode());
        switch(channel.getTarget().getPath()) {
            case TRANSLATION:
                {
                    List<Vector3f> data = getVector3fs(gltf, loadedBuffers, sampler.getOutput());
                    channelReaders.add(new BufferChannelReader<>(times, data, sampler.getInterpolation()::interpolate, x -> x.getPosition(bone)));
                    break;
                }
            case ROTATION:
                {
                    List<Quaternionf> data = getQuat4fs(gltf, loadedBuffers, sampler.getOutput());
                    channelReaders.add(new BufferChannelReader<>(times, data, sampler.getInterpolation()::interpolate, x -> x.getRotation(bone)));
                    break;
                }
            case SCALE:
                {
                    List<Vector3f> data = getVector3fs(gltf, loadedBuffers, sampler.getOutput());
                    channelReaders.add(new BufferChannelReader<>(times, data, sampler.getInterpolation()::interpolate, x -> x.getBoneScale(bone)));
                    break;
                }
            default:
                break;
        }
    }
    int frameCount = (int) (channelReaders.stream().map(ChannelReader::endTime).reduce(Float::max).orElse(0f) / TIME_PER_FRAME) + 1;
    List<MeshAnimationFrame> frames = new ArrayList<>(frameCount);
    for (int i = 0; i < frameCount; i++) {
        float time = i * TIME_PER_FRAME;
        List<Vector3f> boneLocations = new ArrayList<>();
        List<Quaternionf> boneRotations = new ArrayList<>();
        List<Vector3f> boneScales = new ArrayList<>();
        for (Bone bone : bones) {
            boneLocations.add(new Vector3f(bone.getLocalPosition()));
            boneRotations.add(new Quaternionf(bone.getLocalRotation()));
            boneScales.add(new Vector3f(bone.getLocalScale()));
        }
        MeshAnimationFrame frame = new MeshAnimationFrame(boneLocations, boneRotations, boneScales);
        channelReaders.forEach(x -> x.updateFrame(time, frame));
        frames.add(frame);
    }
    return new MeshAnimationData(boneNames, boneParents, frames, TIME_PER_FRAME, new AABBf(0, 0, 0));
}
Also used : GLTFAnimationSampler(org.terasology.engine.rendering.gltf.model.GLTFAnimationSampler) MeshAnimationFrame(org.terasology.engine.rendering.assets.animation.MeshAnimationFrame) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) TFloatArrayList(gnu.trove.list.array.TFloatArrayList) TFloatList(gnu.trove.list.TFloatList) GLTFChannel(org.terasology.engine.rendering.gltf.model.GLTFChannel) Quaternionf(org.joml.Quaternionf) AABBf(org.terasology.joml.geom.AABBf) Vector3f(org.joml.Vector3f) MeshAnimationData(org.terasology.engine.rendering.assets.animation.MeshAnimationData) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) TFloatList(gnu.trove.list.TFloatList) TIntList(gnu.trove.list.TIntList) TFloatArrayList(gnu.trove.list.array.TFloatArrayList) List(java.util.List) Bone(org.terasology.engine.rendering.assets.skeletalmesh.Bone)

Aggregations

TIntList (gnu.trove.list.TIntList)2 TIntArrayList (gnu.trove.list.array.TIntArrayList)2 MeshAnimationData (org.terasology.engine.rendering.assets.animation.MeshAnimationData)2 Bone (org.terasology.engine.rendering.assets.skeletalmesh.Bone)2 TFloatList (gnu.trove.list.TFloatList)1 TFloatArrayList (gnu.trove.list.array.TFloatArrayList)1 TIntIntMap (gnu.trove.map.TIntIntMap)1 TIntIntHashMap (gnu.trove.map.hash.TIntIntHashMap)1 IOException (java.io.IOException)1 InputStreamReader (java.io.InputStreamReader)1 Reader (java.io.Reader)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Quaternionf (org.joml.Quaternionf)1 Vector3f (org.joml.Vector3f)1 MeshAnimationBundleData (org.terasology.engine.rendering.assets.animation.MeshAnimationBundleData)1 MeshAnimationFrame (org.terasology.engine.rendering.assets.animation.MeshAnimationFrame)1 GLTF (org.terasology.engine.rendering.gltf.model.GLTF)1 GLTFAnimation (org.terasology.engine.rendering.gltf.model.GLTFAnimation)1