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

📄 x3dtojme.java

📁 java 3d game jme 工程开发源代码
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    }

    /**
     * Loads a scene (model) from the X3D file contained in the specified input
     * stream.<br />
     * <strong>Please note:</strong> This loader is NOT thread-safe!
     * 
     * @param x3dIn
     *            An InputStream holding the X3D file
     * @param texData
     *            A Map mapping the paths of texture files to InputStreams
     *            holding the file content
     * @param lightState
     *            The LightState to attach scene lights to. If <code>null</code>
     *            is passed, a new LightState is created and attached to the
     *            model root, which causes the lights in the X3D scene to light
     *            only the X3D scene itself
     * @return The model, if it was successfully loaded, otherwise
     *         <code>null</code>
     * @throws An
     *             Exception, in case any error occurs
     */
    public Spatial loadScene(InputStream x3dIn,
            Map<String, InputStream> texData, LightState lightState)
            throws Exception {

        this.texData = texData;

        // Timer timer = Timer.getTimer();
        // timer.reset();

        // Parse the XML document, build the DOM-document
        Document doc;
        // try {
        doc = documentBuilder.parse(x3dIn);
        // } catch (Exception e) {
        // logger.info("Unable to parse X3D file: " + e + " ("
        // + e.getMessage() + ")");
        // return new com.jme.scene.Node();
        // }

        // float parsingTime = timer.getTimeInSeconds();
        // logger.info("X3D parsed in "+(parsingTime * 1000)+" ms");
        // timer.reset();

        // Create the scene root
        NodeList nodes = doc.getElementsByTagName("X3D");
        if (nodes.getLength() == 0) {
            logger.info("No X3D document root!");
            return new com.jme.scene.Node();
        }
        Node scene = getChildNode(nodes.item(0), "Scene");
        com.jme.scene.Node sceneRoot = new com.jme.scene.Node();

        /*
         * Check the LightState. If none has been passed, create a new one and
         * attach it to the scene root
         */
        if (lightState == null) {
            this.lightState = DisplaySystem.getDisplaySystem().getRenderer()
                    .createLightState();
            this.lightState.setEnabled(true);
            sceneRoot.setRenderState(this.lightState);
        } else {
            this.lightState = lightState;
        }

        // Set the scene's title
        Node worldInfo = getChildNode(scene, "WorldInfo");
        if (worldInfo != null) {
            Node titleNode = worldInfo.getAttributes().getNamedItem("title");
            if (titleNode != null) {
                sceneRoot.setName(titleNode.getNodeValue());
            }
        }

        // Check for a Layer3D child node. If one exists, use it instead of X3D
        Node layer3D = getChildNode(scene, "Layer3D");
        if (layer3D != null) {
            scene = layer3D;
        }

        // Process all child nodes
        Node child = scene.getFirstChild();
        while (child != null) {
            if (child.getNodeType() != Node.TEXT_NODE
                    && child.getNodeType() != Node.COMMENT_NODE) {
                Spatial node = parseNode(child);
                if (node != null) {
                    sceneRoot.attachChild(node);
                }
            }
            child = child.getNextSibling();
        }

        // Update the bounds of the root node and all children
        sceneRoot.setModelBound(new BoundingBox());
        sceneRoot.updateModelBound();

        // Reset all used data
        defs.clear();
        this.texData = null;
        this.lightState = null;
        this.addToTransparentQueue = false;
        this.createBumpController = false;
        try {
            x3dIn.close();
        } catch (IOException e) {
        }

        // parsingTime = timer.getTimeInSeconds();
        // logger.info("Scene parsed in "+(parsingTime * 1000)+" ms");

        return sceneRoot;
    }

    /**
     * Gets the child node with the specified name from the specified node.
     * 
     * @param node
     *            The node to get the child node from
     * @param name
     *            The name of the child element to get (case is ignored)
     * @return The first child node with the specified name, or
     *         <code>null</code> if such a node does not exist
     */
    private Node getChildNode(Node node, String name) {
        Node child = node.getFirstChild();
        while (child != null && child.getNodeName() != name) {
            child = child.getNextSibling();
        }
        return child;
    }

    /**
     * Parses a node in the DOM (grouping, shape or light node) and creates a
     * scene node according to the DOM node's attributes and child elements.
     * 
     * @param node
     *            The DOM node
     * @return The jME Node
     * @throws Exception
     *             In case an error occurs during parsing
     */
    private Spatial parseNode(Node node) throws Exception {
        // Check for the USE attribute
        Node use = node.getAttributes().getNamedItem("USE");
        if (use != null) {
            return (Spatial) getDef(use.getNodeValue());
        }

        // Parse the node
        String type = node.getNodeName();
        Spatial result = null;
        if (type.equals("Group") || type.equals("StaticGroup")
                || type.equals("Transform") || type.equals("Switch")) {
            result = parseGroup(node);
        } else if (type.equals("Shape")) {
            result = parseShape(node);
        } else if (type.equals("DirectionalLight") || type.equals("PointLight")
                || type.equals("SpotLight")) {
            result = parseLight(node);
        }

        // Check for the DEF attribute
        if (result != null) {
            Node def = node.getAttributes().getNamedItem("DEF");
            if (def != null) {
                result.setName(def.getNodeValue());
                CloneImportExport cloneEx = new CloneImportExport();
                cloneEx.saveClone(result);
                defs.put(def.getNodeValue(), cloneEx);
            }
        }

        return result;
    }

    /**
     * Gets a clone of a previously defined Savable.
     * 
     * @param result
     *            A Savable to store the clone data.
     * @param def
     *            The ID of the predefined Savable
     * @return The passed Savable, filled with the clone data, or
     *         <code>null</code> if no predefined object matching the ID was
     *         found
     */
    private Savable getDef(String def) {
        CloneImportExport cloneIn = (CloneImportExport) defs.get(def);
        if (cloneIn != null) {
            return cloneIn.loadClone();
        }
        return null;
    }

    /**
     * Parses a DOM Group, StaticGroup, TransformGroup or Switch node and
     * creates a jME node with the appropriate properties
     * 
     * @param node
     *            The DOM node
     * @return The jME node
     * @throws Exception
     *             In case an error occurs during parsing
     */
    private com.jme.scene.Node parseGroup(Node node) throws Exception {
        // Init node
        boolean isSwitch;
        com.jme.scene.Node group;
        if (node.getNodeName().equals("Switch")) {
            group = new SwitchNode();
            isSwitch = true;
        } else {
            group = new com.jme.scene.Node();
            isSwitch = false;
        }

        // Parse BoundingBox
        BoundingBox bbox = parseBoundingBox(node);
        if (bbox != null) {
            group.setModelBound(bbox);
        }

        // Parse children
        Node child = node.getFirstChild();
        while (child != null) {
            if (isSceneNodeType(child.getNodeName())) {
                Spatial subnode = parseNode(child);
                if (subnode != null) {
                    group.attachChild(subnode);
                }
            }
            child = child.getNextSibling();
        }

        // Extra settings for Switch and Transform nodes
        if (isSwitch) {
            String selection = node.getAttributes().getNamedItem("whichChoice")
                    .getNodeValue().trim();
            try {
                int item = Integer.parseInt(selection);
                ((SwitchNode) group).setActiveChild(item);
            } catch (NumberFormatException e) {
                ((SwitchNode) group).setActiveChild(-1);
            }
        } else if (node.getNodeName().equals("Transform")) {
            setTransformation(group, node);
        }

        return group;
    }

    /**
     * Creates a BoundingBox according to the attributes bboxCenter and bboxSize
     * of the given node.
     * 
     * @param node
     *            The node
     * @return A BoundingBox created from the attribute values, or
     *         <code>null</code> if the attributes were unavailable or
     *         specified a buggy or negative box.
     */
    private BoundingBox parseBoundingBox(Node node) {
        NamedNodeMap attrs = node.getAttributes();

        // Parse size
        Node sizeNode = attrs.getNamedItem("bboxSize");
        if (sizeNode == null) {
            return null;
        }
        String size = sizeNode.getNodeValue().trim();
        String[] split = size.split(WHITESPACE_REGEX);
        if (split.length < 3) {
            return null;
        }
        float sizeX = getFloat(split[0], -1);
        float sizeY = getFloat(split[1], -1);
        float sizeZ = getFloat(split[2], -1);
        if (sizeX < 0 || sizeY < 0 || sizeZ < 0) {
            return null;
        }

        // Parse center
        Node centerNode = attrs.getNamedItem("bboxCenter");
        if (centerNode == null) {
            return null;
        }
        String center = centerNode.getNodeValue().trim();
        split = center.split(WHITESPACE_REGEX);
        if (split.length < 3) {
            return null;
        }
        float centerX = getFloat(split[0], 0);
        float centerY = getFloat(split[1], 0);
        float centerZ = getFloat(split[2], 0);

        return new BoundingBox(new Vector3f(centerX, centerY, centerZ),
                sizeX * 0.5f, sizeY * 0.5f, sizeZ * 0.5f);
    }

    /**
     * Checks if the specified String represents a scene node type (i.e. a
     * group, shape or light type)
     * 
     * @param type
     *            The type String
     * @return <code>true</code>, if the String is a scene node type,
     *         otherwise <code>false</code>
     */
    private boolean isSceneNodeType(String type) {
        for (String node : SCENE_NODE_TYPES) {
            if (type.equals(node)) {
                return true;
            }
        }
        return false;
    }

    /**
     * Sets the translation, rotation and scaling values for the given scene
     * node according to the attributes of the DOM node, if it is a Transform
     * node.
     * 
     * @param sceneNode
     *            The scene node to set the transformation for
     * @param node
     *            The DOM node
     */
    private void setTransformation(com.jme.scene.Node sceneNode, Node node) {
        NamedNodeMap attrs = node.getAttributes();

⌨️ 快捷键说明

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