Search in sources :

Example 21 with Matrix4x4

use of net.drewke.tdme.math.Matrix4x4 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

Matrix4x4 (net.drewke.tdme.math.Matrix4x4)21 Group (net.drewke.tdme.engine.model.Group)6 Joint (net.drewke.tdme.engine.model.Joint)5 Vector3 (net.drewke.tdme.math.Vector3)5 StringTokenizer (java.util.StringTokenizer)3 Skinning (net.drewke.tdme.engine.model.Skinning)3 Element (org.w3c.dom.Element)3 ArrayList (java.util.ArrayList)2 Animation (net.drewke.tdme.engine.model.Animation)2 JointWeight (net.drewke.tdme.engine.model.JointWeight)2 HashMap (net.drewke.tdme.utils.HashMap)2 File (java.io.File)1 DocumentBuilder (javax.xml.parsers.DocumentBuilder)1 Entity (net.drewke.tdme.engine.Entity)1 Rotation (net.drewke.tdme.engine.Rotation)1 Transformations (net.drewke.tdme.engine.Transformations)1 Face (net.drewke.tdme.engine.model.Face)1 FacesEntity (net.drewke.tdme.engine.model.FacesEntity)1 Model (net.drewke.tdme.engine.model.Model)1 UpVector (net.drewke.tdme.engine.model.Model.UpVector)1