Example usage for com.badlogic.gdx.graphics.g3d.model.skeleton SkeletonSubMesh SkeletonSubMesh

List of usage examples for com.badlogic.gdx.graphics.g3d.model.skeleton SkeletonSubMesh SkeletonSubMesh

Introduction

In this page you can find the example usage for com.badlogic.gdx.graphics.g3d.model.skeleton SkeletonSubMesh SkeletonSubMesh.

Prototype

public SkeletonSubMesh(String name, Mesh mesh, int primitiveType) 

Source Link

Usage

From source file:com.xoppa.android.loaders.model.g3d.G3dxLoader.java

License:Apache License

public static SkeletonModel loadSkeletonModel(FileHandle handle) {
    Chunk root = null;/*from w  w  w  . j  a  v a2  s. c  o m*/
    InputStream in = null;
    try {
        in = handle.read();
        root = ChunkReader.readChunks(in);

        // check root tag
        if (root.getId() != G3dConstants.G3D_ROOT)
            throw new GdxRuntimeException("Invalid root tag id: " + root.getId());

        // check version
        Chunk version = root.getChild(G3dConstants.VERSION_INFO);
        if (version == null)
            throw new GdxRuntimeException("No version chunk found");
        int major = version.readByte();
        int minor = version.readByte();
        if (major != 0 || minor != 1)
            throw new GdxRuntimeException("Invalid version, required 0.1, got " + major + "." + minor);

        // read skeleton model
        Chunk skeletonModel = root.getChild(G3dConstants.SKELETON_MODEL);
        if (skeletonModel == null)
            throw new GdxRuntimeException("No skeletonModel chunk found");
        int numSubMeshes = skeletonModel.readInt();

        // read submeshes
        SkeletonSubMesh[] meshes = new SkeletonSubMesh[numSubMeshes];
        Chunk[] meshChunks = skeletonModel.getChildren(G3dConstants.SKELETON_SUBMESH);
        if (meshChunks.length != numSubMeshes)
            throw new GdxRuntimeException(
                    "Number of submeshes not equal to number specified in still model chunk, expected "
                            + numSubMeshes + ", got " + meshChunks.length);
        for (int i = 0; i < numSubMeshes; i++) {
            Chunk subMeshChunk = meshChunks[i];

            // read attributes
            Chunk attributes = subMeshChunk.getChild(G3dConstants.VERTEX_ATTRIBUTES);
            if (attributes == null)
                throw new GdxRuntimeException("No vertex attribute chunk given");
            int numAttributes = attributes.readInt();
            Chunk[] attributeChunks = attributes.getChildren(G3dConstants.VERTEX_ATTRIBUTE);
            if (attributeChunks.length != numAttributes)
                new GdxRuntimeException(
                        "Number of attributes not equal to number specified in attributes chunk, expected "
                                + numAttributes + ", got " + attributeChunks.length);
            VertexAttribute[] vertAttribs = new VertexAttribute[numAttributes];
            for (int j = 0; j < numAttributes; j++) {
                vertAttribs[j] = new VertexAttribute(attributeChunks[j].readInt(), attributeChunks[j].readInt(),
                        attributeChunks[j].readString());
            }

            // read static components, sort of like a bind pose mesh
            Chunk vertices = subMeshChunk.getChild(G3dConstants.VERTEX_LIST);
            int numVertices = vertices.readInt();
            float[] meshVertices = vertices.readFloats();

            // read indices
            Chunk indices = subMeshChunk.getChild(G3dConstants.INDEX_LIST);
            int numIndices = indices.readInt();
            short[] meshIndices = indices.readShorts();

            //read bone weight
            Chunk boneWeights = subMeshChunk.getChild(G3dConstants.BONE_WEIGHTS);
            int numBonesWeights = boneWeights.readInt();
            Chunk[] boneWeightChunks = boneWeights.getChildren(G3dConstants.BONE_WEIGHT);
            if (attributeChunks.length != numAttributes)
                new GdxRuntimeException(
                        "Number of bone weights not equal to number specified in bone weights chunk, expected "
                                + numBonesWeights + ", got " + boneWeightChunks.length);
            float[][] meshBoneWeights = new float[numBonesWeights][];
            for (int j = 0; j < numBonesWeights; j++) {
                int count = boneWeightChunks[j].readInt();
                meshBoneWeights[j] = boneWeightChunks[j].readFloats();
            }

            //read bone assignment
            Chunk boneAssignments = subMeshChunk.getChild(G3dConstants.BONE_ASSIGNMENTS);
            int numBoneAssignments = boneAssignments.readInt();
            Chunk[] boneAssignmentChunks = boneAssignments.getChildren(G3dConstants.BONE_ASSIGNMENT);
            if (boneAssignmentChunks.length != numBoneAssignments)
                new GdxRuntimeException(
                        "Number of bone assignment not equal to number specified in bone assignment chunk, expected "
                                + numBoneAssignments + ", got " + boneAssignmentChunks.length);
            int[][] meshBoneAssignments = new int[numBoneAssignments][];
            for (int j = 0; j < numBoneAssignments; j++) {
                int count = boneAssignmentChunks[j].readInt();
                meshBoneAssignments[j] = boneAssignmentChunks[j].readInts();
            }

            SkeletonSubMesh subMesh = new SkeletonSubMesh(subMeshChunk.readString(),
                    new Mesh(false, numVertices, numIndices, vertAttribs), subMeshChunk.readInt());

            subMesh.indices = meshIndices;
            subMesh.boneAssignments = meshBoneAssignments;
            subMesh.boneWeights = meshBoneWeights;
            subMesh.vertices = meshVertices;

            subMesh.mesh.setVertices(subMesh.vertices);
            subMesh.mesh.setIndices(subMesh.indices);
            subMesh.skinnedVertices = new float[subMesh.vertices.length];
            System.arraycopy(subMesh.vertices, 0, subMesh.skinnedVertices, 0, subMesh.vertices.length);
            meshes[i] = subMesh;
        }

        //read Skeleton hierarchy
        Skeleton skeleton = new Skeleton();
        Chunk skeletonChunk = skeletonModel.getChild(G3dConstants.SKELETON);
        {
            // read Skeleton hierarchy
            Chunk hierarchy = skeletonChunk.getChild(G3dConstants.SKELETON_HIERARCHY);
            int numHierarchyJoints = hierarchy.readInt();
            for (int i = 0; i < numHierarchyJoints; i++) {
                skeleton.hierarchy.add(readSkeletonJoint(hierarchy));
            }

            // read Skeleton animations
            Chunk animations = skeletonChunk.getChild(G3dConstants.SKELETON_ANIMATIONS);
            int numAnimations = animations.readInt();
            Chunk[] animationChunks = animations.getChildren(G3dConstants.SKELETON_ANIMATION);
            if (animationChunks.length != numAnimations)
                new GdxRuntimeException(
                        "Number of animations not equal to number specified in animations chunk, expected "
                                + numAnimations + ", got " + animationChunks.length);
            for (int i = 0; i < numAnimations; i++) {
                Chunk animation = animationChunks[i];

                String name = animation.readString();
                float totalDuration = animation.readFloat();

                int numJoints = animation.readInt();
                SkeletonKeyframe perJointKeyFrames[][] = new SkeletonKeyframe[numJoints][];
                for (int j = 0; j < numJoints; j++) {
                    int numFrames = animation.readInt();
                    perJointKeyFrames[j] = new SkeletonKeyframe[numFrames];

                    for (int k = 0; k < numFrames; k++) {
                        SkeletonKeyframe frame = new SkeletonKeyframe();

                        frame.timeStamp = animation.readFloat();
                        frame.parentIndex = animation.readInt();
                        frame.position.x = animation.readFloat();
                        frame.position.y = animation.readFloat();
                        frame.position.z = animation.readFloat();
                        frame.rotation.w = animation.readFloat();
                        frame.rotation.x = animation.readFloat();
                        frame.rotation.y = animation.readFloat();
                        frame.rotation.z = animation.readFloat();
                        frame.scale.x = animation.readFloat();
                        frame.scale.y = animation.readFloat();
                        frame.scale.z = animation.readFloat();
                        perJointKeyFrames[j][k] = frame;
                    }
                }

                skeleton.animations.put(name, new SkeletonAnimation(name, totalDuration, perJointKeyFrames));
            }
        }
        skeleton.buildFromHierarchy();

        SkeletonModel model = new SkeletonModel(skeleton, meshes);
        model.setMaterial(new Material("default"));
        return model;
    } catch (IOException e) {
        throw new GdxRuntimeException(
                "Couldn't load skeleton model from '" + handle.name() + "', " + e.getMessage(), e);
    } finally {
        if (in != null)
            try {
                in.close();
            } catch (IOException e) {
            }
    }
}