Search in sources :

Example 1 with JointWeight

use of net.drewke.tdme.engine.model.JointWeight in project tdme by andreasdr.

the class TMReader method readSkinning.

/**
	 * Read skinning from input stream
	 * @param input stream
	 * @param group
	 * @throws IOException
	 */
private static void readSkinning(InputStream is, Group g) throws IOException, ModelFileIOException {
    if (readBoolean(is) == true) {
        Skinning skinning = g.createSkinning();
        skinning.setWeights(readFloatArray(is));
        Joint[] joints = new Joint[readInt(is)];
        for (int i = 0; i < joints.length; i++) {
            joints[i] = readSkinningJoint(is);
        }
        skinning.setJoints(joints);
        JointWeight[][] verticesJointsWeight = new JointWeight[readInt(is)][];
        for (int i = 0; i < verticesJointsWeight.length; i++) {
            verticesJointsWeight[i] = new JointWeight[readInt(is)];
            for (int j = 0; j < verticesJointsWeight[i].length; j++) {
                verticesJointsWeight[i][j] = readSkinningJointWeight(is);
            }
        }
        skinning.setVerticesJointsWeights(verticesJointsWeight);
    }
}
Also used : Skinning(net.drewke.tdme.engine.model.Skinning) Joint(net.drewke.tdme.engine.model.Joint) JointWeight(net.drewke.tdme.engine.model.JointWeight) Joint(net.drewke.tdme.engine.model.Joint)

Example 2 with JointWeight

use of net.drewke.tdme.engine.model.JointWeight in project tdme by andreasdr.

the class Object3DGroupMesh method createMesh.

/**
	 * Creates a object3d group mesh from group
	 * @param animation processing target
	 * @param group
	 * @param transformationm matrices
	 * @return object 3d group mesh
	 */
protected static Object3DGroupMesh createMesh(Engine.AnimationProcessingTarget animationProcessingTarget, Group group, HashMap<String, Matrix4x4> transformationMatrices) {
    Object3DGroupMesh mesh = new Object3DGroupMesh();
    // group data
    Vector3[] groupVertices = group.getVertices();
    Vector3[] groupNormals = group.getNormals();
    TextureCoordinate[] groupTextureCoordinates = group.getTextureCoordinates();
    Vector3[] groupTangents = group.getTangents();
    Vector3[] groupBitangents = group.getBitangents();
    // determine face count
    int faceCount = group.getFaceCount();
    // set up face count
    mesh.faces = faceCount;
    // animation processing target
    mesh.animationProcessingTarget = animationProcessingTarget;
    // transformations for skinned meshes
    Skinning skinning = group.getSkinning();
    mesh.skinning = skinning != null;
    // transformed mesh vertices
    mesh.transformedVertices = new Vector3[groupVertices.length];
    for (int j = 0; j < mesh.transformedVertices.length; j++) {
        mesh.transformedVertices[j] = new Vector3().set(groupVertices[j]);
    }
    // transformed mesh normals
    mesh.transformedNormals = new Vector3[groupNormals.length];
    for (int j = 0; j < mesh.transformedNormals.length; j++) {
        mesh.transformedNormals[j] = new Vector3().set(groupNormals[j]);
    }
    // texture coordinates
    if (groupTextureCoordinates != null) {
        mesh.textureCoordinates = new TextureCoordinate[groupTextureCoordinates.length];
        for (int j = 0; j < mesh.textureCoordinates.length; j++) {
            mesh.textureCoordinates[j] = new TextureCoordinate(groupTextureCoordinates[j]);
        }
    }
    // transformed mesh tangents
    if (groupTangents != null) {
        mesh.transformedTangents = new Vector3[groupTangents.length];
        for (int j = 0; j < mesh.transformedTangents.length; j++) {
            mesh.transformedTangents[j] = new Vector3().set(groupTangents[j]);
        }
    }
    // transformed mesh bitangents
    if (groupBitangents != null) {
        mesh.transformedBitangents = new Vector3[groupBitangents.length];
        for (int j = 0; j < mesh.transformedBitangents.length; j++) {
            mesh.transformedBitangents[j] = new Vector3().set(groupBitangents[j]);
        }
    }
    // indices
    int indicesCount = 0;
    for (FacesEntity facesEntity : group.getFacesEntities()) {
        indicesCount += 3 * facesEntity.getFaces().length;
    }
    mesh.indices = new short[indicesCount];
    {
        int j = 0;
        // create face vertex indices
        for (FacesEntity facesEntity : group.getFacesEntities()) for (Face face : facesEntity.getFaces()) for (int vertexIndex : face.getVertexIndices()) {
            mesh.indices[j++] = (short) vertexIndex;
        }
    }
    //
    mesh.recreatedBuffers = false;
    // create mesh upload buffers
    if (mesh.animationProcessingTarget != Engine.AnimationProcessingTarget.CPU_NORENDERING) {
        mesh.sbIndices = ByteBuffer.allocateDirect(mesh.faces * 3 * Short.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asShortBuffer();
        mesh.fbVertices = ByteBuffer.allocateDirect(groupVertices.length * 3 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
        mesh.fbNormals = ByteBuffer.allocateDirect(groupNormals.length * 3 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
        mesh.fbTextureCoordinates = groupTextureCoordinates != null ? ByteBuffer.allocateDirect(groupTextureCoordinates.length * 2 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer() : null;
        mesh.fbTangents = groupTangents != null ? ByteBuffer.allocateDirect(groupTangents.length * 3 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer() : null;
        mesh.fbBitangents = groupBitangents != null ? ByteBuffer.allocateDirect(groupBitangents.length * 3 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer() : null;
        // create face vertex indices, will never be changed in engine
        for (FacesEntity facesEntity : group.getFacesEntities()) for (Face face : facesEntity.getFaces()) for (int vertexIndex : face.getVertexIndices()) {
            mesh.sbIndices.put((short) vertexIndex);
        }
        mesh.sbIndices.flip();
        // create texture coordinates buffer, will never be changed in engine
        if (mesh.fbTextureCoordinates != null) {
            // construct texture coordinates byte buffer as this will not change usually
            for (TextureCoordinate textureCoordinate : groupTextureCoordinates) {
                mesh.fbTextureCoordinates.put(textureCoordinate.getArray());
            }
            mesh.fbTextureCoordinates.flip();
        }
    }
    // group transformations matrix
    if (mesh.animationProcessingTarget == Engine.AnimationProcessingTarget.CPU || mesh.animationProcessingTarget == Engine.AnimationProcessingTarget.CPU_NORENDERING) {
        // group transformations matrix 
        mesh.cGroupTransformationsMatrix = transformationMatrices.get(group.getId());
    }
    // skinning
    if (skinning != null) {
        // skinning computation caches if computing skinning on CPU
        if (mesh.animationProcessingTarget == Engine.AnimationProcessingTarget.CPU || mesh.animationProcessingTarget == Engine.AnimationProcessingTarget.CPU_NORENDERING) {
            mesh.cSkinningJointWeight = new float[groupVertices.length][];
            mesh.cSkinningJointBindMatrices = new Matrix4x4[groupVertices.length][];
            mesh.cSkinningJointTransformationsMatrices = new Matrix4x4[groupVertices.length][];
            mesh.cTransformationsMatrix = new Matrix4x4();
            // compute joint weight caches
            Joint[] joints = skinning.getJoints();
            float[] weights = skinning.getWeights();
            JointWeight[][] jointsWeights = skinning.getVerticesJointsWeights();
            for (int vertexIndex = 0; vertexIndex < groupVertices.length; vertexIndex++) {
                int vertexJointWeights = jointsWeights[vertexIndex].length;
                if (vertexJointWeights > mesh.cSkinningMaxVertexWeights)
                    mesh.cSkinningMaxVertexWeights = vertexJointWeights;
                mesh.cSkinningJointWeight[vertexIndex] = new float[vertexJointWeights];
                mesh.cSkinningJointBindMatrices[vertexIndex] = new Matrix4x4[vertexJointWeights];
                mesh.cSkinningJointTransformationsMatrices[vertexIndex] = new Matrix4x4[vertexJointWeights];
                int jointWeightIdx = 0;
                for (JointWeight jointWeight : jointsWeights[vertexIndex]) {
                    Joint joint = joints[jointWeight.getJointIndex()];
                    // 
                    mesh.cSkinningJointWeight[vertexIndex][jointWeightIdx] = weights[jointWeight.getWeightIndex()];
                    mesh.cSkinningJointBindMatrices[vertexIndex][jointWeightIdx] = joint.getBindMatrix();
                    mesh.cSkinningJointTransformationsMatrices[vertexIndex][jointWeightIdx] = transformationMatrices.get(joint.getGroupId());
                    // next
                    jointWeightIdx++;
                }
            }
        } else // GPU setup
        if (mesh.animationProcessingTarget == Engine.AnimationProcessingTarget.GPU) {
            // create skinning buffers
            mesh.gIbSkinningVerticesJoints = ByteBuffer.allocateDirect(groupVertices.length * 1 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
            mesh.gFbSkinningVerticesVertexJointsIdxs = ByteBuffer.allocateDirect(groupVertices.length * 4 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
            mesh.gFbSkinningVerticesVertexJointsWeights = ByteBuffer.allocateDirect(groupVertices.length * 4 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
            mesh.gFbSkinningJointsTransformationsMatrices = ByteBuffer.allocateDirect(60 * 16 * Float.SIZE / Byte.SIZE).order(ByteOrder.nativeOrder()).asFloatBuffer();
            mesh.gFbSkinningTransformationMatrix = new Matrix4x4();
            // fill skinning buffers, joint bind matrices
            mesh.skinningJoints = skinning.getJoints().length;
            mesh.gSkinningJointBindMatrices = new ArrayList<Matrix4x4>();
            for (Joint joint : skinning.getJoints()) {
                mesh.gSkinningJointBindMatrices.add(joint.getBindMatrix());
            }
            //
            JointWeight[][] jointsWeights = skinning.getVerticesJointsWeights();
            float[] weights = skinning.getWeights();
            for (int groupVertexIndex = 0; groupVertexIndex < groupVertices.length; groupVertexIndex++) {
                int vertexJoints = jointsWeights[groupVertexIndex].length;
                // put number of joints
                mesh.gIbSkinningVerticesJoints.put((float) vertexJoints);
                // vertex joint idx 1..4
                for (int i = 0; i < 4; i++) {
                    mesh.gFbSkinningVerticesVertexJointsIdxs.put((float) (vertexJoints > i ? jointsWeights[groupVertexIndex][i].getJointIndex() : -1));
                }
                // vertex joint weight 1..4
                for (int i = 0; i < 4; i++) {
                    mesh.gFbSkinningVerticesVertexJointsWeights.put(vertexJoints > i ? weights[jointsWeights[groupVertexIndex][i].getWeightIndex()] : 0.0f);
                }
            }
            // put number of joints
            mesh.gIbSkinningVerticesJoints.flip();
            // vertex joint idx 1..4
            mesh.gFbSkinningVerticesVertexJointsIdxs.flip();
            // vertex joint weight 1..4
            mesh.gFbSkinningVerticesVertexJointsWeights.flip();
        }
    }
    // temp vector3
    mesh.tmpVector3 = new Vector3();
    // issue a recreate buffer and upload to graphics board
    mesh.recreateBuffers(group);
    //
    return mesh;
}
Also used : FacesEntity(net.drewke.tdme.engine.model.FacesEntity) ArrayList(java.util.ArrayList) Vector3(net.drewke.tdme.math.Vector3) Joint(net.drewke.tdme.engine.model.Joint) JointWeight(net.drewke.tdme.engine.model.JointWeight) Joint(net.drewke.tdme.engine.model.Joint) Matrix4x4(net.drewke.tdme.math.Matrix4x4) TextureCoordinate(net.drewke.tdme.engine.model.TextureCoordinate) Skinning(net.drewke.tdme.engine.model.Skinning) Face(net.drewke.tdme.engine.model.Face)

Example 3 with JointWeight

use of net.drewke.tdme.engine.model.JointWeight in project tdme by andreasdr.

the class DAEReader method readVisualSceneInstanceController.

/**
	 * Reads a instance controller
	 * @param authoring tool
	 * @param path name
	 * @param model
	 * @param parent group
	 * @param xml root
	 * @param xml node
	 * @return Group
	 * @throws Exception
	 */
private static Group readVisualSceneInstanceController(AuthoringTool authoringTool, String pathName, Model model, Group parentGroup, Element xmlRoot, Element xmlNode) throws Exception {
    StringTokenizer t;
    String xmlNodeId = xmlNode.getAttribute("id");
    String xmlNodeName = xmlNode.getAttribute("name");
    HashMap<String, String> materialSymbols = new HashMap<String, String>();
    // geometry id
    String xmlGeometryId = null;
    // parse library controllers, find our controller
    List<Element> xmlInstanceControllers = getChildrenByTagName(xmlNode, "instance_controller");
    Element xmlSkin = null;
    Element xmlInstanceController = xmlInstanceControllers.get(0);
    // parse material symbols
    for (Element xmlBindMaterial : getChildrenByTagName(xmlInstanceController, "bind_material")) for (Element xmlTechniqueCommon : getChildrenByTagName(xmlBindMaterial, "technique_common")) for (Element xmlInstanceMaterial : getChildrenByTagName(xmlTechniqueCommon, "instance_material")) {
        materialSymbols.put(xmlInstanceMaterial.getAttribute("symbol"), xmlInstanceMaterial.getAttribute("target"));
    }
    String xmlInstanceControllerId = xmlInstanceController.getAttribute("url").substring(1);
    Element xmlLibraryControllers = getChildrenByTagName(xmlRoot, "library_controllers").get(0);
    for (Element xmlLibraryController : getChildrenByTagName(xmlLibraryControllers, "controller")) {
        // our controller ?
        if (xmlLibraryController.getAttribute("id").equals(xmlInstanceControllerId)) {
            // parse skin
            List<Element> xmlSkins = getChildrenByTagName(xmlLibraryController, "skin");
            if (xmlSkins.isEmpty() == false) {
                xmlSkin = xmlSkins.get(0);
            }
        }
    }
    // check for xml skin
    if (xmlSkin == null) {
        throw new ModelFileIOException("skin not found for instance controller " + xmlNodeId);
    }
    // get geometry id
    xmlGeometryId = xmlSkin.getAttribute("source").substring(1);
    // parse bind shape matrix
    String xmlMatrix = getChildrenByTagName(xmlSkin, "bind_shape_matrix").get(0).getTextContent();
    t = new StringTokenizer(xmlMatrix, " \n\r");
    // 
    Matrix4x4 bindShapeMatrix = new Matrix4x4(Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken())).transpose();
    // tdme model definitions
    Group group = new Group(model, parentGroup, xmlNodeId, xmlNodeName);
    // create skinning
    Skinning skinning = group.createSkinning();
    // parse geometry
    readGeometry(authoringTool, pathName, model, group, xmlRoot, xmlGeometryId, materialSymbols);
    // parse joints
    String xmlJointsSource = null;
    String xmlJointsInverseBindMatricesSource = null;
    Element xmlJoints = getChildrenByTagName(xmlSkin, "joints").get(0);
    for (Element xmlJointsInput : getChildrenByTagName(xmlJoints, "input")) {
        if (xmlJointsInput.getAttribute("semantic").equals("JOINT")) {
            xmlJointsSource = xmlJointsInput.getAttribute("source").substring(1);
        } else if (xmlJointsInput.getAttribute("semantic").equals("INV_BIND_MATRIX")) {
            xmlJointsInverseBindMatricesSource = xmlJointsInput.getAttribute("source").substring(1);
        }
    }
    // check for joints sources
    if (xmlJointsSource == null) {
        throw new ModelFileIOException("joint source not found for instance controller " + xmlNodeId);
    }
    // parse joint ids
    ArrayList<Joint> joints = new ArrayList<Joint>();
    for (Element xmlSkinSource : getChildrenByTagName(xmlSkin, "source")) {
        if (xmlSkinSource.getAttribute("id").equals(xmlJointsSource)) {
            t = new StringTokenizer(getChildrenByTagName(xmlSkinSource, "Name_array").get(0).getTextContent(), " \n\r");
            while (t.hasMoreTokens()) {
                joints.add(new Joint(t.nextToken()));
            }
        }
    }
    skinning.setJoints(joints);
    // check for inverse bind matrices source
    if (xmlJointsInverseBindMatricesSource == null) {
        throw new ModelFileIOException("inverse bind matrices source not found for instance controller " + xmlNodeId);
    }
    // Create joints bind matrices
    for (Element xmlSkinSource : getChildrenByTagName(xmlSkin, "source")) {
        if (xmlSkinSource.getAttribute("id").equals(xmlJointsInverseBindMatricesSource)) {
            t = new StringTokenizer(getChildrenByTagName(xmlSkinSource, "float_array").get(0).getTextContent(), " \n\r");
            Joint[] _joints = skinning.getJoints();
            for (int i = 0; i < _joints.length; i++) {
                _joints[i].getBindMatrix().multiply(bindShapeMatrix);
                _joints[i].getBindMatrix().multiply(// The transformation to the local space of the joint is called the inverse bind matrix
                new Matrix4x4(Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken()), Float.parseFloat(t.nextToken())).transpose());
            }
        }
    }
    // read vertex influences
    ArrayList<Float> weights = new ArrayList<Float>();
    int xmlJointOffset = -1;
    int xmlWeightOffset = -1;
    String xmlWeightsSource = null;
    Element xmlVertexWeights = getChildrenByTagName(xmlSkin, "vertex_weights").get(0);
    List<Element> xmlVertexWeightInputs = getChildrenByTagName(xmlVertexWeights, "input");
    for (Element xmlVertexWeightInput : xmlVertexWeightInputs) {
        if (xmlVertexWeightInput.getAttribute("semantic").equals("JOINT")) {
            if (xmlVertexWeightInput.getAttribute("source").substring(1).equals(xmlJointsSource) == false) {
                throw new ModelFileIOException("joint inverse bind matrices source do not match");
            }
            xmlJointOffset = Integer.parseInt(xmlVertexWeightInput.getAttribute("offset"));
        } else if (xmlVertexWeightInput.getAttribute("semantic").equals("WEIGHT")) {
            xmlWeightOffset = Integer.parseInt(xmlVertexWeightInput.getAttribute("offset"));
            xmlWeightsSource = xmlVertexWeightInput.getAttribute("source").substring(1);
        }
    }
    // check for vertex weight parameter 
    if (xmlJointOffset == -1) {
        throw new ModelFileIOException("xml vertex weight joint offset missing for node " + xmlNodeId);
    }
    if (xmlWeightOffset == -1) {
        throw new ModelFileIOException("xml vertex weight weight offset missing for node " + xmlNodeId);
    }
    if (xmlWeightsSource == null) {
        throw new ModelFileIOException("xml vertex weight weight source missing for node " + xmlNodeId);
    }
    // parse weights
    for (Element xmlSkinSource : getChildrenByTagName(xmlSkin, "source")) {
        if (xmlSkinSource.getAttribute("id").equals(xmlWeightsSource)) {
            t = new StringTokenizer(getChildrenByTagName(xmlSkinSource, "float_array").get(0).getTextContent(), " \n\r");
            while (t.hasMoreTokens()) {
                weights.add(new Float(Float.parseFloat(t.nextToken())));
            }
        }
    }
    skinning.setWeights(weights);
    // actually do parse joint influences of each vertex
    int xmlVertexWeightInputCount = xmlVertexWeightInputs.size();
    String vertexJointsInfluenceCountString = getChildrenByTagName(xmlVertexWeights, "vcount").get(0).getTextContent();
    String vertexJointsInfluencesString = getChildrenByTagName(xmlVertexWeights, "v").get(0).getTextContent();
    t = new StringTokenizer(vertexJointsInfluenceCountString, " \n\r");
    StringTokenizer t2 = new StringTokenizer(vertexJointsInfluencesString, " \n\r");
    int offset = 0;
    ArrayList<ArrayList<JointWeight>> verticesJointsWeights = new ArrayList<ArrayList<JointWeight>>();
    while (t.hasMoreTokens()) {
        // read joint influences for current vertex
        int vertexJointsInfluencesCount = Integer.parseInt(t.nextToken());
        ArrayList<JointWeight> vertexJointsWeights = new ArrayList<JointWeight>();
        for (int i = 0; i < vertexJointsInfluencesCount; i++) {
            int vertexJoint = -1;
            int vertexWeight = -1;
            while (vertexJoint == -1 || vertexWeight == -1) {
                int value = Integer.parseInt(t2.nextToken());
                if (offset % xmlVertexWeightInputCount == xmlJointOffset) {
                    vertexJoint = value;
                } else if (offset % xmlVertexWeightInputCount == xmlWeightOffset) {
                    vertexWeight = value;
                }
                offset++;
            }
            vertexJointsWeights.add(new JointWeight(vertexJoint, vertexWeight));
        }
        verticesJointsWeights.add(vertexJointsWeights);
    }
    skinning.setVerticesJointsWeights(verticesJointsWeights);
    return group;
}
Also used : Group(net.drewke.tdme.engine.model.Group) HashMap(net.drewke.tdme.utils.HashMap) Element(org.w3c.dom.Element) ArrayList(java.util.ArrayList) Joint(net.drewke.tdme.engine.model.Joint) JointWeight(net.drewke.tdme.engine.model.JointWeight) Matrix4x4(net.drewke.tdme.math.Matrix4x4) Joint(net.drewke.tdme.engine.model.Joint) StringTokenizer(java.util.StringTokenizer) Skinning(net.drewke.tdme.engine.model.Skinning)

Aggregations

Joint (net.drewke.tdme.engine.model.Joint)3 JointWeight (net.drewke.tdme.engine.model.JointWeight)3 Skinning (net.drewke.tdme.engine.model.Skinning)3 ArrayList (java.util.ArrayList)2 Matrix4x4 (net.drewke.tdme.math.Matrix4x4)2 StringTokenizer (java.util.StringTokenizer)1 Face (net.drewke.tdme.engine.model.Face)1 FacesEntity (net.drewke.tdme.engine.model.FacesEntity)1 Group (net.drewke.tdme.engine.model.Group)1 TextureCoordinate (net.drewke.tdme.engine.model.TextureCoordinate)1 Vector3 (net.drewke.tdme.math.Vector3)1 HashMap (net.drewke.tdme.utils.HashMap)1 Element (org.w3c.dom.Element)1