Package org.jdesktop.wonderland.client.jme.utils

Source Code of org.jdesktop.wonderland.client.jme.utils.ScenegraphUtils$FindNamedNodeListener

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/

package org.jdesktop.wonderland.client.jme.utils;

import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.TriMesh;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger;
import org.jdesktop.wonderland.client.jme.utils.traverser.ProcessNodeInterface;
import org.jdesktop.wonderland.client.jme.utils.traverser.TreeScan;
import org.jdesktop.wonderland.common.cell.CellTransform;

/**
* Various utilties for the JME scene graph
*
* @author paulby
* @author Bernard Horan
*/
public class ScenegraphUtils {

    /**
     * Print the children of the parameter node on the parameter buffer
     * @param aNode the node whose children are to be printed
     * @param buffer the buffer that will contain the tree of printed nodes
     */
    public static void printChildren(Node aNode, StringBuffer buffer) {
        printChildren(aNode, buffer, 0);
    }

    /**
     * Print the children of the parameter node on the parameter buffer, using
     * an indent count to produce an indented tree
     * @param aNode the node whose children are to be printed
     * @param buffer the buffer that will contain the tree of printed nodes
     * @param indent a count of how deep this branch is
     */
    public static void printChildren(Node aNode, StringBuffer buffer, int indent) {
        StringBuffer indentBuffer = new StringBuffer();
        for (int i = 0; i < indent ; i++) {
            indentBuffer.append('\t');
        }
        buffer.append(indentBuffer.toString());
        buffer.append(aNode.toString());
        buffer.append('\n');
        List<Spatial> children = aNode.getChildren();
        if (children == null) {
            return;
        }
        indentBuffer.append('\t');
        for (Iterator<Spatial> it = children.iterator(); it.hasNext();) {
            Spatial spatial = it.next();
            if (spatial instanceof Node) {
                printChildren((Node) spatial, buffer, indent +1);
            } else {
                buffer.append(indentBuffer.toString());
                buffer.append(spatial.toString());
                buffer.append('\n');
            }
        }
    }

    /**
     * Print the parents of the parameter spatial on the parameter buffer
     * @param aSpatial the spatial whose parents are to be printed
     * @param buffer the buffer that will contain the tree of printed spatials
     */
    public static void printParents(Spatial aSpatial, StringBuffer buffer) {
        printParents(aSpatial, buffer, 0);
    }

    /**
     * Print the parents of the parameter spatial on the parameter buffer, using
     * an indent count to indent the printing
     * @param aSpatial the spatial whose parents are to be printed
     * @param buffer the buffer that will contain the tree of printed spatials
     * @param indent a count of how deep the parent is up the tree
     */
    public static void printParents(Spatial aSpatial, StringBuffer buffer, int indent) {
         StringBuffer indentBuffer = new StringBuffer();
        for (int i = 0; i < indent ; i++) {
            indentBuffer.append('\t');
        }
        buffer.append(indentBuffer.toString());
        buffer.append(aSpatial.toString());
        buffer.append('\n');
        Node parent = aSpatial.getParent();
        if (parent != null) {
            printParents(parent, buffer, indent + 1);
        }
    }


    /**
     * Traverse the scene graph from rootNode and return the first
     * node with the given name. Returns null if no node is found
     *
     * @param rootNode the root of the graph
     * @param name the name to search for
     * @return the named node, or null
     */
    public static Spatial findNamedNode(Node rootNode, String name) {
        FindNamedNodeListener listener = new FindNamedNodeListener(name);

        TreeScan.findNode(rootNode, listener);

        return listener.getResult();
    }

    /**
     * Scan the graph and add all named nodes (non null names only) to the nodeMap.
     * If there are duplicate names a logger warning will be printed and previous
     * name/node will be overwritten
     *
     * @param rootNode root of graph
     * @param nodeMap the HashMap to which nodes are added
     */
    public static void getNamedNodes(Node rootNode, final HashMap<String, Spatial> nodeMap) {
        TreeScan.findNode(rootNode, new ProcessNodeInterface() {

            public boolean processNode(Spatial node) {
                if (node.getName()!=null) {
                    Spatial old = nodeMap.put(node.getName(), node);
                    if (old!=null)
                        Logger.getLogger(ScenegraphUtils.class.getName()).warning("Duplicate node name in scene "+node.getName());
                }
                return true;
            }
        });
    }

    /**
     * Given the world coordinates of a child compute the childs localTransform
     * asssuming it will become a child of the parent with the supplied world transform
     *
     * @param parent
     * @param childWorldTransform
     * @return
     */
    public static CellTransform computeChildTransform(CellTransform parentWorld, CellTransform childWorldTransform) {

        CellTransform pInv = parentWorld.clone(null).invert();

        CellTransform newChildLocal = new CellTransform();
        newChildLocal.mul(pInv, childWorldTransform);

        return newChildLocal;
    }

    private static Node createTestNode() {
        Node rootNode = new Node("Root");
        for (int i = 100; i <= 500; i +=100) {
            Node iNode = new Node(String.valueOf(i));
            rootNode.attachChild(iNode);
            for (int j = 10; j <= 50; j +=10) {
                Node jNode = new Node(String.valueOf(i+j));
                iNode.attachChild(jNode);
                for (int k = 1; k <= 5; k++) {
                    TriMesh kMesh = new TriMesh(String.valueOf(i+j+k));
                    jNode.attachChild(kMesh);
                }
            }
        }
        return rootNode;
    }

    private static void testPrintNamedNodes(Node testNode) {
        System.out.println("TEST: PRINTING NAMED NODES");
        HashMap<String, Spatial> nodeMap = new HashMap<String, Spatial>();
        getNamedNodes(testNode, nodeMap);
        Set<String> mapKeys = nodeMap.keySet();
        for (String key : mapKeys) {
            System.out.println("key: " + key + " --> " + nodeMap.get(key));
        }
    }

    private static void testNamedNode(Node testNode, String string) {
        System.out.println("TEST: FINDING NAMED NODE");
        Spatial found = findNamedNode(testNode, string);
        if (found != null) {
            System.out.println("Found spatial for " + string + " --> " + found);
        } else {
            System.err.println("Failed to find node for " + string);
        }
    }

    private static void testPrintChildren(Node testNode) {
        System.out.println("TEST: PRINT CHILDREN");
        StringBuffer buffer = new StringBuffer();
        printChildren(testNode, buffer);
        System.out.println(buffer.toString());
    }

    private static void testPrintParents(Node testNode, String string) {
        System.out.println("TEST: PRINT PARENTS");
        Spatial found = findNamedNode(testNode, string);
        if (found != null) {
            StringBuffer buffer = new StringBuffer();
            printParents(found, buffer);
            System.out.println(buffer.toString());
        } else {
            System.err.println("Failed to find node for " + string);
        }
    }

    /**
     * Given a list of cell transforms, multiply them together and return the
     * 'world' transform of the leaf transform. This mimics the transform calculation in the scene
     * graph, where the first element of the array is the graph root and the last
     * element is the leaf.
     * @param graphLocal list of cell transforms
     * @return the 'world' transform of the leaf
     */
//    public static CellTransform computeGraph(ArrayList<CellTransform> graphLocal) {
//        CellTransform result = new CellTransform();
//        for(int i=0; i<graphLocal.size(); i++) {
//            result.mul(graphLocal.get(i));
//        }
//        return result;
//    }

    static class FindNamedNodeListener implements ProcessNodeInterface {

        private String nodeName;
        private Spatial result=null;

        public FindNamedNodeListener(String name) {
            nodeName = name;
        }

        public boolean processNode(Spatial node) {
            if (node.getName().equals(nodeName)) {
                result = node;
                return false;
            }
            return true;
        }

        public Spatial getResult() {
            return result;
        }
    }

    public static void main(String[] args) {
        Node testNode = createTestNode();
        testPrintNamedNodes(testNode);
        testNamedNode(testNode, "444");
        testPrintChildren(testNode);
        testPrintParents(testNode, "444");
    }

}
TOP

Related Classes of org.jdesktop.wonderland.client.jme.utils.ScenegraphUtils$FindNamedNodeListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.