Search in sources :

Example 1 with Bone

use of org.terasology.rendering.assets.skeletalmesh.Bone in project Terasology by MovingBlocks.

the class MD5SkeletonLoader method load.

@Override
public SkeletalMeshData load(ResourceUrn urn, List<AssetDataFile> inputs) throws IOException {
    try (InputStream stream = inputs.get(0).openStream()) {
        MD5 md5 = parse(stream);
        SkeletalMeshDataBuilder skeletonBuilder = new SkeletalMeshDataBuilder();
        List<Bone> bones = Lists.newArrayListWithCapacity(md5.numJoints);
        for (int i = 0; i < md5.numJoints; ++i) {
            MD5Joint joint = md5.joints[i];
            Bone bone = new Bone(i, joint.name, joint.position, joint.orientation);
            bones.add(bone);
            if (joint.parent != -1) {
                bones.get(joint.parent).addChild(bone);
            }
            skeletonBuilder.addBone(bone);
        }
        if (md5.meshes.length > 0) {
            // TODO: Support multiple mesh somehow?
            MD5Mesh mesh = md5.meshes[0];
            for (MD5Weight weight : mesh.weightList) {
                skeletonBuilder.addWeight(new BoneWeight(weight.position, weight.bias, weight.jointIndex));
            }
            List<Vector2f> uvs = Lists.newArrayList();
            TIntList vertexStartWeight = new TIntArrayList(mesh.numVertices);
            TIntList vertexWeightCount = new TIntArrayList(mesh.numVertices);
            for (MD5Vertex vert : mesh.vertexList) {
                uvs.add(vert.uv);
                vertexStartWeight.add(vert.startWeight);
                vertexWeightCount.add(vert.countWeight);
            }
            skeletonBuilder.setVertexWeights(vertexStartWeight, vertexWeightCount);
            skeletonBuilder.setUvs(uvs);
            TIntList indices = new TIntArrayList(mesh.indexList.length);
            for (int i = 0; i < mesh.numTriangles; ++i) {
                indices.add(mesh.indexList[i * 3]);
                indices.add(mesh.indexList[i * 3 + 2]);
                indices.add(mesh.indexList[i * 3 + 1]);
            }
            skeletonBuilder.setIndices(indices);
        }
        return skeletonBuilder.build();
    } catch (NumberFormatException e) {
        throw new IOException("Error parsing " + inputs.get(0).getFilename(), e);
    }
}
Also used : InputStream(java.io.InputStream) IOException(java.io.IOException) TIntArrayList(gnu.trove.list.array.TIntArrayList) BoneWeight(org.terasology.rendering.assets.skeletalmesh.BoneWeight) SkeletalMeshDataBuilder(org.terasology.rendering.assets.skeletalmesh.SkeletalMeshDataBuilder) Vector2f(org.terasology.math.geom.Vector2f) Bone(org.terasology.rendering.assets.skeletalmesh.Bone) TIntList(gnu.trove.list.TIntList)

Example 2 with Bone

use of org.terasology.rendering.assets.skeletalmesh.Bone in project Terasology by MovingBlocks.

the class ColladaLoader method parseSkeletalMeshData.

protected void parseSkeletalMeshData(Element rootElement) throws ColladaParseException {
    List<MD5Joint> md5JointList = new ArrayList<>();
    List<MD5Mesh> md5MeshList = new ArrayList<>();
    skeletonBuilder = new SkeletalMeshDataBuilder();
    // TODO: we need a better way to construct the parent/child nodes, especially for the non-joint nodes
    // MAYBE we can construct all of the nodes up-front, and then fill in the missing data for the ones of type JOINT later
    // And only keep the MD5 nodes in the final list if they are used?
    Map<String, MD5Joint> md5JointBySidMap = new HashMap<>();
    MD5Joint parentMD5Joint = null;
    ElementSet nodeParentSet = rootElement.find("library_visual_scenes", "visual_scene", "node");
    for (Element element : nodeParentSet) {
        createMd5JointForElementAndParent(md5JointBySidMap, element, parentMD5Joint);
    }
    ElementSet controllerSet = rootElement.find("library_controllers", "controller");
    for (Element controller : controllerSet) {
        ElementSet skinSet = controller.find("skin");
        if (1 != skinSet.size()) {
            throw new ColladaParseException("Found " + skinSet.size() + " skin sets for controller id=" + controller.id() + " name=" + controller.name());
        }
        Element skin = skinSet.first();
        ElementSet jointsSet = skin.find("joints");
        if (1 != jointsSet.size()) {
            throw new ColladaParseException("Found " + jointsSet.size() + " joints sets for controller id=" + controller.id() + " name=" + controller.name());
        }
        Element joints = jointsSet.first();
        ElementSet vertexWeightsSet = skin.find("vertex_weights");
        if (1 != vertexWeightsSet.size()) {
            throw new ColladaParseException("Found " + vertexWeightsSet.size() + " vertex weights sets for controller id=" + controller.id() + " name=" + controller.name());
        }
        Element vertexWeights = vertexWeightsSet.first();
        String vertexWeightsCountString = vertexWeights.attr("count");
        int vertexWeightsCount = Integer.parseInt(vertexWeightsCountString);
        String[] jointNameArray = null;
        float[] inverseBindMatrixArray;
        Quat4f[] rotationArray;
        ElementSet jointsInputSet = joints.find("input");
        List<Input> inputList = parseInputs(jointsInputSet);
        for (Input jointsInput : inputList) {
            if ("JOINT".equals(jointsInput.semantic)) {
                Element jointNameSourceElement = skin.select(jointsInput.sourceName);
                Source jointNameSource = parseSource(jointNameSourceElement);
                jointNameArray = jointNameSource.nameValues;
            }
            if ("INV_BIND_MATRIX".equals(jointsInput.semantic)) {
                Element jointMatrixSourceElement = skin.select(jointsInput.sourceName);
                Source jointMatrixSource = parseSource(jointMatrixSourceElement);
                inverseBindMatrixArray = jointMatrixSource.floatValues;
                rotationArray = quad4fArrayFromFloat16ArrayData(inverseBindMatrixArray);
            }
        }
        List<MD5Weight> md5WeightList = Lists.newArrayList();
        float[] weightsArray = null;
        ElementSet vertexWeightsInputSet = vertexWeights.find("input");
        List<Input> vertexWeightsInputList = parseInputs(vertexWeightsInputSet);
        // TODO: for now, assume the offsets will always perfectly match the sorted-by-offset list indexes
        Collections.sort(vertexWeightsInputList, (i1, i2) -> i1.offset - i2.offset);
        for (int i = 0; i < vertexWeightsInputList.size(); i++) {
            Input input = vertexWeightsInputList.get(i);
            if (input.offset != i) {
                throw new ColladaParseException("vertex weights input list offset does not match list index for vertex weights input " + input + " for controller id=" + controller.id() + " name=" + controller.name());
            }
        }
        for (Input vertexWeightsInput : vertexWeightsInputList) {
            // }
            if ("WEIGHT".equals(vertexWeightsInput.semantic)) {
                Element jointMatrixSourceElement = skin.select(vertexWeightsInput.sourceName);
                Source weightsArraySource = parseSource(jointMatrixSourceElement);
                weightsArray = weightsArraySource.floatValues;
            }
        }
        ElementSet vertexWeightsVCountDataSet = vertexWeights.find("vcount");
        if (1 != vertexWeightsVCountDataSet.size()) {
            throw new ColladaParseException("Found " + vertexWeightsVCountDataSet.size() + " vertex weights vcount sets for controller id=" + controller.id() + " name=" + controller.name());
        }
        Element vertexWeightsVCountData = vertexWeightsVCountDataSet.first();
        String vertexWeightsVCountString = vertexWeightsVCountData.text();
        String[] vertexWeightsVCountStrings = getItemsInString(vertexWeightsVCountString);
        if (vertexWeightsVCountStrings.length != vertexWeightsCount) {
            throw new ColladaParseException("Expected " + vertexWeightsCount + " but was " + vertexWeightsVCountStrings.length + " for controller id=" + controller.id() + " name=" + controller.name());
        }
        ElementSet vertexWeightsVDataSet = vertexWeights.find("v");
        if (1 != vertexWeightsVDataSet.size()) {
            throw new ColladaParseException("Found " + vertexWeightsVDataSet.size() + " vertex weights v sets for controller id=" + controller.id() + " name=" + controller.name());
        }
        Element vertexWeightsVData = vertexWeightsVDataSet.first();
        String vertexWeightsVDataString = vertexWeightsVData.text();
        String[] vertexWeightsVStrings = getItemsInString(vertexWeightsVDataString);
        // if (vertexWeightsVStrings.length != (vertexWeightsCount * vertexWeightsInputList.size())) {
        // throw new ColladaParseException("Expected " + vertexWeightsCount + " * input count of "
        // + vertexWeightsInputList.size() + " but was "
        // + vertexWeightsVStrings.length + " for controller id=" + controller.id() + " name=" + controller.name());
        // }
        // TODO: these aren't actually needed once we are populating MD5Weight records
        String[] vertexWeightsJointNameArray = new String[vertexWeightsCount];
        float[] vertexWeightsArray = new float[vertexWeightsCount];
        int vertexWeightsVDataIndex = -1;
        for (int vertexWeightsIndex = 0; vertexWeightsIndex < vertexWeightsCount; vertexWeightsIndex++) {
            MD5Weight md5Weight = new MD5Weight();
            Vector3f vertexPosition = new Vector3f();
            vertexPosition.x = vertices.get(3 * vertexWeightsIndex + 0);
            vertexPosition.y = vertices.get(3 * vertexWeightsIndex + 1);
            vertexPosition.z = vertices.get(3 * vertexWeightsIndex + 2);
            md5Weight.position = vertexPosition;
            md5WeightList.add(md5Weight);
            String vCountString = vertexWeightsVCountStrings[vertexWeightsIndex];
            int vCount = Integer.parseInt(vCountString);
            for (int vCountIndex = 0; vCountIndex < vCount; vCountIndex++) {
                for (Input vertexWeightsInput : vertexWeightsInputList) {
                    // vCount varies each time
                    ++vertexWeightsVDataIndex;
                    String indexString = vertexWeightsVStrings[vertexWeightsVDataIndex];
                    int index = Integer.parseInt(indexString);
                    if (-1 == index) {
                        throw new ColladaParseException("We do not support indexing into the bind shape yet");
                    }
                    if ("JOINT".equals(vertexWeightsInput.semantic)) {
                        md5Weight.jointIndex = index;
                        vertexWeightsJointNameArray[vertexWeightsIndex] = jointNameArray[index];
                    // logger.debug(String.valueOf(vertexWeightsVDataIndex) + ": " + "jointName=" + vertexWeightsJointNameArray[vertexWeightsIndex]);
                    } else if ("WEIGHT".equals(vertexWeightsInput.semantic)) {
                        md5Weight.bias = weightsArray[index];
                        vertexWeightsArray[vertexWeightsIndex] = weightsArray[index];
                    // logger.debug(String.valueOf(vertexWeightsVDataIndex) + ": " + "weight=" + vertexWeightsArray[vertexWeightsIndex]);
                    } else {
                        throw new ColladaParseException("Found unexpected vertex weights Input semantic " + vertexWeightsInput.semantic + " for controller id=" + controller.id() + " name=" + controller.name());
                    }
                }
            }
        }
        MD5Mesh md5Mesh = new MD5Mesh();
        md5Mesh.weightList = md5WeightList;
        // Find a node with sid="joint-name"
        for (String jointName : jointNameArray) {
            MD5Joint md5Joint = md5JointBySidMap.get(jointName);
            if (null == md5Joint) {
                throw new ColladaParseException("Cannot find joint node for node sid value for joint " + jointName + " in nodes for library_visual_scenes");
            }
            md5JointList.add(md5Joint);
        }
    }
    Deque<MD5Joint> jointsToProcess = new LinkedList<>(md5JointList);
    while (!jointsToProcess.isEmpty()) {
        MD5Joint joint = jointsToProcess.pop();
        MD5Joint parentJoint = joint.parent;
        if (null != parentJoint) {
            if (!md5JointList.contains(parentJoint)) {
                md5JointList.add(parentJoint);
                jointsToProcess.push(parentJoint);
            }
        }
    }
    for (MD5Joint joint : md5JointList) {
        if (null == joint.position) {
            throw new ColladaParseException("no joint position for joint with element id " + joint.element.id());
        }
        if (null == joint.orientation) {
            throw new ColladaParseException("no joint orientation for joint with element id " + joint.element.id());
        }
        // index argument is not used for anything currently, so we'll just set it to -1
        joint.bone = new Bone(-1, joint.name, joint.position, joint.orientation);
    }
    for (MD5Joint joint : md5JointList) {
        // We can probably skip unused end nodes
        joint.childList.stream().filter(childJoint -> childJoint.bone != null).forEach(childJoint -> joint.bone.addChild(childJoint.bone));
    }
    for (MD5Joint joint : md5JointList) {
        skeletonBuilder.addBone(joint.bone);
    }
    if (md5MeshList.size() > 0) {
        // TODO: Support multiple mesh somehow?
        MD5Mesh mesh = md5MeshList.get(0);
        for (MD5Weight weight : mesh.weightList) {
            skeletonBuilder.addWeight(new BoneWeight(weight.position, weight.bias, weight.jointIndex));
        }
        List<Vector2f> uvs = Lists.newArrayList();
        TIntList vertexStartWeight = new TIntArrayList(vertices.size() / 3);
        TIntList vertexWeightCount = new TIntArrayList(vertices.size() / 3);
        for (int i = 0; i < vertices.size() / 3; i++) {
            vertexStartWeight.add(i);
            vertexWeightCount.add(1);
        }
        skeletonBuilder.setVertexWeights(vertexStartWeight, vertexWeightCount);
        for (int i = 0; i < normals.size() / 2; i++) {
            uvs.add(new Vector2f(normals.get(i * 2 + 0), normals.get(i * 2 + 1)));
        }
        skeletonBuilder.setUvs(uvs);
        skeletonBuilder.setIndices(indices);
    }
// Now if you have come this far, you should be able to read the geometry data,
// as well as the skeleton and skinning data from COLLADA documents. And you should be able to draw
// the model in raw triangles, as well as draw the skeleton. Although I haven't discussed how you
// can accumulate the world matrices for each joint and then draw in world coordinates for debugging
// purposes but I think I gave a hint that we have to multiply parent joint's world matrix with current
// joint's Joint matrix and save the result in current joint's world matrix. We have to start this
// process from the root bone. So that we don't have dirty world matrices from parents, and the root
// Joint's world matrix becomes the Joint matrix, since root don't have any parent. If you are also
// reading the COLLADA specification version 1.5 you can find the skinning equation so you should also
// be able to put the model in bind shape. How can we animate this model is still not covered and will
// be covered in the following sections.
// THIS IS THE TARGET GOAL:
/*
        Bones
        - String name
        - int index
        - V3 object position
        - Quat4f obj rotation
        - parent / children bones

        SkeletalMesh


        // This part may not be required if we can implement SkeletalMeshData methods without it

        //////////////

        public SkeletalMeshData(List<Bone> bones, List<BoneWeight> weights,
           List<Vector2f> uvs,
           TIntList vertexStartWeights, TIntList vertexWeightCounts,
           TIntList indices) {

        BoneWeight
        Vector3f position = new Vector3f();
        float bias;
        int boneIndex;
        Vector3f normal = new Vector3f();

        //////////////


           public Collection<Bone> getBones();
           public Bone getRootBone();
           public Bone getBone(String name);

           public int getVertexCount();

           public List<Vector3f> getBindPoseVertexPositions();
           public List<Vector3f> getVertexPositions(List<Vector3f> bonePositions, List<Quat4f> boneRotations);

           public List<Vector3f> getBindPoseVertexNormals();
           public List<Vector3f> getVertexNormals(List<Vector3f> bonePositions, List<Quat4f> boneRotations);

           public TIntList getIndices();
           public List<Vector2f> getUVs();
         */
}
Also used : Bone(org.terasology.rendering.assets.skeletalmesh.Bone) Arrays(java.util.Arrays) BoneWeight(org.terasology.rendering.assets.skeletalmesh.BoneWeight) TIntArrayList(gnu.trove.list.array.TIntArrayList) Element(org.eaxy.Element) LoggerFactory(org.slf4j.LoggerFactory) Vector3f(org.terasology.math.geom.Vector3f) SkeletalMeshDataBuilder(org.terasology.rendering.assets.skeletalmesh.SkeletalMeshDataBuilder) HashMap(java.util.HashMap) Deque(java.util.Deque) Document(org.eaxy.Document) Matrix4f(org.terasology.math.geom.Matrix4f) ArrayList(java.util.ArrayList) ElementSet(org.eaxy.ElementSet) Lists(com.google.common.collect.Lists) Map(java.util.Map) TFloatList(gnu.trove.list.TFloatList) LinkedList(java.util.LinkedList) TIntList(gnu.trove.list.TIntList) TFloatArrayList(gnu.trove.list.array.TFloatArrayList) Logger(org.slf4j.Logger) SkeletalMeshData(org.terasology.rendering.assets.skeletalmesh.SkeletalMeshData) NonMatchingPathException(org.eaxy.NonMatchingPathException) Vector2f(org.terasology.math.geom.Vector2f) IOException(java.io.IOException) List(java.util.List) Quat4f(org.terasology.math.geom.Quat4f) Collections(java.util.Collections) Xml(org.eaxy.Xml) InputStream(java.io.InputStream) ElementSet(org.eaxy.ElementSet) HashMap(java.util.HashMap) Element(org.eaxy.Element) TIntArrayList(gnu.trove.list.array.TIntArrayList) ArrayList(java.util.ArrayList) TFloatArrayList(gnu.trove.list.array.TFloatArrayList) BoneWeight(org.terasology.rendering.assets.skeletalmesh.BoneWeight) SkeletalMeshDataBuilder(org.terasology.rendering.assets.skeletalmesh.SkeletalMeshDataBuilder) Vector2f(org.terasology.math.geom.Vector2f) LinkedList(java.util.LinkedList) TIntArrayList(gnu.trove.list.array.TIntArrayList) Vector3f(org.terasology.math.geom.Vector3f) Bone(org.terasology.rendering.assets.skeletalmesh.Bone) TIntList(gnu.trove.list.TIntList) Quat4f(org.terasology.math.geom.Quat4f)

Example 3 with Bone

use of org.terasology.rendering.assets.skeletalmesh.Bone in project Terasology by MovingBlocks.

the class SkeletonRenderer method renderOpaque.

@Override
public void renderOpaque() {
    Vector3f cameraPosition = worldRenderer.getActiveCamera().getPosition();
    Quat4f worldRot = new Quat4f();
    Vector3f worldPos = new Vector3f();
    Quat4f inverseWorldRot = new Quat4f();
    FloatBuffer tempMatrixBuffer44 = BufferUtils.createFloatBuffer(16);
    FloatBuffer tempMatrixBuffer33 = BufferUtils.createFloatBuffer(12);
    for (EntityRef entity : entityManager.getEntitiesWith(SkeletalMeshComponent.class, LocationComponent.class)) {
        SkeletalMeshComponent skeletalMesh = entity.getComponent(SkeletalMeshComponent.class);
        if (skeletalMesh.mesh == null || skeletalMesh.material == null || skeletalMesh.boneEntities == null || !skeletalMesh.material.isRenderable()) {
            continue;
        }
        AABB aabb;
        MeshAnimation animation = skeletalMesh.animation;
        if (animation != null) {
            aabb = animation.getAabb();
        } else {
            aabb = skeletalMesh.mesh.getStaticAabb();
        }
        LocationComponent location = entity.getComponent(LocationComponent.class);
        location.getWorldRotation(worldRot);
        inverseWorldRot.inverse(worldRot);
        location.getWorldPosition(worldPos);
        float worldScale = location.getWorldScale();
        aabb = aabb.transform(worldRot, worldPos, worldScale);
        if (!worldRenderer.getActiveCamera().hasInSight(aabb)) {
            continue;
        }
        skeletalMesh.material.enable();
        skeletalMesh.material.setFloat("sunlight", 1.0f, true);
        skeletalMesh.material.setFloat("blockLight", 1.0f, true);
        skeletalMesh.material.setFloat3("colorOffset", skeletalMesh.color.rf(), skeletalMesh.color.gf(), skeletalMesh.color.bf(), true);
        skeletalMesh.material.setMatrix4("projectionMatrix", worldRenderer.getActiveCamera().getProjectionMatrix());
        skeletalMesh.material.bindTextures();
        Vector3f worldPositionCameraSpace = new Vector3f();
        worldPositionCameraSpace.sub(worldPos, cameraPosition);
        worldPos.y -= skeletalMesh.heightOffset;
        Matrix4f matrixCameraSpace = new Matrix4f(worldRot, worldPositionCameraSpace, worldScale);
        Matrix4f modelViewMatrix = MatrixUtils.calcModelViewMatrix(worldRenderer.getActiveCamera().getViewMatrix(), matrixCameraSpace);
        MatrixUtils.matrixToFloatBuffer(modelViewMatrix, tempMatrixBuffer44);
        skeletalMesh.material.setMatrix4("worldViewMatrix", tempMatrixBuffer44, true);
        MatrixUtils.matrixToFloatBuffer(MatrixUtils.calcNormalMatrix(modelViewMatrix), tempMatrixBuffer33);
        skeletalMesh.material.setMatrix3("normalMatrix", tempMatrixBuffer33, true);
        skeletalMesh.material.setFloat("sunlight", worldRenderer.getMainLightIntensityAt(worldPos), true);
        skeletalMesh.material.setFloat("blockLight", worldRenderer.getBlockLightIntensityAt(worldPos), true);
        List<Vector3f> bonePositions = Lists.newArrayListWithCapacity(skeletalMesh.mesh.getVertexCount());
        List<Quat4f> boneRotations = Lists.newArrayListWithCapacity(skeletalMesh.mesh.getVertexCount());
        for (Bone bone : skeletalMesh.mesh.getBones()) {
            EntityRef boneEntity = skeletalMesh.boneEntities.get(bone.getName());
            if (boneEntity == null) {
                boneEntity = EntityRef.NULL;
            }
            LocationComponent boneLocation = boneEntity.getComponent(LocationComponent.class);
            if (boneLocation != null) {
                Vector3f pos = boneLocation.getWorldPosition();
                pos.sub(worldPos);
                inverseWorldRot.rotate(pos, pos);
                bonePositions.add(pos);
                Quat4f rot = new Quat4f(inverseWorldRot);
                rot.mul(boneLocation.getWorldRotation());
                boneRotations.add(rot);
            } else {
                logger.warn("Unable to resolve bone \"{}\"", bone.getName());
                bonePositions.add(new Vector3f());
                boneRotations.add(new Quat4f());
            }
        }
        ((OpenGLSkeletalMesh) skeletalMesh.mesh).setScaleTranslate(skeletalMesh.scale, skeletalMesh.translate);
        ((OpenGLSkeletalMesh) skeletalMesh.mesh).render(bonePositions, boneRotations);
    }
}
Also used : FloatBuffer(java.nio.FloatBuffer) LocationComponent(org.terasology.logic.location.LocationComponent) Matrix4f(org.terasology.math.geom.Matrix4f) OpenGLSkeletalMesh(org.terasology.rendering.opengl.OpenGLSkeletalMesh) Vector3f(org.terasology.math.geom.Vector3f) BaseVector3f(org.terasology.math.geom.BaseVector3f) MeshAnimation(org.terasology.rendering.assets.animation.MeshAnimation) Bone(org.terasology.rendering.assets.skeletalmesh.Bone) EntityRef(org.terasology.entitySystem.entity.EntityRef) BaseQuat4f(org.terasology.math.geom.BaseQuat4f) Quat4f(org.terasology.math.geom.Quat4f) AABB(org.terasology.math.AABB)

Example 4 with Bone

use of org.terasology.rendering.assets.skeletalmesh.Bone in project Terasology by MovingBlocks.

the class SkeletonRenderer method newSkeleton.

@ReceiveEvent(components = { SkeletalMeshComponent.class, LocationComponent.class })
public void newSkeleton(OnActivatedComponent event, EntityRef entity) {
    SkeletalMeshComponent skeleton = entity.getComponent(SkeletalMeshComponent.class);
    if (skeleton.mesh == null) {
        return;
    }
    if (skeleton.boneEntities == null) {
        skeleton.boneEntities = Maps.newHashMap();
        for (Bone bone : skeleton.mesh.getBones()) {
            LocationComponent loc = new LocationComponent();
            EntityRef parent = (bone.getParent() != null) ? skeleton.boneEntities.get(bone.getParent().getName()) : entity;
            EntityRef boneEntity = entityManager.create(loc);
            Location.attachChild(parent, boneEntity);
            loc.setLocalPosition(bone.getLocalPosition());
            loc.setLocalRotation(bone.getLocalRotation());
            if (bone.getParent() == null) {
                skeleton.rootBone = boneEntity;
            }
            skeleton.boneEntities.put(bone.getName(), boneEntity);
        }
        entity.saveComponent(skeleton);
    }
}
Also used : Bone(org.terasology.rendering.assets.skeletalmesh.Bone) LocationComponent(org.terasology.logic.location.LocationComponent) EntityRef(org.terasology.entitySystem.entity.EntityRef) ReceiveEvent(org.terasology.entitySystem.event.ReceiveEvent)

Example 5 with Bone

use of org.terasology.rendering.assets.skeletalmesh.Bone in project Terasology by MovingBlocks.

the class MeshAnimationImpl method isValidAnimationFor.

@Override
public boolean isValidAnimationFor(SkeletalMesh mesh) {
    for (int i = 0; i < data.getBoneNames().size(); ++i) {
        Bone bone = mesh.getBone(data.getBoneNames().get(i));
        boolean hasParent = data.getBoneParent().get(i) != MeshAnimationData.NO_PARENT;
        if (hasParent && (bone.getParent() == null || !bone.getParent().getName().equals(data.getBoneNames().get(data.getBoneParent().get(i))))) {
            return false;
        } else if (!hasParent && bone.getParent() != null) {
            return false;
        }
    }
    return true;
}
Also used : Bone(org.terasology.rendering.assets.skeletalmesh.Bone)

Aggregations

Bone (org.terasology.rendering.assets.skeletalmesh.Bone)5 TIntList (gnu.trove.list.TIntList)2 TIntArrayList (gnu.trove.list.array.TIntArrayList)2 IOException (java.io.IOException)2 InputStream (java.io.InputStream)2 EntityRef (org.terasology.entitySystem.entity.EntityRef)2 LocationComponent (org.terasology.logic.location.LocationComponent)2 Matrix4f (org.terasology.math.geom.Matrix4f)2 Quat4f (org.terasology.math.geom.Quat4f)2 Vector2f (org.terasology.math.geom.Vector2f)2 Vector3f (org.terasology.math.geom.Vector3f)2 BoneWeight (org.terasology.rendering.assets.skeletalmesh.BoneWeight)2 SkeletalMeshDataBuilder (org.terasology.rendering.assets.skeletalmesh.SkeletalMeshDataBuilder)2 Lists (com.google.common.collect.Lists)1 TFloatList (gnu.trove.list.TFloatList)1 TFloatArrayList (gnu.trove.list.array.TFloatArrayList)1 FloatBuffer (java.nio.FloatBuffer)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 Collections (java.util.Collections)1