Behold, Nenya, Ring of Water and repository for our media and animation related

goodies, both Java 2D and LWJGL/JME 3D.


git-svn-id: svn+ssh://src.earth.threerings.net/nenya/trunk@1 ed5b42cb-e716-0410-a449-f6a68f950b19
This commit is contained in:
Michael Bayne
2006-06-23 18:07:28 +00:00
commit c2117ee86d
570 changed files with 61913 additions and 0 deletions
@@ -0,0 +1,62 @@
//
// $Id$
package com.threerings.jme;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import com.jme.bounding.BoundingBox;
import com.jme.math.Vector3f;
import com.jme.scene.shape.Box;
/**
* Tests the JME/AWT integration bits.
*/
public class JmeCanvasTest extends JmeCanvasApp
{
public static void main (String[] args)
{
final JmeCanvasTest app = new JmeCanvasTest();
JFrame frame = new JFrame("JmeCanvasTest");
frame.getContentPane().add(app.getCanvas(), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setVisible(true);
JButton button = new JButton("Create box");
frame.getContentPane().add(button, BorderLayout.SOUTH);
button.addActionListener(new ActionListener() {
public void actionPerformed (ActionEvent event) {
app.addBox();
}
});
app.run();
}
public void addBox ()
{
Vector3f max = new Vector3f(5, 5, 5);
Vector3f min = new Vector3f(-5, -5, -5);
Box box = new Box("Box", min, max);
box.setModelBound(new BoundingBox());
box.updateModelBound();
box.setLocalTranslation(new Vector3f(0, 0, -10));
_geom.attachChild(box);
_geom.updateRenderState();
}
protected JmeCanvasTest ()
{
super(800, 600);
}
protected void initRoot ()
{
super.initRoot();
}
}
@@ -0,0 +1,160 @@
//
// $Id: JabberApp.java 3098 2004-08-27 02:12:55Z mdb $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.jme.client;
import java.io.InputStream;
import java.io.InputStreamReader;
import com.jme.bounding.BoundingBox;
import com.jme.math.FastMath;
import com.jme.math.Matrix3f;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Box;
import com.jme.util.LoggingSystem;
import com.jme.util.geom.BufferUtils;
import com.jmex.bui.BStyleSheet;
import com.threerings.util.Name;
import com.threerings.presents.client.Client;
import com.threerings.presents.net.UsernamePasswordCreds;
import com.threerings.jme.Log;
import com.threerings.jme.JmeApp;
/**
* The main point of entry for the Jabber client application. It creates
* and initializes the myriad components of the client and sets all the
* proper wheels in motion.
*/
public class JabberApp extends JmeApp
{
/** Used to configure our user interface. */
public static BStyleSheet stylesheet;
// documentation inherited
public boolean init ()
{
if (!super.init()) {
return false;
}
// initialize our client instance
_client = new JabberClient();
_client.init(this);
// add some simple geometry for kicks
Vector3f max = new Vector3f(15, 15, 15);
Vector3f min = new Vector3f(5, 5, 5);
Box t = new Box("Box", min, max);
t.setModelBound(new BoundingBox());
t.updateModelBound();
t.setLocalTranslation(new Vector3f(0, 0, -15));
ColorRGBA[] colors = new ColorRGBA[24];
for (int i = 0; i < 24; i++) {
colors[i] = ColorRGBA.randomColor();
}
t.setColorBuffer(0, BufferUtils.createFloatBuffer(colors));
_root.attachChild(t);
_root.updateRenderState();
// set up the camera
Vector3f loc = new Vector3f(0, -200, 200);
_camera.setLocation(loc);
Matrix3f rotm = new Matrix3f();
rotm.fromAngleAxis(-FastMath.PI/5, _camera.getLeft());
rotm.mult(_camera.getDirection(), _camera.getDirection());
rotm.mult(_camera.getUp(), _camera.getUp());
rotm.mult(_camera.getLeft(), _camera.getLeft());
_camera.update();
// speed up key input
_input.setActionSpeed(100f);
return true;
}
public void run (String server, String username, String password)
{
Client client = _client.getContext().getClient();
// pass them on to the client
Log.info("Using [server=" + server + ".");
client.setServer(server, Client.DEFAULT_SERVER_PORTS);
// configure the client with some credentials and logon
if (username != null && password != null) {
// create and set our credentials
client.setCredentials(
new UsernamePasswordCreds(new Name(username), password));
client.logon();
}
// now start up the main event loop
run();
}
// documentation inherited
public void stop ()
{
// log off before we shutdown
Client client = _client.getContext().getClient();
if (client.isLoggedOn()) {
client.logoff(false);
}
Log.info("Stopping.");
super.stop();
}
public static void main (String[] args)
{
LoggingSystem.getLogger().setLevel(java.util.logging.Level.OFF);
String server = "localhost";
if (args.length > 0) {
server = args[0];
}
// load up the default BUI stylesheet
try {
InputStream stin = JabberApp.class.getClassLoader().
getResourceAsStream("rsrc/style.bss");
stylesheet = new BStyleSheet(
new InputStreamReader(stin),
new BStyleSheet.DefaultResourceProvider());
} catch (Exception e) {
e.printStackTrace(System.err);
System.exit(-1);
}
String username = (args.length > 1) ? args[1] : null;
String password = (args.length > 2) ? args[2] : null;
JabberApp app = new JabberApp();
app.init();
app.run(server, username, password);
}
protected JabberClient _client;
}
@@ -0,0 +1,228 @@
//
// $Id: JabberClient.java 3283 2004-12-22 19:23:00Z ray $
//
// Narya library - tools for developing networked games
// Copyright (C) 2002-2004 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/narya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
package com.threerings.jme.client;
import com.jmex.bui.BRootNode;
import com.jme.input.InputHandler;
import com.jme.renderer.Renderer;
import com.jme.scene.Node;
import com.jme.system.DisplaySystem;
import com.samskivert.util.Config;
import com.threerings.util.MessageManager;
import com.threerings.presents.client.Client;
import com.threerings.presents.client.SessionObserver;
import com.threerings.presents.dobj.DObjectManager;
import com.threerings.crowd.chat.client.ChatDirector;
import com.threerings.crowd.client.LocationDirector;
import com.threerings.crowd.client.OccupantDirector;
import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.jme.JmeContext;
import com.threerings.jme.camera.CameraHandler;
/**
* The Jabber client takes care of instantiating all of the proper
* managers and loading up all of the necessary configuration and getting
* the client bootstrapped. It can be extended by games that require an
* extended context implementation.
*/
public class JabberClient
implements SessionObserver
{
/**
* Initializes a new client and provides it with a frame in which to
* display everything.
*/
public void init (JabberApp app)
{
_app = app;
// create our context
_ctx = createContextImpl();
// create the directors/managers/etc. provided by the context
createContextServices(app);
// for test purposes, hardcode the server info
_client.setServer("localhost", Client.DEFAULT_SERVER_PORTS);
_client.addClientObserver(this);
}
/**
* Returns a reference to the context in effect for this client. This
* reference is valid for the lifetime of the application.
*/
public CrowdContext getContext ()
{
return _ctx;
}
// documentation inherited from interface SessionObserver
public void clientDidLogon (Client client)
{
// enter the one and only chat room; giant hack warning: we know
// that the place we're headed to is ID 2 because there's only one
// place on the whole server; a normal client would either issue
// an invocation service request at this point or look at
// something in the BootstrapData to figure out what to do
_ctx.getLocationDirector().moveTo(2);
}
// documentation inherited from interface SessionObserver
public void clientObjectDidChange (Client client)
{
// nada
}
// documentation inherited from interface SessionObserver
public void clientDidLogoff (Client client)
{
System.exit(0);
}
/**
* Creates the {@link JabberContext} implementation that will be
* passed around to all of the client code. Derived classes may wish
* to override this and create some extended context implementation.
*/
protected CrowdContext createContextImpl ()
{
return new JabberContextImpl();
}
/**
* Creates and initializes the various services that are provided by
* the context. Derived classes that provide an extended context
* should override this method and create their own extended
* services. They should be sure to call
* <code>super.createContextServices</code>.
*/
protected void createContextServices (JabberApp app)
{
// create the handles on our various services
_client = new Client(null, app);
// create our managers and directors
_locdir = new LocationDirector(_ctx);
_occdir = new OccupantDirector(_ctx);
_msgmgr = new MessageManager(MESSAGE_MANAGER_PREFIX);
_chatdir = new ChatDirector(_ctx, _msgmgr, null);
}
/**
* The context implementation. This provides access to all of the
* objects and services that are needed by the operating client.
*/
protected class JabberContextImpl implements CrowdContext, JmeContext
{
/**
* Apparently the default constructor has default access, rather
* than protected access, even though this class is declared to be
* protected. Why, I don't know, but we need to be able to extend
* this class elsewhere, so we need this.
*/
protected JabberContextImpl () {
}
public Client getClient () {
return _client;
}
public DObjectManager getDObjectManager () {
return _client.getDObjectManager();
}
public Config getConfig () {
return _config;
}
public LocationDirector getLocationDirector () {
return _locdir;
}
public OccupantDirector getOccupantDirector () {
return _occdir;
}
public ChatDirector getChatDirector () {
return _chatdir;
}
public void setPlaceView (PlaceView view) {
// TBD
}
public void clearPlaceView (PlaceView view) {
// we'll just let the next place view replace our old one
}
public Renderer getRenderer () {
return _app.getContext().getRenderer();
}
public DisplaySystem getDisplay () {
return _app.getContext().getDisplay();
}
public CameraHandler getCameraHandler () {
return _app.getContext().getCameraHandler();
}
public Node getGeometry () {
return _app.getContext().getGeometry();
}
public Node getInterface () {
return _app.getContext().getInterface();
}
public InputHandler getInputHandler () {
return _app.getContext().getInputHandler();
}
// public InputHandler getBufferedInputHandler () {
// return _app.getContext().getBufferedInputHandler();
// }
public BRootNode getRootNode () {
return _app.getContext().getRootNode();
}
}
protected CrowdContext _ctx;
protected JabberApp _app;
protected Config _config = new Config("jabber");
protected Client _client;
protected LocationDirector _locdir;
protected OccupantDirector _occdir;
protected ChatDirector _chatdir;
protected MessageManager _msgmgr;
/** The prefix prepended to localization bundle names before looking
* them up in the classpath. */
protected static final String MESSAGE_MANAGER_PREFIX = "rsrc.i18n";
}
@@ -0,0 +1,19 @@
//
// $Id$
package com.threerings.jme.client;
import com.threerings.crowd.client.PlaceController;
import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.util.CrowdContext;
/**
* Handles the basic bits for our simple chat room.
*/
public class JabberController extends PlaceController
{
protected PlaceView createPlaceView (CrowdContext ctx)
{
return new JabberView(ctx);
}
}
@@ -0,0 +1,51 @@
//
// $Id$
package com.threerings.jme.client;
import com.jmex.bui.BLabel;
import com.jmex.bui.BWindow;
import com.jmex.bui.layout.BorderLayout;
import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.util.CrowdContext;
import com.threerings.jme.JmeContext;
import com.threerings.jme.chat.ChatView;
/**
* Manages the "view" when we're in the chat room.
*/
public class JabberView extends BWindow
implements PlaceView
{
public JabberView (CrowdContext ctx)
{
super(JabberApp.stylesheet, new BorderLayout());
_ctx = ctx;
_jctx = (JmeContext)ctx;
_chat = new ChatView(_jctx, _ctx.getChatDirector());
add(_chat, BorderLayout.CENTER);
_jctx.getRootNode().addWindow(this);
setBounds(0, 40, 640, 240);
}
// documentation inherited from interface PlaceView
public void willEnterPlace (PlaceObject plobj)
{
_chat.willEnterPlace(plobj);
}
// documentation inherited from interface PlaceView
public void didLeavePlace (PlaceObject plobj)
{
_chat.didLeavePlace(plobj);
}
protected CrowdContext _ctx;
protected JmeContext _jctx;
protected ChatView _chat;
}
@@ -0,0 +1,26 @@
//
// $Id$
package com.threerings.jme.data;
import com.threerings.crowd.data.PlaceConfig;
import com.threerings.jme.client.JabberController;
/**
* Defines the necessary bits for our chat room.
*/
public class JabberConfig extends PlaceConfig
{
// documentation inherited
public Class getControllerClass ()
{
return JabberController.class;
}
// documentation inherited
public String getManagerClassName ()
{
// nothing special needed on the server side
return "com.threerings.crowd.server.PlaceManager";
}
}
@@ -0,0 +1,49 @@
//
// $Id$
package com.threerings.jme.server;
import com.threerings.crowd.Log;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.crowd.server.CrowdServer;
import com.threerings.crowd.server.PlaceManager;
import com.threerings.crowd.server.PlaceRegistry;
import com.threerings.jme.data.JabberConfig;
/**
* A basic server that creates a single room and sticks everyone in it
* where they can chat with one another.
*/
public class JabberServer extends CrowdServer
{
// documentation inherited
public void init ()
throws Exception
{
super.init();
// create a single location
plreg.createPlace(
new JabberConfig(), new PlaceRegistry.CreationObserver() {
public void placeCreated (PlaceObject place, PlaceManager pmgr) {
Log.info("Created chat room " + pmgr.where() + ".");
_place = pmgr;
}
});
}
public static void main (String[] args)
{
JabberServer server = new JabberServer();
try {
server.init();
server.run();
} catch (Exception e) {
Log.warning("Unable to initialize server.");
Log.logStackTrace(e);
}
}
protected PlaceManager _place;
}
@@ -0,0 +1,150 @@
//
// $Id$
package com.threerings.jme.sprite;
import java.util.Arrays;
import java.util.logging.Level;
import com.jme.math.FastMath;
import com.jme.math.Matrix3f;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.renderer.ColorRGBA;
import com.jme.scene.shape.Box;
import com.jme.scene.shape.Disk;
import com.jme.scene.shape.Quad;
import com.jme.scene.shape.Sphere;
import com.jme.scene.state.LightState;
import com.jme.util.LoggingSystem;
import com.threerings.jme.JmeApp;
import com.threerings.jme.sprite.LineSegmentPath;
/**
* Used for testing paths.
*/
public class PathTest extends JmeApp
{
protected void initRoot ()
{
super.initRoot();
float dist = 10;
// set up the camera
Vector3f loc = new Vector3f(0, -dist, 10);
_camera.setLocation(loc);
Matrix3f rotm = new Matrix3f();
rotm.fromAngleAxis(-FastMath.PI/4, _camera.getLeft());
rotm.multLocal(_camera.getDirection());
rotm.multLocal(_camera.getUp());
rotm.multLocal(_camera.getLeft());
_camera.update();
for (int yy = -1; yy < 1; yy++) {
for (int xx = -1; xx < 1; xx++) {
Quad quad = new Quad("ground", 10, 10);
quad.setLightCombineMode(LightState.OFF);
int index = (yy+1)*2 + (xx+1);
quad.setSolidColor(COLORS[index]);
quad.setLocalTranslation(
new Vector3f(xx * 10 + 5, yy * 10 + 5, -1));
_geom.attachChild(quad);
}
}
for (int yy = -1; yy <= 1; yy++) {
for (int xx = -1; xx <= 1; xx++) {
if (xx != 0 || yy != 0) {
setup(xx * dist, yy * dist);
}
}
}
}
protected void setup (float x, float y)
{
Box target = new Box("target", new Vector3f(-.1f, -.1f, -.1f),
new Vector3f(.1f, .1f, .1f));
target.setLocalTranslation(new Vector3f(x, y, 0));
_geom.attachChild(target);
Box box = new Box("box", new Vector3f(-1, -0.5f, -0.25f),
new Vector3f(1, 0.5f, 0.25f));
Disk disk = new Disk("dot", 10, 10, 0.5f);
disk.setLightCombineMode(LightState.OFF);
disk.setLocalTranslation(new Vector3f(0.5f, 0f, 0.3f));
Sprite shot = new Sprite();
shot.attachChild(box);
shot.attachChild(disk);
_geom.attachChild(shot);
testBallistic(shot, target);
// testLineSegment(shot);
}
protected void testBallistic (Sprite shot, Box target)
{
// start with the "cannon" pointed along the x axis
Vector3f diff = target.getLocalTranslation().subtract(
shot.getLocalTranslation());
Vector3f vel = diff.normalize();
float range = diff.length(), angle = -FastMath.PI/4;
Vector3f axis = UP.cross(vel);
axis.normalizeLocal();
// rotate it up (around the y axis) the necessary elevation
Quaternion rot = new Quaternion();
rot.fromAngleAxis(angle, axis);
rot.multLocal(vel);
// give the cannon its muzzle velocity
float muzvel = FastMath.sqrt(range * BallisticPath.G /
FastMath.sin(2*angle));
vel.multLocal(muzvel);
Vector3f start = new Vector3f(0, 0, 0);
float time = BallisticPath.computeFlightTime(range, muzvel, angle);
shot.move(new OrientingBallisticPath(
shot, new Vector3f(1, 0, 0), start, vel, GRAVITY, time));
System.out.println("Range: " + range);
System.out.println("Muzzle velocity: " + muzvel);
System.out.println("Rotation axis: " + axis);
System.out.println("Angle: " + angle + " (" +
(angle * 180 / FastMath.PI) + ")");
System.out.println("Flight time: " + time);
System.out.println("Velocity: " + vel);
}
protected void testLineSegment (Sprite shot)
{
Vector3f[] points = new Vector3f[] {
new Vector3f(0, 0, 0), new Vector3f(2, 0, 0), new Vector3f(3, 0, 0),
new Vector3f(3, 2, 0), new Vector3f(5, 2, 0), new Vector3f(5, -2, 0),
new Vector3f(-4, -2, 0)
};
float[] durations = new float[points.length];
Arrays.fill(durations, 1f);
Vector3f up = new Vector3f(0, 0, 1);
Vector3f orient = new Vector3f(1, 0, 0);
shot.move(new LineSegmentPath(shot, up, orient, points, durations));
}
public static void main (String[] args)
{
LoggingSystem.getLogger().setLevel(Level.OFF);
PathTest test = new PathTest();
if (!test.init()) {
System.exit(-1);
}
test.run();
}
protected static final Vector3f GRAVITY = new Vector3f(0, 0, -9.8f);
protected static final Vector3f UP = new Vector3f(0, 0, 1);
protected static final ColorRGBA[] COLORS = {
ColorRGBA.red, ColorRGBA.green, ColorRGBA.blue, ColorRGBA.gray };
}