sceneobject.java

来自「Java mulitplayer strategy game. Adaptati」· Java 代码 · 共 219 行

JAVA
219
字号
/*
 * Created on 2005-10-11
 * $Id: SceneObject.java,v 1.3 2006/01/11 20:33:48 macx2k Exp $
 */
package net.sf.jawp.j3d.object;

import javax.media.j3d.BranchGroup;
import javax.media.j3d.Node;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;

import net.sf.jawp.j3d.picking.PickingHelper;

/**
 * Wrapper for business objects that can be rendered on Java3D scene.
 * 
 * @author Maciej Malecki
 * @version $Revision: 1.3 $
 * @param <RENDERABLE>
 *            type which will be rendered (a Java3D SceneGraphObject will be
 *            produced) using this renderer
 */
public abstract class SceneObject<RENDERABLE>
{
	/**
	 * Wrapped business object to be rendered.
	 */
	protected final RENDERABLE renderedObject;

	private final boolean pickable;

	private final boolean moveable;

	private boolean inited = false;

	private BranchGroup branchGroup;

	private Node scenegraphNode;

	private TransformGroup positionTG;

	private TransformGroup rotation1TG;

	private TransformGroup rotation2TG;

	private TransformGroup rotation3TG;

	private Transform3D transform3d = new Transform3D();

	/**
	 * Creates new instance of ObjectSceneNode.
	 * 
	 * @param renderedObject
	 *            object to be wrapped (never null)
	 * @param pickable
	 *            if this scenegraph node can be picked
	 * @throws NullPointerException
	 *             if renderedObject attribute is null
	 */
	protected SceneObject(final RENDERABLE renderedObject,
			final boolean pickable, final boolean moveable)
	{
		if (renderedObject == null)
		{
			throw new NullPointerException("Rendered object is null");
		}
		this.renderedObject = renderedObject;
		this.pickable = pickable;
		this.moveable = moveable;
	}

	public final BranchGroup getSceneObject()
	{
		if (!inited)
		{
			init();
		}
		return branchGroup;
	}

	/**
	 * Updates scenegraph node positon with attached business object data.
	 * 
	 * @throws IllegalStateException
	 *             when there is no business object connected
	 */
	public final void update()
	{
		// update position
		positionTG.getTransform(transform3d);
		updatePosition(renderedObject, transform3d);
		positionTG.setTransform(transform3d);
		
		// update direction
		rotation1TG.getTransform(transform3d);
		updateDirection1(renderedObject, transform3d);
		rotation1TG.setTransform(transform3d);
		
		rotation2TG.getTransform(transform3d);
		updateDirection2(renderedObject, transform3d);
		rotation2TG.setTransform(transform3d);
		
		rotation3TG.getTransform(transform3d);
		updateDirection3(renderedObject, transform3d);
		rotation3TG.setTransform(transform3d);
	}

	/**
	 * This method is called when positioning of Scene Object is needed (in this
	 * case it is during initiation only, as this Scene Object is not movable).
	 * Overriding method should use business position data stored in
	 * renderedObject for updating transform3d transformation data.
	 * 
	 * @param renderedObject
	 *            object which is wrapped by this Scenegraph wrapper
	 * @param transform3d
	 *            transformation for this scene graph object
	 */
	protected abstract void updatePosition(final RENDERABLE renderedObject,
			final Transform3D transform3d);

	protected void updateDirection1(final RENDERABLE renderedObject,
			final Transform3D rotate)
	{
	}

	protected void updateDirection2(final RENDERABLE renderedObject,
			final Transform3D rotate)
	{
	}

	protected void updateDirection3(final RENDERABLE renderedObject,
			final Transform3D rotate)
	{
	}

	/**
	 * This method will construct scene object. Note that it is not actually
	 * called by constructor, but by public method {@link #init()}.
	 * 
	 * @param renderedObject
	 *            object which is wrapped by this Scenegraph wrapper
	 * @return scenegraph node (should never be null)
	 */
	protected abstract Node createScenegraphObject(
			final RENDERABLE renderedObject);

	protected void setUserData(final RENDERABLE renderedObject)
	{
		scenegraphNode.setUserData(renderedObject);
	}

	/**
	 * Builds scenegraph node. This method should be called always and before
	 * this wrapper is put into Java 3D scene.
	 */
	private void init()
	{
		if (inited)
		{
			throw new IllegalStateException("Scene object is already inited");
		}
		inited = true;

		branchGroup = new BranchGroup();

		final Transform3D transform3d = new Transform3D();

		positionTG = new TransformGroup(transform3d);
		if (moveable)
		{
			positionTG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
			positionTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		}

		// define direction transformations
		rotation1TG = new TransformGroup();
		if (moveable)
		{
			rotation1TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
			rotation1TG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		}

		rotation2TG = new TransformGroup();
		if (moveable)
		{
			rotation2TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
			rotation2TG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		}

		rotation3TG = new TransformGroup();
		if (moveable)
		{
			rotation3TG.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
			rotation3TG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		}

		scenegraphNode = createScenegraphObject(renderedObject);
		assert scenegraphNode != null : "Created scenegraph object is null";

		setUserData(renderedObject);
		if (pickable)
		{
			PickingHelper.enablePicking(scenegraphNode);
		}
		
		rotation1TG.addChild(scenegraphNode);
		rotation2TG.addChild(rotation1TG);
		rotation3TG.addChild(rotation2TG);
		positionTG.addChild(rotation3TG);
		branchGroup.addChild(positionTG);

		if (!moveable)
		{
			update();
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?