Package org.jdesktop.wonderland.modules.defaultenvironment.client

Source Code of org.jdesktop.wonderland.modules.defaultenvironment.client.DirectionalLightViewerEntity

/**
* Open Wonderland
*
* Copyright (c) 2010 - 2012, Open Wonderland Foundation, 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.
*
* The Open Wonderland Foundation designates this particular file as
* subject to the "Classpath" exception as provided by the Open Wonderland
* Foundation in the License file that accompanied this code.
*/

/**
* 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.modules.defaultenvironment.client;

import com.jme.light.DirectionalLight;
import com.jme.light.LightNode;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.Node;
import com.jme.scene.shape.Arrow;
import com.jme.scene.state.BlendState;
import com.jme.scene.state.MaterialState;
import com.jme.scene.state.RenderState.StateType;
import com.jme.scene.state.ZBufferState;
import java.awt.Color;
import java.awt.Font;
import java.util.logging.Logger;
import org.jdesktop.mtgame.Entity;
import org.jdesktop.mtgame.RenderComponent;
import org.jdesktop.mtgame.RenderManager;
import org.jdesktop.mtgame.RenderUpdater;
import org.jdesktop.mtgame.WorldManager;
import org.jdesktop.wonderland.client.cell.Cell;
import org.jdesktop.wonderland.client.cell.TransformChangeListener;
import org.jdesktop.wonderland.client.jme.ClientContextJME;
import org.jdesktop.wonderland.client.jme.utils.TextLabel2D;
import org.jdesktop.wonderland.common.cell.CellTransform;

/**
* A visual Entity that displays a directional light as 3D arrow.
*
* @author Jordan Slott <jslott@dev.java.net>
* @author JagWire
*/
public class DirectionalLightViewerEntity extends Entity {

    // The Cell to display the bounds
    private Cell cell = null;

    // The root node of the bounds viewer scene graph
    private Node rootNode = null;

    // Listener for changes in the transform of the cell
    private TransformChangeListener updateListener = null;

    // True if the bounds viewer Entity is visible, false if not
    private boolean isVisible = false;

   
    private static final Logger LOGGER = Logger.getLogger(DirectionalLightViewerEntity.class.getName());
    /**
     * Constructor that takes the root Node of the Cell's scene graph
     */
    public DirectionalLightViewerEntity(Cell cell) {
        super("Light Viewer");

        // Create a new Node that serves as the root for the bounds viewer
        // scene graph
        this.cell = cell;
    }

    public void showLight(final LightNode lightNode, final String name) {
  if (rootNode != null) {
      dispose();
  }
       
        DirectionalLight directionalLight = (DirectionalLight)lightNode.getLight();

        rootNode = new Node("Light Viewer Node");
        RenderManager rm = ClientContextJME.getWorldManager().getRenderManager();
        RenderComponent rc = rm.createRenderComponent(rootNode);
        this.addComponent(RenderComponent.class, rc);
       
        // Set the Z-buffer state on the root node
        ZBufferState zbuf = (ZBufferState)rm.createRendererState(StateType.ZBuffer);
        zbuf.setEnabled(true);
        zbuf.setFunction(ZBufferState.TestFunction.LessThanOrEqualTo);
       
        rootNode.setRenderState(zbuf);

        // Set the wireframe state on the root node
//        WireframeState wf = (WireframeState)rm.createRendererState(StateType.Wireframe);
//        wf.setEnabled(true);
//        rootNode.setRenderState(wf);
        MaterialState ms = (MaterialState)rm.createRendererState(StateType.Material);
        ms.setAmbient(new ColorRGBA(0.25f, 0, 0.5f, 0.40f));
        ms.setDiffuse(new ColorRGBA(0.25f, 0, 0.5f, 0.40f));
        ms.setMaterialFace(MaterialState.MaterialFace.FrontAndBack);;
        //ms.setSpecular(new ColorRGBA(1f, 1, 1f, 1f));
       
        ms.setEnabled(true);
        rootNode.setRenderState(ms);
       
        BlendState bs = (BlendState)rm.createRendererState(StateType.Blend);
        bs.setEnabled(true);
        bs.setBlendEnabled(true);
        bs.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
        bs.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
        bs.setTestEnabled(true);
        bs.setTestFunction(BlendState.TestFunction.GreaterThan);
        rootNode.setRenderState(bs);

        CellTransform transform = cell.getWorldTransform();
        // Draw an arrow that mimics the light position --direction still under
        //construction.
        TextLabel2D label = new TextLabel2D(name,
                                            Color.black, Color.white, 1.0f, true, Font.getFont("SANS_SERIF"));
       
        Vector3f direction = directionalLight.getDirection();
        Vector3f position = lightNode.getLocalTranslation();
        Vector3f labelPosition = new Vector3f(position.x, position.y + 3, position.z);
       
        Arrow arrow = new Arrow("Arrow", 3, 0.5f);
        Node rotatedOnX = new Node("Rotated For Arrow");
        rotatedOnX.setLocalRotation(new Quaternion().fromAngleAxis(90*FastMath.DEG_TO_RAD, new Vector3f(1, 0, 0)));
        rotatedOnX.attachChild(arrow);
        rotatedOnX.setLocalTranslation(position);
//        arrow.setLocalTranslation(position);
        label.setLocalTranslation(labelPosition);
        arrow.lookAt(direction, new Vector3f(0,1,0));
        rootNode.attachChild(label);
        rootNode.attachChild(rotatedOnX);
        // Fetch the world translation for the root node of the cell and set
        // the translation for this entity root node
        rootNode.setLocalTranslation(transform.getTranslation(null));
  rootNode.setLocalRotation(transform.getRotation(null));
        // OWL issue #61: make sure to take scale into account
        rootNode.setLocalScale(transform.getScaling(null));
       
        // Listen for changes to the cell's translation and apply the same
        // update to the root node of the bounds viewer. We also re-set the size
        // of the bounds: this handles the case where the bounds of the
        // scene graph has changed and we need to update the bounds viewer
        // accordingly.
        updateListener = new TransformChangeListener() {
            public void transformChanged(final Cell cell, ChangeSource source) {
                // We need to perform this work inside a proper updater, to
                // make sure we are MT thread safe
                final WorldManager wm = ClientContextJME.getWorldManager();
                RenderUpdater u = new RenderUpdater() {
                    public void update(Object obj) {
                        CellTransform transform = cell.getWorldTransform();
                        rootNode.setLocalTranslation(transform.getTranslation(null));
      rootNode.setLocalRotation(transform.getRotation(null));
                        rootNode.setLocalScale(transform.getScaling(null));
                        wm.addToUpdateList(rootNode);
                    }
                };
                wm.addRenderUpdater(u, this);
            }
        };
        cell.addTransformChangeListener(updateListener);
  setVisible(true);
    }

    /**
     * Returns the root Node for the bounds viewer Entity.
     *
     * @param The Entity root Node
     */
    public Node getRootNode() {
        return rootNode;
    }

    /**
     * Sets whether the bounds viewer is visible (true) or invisible (false).
     *
     * @param visible True to make the affordance visible, false to not
     */
    public synchronized void setVisible(boolean visible) {
        WorldManager wm = ClientContextJME.getWorldManager();

        // If we want to make the affordance visible and it already is not
        // visible, then make it visible. We do not need to put add/remove
        // Entities on the MT Game render thread, they are already thread safe.
        if (visible == true && isVisible == false) {
            wm.addEntity(this);
            isVisible = true;
            return;
        }

        // If we want to make the affordance invisible and it already is
        // visible, then make it invisible
        if (visible == false && isVisible == true) {
            wm.removeEntity(this);
            isVisible = false;
            return;
        }
    }

    public void dispose() {
        // First, to make sure the affordance is no longer visible
        setVisible(false);

        // Clean up all of the listeners so this class gets properly garbage
        // collected.
        cell.removeTransformChangeListener(updateListener);
        updateListener = null;
  rootNode = null;
    }

}
TOP

Related Classes of org.jdesktop.wonderland.modules.defaultenvironment.client.DirectionalLightViewerEntity

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.