📄 scene.java
字号:
/*
* Created on 2005-10-03
* $Id: Scene.java,v 1.46 2005/11/10 13:53:56 macx2k Exp $
*/
package net.sf.jawp.gui.client.j3d;
import java.awt.event.MouseAdapter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.media.j3d.AmbientLight;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Group;
import javax.media.j3d.Node;
import javax.media.j3d.View;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import net.sf.jawp.api.domain.Fleet;
import net.sf.jawp.api.domain.Planet;
import net.sf.jawp.client.GameData;
import net.sf.jawp.gui.client.MouseButton;
import net.sf.jawp.gui.client.SelectionController;
import net.sf.jawp.gui.client.SelectionListener;
import net.sf.jawp.j3d.model.ModelFactory;
import net.sf.jawp.j3d.model.ModelProducer;
import net.sf.jawp.j3d.object.TemporaryObjectLayer;
import net.sf.jawp.j3d.texture.TextureManager;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;
import com.sun.j3d.utils.picking.PickCanvas;
import com.sun.j3d.utils.picking.PickResult;
import com.sun.j3d.utils.picking.PickTool;
import com.sun.j3d.utils.universe.SimpleUniverse;
/**
* Helper object managing all details of Java 3D.
*
* @author Maciej Malecki
* @version $Revision: 1.46 $
*/
public final class Scene implements SelectionListener
{
private static final float ZOOM_FACTOR = 10000f;
private static final float FRONT_CLIP_DISTANCE = 100f;
private static final float BACK_CLIP_DISTANCE = 50000f;
/**
* Bounds of visible world, counting from point [0,0,0].
*/
private static final float WORLD_BOUNDS = 1000000f;
private static final float CAMERA_BOUNDS = Float.POSITIVE_INFINITY;
private final SimpleUniverse universe;
private final GameData gameData;
private final TextureManager textureManager;
private final Canvas3D canvas;
private PickCanvas pick;
private TemporaryObjectLayer<Fleet> fleetPool;
private OrbitBehavior cameraBehavior = null;
private Point3d center = new Point3d();
private BranchGroup planetsGroup = null;
private final Map<Long, PlanetSceneNode> planets = new HashMap<Long, PlanetSceneNode>();
private final SelectionController selectionController;
private PlanetSceneNode lastSelected = null;
private boolean showNames = true;
private boolean markOwnership = true;
private ModelProducer spaceshipFactory = null;
/**
* Creates new instance of Scene.
*
* @param canvas
* @param gameData
* @param controller
*/
Scene(final Canvas3D canvas, final GameData gameData,
final SelectionController controller)
{
this.gameData = gameData;
this.canvas = canvas;
this.selectionController = controller;
this.textureManager = new TextureManager(getClass()
.getResourceAsStream("textures.xml"));
// create new universe
universe = new SimpleUniverse(this.canvas);
// set clipping
final View view = universe.getViewer().getView();
view.setFrontClipDistance(FRONT_CLIP_DISTANCE);
view.setBackClipDistance(BACK_CLIP_DISTANCE);
init();
this.selectionController.addListener(this);
}
/**
* Centers camera at given position.
*
* @param position
*/
public void center(final Point3f position)
{
cameraBehavior.getRotationCenter(center);
center.set(position);
cameraBehavior.setRotationCenter(center);
}
/**
* Updates planet ownership (by changing ownership colors).
*
* @param planet
*/
public void updatePlanetOwnership(final Planet planet)
{
final PlanetSceneNode node = planets.get(planet.getKey());
if (node != null)
{
node.updatePlanetOwnership();
}
}
/**
* Disposes the scene. Must be always called when parent window is disposed.
*/
public void dispose()
{
selectionController.removeListener(this);
universe.cleanup();
}
public void addFleet(final Fleet fleet)
{
fleetPool.show(fleet);
}
public void removeFleet(final Fleet fleet)
{
fleetPool.hide(fleet);
}
public void updateFleet(final Fleet fleet)
{
fleetPool.update(fleet);
}
public void unselectPlanet()
{
if (lastSelected != null)
{
lastSelected.setSelected(false);
lastSelected = null;
}
}
/**
* {@inheritDoc}
*/
public void onPlanetSelected(final Planet planet, final MouseButton button)
{
if (button == MouseButton.LEFT)
{
unselectPlanet();
lastSelected = planets.get(planet.getKey());
lastSelected.setSelected(true);
}
else if (button == MouseButton.RIGHT)
{
}
else if (button == MouseButton.MIDDLE)
{
center(J3DHelper.toJ3dPoint(planet.getCoords()));
}
}
public void setShowNames(final boolean flag)
{
for (PlanetSceneNode psn : planets.values())
{
psn.setShowNames(flag);
}
showNames = flag;
}
public boolean isShowNames()
{
return showNames;
}
public void setMarkOwnership(final boolean flag)
{
for (PlanetSceneNode psn : planets.values())
{
psn.setMarkOwnership(flag);
}
markOwnership = flag;
}
public boolean isMarkOwnership()
{
return markOwnership;
}
void addPlanet(final Planet planet)
{
if (planets.containsKey(planet.getKey()))
{
throw new IllegalArgumentException("Planet " + planet
+ " already exists in the scene");
}
final PlanetSceneNode pr = new PlanetSceneNode(planet, textureManager,
gameData);
planetsGroup.addChild(pr.getSceneObject());
planets.put(planet.getKey(), pr);
pr.setShowNames(showNames);
}
private void init()
{
// init spaceship factory
try
{
spaceshipFactory = ModelFactory.instance().loadFromResource(
getClass(), "/models/sulaco.3ds");
}
catch (final IOException e)
{
e.printStackTrace();
}
// create scene
final BranchGroup scene = createScene();
// define camera behavior
cameraBehavior = new OrbitBehavior(canvas,
OrbitBehavior.DISABLE_TRANSLATE);
cameraBehavior.setSchedulingBounds(getCameraBoundingSphere());
cameraBehavior.setZoomFactor(ZOOM_FACTOR);
universe.getViewingPlatform().setViewPlatformBehavior(cameraBehavior);
// create pick tool
pick = new PickCanvas(canvas, scene);
pick.setMode(PickTool.GEOMETRY);
scene.compile();
universe.addBranchGraph(scene);
canvas.addMouseListener(new MouseAdapter()
{
public void mouseClicked(final java.awt.event.MouseEvent e)
{
pick.setShapeLocation(e);
final PickResult result = pick.pickClosest();
if (result != null)
{
final Node node = result.getNode(PickResult.PRIMITIVE);
if (node != null)
{
final Object userData = node.getUserData();
if (userData != null && userData instanceof Planet)
{
selectionController.selectPlanet((Planet) userData,
MouseButton.fromEvent(e));
}
}
}
};
});
}
private BranchGroup createScene()
{
final BranchGroup root = new BranchGroup();
planetsGroup = new BranchGroup();
planetsGroup.setCapability(Group.ALLOW_CHILDREN_EXTEND);
root.addChild(planetsGroup);
// planets
for (Planet planet : gameData.getVisiblePlanets())
{
final PlanetSceneNode pr = new PlanetSceneNode(planet,
textureManager, gameData);
root.addChild(pr.getSceneObject());
planets.put(planet.getKey(), pr);
}
// fleets
fleetPool = new FleetPool(5, spaceshipFactory);
root.addChild(fleetPool.getSceneObjects());
// lights
root.addChild(createLights());
return root;
}
private Node createLights()
{
final BranchGroup bg = new BranchGroup();
final DirectionalLight light = new DirectionalLight(true, new Color3f(
1.0f, 1.0f, 1.0f), new Vector3f(1f, 1f, -1f));
light.setInfluencingBounds(getBoundingSphere());
bg.addChild(light);
final AmbientLight ambient = new AmbientLight(new Color3f(0.3f, 0.3f,
0.3f));
ambient.setInfluencingBounds(getBoundingSphere());
bg.addChild(ambient);
return bg;
}
static BoundingSphere getBoundingSphere()
{
final BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0,
0.0), WORLD_BOUNDS);
return bounds;
}
static BoundingSphere getCameraBoundingSphere()
{
final BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0,
0.0), CAMERA_BOUNDS);
return bounds;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -