Package org.jdesktop.wonderland.client.cell.utils

Source Code of org.jdesktop.wonderland.client.cell.utils.CellUtils

/**
* 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-2010, 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.cell.utils;

import com.jme.bounding.BoundingSphere;
import com.jme.bounding.BoundingVolume;
import com.jme.math.Vector3f;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.wonderland.client.cell.Cell;
import org.jdesktop.wonderland.client.cell.CellEditChannelConnection;
import org.jdesktop.wonderland.client.cell.view.ViewCell;
import org.jdesktop.wonderland.client.comms.WonderlandSession;
import org.jdesktop.wonderland.client.jme.ViewManager;
import org.jdesktop.wonderland.client.jme.utils.ScenegraphUtils;
import org.jdesktop.wonderland.client.login.ServerSessionManager;
import org.jdesktop.wonderland.common.cell.CellEditConnectionType;
import org.jdesktop.wonderland.common.cell.CellID;
import org.jdesktop.wonderland.common.cell.CellTransform;
import org.jdesktop.wonderland.common.cell.messages.CellCreateMessage;
import org.jdesktop.wonderland.common.cell.messages.CellCreatedMessage;
import org.jdesktop.wonderland.common.cell.messages.CellDeleteMessage;
import org.jdesktop.wonderland.common.cell.state.BoundingVolumeHint;
import org.jdesktop.wonderland.common.cell.state.CellServerState;
import org.jdesktop.wonderland.common.cell.state.PositionComponentServerState;
import org.jdesktop.wonderland.common.cell.state.ViewComponentServerState;
import org.jdesktop.wonderland.common.messages.ResponseMessage;

/**
* A collection of useful utility routines pertaining to Cells.
*
* @author Jordan Slott <jslott@dev.java.net>
*/
public class CellUtils {

    private static Logger logger = Logger.getLogger(CellUtils.class.getName());

    /** The default bounds radius to use if no hint is given */
    private static final float DEFAULT_RADIUS = 1.0f;

    /**
     * Creates a cell in the world given the CellServerState of the cell. If the
     * given CellServerState is null, this method simply does not create a Cell.
     * This method attempts to position the Cell "optimally" so that the avatar
     * can see it, based upon "hints" about the Cell bounds given to it in the
     * CellServerState.
     *
     * @param state The cell server state for the new cell
     * @throw CellCreationException Upon error creating the cell
     */
    public static CellID createCell(CellServerState state)
            throws CellCreationException
    {
        // Find the parent cell for this creation (may be null)
        CellID parentID = null;
        Cell parent = CellCreationParentRegistry.getCellCreationParent();
        if (parent != null) {
            parentID = parent.getCellID();
            logger.info("Using parent with Cell ID " + parentID.toString());
        }
       
        return createCell(state, parentID)
    }

    /**
     * Creates a cell in the world given the CellServerState of the cell. If the
     * given CellServerState is null, this method simply does not create a Cell.
     * This method attempts to position the Cell "optimally" so that the avatar
     * can see it, based upon "hints" about the Cell bounds given to it in the
     * CellServerState.
     *
     * @param state The cell server state for the new cell
     * @param parentCellID The Cell ID of the parent, of null for world root
     * @throw CellCreationException Upon error creating the cell
     */
    public static CellID createCell(CellServerState state, CellID parentCellID)
            throws CellCreationException
    {
        // Check to see if the Cell server state is null, and fail quietly if
        // so
        if (state == null) {
            logger.fine("Creating cell with null server state. Returning.");
            return null;
        }

        // Fetch the transform of the view (avatar) Cell and its "look at"
        // direction.
        ViewManager vm = ViewManager.getViewManager();
        ViewCell viewCell = vm.getPrimaryViewCell();
        CellTransform viewTransform = viewCell.getWorldTransform();
        ServerSessionManager manager =
                viewCell.getCellCache().getSession().getSessionManager();

        // The Cell Transform to apply to the Cell
        CellTransform transform = null;

        // Look for the "bounds hint" provided by the Cell. There are three
        // possible cases:
        //
        // (1) There is a hint and the Cell wants us to do the optimal layout
        // so go ahead and do it.
        //
        // (2) There is no hint, so use the default bounds radius and do the
        // optimal layout
        //
        // (3) There is a hint that says do not do the optimal layout, so we
        // will just put the Cell right on top of the avatar.
        BoundingVolumeHint hint = state.getBoundingVolumeHint();

        logger.info("Using bounding volume hint " + hint.getBoundsHint() +
                ", do placement=" + hint.isDoSystemPlacement());
       
        if (hint != null && hint.isDoSystemPlacement() == true) {
            // Case (1): We have a bounds hint and we want to do the layout,
            // so we find the distance away from the avatar and also the height
            // above the ground.
            BoundingVolume boundsHint = hint.getBoundsHint();
            transform = CellPlacementUtils.getCellTransform(manager, boundsHint,
                    viewTransform);
        }
        else if (hint == null) {
            // Case (2): Do the optimal placement using the default radius.
            BoundingVolume boundsHint = new BoundingSphere(DEFAULT_RADIUS, Vector3f.ZERO);
            transform = CellPlacementUtils.getCellTransform(manager, boundsHint,
                    viewTransform);
        }
        else if (hint != null && hint.isDoSystemPlacement() == false) {
            // Case (3): The Cell will take care of its own placement, use
            // the origin of the avatar as the initial placement.
           
            // Issue 998: make sure this is actually the current location of
            // the avatar, and not the origin.  This guarantees that the
            // cell will be in the viewcache of the creator at least, so
            // that the cell object can be (for example) positioned manually
            // by the client.
            transform = viewTransform;
        }
       
        // We also need to convert the initial origin of the Cell (in world
        // coordinates to the coordinates of the parent Cell (if non-null)
        if (parentCellID != null) {
            Cell parent = viewCell.getCellCache().getCell(parentCellID);
            CellTransform worldTransform = new CellTransform(null, null);
            CellTransform parentTransform = parent.getWorldTransform();

            logger.info("Transform of the parent cell: translation=" +
                    parentTransform.getTranslation(null).toString() + ", rotation=" +
                    parentTransform.getRotation(null).toString());

            transform = ScenegraphUtils.computeChildTransform(parentTransform,
                                                              transform);
        }
       
        logger.info("Final adjusted origin " + transform.getTranslation(null).toString());
       
        // Create a position component that will set the initial origin
        PositionComponentServerState position = (PositionComponentServerState)
                state.getComponentServerState(PositionComponentServerState.class);
        if (position == null) {
            position = new PositionComponentServerState();
            state.addComponentServerState(position);
        }
        position.setTranslation(transform.getTranslation(null));
        position.setRotation(transform.getRotation(null));
        position.setScaling(transform.getScaling(null));

        // Always pass in the view transform to the Cell's server state
        state.addComponentServerState(new ViewComponentServerState(viewTransform));

        // Send the message to the server
        WonderlandSession session = manager.getPrimarySession();
        CellEditChannelConnection connection = (CellEditChannelConnection)
                session.getConnection(CellEditConnectionType.CLIENT_TYPE);
        CellCreateMessage msg = new CellCreateMessage(parentCellID, state);
//        connection.send(msg);
        ResponseMessage response = null;
        try {
            response = connection.sendAndWait(msg);
        } catch (InterruptedException ex) {
            Logger.getLogger(CellUtils.class.getName()).log(Level.SEVERE, null, ex);
        }
        if(response == null || !(response instanceof CellCreatedMessage)) {
            //handle here.
            return null;
        }
       
        //if things went okay, go ahead and cast and return;
        CellCreatedMessage ccm = (CellCreatedMessage)response;
        return ccm.getCellID();  
    }

    /**
     * Requests the server to delete the given cell from the world
     * of the primary session. Returns true if the deletion succeeds.
     * <br><br>
     * Note: currently always returns true because the server doesn't send
     * any response to the cell delete message.
     */
    public static boolean deleteCell (Cell cell) {
        WonderlandSession session = cell.getCellCache().getSession();
        CellEditChannelConnection connection = (CellEditChannelConnection)
            session.getConnection(CellEditConnectionType.CLIENT_TYPE);
        CellDeleteMessage msg = new CellDeleteMessage(cell.getCellID());
        connection.send(msg);

        // TODO: there really really should be an OK/Error response from the server!

        return true;
    }
}
TOP

Related Classes of org.jdesktop.wonderland.client.cell.utils.CellUtils

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.