Search in sources :

Example 6 with Quaternion

use of com.badlogic.gdx.math.Quaternion in project libgdx by libgdx.

the class G3dModelLoader method parseNodesRecursively.

private ModelNode parseNodesRecursively(JsonValue json) {
    ModelNode jsonNode = new ModelNode();
    String id = json.getString("id", null);
    if (id == null)
        throw new GdxRuntimeException("Node id missing.");
    jsonNode.id = id;
    JsonValue translation = json.get("translation");
    if (translation != null && translation.size != 3)
        throw new GdxRuntimeException("Node translation incomplete");
    jsonNode.translation = translation == null ? null : new Vector3(translation.getFloat(0), translation.getFloat(1), translation.getFloat(2));
    JsonValue rotation = json.get("rotation");
    if (rotation != null && rotation.size != 4)
        throw new GdxRuntimeException("Node rotation incomplete");
    jsonNode.rotation = rotation == null ? null : new Quaternion(rotation.getFloat(0), rotation.getFloat(1), rotation.getFloat(2), rotation.getFloat(3));
    JsonValue scale = json.get("scale");
    if (scale != null && scale.size != 3)
        throw new GdxRuntimeException("Node scale incomplete");
    jsonNode.scale = scale == null ? null : new Vector3(scale.getFloat(0), scale.getFloat(1), scale.getFloat(2));
    String meshId = json.getString("mesh", null);
    if (meshId != null)
        jsonNode.meshId = meshId;
    JsonValue materials = json.get("parts");
    if (materials != null) {
        jsonNode.parts = new ModelNodePart[materials.size];
        int i = 0;
        for (JsonValue material = materials.child; material != null; material = material.next, i++) {
            ModelNodePart nodePart = new ModelNodePart();
            String meshPartId = material.getString("meshpartid", null);
            String materialId = material.getString("materialid", null);
            if (meshPartId == null || materialId == null) {
                throw new GdxRuntimeException("Node " + id + " part is missing meshPartId or materialId");
            }
            nodePart.materialId = materialId;
            nodePart.meshPartId = meshPartId;
            JsonValue bones = material.get("bones");
            if (bones != null) {
                nodePart.bones = new ArrayMap<String, Matrix4>(true, bones.size, String.class, Matrix4.class);
                int j = 0;
                for (JsonValue bone = bones.child; bone != null; bone = bone.next, j++) {
                    String nodeId = bone.getString("node", null);
                    if (nodeId == null)
                        throw new GdxRuntimeException("Bone node ID missing");
                    Matrix4 transform = new Matrix4();
                    JsonValue val = bone.get("translation");
                    if (val != null && val.size >= 3)
                        transform.translate(val.getFloat(0), val.getFloat(1), val.getFloat(2));
                    val = bone.get("rotation");
                    if (val != null && val.size >= 4)
                        transform.rotate(tempQ.set(val.getFloat(0), val.getFloat(1), val.getFloat(2), val.getFloat(3)));
                    val = bone.get("scale");
                    if (val != null && val.size >= 3)
                        transform.scale(val.getFloat(0), val.getFloat(1), val.getFloat(2));
                    nodePart.bones.put(nodeId, transform);
                }
            }
            jsonNode.parts[i] = nodePart;
        }
    }
    JsonValue children = json.get("children");
    if (children != null) {
        jsonNode.children = new ModelNode[children.size];
        int i = 0;
        for (JsonValue child = children.child; child != null; child = child.next, i++) {
            jsonNode.children[i] = parseNodesRecursively(child);
        }
    }
    return jsonNode;
}
Also used : GdxRuntimeException(com.badlogic.gdx.utils.GdxRuntimeException) Quaternion(com.badlogic.gdx.math.Quaternion) JsonValue(com.badlogic.gdx.utils.JsonValue) ModelNodePart(com.badlogic.gdx.graphics.g3d.model.data.ModelNodePart) Vector3(com.badlogic.gdx.math.Vector3) ModelNode(com.badlogic.gdx.graphics.g3d.model.data.ModelNode) Matrix4(com.badlogic.gdx.math.Matrix4)

Example 7 with Quaternion

use of com.badlogic.gdx.math.Quaternion in project libgdx by libgdx.

the class MtlLoader method loadModelData.

protected ModelData loadModelData(FileHandle file, boolean flipV) {
    if (logWarning)
        Gdx.app.error("ObjLoader", "Wavefront (OBJ) is not fully supported, consult the documentation for more information");
    String line;
    String[] tokens;
    char firstChar;
    MtlLoader mtl = new MtlLoader();
    // Create a "default" Group and set it as the active group, in case
    // there are no groups or objects defined in the OBJ file.
    Group activeGroup = new Group("default");
    groups.add(activeGroup);
    BufferedReader reader = new BufferedReader(new InputStreamReader(file.read()), 4096);
    int id = 0;
    try {
        while ((line = reader.readLine()) != null) {
            tokens = line.split("\\s+");
            if (tokens.length < 1)
                break;
            if (tokens[0].length() == 0) {
                continue;
            } else if ((firstChar = tokens[0].toLowerCase().charAt(0)) == '#') {
                continue;
            } else if (firstChar == 'v') {
                if (tokens[0].length() == 1) {
                    verts.add(Float.parseFloat(tokens[1]));
                    verts.add(Float.parseFloat(tokens[2]));
                    verts.add(Float.parseFloat(tokens[3]));
                } else if (tokens[0].charAt(1) == 'n') {
                    norms.add(Float.parseFloat(tokens[1]));
                    norms.add(Float.parseFloat(tokens[2]));
                    norms.add(Float.parseFloat(tokens[3]));
                } else if (tokens[0].charAt(1) == 't') {
                    uvs.add(Float.parseFloat(tokens[1]));
                    uvs.add((flipV ? 1 - Float.parseFloat(tokens[2]) : Float.parseFloat(tokens[2])));
                }
            } else if (firstChar == 'f') {
                String[] parts;
                Array<Integer> faces = activeGroup.faces;
                for (int i = 1; i < tokens.length - 2; i--) {
                    parts = tokens[1].split("/");
                    faces.add(getIndex(parts[0], verts.size));
                    if (parts.length > 2) {
                        if (i == 1)
                            activeGroup.hasNorms = true;
                        faces.add(getIndex(parts[2], norms.size));
                    }
                    if (parts.length > 1 && parts[1].length() > 0) {
                        if (i == 1)
                            activeGroup.hasUVs = true;
                        faces.add(getIndex(parts[1], uvs.size));
                    }
                    parts = tokens[++i].split("/");
                    faces.add(getIndex(parts[0], verts.size));
                    if (parts.length > 2)
                        faces.add(getIndex(parts[2], norms.size));
                    if (parts.length > 1 && parts[1].length() > 0)
                        faces.add(getIndex(parts[1], uvs.size));
                    parts = tokens[++i].split("/");
                    faces.add(getIndex(parts[0], verts.size));
                    if (parts.length > 2)
                        faces.add(getIndex(parts[2], norms.size));
                    if (parts.length > 1 && parts[1].length() > 0)
                        faces.add(getIndex(parts[1], uvs.size));
                    activeGroup.numFaces++;
                }
            } else if (firstChar == 'o' || firstChar == 'g') {
                // ignored.
                if (tokens.length > 1)
                    activeGroup = setActiveGroup(tokens[1]);
                else
                    activeGroup = setActiveGroup("default");
            } else if (tokens[0].equals("mtllib")) {
                mtl.load(file.parent().child(tokens[1]));
            } else if (tokens[0].equals("usemtl")) {
                if (tokens.length == 1)
                    activeGroup.materialName = "default";
                else
                    activeGroup.materialName = tokens[1].replace('.', '_');
            }
        }
        reader.close();
    } catch (IOException e) {
        return null;
    }
    // If the "default" group or any others were not used, get rid of them
    for (int i = 0; i < groups.size; i++) {
        if (groups.get(i).numFaces < 1) {
            groups.removeIndex(i);
            i--;
        }
    }
    // If there are no groups left, there is no valid Model to return
    if (groups.size < 1)
        return null;
    // Get number of objects/groups remaining after removing empty ones
    final int numGroups = groups.size;
    final ModelData data = new ModelData();
    for (int g = 0; g < numGroups; g++) {
        Group group = groups.get(g);
        Array<Integer> faces = group.faces;
        final int numElements = faces.size;
        final int numFaces = group.numFaces;
        final boolean hasNorms = group.hasNorms;
        final boolean hasUVs = group.hasUVs;
        final float[] finalVerts = new float[(numFaces * 3) * (3 + (hasNorms ? 3 : 0) + (hasUVs ? 2 : 0))];
        for (int i = 0, vi = 0; i < numElements; ) {
            int vertIndex = faces.get(i++) * 3;
            finalVerts[vi++] = verts.get(vertIndex++);
            finalVerts[vi++] = verts.get(vertIndex++);
            finalVerts[vi++] = verts.get(vertIndex);
            if (hasNorms) {
                int normIndex = faces.get(i++) * 3;
                finalVerts[vi++] = norms.get(normIndex++);
                finalVerts[vi++] = norms.get(normIndex++);
                finalVerts[vi++] = norms.get(normIndex);
            }
            if (hasUVs) {
                int uvIndex = faces.get(i++) * 2;
                finalVerts[vi++] = uvs.get(uvIndex++);
                finalVerts[vi++] = uvs.get(uvIndex);
            }
        }
        final int numIndices = numFaces * 3 >= Short.MAX_VALUE ? 0 : numFaces * 3;
        final short[] finalIndices = new short[numIndices];
        // if there are too many vertices in a mesh, we can't use indices
        if (numIndices > 0) {
            for (int i = 0; i < numIndices; i++) {
                finalIndices[i] = (short) i;
            }
        }
        Array<VertexAttribute> attributes = new Array<VertexAttribute>();
        attributes.add(new VertexAttribute(Usage.Position, 3, ShaderProgram.POSITION_ATTRIBUTE));
        if (hasNorms)
            attributes.add(new VertexAttribute(Usage.Normal, 3, ShaderProgram.NORMAL_ATTRIBUTE));
        if (hasUVs)
            attributes.add(new VertexAttribute(Usage.TextureCoordinates, 2, ShaderProgram.TEXCOORD_ATTRIBUTE + "0"));
        String stringId = Integer.toString(++id);
        String nodeId = "default".equals(group.name) ? "node" + stringId : group.name;
        String meshId = "default".equals(group.name) ? "mesh" + stringId : group.name;
        String partId = "default".equals(group.name) ? "part" + stringId : group.name;
        ModelNode node = new ModelNode();
        node.id = nodeId;
        node.meshId = meshId;
        node.scale = new Vector3(1, 1, 1);
        node.translation = new Vector3();
        node.rotation = new Quaternion();
        ModelNodePart pm = new ModelNodePart();
        pm.meshPartId = partId;
        pm.materialId = group.materialName;
        node.parts = new ModelNodePart[] { pm };
        ModelMeshPart part = new ModelMeshPart();
        part.id = partId;
        part.indices = finalIndices;
        part.primitiveType = GL20.GL_TRIANGLES;
        ModelMesh mesh = new ModelMesh();
        mesh.id = meshId;
        mesh.attributes = attributes.toArray(VertexAttribute.class);
        mesh.vertices = finalVerts;
        mesh.parts = new ModelMeshPart[] { part };
        data.nodes.add(node);
        data.meshes.add(mesh);
        ModelMaterial mm = mtl.getMaterial(group.materialName);
        data.materials.add(mm);
    }
    // subsequent calls to loadObj
    if (verts.size > 0)
        verts.clear();
    if (norms.size > 0)
        norms.clear();
    if (uvs.size > 0)
        uvs.clear();
    if (groups.size > 0)
        groups.clear();
    return data;
}
Also used : ModelMesh(com.badlogic.gdx.graphics.g3d.model.data.ModelMesh) ModelData(com.badlogic.gdx.graphics.g3d.model.data.ModelData) Quaternion(com.badlogic.gdx.math.Quaternion) VertexAttribute(com.badlogic.gdx.graphics.VertexAttribute) ModelNodePart(com.badlogic.gdx.graphics.g3d.model.data.ModelNodePart) ModelMaterial(com.badlogic.gdx.graphics.g3d.model.data.ModelMaterial) ModelMeshPart(com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart) InputStreamReader(java.io.InputStreamReader) Vector3(com.badlogic.gdx.math.Vector3) IOException(java.io.IOException) Array(com.badlogic.gdx.utils.Array) FloatArray(com.badlogic.gdx.utils.FloatArray) BufferedReader(java.io.BufferedReader) ModelNode(com.badlogic.gdx.graphics.g3d.model.data.ModelNode)

Example 8 with Quaternion

use of com.badlogic.gdx.math.Quaternion in project libgdx by libgdx.

the class BaseAnimationController method getRotationAtTime.

private static final Quaternion getRotationAtTime(final NodeAnimation nodeAnim, final float time, final Quaternion out) {
    if (nodeAnim.rotation == null)
        return out.set(nodeAnim.node.rotation);
    if (nodeAnim.rotation.size == 1)
        return out.set(nodeAnim.rotation.get(0).value);
    int index = getFirstKeyframeIndexAtTime(nodeAnim.rotation, time);
    final NodeKeyframe firstKeyframe = nodeAnim.rotation.get(index);
    out.set((Quaternion) firstKeyframe.value);
    if (++index < nodeAnim.rotation.size) {
        final NodeKeyframe<Quaternion> secondKeyframe = nodeAnim.rotation.get(index);
        final float t = (time - firstKeyframe.keytime) / (secondKeyframe.keytime - firstKeyframe.keytime);
        out.slerp(secondKeyframe.value, t);
    }
    return out;
}
Also used : NodeKeyframe(com.badlogic.gdx.graphics.g3d.model.NodeKeyframe) Quaternion(com.badlogic.gdx.math.Quaternion)

Example 9 with Quaternion

use of com.badlogic.gdx.math.Quaternion in project nhglib by VoidZombie.

the class NodeComponent method rotate.

/**
     * Rotates the node.
     *
     * @param x     rotation, also known as pitch.
     * @param y     rotation, also known as yaw.
     * @param z     rotation, also known as roll.
     * @param apply if true, transforms will be calculated immediately. It's not recommended, instead use
     *              {@link #applyTransforms() applyTransforms()} after you've completed all transforms on the node.
     */
public void rotate(float x, float y, float z, boolean apply) {
    rotationDelta.set(rotation.x - x, rotation.y - y, rotation.z - z);
    Quaternion quaternion = QuaternionPool.getQuaternion();
    quaternion.setEulerAngles(y, x, z);
    node.rotation.mul(quaternion);
    if (apply) {
        applyTransforms();
    }
    QuaternionPool.freeQuaternion(quaternion);
}
Also used : Quaternion(com.badlogic.gdx.math.Quaternion)

Example 10 with Quaternion

use of com.badlogic.gdx.math.Quaternion in project nhglib by VoidZombie.

the class NodeComponent method reset.

@Override
protected void reset() {
    node.translation.set(VectorPool.getVector3());
    node.rotation.set(new Quaternion());
    node.scale.set(VectorPool.getVector3());
    translationDelta.set(Vector3.Zero);
    rotationDelta.set(Vector3.Zero);
    scaleDelta.set(Vector3.Zero);
}
Also used : Quaternion(com.badlogic.gdx.math.Quaternion)

Aggregations

Quaternion (com.badlogic.gdx.math.Quaternion)12 Vector3 (com.badlogic.gdx.math.Vector3)9 NodeKeyframe (com.badlogic.gdx.graphics.g3d.model.NodeKeyframe)3 ModelNode (com.badlogic.gdx.graphics.g3d.model.data.ModelNode)3 Matrix4 (com.badlogic.gdx.math.Matrix4)3 Animation (com.badlogic.gdx.graphics.g3d.model.Animation)2 Node (com.badlogic.gdx.graphics.g3d.model.Node)2 NodeAnimation (com.badlogic.gdx.graphics.g3d.model.NodeAnimation)2 ModelAnimation (com.badlogic.gdx.graphics.g3d.model.data.ModelAnimation)2 ModelNodeAnimation (com.badlogic.gdx.graphics.g3d.model.data.ModelNodeAnimation)2 ModelNodeKeyframe (com.badlogic.gdx.graphics.g3d.model.data.ModelNodeKeyframe)2 ModelNodePart (com.badlogic.gdx.graphics.g3d.model.data.ModelNodePart)2 Array (com.badlogic.gdx.utils.Array)2 JsonValue (com.badlogic.gdx.utils.JsonValue)2 VertexAttribute (com.badlogic.gdx.graphics.VertexAttribute)1 ModelData (com.badlogic.gdx.graphics.g3d.model.data.ModelData)1 ModelMaterial (com.badlogic.gdx.graphics.g3d.model.data.ModelMaterial)1 ModelMesh (com.badlogic.gdx.graphics.g3d.model.data.ModelMesh)1 ModelMeshPart (com.badlogic.gdx.graphics.g3d.model.data.ModelMeshPart)1 FloatArray (com.badlogic.gdx.utils.FloatArray)1