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

📄 x3dtojme.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
        // Set translation
        Node translationNode = attrs.getNamedItem("translation");
        if (translationNode != null) {
            String translation = translationNode.getNodeValue().trim();
            String[] split = translation.split(WHITESPACE_REGEX);
            if (split.length >= 3) {
                float x = getFloat(split[0], 0f);
                float y = getFloat(split[1], 0f);
                float z = getFloat(split[2], 0f);
                sceneNode.setLocalTranslation(x, y, z);
            }
        }

        // Set rotation
        Node rotationNode = attrs.getNamedItem("rotation");
        if (rotationNode != null) {
            String rotation = rotationNode.getNodeValue().trim();
            String[] split = rotation.split(WHITESPACE_REGEX);
            if (split.length >= 4) {
                try {
                    float axisX = Float.parseFloat(split[0]);
                    float axisY = Float.parseFloat(split[1]);
                    float axisZ = Float.parseFloat(split[2]);
                    float angle = Float.parseFloat(split[3]);
                    // logger.info("Setting rotation: ("+axisX+", "+axisY+",
                    // "+axisZ+"), "+angle);
                    sceneNode.getLocalRotation().fromAngleAxis(angle,
                            new Vector3f(axisX, axisY, axisZ));
                } catch (NumberFormatException e) {
                }
            }
        }

        // Set scaling
        Node scaleNode = attrs.getNamedItem("scale");
        if (scaleNode != null) {
            String scale = scaleNode.getNodeValue().trim();
            String[] split = scale.split(WHITESPACE_REGEX);
            if (split.length >= 3) {
                float x = getFloat(split[0], 1f);
                float y = getFloat(split[1], 1f);
                float z = getFloat(split[2], 1f);
                // logger.info("Setting scaling: ("+x+", "+y+", "+z+")");
                sceneNode.setLocalScale(new Vector3f(x, y, z));
            }
        }
    }

    /**
     * Gets an integer value from the specified String.
     * 
     * @param num
     *            The String containing the value
     * @param standard
     *            A value to be used in case the String is <code>null</code>
     *            or the parsing fails
     * @return The resulting int value
     */
    private int getInt(String num, int standard) {
        if (num != null) {
            try {
                return Integer.parseInt(num);
            } catch (NumberFormatException e) {
            }
        }
        return standard;
    }

    /**
     * Gets a float value from the specified String.
     * 
     * @param num
     *            The String containing the value
     * @param standard
     *            A value to be used in case the String is <code>null</code>
     *            or the parsing fails
     * @return The resulting float value
     */
    private float getFloat(String num, float standard) {
        if (num != null) {
            try {
                return Float.parseFloat(num);
            } catch (NumberFormatException e) {
            }
        }
        return standard;
    }

    /**
     * Parses the contents of an X3D Shape node and its children and creates a
     * jME Node containing the geometry and appearance parameters read from the
     * X3D shape node.
     * 
     * @param node
     *            The Shape node
     * @return The jME Geometry
     * @throws Exception
     *             In case an error occurs during loading
     */
    private Spatial parseShape(Node node) throws Exception {
        com.jme.scene.Node shape = new com.jme.scene.Node();
        // Check for a bounding box definition
        BoundingBox bbox = parseBoundingBox(node);

        // Find the geometry and appearance nodes
        Node geometryNode = null;
        Node appearanceNode = null;
        Node child = node.getFirstChild();
        while (child != null) {
            if (child.getNodeName().equals("Appearance")) {
                appearanceNode = child;
            } else if (isGeometryType(child.getNodeName())) {
                geometryNode = child;
            }
            child = child.getNextSibling();
        }

        // Parse and add the geometry, if available
        Geometry geom = null;
        if (geometryNode != null) {
            geom = parseGeometry(geometryNode);
            if (geom != null) {
                shape.attachChild(geom);
            }
            if (geom != null && bbox != null) {
                geom.setModelBound(bbox);
            }
        }

        // Parse and set the appearance properties, if available
        createBumpController = false; // Reset the create controller flag
        addToTransparentQueue = false;
        if (appearanceNode != null) {
            RenderState[] states = parseAppearance(appearanceNode);
            if (states != null && geom != null) {
                /*
                 * Check if the parsed Appearance contained a Bump Map => set up
                 * a BumpMapColorController for the Geometry
                 */
                if (createBumpController) {
                    BumpMapColorController con = new BumpMapColorController(
                            geom);
                    geom.addController(con);
                }

                /*
                 * Check if the parsed Appearance contained transparency => add
                 * the geometry to the transparency renderQueue
                 */
                if (addToTransparentQueue) {
                    geom.setRenderQueueMode(Renderer.QUEUE_TRANSPARENT);
                }

                // Apply the RenderStates
                for (RenderState state : states) {
                    if (state != null) {
                        shape.setRenderState(state);
                        // If there are multiple textures, copy the texCoords
                        // (DUMMY)
                        if (state instanceof TextureState
                                && ((TextureState) state)
                                        .getNumberOfSetTextures() > 1) {
                            copyTexCoords((TextureState) state, geom);
                        }
                    }
                }
            }
        }

        return shape;
    }

    /**
     * Checks if the given String represents one of the types of geometry nodes
     * this loader understands.
     * 
     * @param type
     *            The String to check
     * @return <code>true</code>, if the String contains a valid geometry
     *         type, otherwise <code>false</code>
     */
    private boolean isGeometryType(String type) {
        for (String geom : GEOMETRY_TYPES) {
            if (type.equals(geom)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Parses any X3D geometry node (Box, Cone, Cylinder, IndexedFaceSet,
     * Sphere) and creates a corresponding jME Geometry object.
     * 
     * @param node
     *            The X3D node
     * @return The jME Geometry
     * @throws Exception
     *             In case an error occurs during parsing
     */
    private Geometry parseGeometry(Node node) throws Exception {
        // Check for the USE attribute
        Node use = node.getAttributes().getNamedItem("USE");
        if (use != null) {
            return (Geometry) getDef(use.getNodeValue());
        }

        // Check for the DEF attribute
        Node def = node.getAttributes().getNamedItem("DEF");
        String title = null;
        if (def != null) {
            title = def.getNodeValue();
        }

        // Parse the Geometry
        Geometry geom = null;
        String nodeName = node.getNodeName();
        if (nodeName.equals("Box")) {
            geom = parseBox(node, title);
        } else if (nodeName.equals("IndexedFaceSet")) {
            geom = parseIFS(node, title);
        } else if (nodeName.equals("Sphere")) {
            geom = parseSphere(node, title);
        } else if (nodeName.equals("Cylinder")) {
            geom = parseCylinder(node, title);
        } else if (nodeName.equals("Cone")) {
            geom = parseCone(node, title);
        } else if (nodeName.equals("LineSet")) {
            geom = parseLS(node, title);
        }

        if (geom != null) {
            // Set up bounding volume
            geom.setModelBound(new BoundingBox());

            // Translate attribute "solid" into a CullState
            boolean solid = true; // X3D default: true
            Node solidNode = node.getAttributes().getNamedItem("solid");
            if (solidNode != null
                    && solidNode.getNodeValue().equalsIgnoreCase("false")) {
                solid = false;
            }
            if (solid) {
                CullState culling = DisplaySystem.getDisplaySystem()
                        .getRenderer().createCullState();
                culling.setCullFace(CullState.Face.Back);
                geom.setRenderState(culling);
            }

            // If the DEF attribute exists, store the Geometry for future USEs
            if (title != null) {
                CloneImportExport cloneEx = new CloneImportExport();
                cloneEx.saveClone(geom);
                defs.put(title, cloneEx);
            }
        }

        return geom;
    }

    /**
     * Parses an X3D Box node and creates a corresponding jME Box.
     * 
     * @param node
     *            The X3D Box node
     * @param title
     *            A title for the box. If <code>null</code> is passed, a
     *            generic title is used.
     * @return The jME Box
     */
    private Box parseBox(Node node, String title) {
        Box box = null;
        String size = node.getAttributes().getNamedItem("size").getNodeValue()
                .trim();
        String[] split = size.split(WHITESPACE_REGEX);
        if (split.length >= 3) {
            // jME interprets scaling as extent from center => size is scaled by
            // 0.5
            float x = getFloat(split[0], 0) * 0.5f;
            float y = getFloat(split[1], 0) * 0.5f;
            float z = getFloat(split[2], 0) * 0.5f;
            if (x > 0 && y > 0 && z > 0) {
                if (title != null) {
                    box = new Box(title, new Vector3f(), x, y, z);
                } else {
                    box = new Box("X3D_Box", new Vector3f(), x, y, z);
                }
            }
        }
        return box;
    }

    /**
     * Parses an X3D IndexedFaceSet node and creates a corresponding jME
     * Geometry node. Because of jME's limitation that there can only be one
     * index array that is used for vertices as well as normals, colors and
     * texture coordinates, this method uses a workaround for the X3D
     * IndexedFaceSet's colorIndex, normalIndex and texCoordIndex attributes:
     * The vertices are "expanded" according to the indices from the coordIndex
     * attributes, so that every three consecutive vertices define one triangle
     * and the corresponding index array looks like [0, 1, 2, 3, 4, ...];
     * polygons with more than three vertices are split up into triangles in the
     * process. The attributes colorPerVertex and normalPerVertex are ignored,
     * most likely resulting in an ArrayOutOfBoundsException or simply rendering
     * errors when they are used in the X3D file (this should be fixed sometime
     * in the future, so that colors or normals respectively are ignored
     * altogether if these attributes are used)
     * 
     * @param node
     *            The X3D IndexedFaceSet node
     * @param title
     *            The name for the node
     * @return The jME Geometry for the IndexedFaceSet
     */
    private Geometry parseIFS(Node node, String title) {
        // Parse the vertices
        float[] vertices = null;
        Node coords = getChildNode(node, "Coordinate");
        if (coords != null) {
            vertices = parseValues(coords, "point");
        }
        if (vertices == null) {
            return null;
        }

        // Parse the coord indices
        int[] indices = parseIndices(node, "coordIndex");
        boolean indicesAvailable = false;
        if (indices == null) {
            // No indices specified => Every three consecutive vertices define a
            // triangle
            indices = new int[vertices.length];
            for (int i = 0; i < indices.length; i++) {

⌨️ 快捷键说明

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