Package org.jdesktop.wonderland.server.spatial.impl

Source Code of org.jdesktop.wonderland.server.spatial.impl.SpaceManagerGridImpl

/**
* 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.server.spatial.impl;

import com.jme.bounding.BoundingBox;
import com.jme.bounding.BoundingSphere;
import com.jme.bounding.BoundingVolume;
import com.jme.math.Vector3f;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Logger;

/**
*
* @author paulby
*/
class SpaceManagerGridImpl implements SpaceManager {

    static final int SPACE_SIZE = 50; // Radius

    private HashMap<String, Space> spaces = new HashMap();
    public void initialize() {
    }
   
    /**
     * Return the space that encloses this point, if the space does not exist, create it
     * @param position
     * @return
     */
    public Iterable<Space> getEnclosingSpace(BoundingVolume volume) {
        ArrayList retList = new ArrayList();

        Vector3f point = volume.getCenter();

        float xf = ((point.x+SPACE_SIZE) / (SPACE_SIZE*2));
        float yf = ((point.y+SPACE_SIZE) / (SPACE_SIZE*2));
        float zf = ((point.z+SPACE_SIZE) / (SPACE_SIZE*2));

        int x,y,z;

        if (xf>0)
            x = (int) Math.floor(xf);
        else
            x = (int) Math.ceil(xf);
        if (yf>0)
            y = (int) Math.floor(yf);
        else
            y = (int) Math.ceil(yf);
        if (zf>0)
            z = (int) Math.floor(zf);
        else
            z = (int) Math.ceil(zf);

        // Get the space that encloses the center of the volume
        Space sp = getEnclosingSpaceImpl(x,y,z);
       
        if (sp==null) {
            sp = createSpace(x, y, z);
//            System.err.println("Created space "+point+"  "+sp.getName()+" "+sp);
//
        }

        // Debug test. TODO REMOVE
//        if (!sp.getWorldBounds().contains(point))
//            Logger.getLogger(SpaceManagerGridImpl.class.getName()).warning("BAD ENCLOSING SPACE "+sp.getWorldBounds()+"  does not contain "+point+"   name "+getSpaceBindingName(x, y, z));
       
        retList.add(sp);

        int xStep;
        int yStep;
        int zStep;

        // Now get all the other spaces within the volume
        if (volume instanceof BoundingBox) {
            xStep = 1+(int) (((BoundingBox)volume).xExtent / (SPACE_SIZE));
            yStep = 1+(int) (((BoundingBox)volume).yExtent / (SPACE_SIZE));
            zStep = 1+(int) (((BoundingBox)volume).zExtent / (SPACE_SIZE));
        } else if (volume instanceof BoundingSphere) {
            xStep = yStep = zStep = 1+(int) (((BoundingSphere)volume).getRadius() / (SPACE_SIZE));
        } else
            throw new RuntimeException("Bounds not supported "+volume.getClass().getName());

//        System.out.println("RADIUS "+radius+"  step "+step);
//        System.err.println("Bounds "+volume);
//        System.err.println("Current "+x+", "+y+", "+z);
//        System.err.println("In space "+getSpaceBindingName(x, y, z)+"   step="+xStep+", "+yStep+", "+zStep);
        // TODO this is brute force, is there a better way ?
        for(int xs=-xStep; xs<=xStep; xs++) {
            for(int ys=-yStep; ys<=yStep; ys++) {
                for(int zs=-zStep; zs<=zStep; zs++) {
                    sp = getEnclosingSpaceImpl(x+xs, y+ys, z+zs);
                    if (sp==null){
                        // Create the space
                        sp = createSpace(x+xs, y+ys, z+zs);
//                        System.out.println("Creating "+sp.getName()+"  "+sp.getWorldBounds());
                    }
//                    System.err.print("Checking "+(x+xs)+", "+(y+ys)+", "+(z+zs)+" "+sp.getWorldBounds());

//                    System.err.println(sp.getName()+"  "+sp.getWorldBounds()+"  "+sp.getWorldBounds().intersects(volume));
                    if (sp.getWorldBounds().intersects(volume)) {
//                        System.err.println("  +");
                        retList.add(sp);
                    } else {
//                        System.err.println();
                    }
                }
            }
        }

        return retList;
    }

    private Space createSpace(int x, int y, int z) {
       
        Vector3f center = new Vector3f(((x) * SPACE_SIZE*2),
                                       ((y) * SPACE_SIZE*2),
                                       ((z) * SPACE_SIZE*2));
        BoundingBox gridBounds = new BoundingBox(center,
                                                 SPACE_SIZE,
                                                 SPACE_SIZE,
                                                 SPACE_SIZE);

        String bindingName = getSpaceBindingName(x, y, z);
        Space space = new Space(gridBounds, bindingName);
        synchronized(spaces) {
            spaces.put(bindingName, space);
        }
       
        return space;
    }
   
    /**
     * Return the space that encloses this point, or null if the space does not exist.
     * @param position
     * @return
     */
    private Space getEnclosingSpaceImpl(int x, int y, int z) {
        synchronized(spaces) {
            return spaces.get(getSpaceBindingName(x,y,z));
        }
    }
   
    private String getSpaceBindingName(int x, int y, int z) {
        return x+"_"+y+"_"+z;
    }
}
TOP

Related Classes of org.jdesktop.wonderland.server.spatial.impl.SpaceManagerGridImpl

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.