Package org.jdesktop.wonderland.modules.artimport.client

Source Code of org.jdesktop.wonderland.modules.artimport.client.DeployedModelCellFactory

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

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.bounding.BoundingVolume;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import java.awt.Image;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdesktop.wonderland.client.cell.asset.AssetUtils;
import org.jdesktop.wonderland.client.cell.registry.annotation.CellFactory;
import org.jdesktop.wonderland.client.cell.registry.spi.CellFactorySPI;
import org.jdesktop.wonderland.client.jme.artimport.DeployedModel;
import org.jdesktop.wonderland.client.jme.artimport.LoaderManager;
import org.jdesktop.wonderland.client.jme.artimport.ModelLoader;
import org.jdesktop.wonderland.common.cell.state.BoundingVolumeHint;
import org.jdesktop.wonderland.common.cell.state.CellServerState;
import org.jdesktop.wonderland.common.cell.state.ModelCellComponentServerState;
import org.jdesktop.wonderland.common.cell.state.ModelCellServerState;
import org.jdesktop.wonderland.common.cell.state.PositionComponentServerState;

/**
* A Cell Factory that loads deployed model (.dep) files. This does not appear
* in the Cell Palette, but supports creation via DnD or the Content Browser.
*
* @author Jordan Slott <jslott@dev.java.net>
*/
@CellFactory
public class DeployedModelCellFactory implements CellFactorySPI {

    // The error logger
    private static final Logger LOGGER =
            Logger.getLogger(DeployedModelCellFactory.class.getName());

    /**
     * {@inheritDoc}
     */
    public String[] getExtensions() {
        return new String[] { "dep" };
    }

    /**
     * {@inheritDoc}
     */
    public <T extends CellServerState> T getDefaultCellServerState(Properties props) {
        // Fetch the URI of the model to load via the "content-uri" property.
        // If not present return null. Convert into a URL
        URL url = null;
        if (props != null) {
            String uri = props.getProperty("content-uri");
            if (uri != null) {
                try {
                    url = AssetUtils.getAssetURL(uri);
                } catch (MalformedURLException excp) {
                    LOGGER.log(Level.WARNING, "Unable to form asset URI from " +
                            uri, excp);
                    url = null;
                }
            }
        }

        // Check to make sure the URL is not null. If so, then just return
        // null
        if (url == null) {
            LOGGER.warning("The URL is null");
            return null;
        }


//        LOGGER.warning("Loading URL " + url.toExternalForm());

        // Simply create a new ModelCell by creating a ModelCellServerState
        // with the URL passed in via the properties. First load the deployed
        // model from the given URL.
        LoaderManager lm = LoaderManager.getLoaderManager();
        DeployedModel dm = null;
        try {
            dm = lm.getLoaderFromDeployment(url);
        } catch (IOException excp) {
            LOGGER.log(Level.WARNING, "Unable to load deployed model from " +
                    url.toExternalForm(), excp);
            return null;
        }

        BoundingVolumeHint hint=null;
        PositionComponentServerState posComp = new PositionComponentServerState();

        if (dm.getModelBounds()==null) {
            // Legacy support, the DeployedModels object for new builds contains
            // the model bounds.
            // Go ahead and load the model. We need to load the model in order to
            // find out its bounds to set the hint.
            ModelLoader loader = dm.getModelLoader();
            Node node = loader.loadDeployedModel(dm, null);
            BoundingVolume bounds = node.getWorldBound();
            hint = getBoundingVolumeHint(bounds);
            posComp.setBounds(bounds);
        } else {
            hint = getBoundingVolumeHint(dm.getModelBounds());
            posComp.setBounds(dm.getModelBounds());
        }

        // Create a new server state for a Model Cell that knows how to display
        // the URL.
        ModelCellServerState state = new ModelCellServerState();
        ModelCellComponentServerState compState = new ModelCellComponentServerState();
        compState.setDeployedModelURL(url.toExternalForm());
        state.addComponentServerState(compState);
        state.setBoundingVolumeHint(hint);
        state.addComponentServerState(posComp);

        // Set the name of the Cell based upon the URL of the model
        state.setName(getFileName(url));

        return (T)state;
    }

    /**
     * {@inheritDoc}
     */
    public String getDisplayName() {
        // Should not appear in the Cell Palette so return null
        return null;
    }

    /**
     * {@inheritDoc}
     */
    public Image getPreviewImage() {
        // Does not appear in the Cell Palette, so no preview image
        return null;
    }

    /**
     * Returns the bounding volume hint based upon the deployed model. If the
     * model is too large, it places it on top of the avatar.
     */
    private BoundingVolumeHint getBoundingVolumeHint(BoundingVolume bounds) {
        // If the model is too large, then set the bounds to extent/radius of
        // 1, so that it essentially appears on top of the avatar. This prevents
        // it from being placed too far away. We keep the y value -- so that
        // the model is placed on the ground, and not in it.
        BoundingVolume hint = bounds;
        if (bounds instanceof BoundingBox) {
            // Handle if the bounding volume is a box. We only care about the
            // x and z extents, since we'll always want to place the model on
            // the floor, no matter how high it is.
            BoundingBox box = (BoundingBox) bounds;
            if (box.xExtent > 20 || box.zExtent > 20) {
                hint = new BoundingBox(Vector3f.ZERO, 1, box.yExtent, 1);
            }
        }
        else if (bounds instanceof BoundingSphere) {
            // Handle if the bounding volume is a sphere. This is a bit tricky.
            // If the radius is too large, we want to place the model close to
            // the avatar, but we also want the model to sit on the floor, not
            // in it. So in this case, we need to create a bounding box for the
            // hint instead of a sphere, so we can set the x and z extents to
            // be 1 and the y extent to be the radius of the sphere.
            BoundingSphere sphere = (BoundingSphere) bounds;
            if (sphere.radius > 20) {
                hint = new BoundingBox(Vector3f.ZERO, 1, sphere.radius, 1);
            }
        }
        return new BoundingVolumeHint(true, hint);
    }

    /**
     * Takes a URL and returns the file name, without the extension.
     */
    private String getFileName(URL url) {
        String fname = url.getFile();

        // Look for the final foward-slash ("/") and take the last token
        int index = fname.lastIndexOf("/");
        if (index != -1) {
            fname = fname.substring(index + 1);
        }

        // Also cut out the file extension, by looking for the last dot (".")
        index = fname.lastIndexOf(".");
        if (index != -1) {
            fname = fname.substring(0, index);
        }
        return fname;
    }
}
TOP

Related Classes of org.jdesktop.wonderland.modules.artimport.client.DeployedModelCellFactory

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.