⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 x3dtojme.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                indices[i] = i;
            }
        } else {
            /*
             * Indices available => in order to also use color and normal
             * indices, the vertices list must be expanded
             */
            indicesAvailable = true;
        }

        // Parse the colors
        float[] colorValues = null;
        int colorSize = 3; // Number of values per color (Color or ColorRGBA)
        Node colors = getChildNode(node, "Color");
        if (colors == null) {
            colorSize = 4;
            colors = getChildNode(node, "ColorRGBA");
        }
        if (colors != null) {
            colorValues = parseValues(colors, "color");
        }

        // Parse the color indices
        int[] colorIndices = null;
        if (colorValues != null) {
            colorIndices = parseIndices(node, "colorIndex");
        }

        // Expand RGB color values to RGBA values
        if (colorValues != null && colorSize == 3) {
            float[] temp = new float[colorValues.length / 3 * 4];
            for (int i = 0; i * 3 < colorValues.length; i++) {
                temp[i * 4 + 0] = colorValues[i * 3 + 0];
                temp[i * 4 + 1] = colorValues[i * 3 + 1];
                temp[i * 4 + 2] = colorValues[i * 3 + 2];
                temp[i * 4 + 3] = 1.0f;
            }
            colorValues = temp;
            colorSize = 4;
        }

        // // If no colors are available, set up default colors
        // if (colorValues == null) {
        // colorValues = new float[indices.length * 4];
        // for (int i = 0; i < colorValues.length; i++) {
        // colorValues[i] = i;
        // }
        // }

        // Parse the normals
        float[] normalValues = null;
        Node normals = getChildNode(node, "Normal");
        if (normals != null) {
            normalValues = parseValues(normals, "vector");
        }

        // Parse the normal indices
        int[] normalIndices = null;
        if (normalValues != null) {
            normalIndices = parseIndices(node, "normalIndex");
        }

        // Get the crease angle, in case no normals are specified
        float creaseAngle = getFloat(node.getAttributes().getNamedItem(
                "creaseAngle").getNodeValue().trim(), 0);

        // Parse the texture coordinates
        // TODO: Enable MultiTextureCoordinate parsing!
        float[] texCoordValues = null;
        Node texCoords = getChildNode(node, "TextureCoordinate");
        if (texCoords != null) {
            texCoordValues = parseValues(texCoords, "point");
        }

        // Parse the texCoord indices
        int[] texCoordIndices = null;
        if (texCoordValues != null) {
            texCoordIndices = parseIndices(node, "texCoordIndex");
        }

        // If no tex coords are available, generate them
        if (texCoordValues == null) {
            texCoordValues = generateTexCoords(vertices);
        }

        // Create the Mesh
        TriMesh mesh;
        if (indicesAvailable && normalIndices == null && colorIndices == null
                && texCoordIndices == null) {

            // The mesh contains vertex indices, but no separate indices for
            // normals, colors or texCoords => The values can be used without
            // modification
            IntBuffer indexBuffer = BufferUtils.createIntBuffer(indices);
            FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertices);
            FloatBuffer colorBuffer = BufferUtils
                    .createFloatBuffer(colorValues);
            FloatBuffer normalBuffer = BufferUtils
                    .createFloatBuffer(normalValues);
            FloatBuffer texCoordBuffer = BufferUtils
                    .createFloatBuffer(texCoordValues);
            mesh = new TriMesh(null, vertexBuffer, normalBuffer, colorBuffer,
                    new TexCoords(texCoordBuffer), indexBuffer);

            // If no normals are available, they are generated
            if (normalBuffer == null) {
                normalGenerator.generateNormals(mesh, creaseAngle);
            }
        } else {
            int[] indicesBackup = indices.clone();

            // If vertex indices are specified as well as normal/color/texCoord
            // indices, the vertices have to be expanded so that every three
            // consecutive vertices define on triangle
            if (indicesAvailable) {
                vertices = expandValues(vertices, indices, 3, true);
            }

            // If separate indices are specified for normals/colors/texCoords,
            // expand the corresponding values accordingly. Otherwise, expand
            // them using the vertex indices, if available
            if (normalValues != null) {
                if (normalIndices != null) {
                    normalValues = expandValues(normalValues, normalIndices, 3,
                            false);
                } else if (indicesAvailable) {
                    normalValues = expandValues(normalValues, indicesBackup, 3,
                            false);
                }
            }
            if (colorValues != null) {
                if (colorIndices != null) {
                    colorValues = expandValues(colorValues, colorIndices,
                            colorSize, false);
                } else if (indicesAvailable) {
                    colorValues = expandValues(colorValues, indicesBackup,
                            colorSize, false);
                }
            }
            if (texCoordValues != null) {
                if (texCoordIndices != null) {
                    texCoordValues = expandValues(texCoordValues,
                            texCoordIndices, 2, false);
                } else if (indicesAvailable) {
                    texCoordValues = expandValues(texCoordValues,
                            indicesBackup, 2, false);
                }
            }

            // If no normals are available, they are generated
            if (normalValues == null) {
                normalValues = nonIndexedNormalGenerator.generateNormals(
                        vertices, indicesBackup, creaseAngle);
            }

            // Set up the mesh
            IntBuffer indexBuffer = BufferUtils.createIntBuffer(indices);
            FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(vertices);
            FloatBuffer colorBuffer = BufferUtils
                    .createFloatBuffer(colorValues);
            FloatBuffer normalBuffer = BufferUtils
                    .createFloatBuffer(normalValues);
            FloatBuffer texCoordBuffer = BufferUtils
                    .createFloatBuffer(texCoordValues);
            mesh = new TriMesh(null, vertexBuffer, normalBuffer, colorBuffer,
                    new TexCoords(texCoordBuffer), indexBuffer);
        }

        if (colorValues == null) {
            mesh.setDefaultColor(ColorRGBA.white.clone());
        }

        String name = (title != null) ? title : "X3D_IndexedFaceSet";
        mesh.setName(name);

        return mesh;
    }

    /**
     * Parses the values contained in the given X3D Coordinate, Color, Color3f
     * or Normal node and stores them in a float array
     * 
     * @param node
     *            The X3D node
     * @param attributeName
     *            The name of the attribute containing the values
     * @return An array containing the values
     */
    private float[] parseValues(Node node, String attributeName) {
        Node valuesNode = node.getAttributes().getNamedItem(attributeName);
        if (valuesNode == null) {
            return null;
        }
        String valuesString = valuesNode.getNodeValue().trim();
        String[] split = valuesString.split(WHITESPACE_COMMA_REGEX);
        float[] values = new float[split.length];
        for (int i = 0; i < split.length; i++) {
            values[i] = getFloat(split[i], 0);
        }
        return values;
    }

    /**
     * Parses one of the index attributes of an X3D IndexedFaceSet node,
     * translates the per-polygon indices into per-triangle indices and returns
     * the indices as an array. This method can be used for all of the index
     * attributes of an IndexedFaceSet, as they are declared in the same manner
     * (consecutive indices define a polygon until a "-1"-index occurs)
     * 
     * @param node
     *            The X3D IndexedFaceSet node
     * @param attributeName
     *            The name of the index attribute to be parsed
     * @return The index array, or <code>null</code> if no coordIndex
     *         attribute was available
     */
    private int[] parseIndices(Node node, String attributeName) {
        Node indexNode = node.getAttributes().getNamedItem(attributeName);
        if (indexNode == null) {
            return null;
        }
        String indexString = indexNode.getNodeValue().trim();
        String[] split = indexString.split(WHITESPACE_COMMA_REGEX);

        int maxVerts = 5;
        int[] polygon = new int[maxVerts];
        int indexCount = 0;
        ArrayList<int[]> triangles = new ArrayList<int[]>(split.length / 4 * 3);
        for (int i = 0; i < split.length; i++) {
            int index = getInt(split[i], 0);
            if (index > -1) {
                // One more index for the current polygon
                if (indexCount == maxVerts) {
                    int[] temp = new int[maxVerts + 1];
                    System.arraycopy(polygon, 0, temp, 0, maxVerts);
                    polygon = temp;
                    maxVerts++;
                }
                polygon[indexCount++] = index;
            } else {
                // Value <= -1: current polygon complete; split up into
                // triangles
                splitPolygon(polygon, triangles, indexCount);
                indexCount = 0;
            }
        }
        if (indexCount > 2) {
            splitPolygon(polygon, triangles, indexCount);
        }

        // Assemble the index array
        int[] result = new int[triangles.size() * 3];
        for (int i = 0; i < triangles.size(); i++) {
            int[] triangle = triangles.get(i);
            result[i * 3 + 0] = triangle[0];
            result[i * 3 + 1] = triangle[1];
            result[i * 3 + 2] = triangle[2];
        }

        return result;
    }

    /**
     * Splits a polygon of 3 or more indices into triangles. This is currently
     * achieved by using the last vertex of the polygon as the center of a fan.
     * 
     * @param polyIndices
     *            An array containing <code>indexCount</code> polygon indices
     * @param triangles
     *            A list to store arrays of indices, each one containing the
     *            indices of one triangle
     * @param indexCount
     *            The number of indices of the current polygon
     */
    private void splitPolygon(int[] polyIndices, ArrayList<int[]> triangles,
            int indexCount) {
        for (int i = 0; i < indexCount - 2; i++) {
            triangles.add(new int[] { polyIndices[i], polyIndices[i + 1],
                    polyIndices[indexCount - 1] });
        }
    }

    /**
     * Expands the list of value sets so that every three consecutive value sets
     * define a triangle. The corresponding index array can be overwritten
     * accordingly, so that it looks like this: (0, 1, 2, 3, 4, ...)
     * 
     * @param values
     *            The values
     * @param indices
     *            The indices
     * @param setLength
     *            The length of one set of values (e.g. a vector, a color, ...).
     *            The length for vectors is 3, for RGB-colors 3, for RGBA-Colors
     *            4 and for texture coordinates 2
     * @param rearrangeIndices
     *            If <code>true</code>, the index array is overwritten
     * @return The expanded vertices list
     */
    private float[] expandValues(float[] values, int[] indices, int setLength,
            boolean rearrangeIndices) {
        float[] expValues = new float[indices.length * setLength];
        for (int i = 0; i < indices.length; i++) {
            for (int j = 0; j < setLength; j++) {
                expValues[i * setLength + j] = values[indices[i] * setLength
                        + j];
            }
            if (rearrangeIndices) {
                indices[i] = i;
            }
        }
        return expValues;
    }

    // /**
    // * Creates an index array that contains equal indices to equal vectors in
    // * the array created by the method
    // * {@link #expandValues(float[], int[], int, boolean)}. Each index points
    // * to the first occurrence of the vector in the expanded value array.
    // * (Yeah, I know the method's name sounds stupid, couldn't find an
    // * appropriate one...)
    // * @param indices An array containing the original vertex indices
    // * @return The array with the changed indices
    // */
    // private int[] changeIndices(int[] indices, int[] target) {
    // int[] sortedIndices = target;
    // if (sortedIndices == null) {
    // sortedIndices = new int[indices.length];
    // }
    // Arrays.fill(sortedIndices, -1);
    // for (int i = 0; i < indices.length; i++) {
    // if (sortedIndices[i] == -1) {
    // for (int j = i; j < indices.length; j++) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -