Search in sources :

Example 11 with Group

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

the class DAEReader method readLevel.

/**
	 * Reads Collada DAE file level
	 * @param path name
	 * @param file name
	 * @throws Exception
	 * @return Model instance
	 */
public static LevelEditorLevel readLevel(String pathName, String fileName) throws Exception {
    // (re)create tm files folder
    File tmFilesFolder = new File(pathName + "/" + fileName + "-models");
    if (tmFilesFolder.exists()) {
        tmFilesFolder.delete();
    }
    tmFilesFolder.mkdir();
    // create level
    LevelEditorLevel levelEditorLevel = new LevelEditorLevel();
    LevelPropertyPresets.getInstance().setDefaultLevelProperties(levelEditorLevel);
    // load dae xml document
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = builder.parse(FileSystem.getInstance().getInputStream(pathName, fileName));
    Element xmlRoot = document.getDocumentElement();
    // authoring tool
    AuthoringTool authoringTool = getAuthoringTool(xmlRoot);
    // up vector and rotation order
    UpVector upVector = getUpVector(xmlRoot);
    RotationOrder rotationOrder = null;
    switch(upVector) {
        case Y_UP:
            rotationOrder = RotationOrder.ZYX;
        case Z_UP:
            rotationOrder = RotationOrder.YZX;
    }
    levelEditorLevel.setRotationOrder(rotationOrder);
    // parse scene from xml
    String xmlSceneId = null;
    Element xmlScene = getChildrenByTagName(xmlRoot, "scene").get(0);
    for (Element xmlInstanceVisualscene : getChildrenByTagName(xmlScene, "instance_visual_scene")) {
        xmlSceneId = xmlInstanceVisualscene.getAttribute("url").substring(1);
    }
    // check for xml scene id
    if (xmlSceneId == null) {
        throw new ModelFileIOException("No scene id found");
    }
    // parse visual scenes
    Element xmlLibraryVisualScenes = getChildrenByTagName(xmlRoot, "library_visual_scenes").get(0);
    for (Element xmlLibraryVisualScene : getChildrenByTagName(xmlLibraryVisualScenes, "visual_scene")) {
        String xmlVisualSceneId = xmlLibraryVisualScene.getAttribute("id");
        if (xmlVisualSceneId.equals(xmlSceneId)) {
            // default FPS
            float fps = 30f;
            // parse frames per second
            List<Element> xmlExtraNodes = getChildrenByTagName(xmlLibraryVisualScene, "extra");
            if (xmlExtraNodes.isEmpty() == false) {
                Element xmlExtraNode = xmlExtraNodes.get(0);
                for (Element xmlTechnique : getChildrenByTagName(xmlExtraNode, "technique")) {
                    List<Element> xmlFrameRateNodes = getChildrenByTagName(xmlTechnique, "frame_rate");
                    if (xmlFrameRateNodes.isEmpty() == false) {
                        fps = Float.parseFloat(xmlFrameRateNodes.get(0).getTextContent());
                        break;
                    }
                }
            }
            // visual scene root nodes
            LevelEditorEntityLibrary entityLibrary = levelEditorLevel.getEntityLibrary();
            LevelEditorEntity emptyEntity = null;
            int nodeIdx = 0;
            for (Element xmlNode : getChildrenByTagName(xmlLibraryVisualScene, "node")) {
                // derive model name from node id
                String modelName = xmlNode.getAttribute("id");
                // replace blender _|-NUMBER, not sure if this is a good idea for all cases, we will see
                modelName = modelName.replaceAll("[\\-\\_]{1}+[0-9]+$", "");
                // replace number at the end still, not sure if this is a good idea for all cases, we will see
                modelName = modelName.replaceAll("[0-9]+$", "");
                // check if name is available, if not extend with numbers :DDD
                boolean haveName = entityLibrary.getEntityCount() == 0;
                if (haveName == false) {
                    for (int i = 0; i < 10000; i++) {
                        haveName = true;
                        String modelNameTry = modelName + (i == 0 ? "" : String.valueOf(i));
                        for (int entityIdx = 0; entityIdx < entityLibrary.getEntityCount(); entityIdx++) {
                            LevelEditorEntity entity = entityLibrary.getEntityAt(entityIdx);
                            if (entity.getName().equals(modelNameTry) == true) {
                                haveName = false;
                                break;
                            }
                        }
                        if (haveName == true) {
                            modelName = modelNameTry;
                            break;
                        }
                    }
                }
                // do we have a name now?
                if (haveName == false) {
                    // nope, cant imagine this will happen 
                    System.out.println("DAEReader::readLevel(): Skipping model '" + modelName + "' as no name could be created for it.");
                    continue;
                }
                // 	create model
                Model model = new Model(pathName + File.separator + fileName + '-' + modelName, fileName + '-' + modelName, upVector, rotationOrder, null);
                // import matrix
                setupModelImportRotationMatrix(xmlRoot, model);
                Matrix4x4 modelImportRotationMatrix = new Matrix4x4(model.getImportTransformationsMatrix());
                setupModelImportScaleMatrix(xmlRoot, model);
                // translation, scaling, rotation
                Vector3 translation = new Vector3();
                Vector3 scale = new Vector3();
                Vector3 rotation = new Vector3();
                Vector3 xAxis = new Vector3();
                Vector3 yAxis = new Vector3();
                Vector3 zAxis = new Vector3();
                // set up local transformations matrix
                Matrix4x4 nodeTransformationsMatrix = null;
                List<Element> xmlMatrixElements = getChildrenByTagName(xmlNode, "matrix");
                if (xmlMatrixElements.size() == 1) {
                    String xmlMatrix = xmlMatrixElements.get(0).getTextContent();
                    StringTokenizer t = new StringTokenizer(xmlMatrix, " \n\r");
                    // 
                    nodeTransformationsMatrix = 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();
                }
                // check if we have node transformations matrix
                if (nodeTransformationsMatrix == null) {
                    throw new ModelFileIOException("missing node transformations matrix for node " + xmlNode.getAttribute("id"));
                }
                // extract coordinate system axes
                nodeTransformationsMatrix.getAxes(xAxis, yAxis, zAxis);
                nodeTransformationsMatrix.getTranslation(translation);
                nodeTransformationsMatrix.getScale(scale);
                // normalize coordinate axes
                xAxis.normalize();
                yAxis.normalize();
                zAxis.normalize();
                // write back normalized x axis
                nodeTransformationsMatrix.setAxes(xAxis, yAxis, zAxis);
                // TODO: move me into Matrix4x4 decomposing code?
                if ((upVector == UpVector.Y_UP && Vector3.computeDotProduct(Vector3.computeCrossProduct(xAxis, yAxis), zAxis) < 0.0f) || (upVector == UpVector.Z_UP && Vector3.computeDotProduct(Vector3.computeCrossProduct(xAxis, zAxis), yAxis) < 0.0f)) {
                    // negate axes
                    xAxis.scale(-1f);
                    yAxis.scale(-1f);
                    zAxis.scale(-1f);
                    // and write back to node transformation matrices
                    nodeTransformationsMatrix.setAxes(xAxis, yAxis, zAxis);
                    // scale
                    scale.scale(-1f);
                }
                // determine rotation
                nodeTransformationsMatrix.computeEulerAngles(rotation);
                // apply model import matrix
                modelImportRotationMatrix.multiply(scale, scale);
                modelImportRotationMatrix.multiply(rotation, rotation);
                model.getImportTransformationsMatrix().multiply(translation, translation);
                // set up frames per seconds
                model.setFPS(fps);
                // read sub groups
                Group group = readVisualSceneNode(authoringTool, pathName, model, null, xmlRoot, xmlNode, fps);
                if (group != null) {
                    group.getTransformationsMatrix().identity();
                    model.getSubGroups().put(group.getId(), group);
                    model.getGroups().put(group.getId(), group);
                }
                // set up joints
                ModelHelper.setupJoints(model);
                // fix animation length
                ModelHelper.fixAnimationLength(model);
                // prepare for indexed rendering
                ModelHelper.prepareForIndexedRendering(model);
                // check if empty model
                EntityType entityType = EntityType.MODEL;
                ModelStatistics modelStatistics = ModelUtilities.computeModelStatistics(model);
                if (modelStatistics.getOpaqueFaceCount() == 0 && modelStatistics.getTransparentFaceCount() == 0) {
                    entityType = EntityType.EMPTY;
                }
                // level editor entity
                LevelEditorEntity levelEditorEntity = null;
                // model
                if (entityType == EntityType.MODEL) {
                    // check if we have that model already
                    for (int i = 0; i < levelEditorLevel.getEntityLibrary().getEntityCount(); i++) {
                        LevelEditorEntity levelEditorEntityCompare = levelEditorLevel.getEntityLibrary().getEntityAt(i);
                        if (levelEditorEntityCompare.getType() != EntityType.MODEL)
                            continue;
                        if (ModelUtilities.equals(model, levelEditorEntityCompare.getModel()) == true) {
                            levelEditorEntity = levelEditorEntityCompare;
                            break;
                        }
                    }
                    // create level editor model, if not yet exists
                    if (levelEditorEntity == null) {
                        // save model
                        TMWriter.write(model, pathName + "/" + fileName + "-models", modelName + ".tm");
                        // create level editor entity
                        levelEditorEntity = entityLibrary.addModel(nodeIdx++, modelName, modelName, pathName + "/" + fileName + "-models", modelName + ".tm", new Vector3());
                    }
                } else // empty
                if (entityType == EntityType.EMPTY) {
                    if (emptyEntity == null) {
                        emptyEntity = entityLibrary.addEmpty(nodeIdx++, "Default Empty", "");
                    }
                    levelEditorEntity = emptyEntity;
                } else {
                    System.out.println("DAEReader::readLevel(): unknown entity type. Skipping");
                    continue;
                }
                // level editor object transformations
                Transformations levelEditorObjectTransformations = new Transformations();
                levelEditorObjectTransformations.getTranslation().set(translation);
                levelEditorObjectTransformations.getRotations().add(new Rotation(rotation.getArray()[rotationOrder.getAxis0VectorIndex()], rotationOrder.getAxis0()));
                levelEditorObjectTransformations.getRotations().add(new Rotation(rotation.getArray()[rotationOrder.getAxis1VectorIndex()], rotationOrder.getAxis1()));
                levelEditorObjectTransformations.getRotations().add(new Rotation(rotation.getArray()[rotationOrder.getAxis2VectorIndex()], rotationOrder.getAxis2()));
                levelEditorObjectTransformations.getScale().set(scale);
                levelEditorObjectTransformations.update();
                // level editor object
                LevelEditorObject object = new LevelEditorObject(xmlNode.getAttribute("id"), xmlNode.getAttribute("id"), levelEditorObjectTransformations, levelEditorEntity);
                // add object to level
                levelEditorLevel.addObject(object);
            }
        }
    }
    // save level
    LevelFileExport.export(pathName + "/" + fileName + ".tl", levelEditorLevel);
    //
    return levelEditorLevel;
}
Also used : Group(net.drewke.tdme.engine.model.Group) Element(org.w3c.dom.Element) Document(org.w3c.dom.Document) ModelStatistics(net.drewke.tdme.engine.subsystems.object.ModelUtilitiesInternal.ModelStatistics) LevelEditorObject(net.drewke.tdme.tools.shared.model.LevelEditorObject) LevelEditorEntity(net.drewke.tdme.tools.shared.model.LevelEditorEntity) UpVector(net.drewke.tdme.engine.model.Model.UpVector) Vector3(net.drewke.tdme.math.Vector3) Rotation(net.drewke.tdme.engine.Rotation) Joint(net.drewke.tdme.engine.model.Joint) Matrix4x4(net.drewke.tdme.math.Matrix4x4) EntityType(net.drewke.tdme.tools.shared.model.LevelEditorEntity.EntityType) LevelEditorEntityLibrary(net.drewke.tdme.tools.shared.model.LevelEditorEntityLibrary) StringTokenizer(java.util.StringTokenizer) LevelEditorLevel(net.drewke.tdme.tools.shared.model.LevelEditorLevel) DocumentBuilder(javax.xml.parsers.DocumentBuilder) RotationOrder(net.drewke.tdme.engine.model.RotationOrder) Model(net.drewke.tdme.engine.model.Model) Transformations(net.drewke.tdme.engine.Transformations) File(java.io.File)

Example 12 with Group

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

the class TMReader method readSubGroups.

/**
	 * Read sub groups
	 * @param input stream
	 * @param model
	 * @param sub groups
	 * @throws IOException
	 * @throws ModelFileIOException
	 * @return group
	 */
private static void readSubGroups(InputStream is, Model model, Group parentGroup, HashMap<String, Group> subGroups) throws IOException, ModelFileIOException {
    int subGroupCount = readInt(is);
    for (int i = 0; i < subGroupCount; i++) {
        Group subGroup = readGroup(is, model, parentGroup);
        subGroups.put(subGroup.getId(), subGroup);
        model.getGroups().put(subGroup.getId(), subGroup);
    }
}
Also used : Group(net.drewke.tdme.engine.model.Group) Joint(net.drewke.tdme.engine.model.Joint)

Example 13 with Group

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

the class TMReader method readGroup.

/**
	 * Write group to output stream
	 * @param input stream
	 * @param model
	 * @param parent group
	 * @throws IOException
	 * @throws ModelFileIOException
	 * @return group
	 */
private static Group readGroup(InputStream is, Model model, Group parentGroup) throws IOException, ModelFileIOException {
    Group group = new Group(model, parentGroup, readString(is), readString(is));
    group.setJoint(readBoolean(is));
    group.getTransformationsMatrix().set(readFloatArray(is));
    group.setVertices(readVertices(is));
    group.setNormals(readVertices(is));
    group.setTextureCoordinates(readTextureCoordinates(is));
    group.setTangents(readVertices(is));
    group.setBitangents(readVertices(is));
    readAnimation(is, group);
    readSkinning(is, group);
    readFacesEntities(is, group);
    group.determineFeatures();
    readSubGroups(is, model, parentGroup, group.getSubGroups());
    return group;
}
Also used : Group(net.drewke.tdme.engine.model.Group)

Example 14 with Group

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

the class DAEReader method read.

/**
	 * Reads Collada DAE file
	 * @param path name
	 * @param file name
	 * @throws Exception
	 * @return Model instance
	 */
public static Model read(String pathName, String fileName) throws Exception {
    // load dae xml document
    DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
    Document document = builder.parse(FileSystem.getInstance().getInputStream(pathName, fileName));
    Element xmlRoot = document.getDocumentElement();
    // authoring tool
    AuthoringTool authoringTool = getAuthoringTool(xmlRoot);
    // up vector and rotation order
    UpVector upVector = getUpVector(xmlRoot);
    RotationOrder rotationOrder = null;
    switch(upVector) {
        case Y_UP:
            rotationOrder = RotationOrder.ZYX;
        case Z_UP:
            rotationOrder = RotationOrder.YZX;
    }
    // 	create model
    Model model = new Model(pathName + File.separator + fileName, fileName, upVector, rotationOrder, null);
    // import matrix
    setupModelImportRotationMatrix(xmlRoot, model);
    setupModelImportScaleMatrix(xmlRoot, model);
    // parse scene from xml
    String xmlSceneId = null;
    Element xmlScene = getChildrenByTagName(xmlRoot, "scene").get(0);
    for (Element xmlInstanceVisualscene : getChildrenByTagName(xmlScene, "instance_visual_scene")) {
        xmlSceneId = xmlInstanceVisualscene.getAttribute("url").substring(1);
    }
    // check for xml scene id
    if (xmlSceneId == null) {
        throw new ModelFileIOException("No scene id found");
    }
    // parse visual scenes
    Element xmlLibraryVisualScenes = getChildrenByTagName(xmlRoot, "library_visual_scenes").get(0);
    for (Element xmlLibraryVisualScene : getChildrenByTagName(xmlLibraryVisualScenes, "visual_scene")) {
        String xmlVisualSceneId = xmlLibraryVisualScene.getAttribute("id");
        if (xmlVisualSceneId.equals(xmlSceneId)) {
            // default FPS
            float fps = 30f;
            // parse frames per second
            List<Element> xmlExtraNodes = getChildrenByTagName(xmlLibraryVisualScene, "extra");
            if (xmlExtraNodes.isEmpty() == false) {
                Element xmlExtraNode = xmlExtraNodes.get(0);
                for (Element xmlTechnique : getChildrenByTagName(xmlExtraNode, "technique")) {
                    List<Element> xmlFrameRateNodes = getChildrenByTagName(xmlTechnique, "frame_rate");
                    if (xmlFrameRateNodes.isEmpty() == false) {
                        fps = Float.parseFloat(xmlFrameRateNodes.get(0).getTextContent());
                        break;
                    }
                }
            }
            // set up frames per seconds
            model.setFPS(fps);
            // visual scene root nodes
            for (Element xmlNode : getChildrenByTagName(xmlLibraryVisualScene, "node")) {
                Group group = readVisualSceneNode(authoringTool, pathName, model, null, xmlRoot, xmlNode, fps);
                if (group != null) {
                    model.getSubGroups().put(group.getId(), group);
                    model.getGroups().put(group.getId(), group);
                }
            }
        }
    }
    // set up joints
    ModelHelper.setupJoints(model);
    // fix animation length
    ModelHelper.fixAnimationLength(model);
    // prepare for indexed rendering
    ModelHelper.prepareForIndexedRendering(model);
    //
    return model;
}
Also used : Group(net.drewke.tdme.engine.model.Group) UpVector(net.drewke.tdme.engine.model.Model.UpVector) DocumentBuilder(javax.xml.parsers.DocumentBuilder) Element(org.w3c.dom.Element) RotationOrder(net.drewke.tdme.engine.model.RotationOrder) Model(net.drewke.tdme.engine.model.Model) Document(org.w3c.dom.Document)

Example 15 with Group

use of net.drewke.tdme.engine.model.Group 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

Group (net.drewke.tdme.engine.model.Group)17 Model (net.drewke.tdme.engine.model.Model)10 ArrayList (java.util.ArrayList)9 Vector3 (net.drewke.tdme.math.Vector3)9 Face (net.drewke.tdme.engine.model.Face)8 FacesEntity (net.drewke.tdme.engine.model.FacesEntity)8 Material (net.drewke.tdme.engine.model.Material)8 Matrix4x4 (net.drewke.tdme.math.Matrix4x4)6 Joint (net.drewke.tdme.engine.model.Joint)5 StringTokenizer (java.util.StringTokenizer)4 TextureCoordinate (net.drewke.tdme.engine.model.TextureCoordinate)4 Element (org.w3c.dom.Element)4 DocumentBuilder (javax.xml.parsers.DocumentBuilder)2 Animation (net.drewke.tdme.engine.model.Animation)2 UpVector (net.drewke.tdme.engine.model.Model.UpVector)2 RotationOrder (net.drewke.tdme.engine.model.RotationOrder)2 Skinning (net.drewke.tdme.engine.model.Skinning)2 HashMap (net.drewke.tdme.utils.HashMap)2 Document (org.w3c.dom.Document)2 BufferedReader (java.io.BufferedReader)1