import javax.media.control.*;
import com.sun.j3d.utils.behaviors.mouse.MouseRotate;
import javax.media.*;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import java.net.URL;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.image.*;
import com.sun.j3d.utils.geometry.Box;
import java.awt.image.BufferedImage;
import javax.media.j3d.ImageComponent2D;
import java.awt.image.*;
import java.awt.geom.*;
import javax.media.format.*;
import java.io.File;
import com.sun.j3d.utils.picking.behaviors.*;
import com.sun.j3d.utils.picking.*;
import com.sun.j3d.utils.picking.behaviors.*;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Point;
import javax.swing.*;
import javax.swing.border.BevelBorder;
import java.net.*;
import java.io.*;
import java.net.*;
import java.util.Vector;
import javax.media.rtp.*;
import javax.media.rtp.event.*;
import javax.media.rtp.rtcp.*;
import javax.media.protocol.*;
import javax.media.protocol.DataSource;
import javax.media.format.AudioFormat;
import javax.media.format.VideoFormat;
import javax.media.Format;
import javax.media.format.FormatChangeEvent;
import javax.media.control.BufferControl;
/**
* VideoCubes to receive RTP transmission using the new RTP API.
*/
public class VideoCubes extends Applet
implements ReceiveStreamListener, SessionListener, ControllerListener {
String sessions[] = null;
RTPManager mgrs[] = null;
boolean stateTransOK = true;
boolean dataReceived = false;
Object dataSync = new Object();
private View view = null;
private PickRotateBehavior behavior1;
private PickZoomBehavior behavior2;
private PickTranslateBehavior behavior3;
Canvas3D c;
TransformGroup objScale;
BranchGroup scene;
BoundingSphere bounds;
private VirtualUniverse universe;
Locale locale;
int platformSpecificImageType;
int iter;
int[] waitSync = new int[0];
public VideoCubes(String sessions[]) {
this.sessions = sessions;
String os = System.getProperty("os.name");
System.out.println("running on " + os);
if ( os.startsWith("W") || os.startsWith("w")) {
platformSpecificImageType = BufferedImage.TYPE_3BYTE_BGR;
} else if (os.startsWith("S") || os.startsWith("s")){
platformSpecificImageType = BufferedImage.TYPE_4BYTE_ABGR;
} else {
platformSpecificImageType = BufferedImage.TYPE_3BYTE_BGR;
}
init3d();
}
public BranchGroup createViewGraph() {
BranchGroup objRoot = new BranchGroup();
Transform3D t = new Transform3D();
t.setTranslation(new Vector3f(0.0f, 0.f,0.0f));
ViewPlatform vp = new ViewPlatform();
TransformGroup vpTrans = new TransformGroup();
vpTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
vpTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
vpTrans.setTransform(t);
vpTrans.addChild(vp);
view.attachViewPlatform(vp);
view.setBackClipDistance(200.f);
NavigationBehavior nav = new NavigationBehavior(vpTrans);
vpTrans.addChild(nav);
nav.setSchedulingBounds(bounds);
objRoot.addChild(vpTrans);
return objRoot;
}
public void init3d() {
setLayout(new BorderLayout());
bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
universe = new VirtualUniverse();
locale = new Locale(universe);
GraphicsConfigTemplate3D g3d = new GraphicsConfigTemplate3D();
GraphicsConfiguration gc = GraphicsEnvironment. getLocalGraphicsEnvironment().
getDefaultScreenDevice(). getBestConfiguration(g3d);
Canvas3D c = new Canvas3D(gc);
add("Center", c);
PhysicalBody body = new PhysicalBody();
PhysicalEnvironment environment = new PhysicalEnvironment();
view = new View();
view.addCanvas3D(c);
view.setPhysicalBody(body);
view.setPhysicalEnvironment(environment);
// Create a simple scene and attach it to the virtual universe
bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
scene = createSceneGraph(c);
scene.setCapability(Group.ALLOW_CHILDREN_EXTEND);
BranchGroup vgraph = createViewGraph();
locale.addBranchGraph(vgraph);
locale.addBranchGraph(scene);
// Create a scene and attach it to the virtual universe
}
protected boolean initialize() {
try {
InetAddress ipAddr;
SessionAddress localAddr = new SessionAddress();
SessionAddress destAddr;
mgrs = new RTPManager[sessions.length];
SessionLabel session;
// Open the RTP sessions.
for (int i = 0; i < sessions.length; i++) {
// Parse the session addresses.
try {
session = new SessionLabel(sessions[i]);
} catch (IllegalArgumentException e) {
System.err.println("Failed to parse the session address given: " +
sessions[i]);
return false;
}
System.err.println(" - Open RTP session for: addr: "
+ session.addr + " port: "
+ session.port + " ttl: " + session.ttl);
mgrs[i] = (RTPManager) RTPManager.newInstance();
mgrs[i].addSessionListener(this);
mgrs[i].addReceiveStreamListener(this);
ipAddr = InetAddress.getByName(session.addr);
if( ipAddr.isMulticastAddress()) {
// local and remote address pairs are identical:
localAddr= new SessionAddress( ipAddr,
session.port,
session.ttl);
destAddr = new SessionAddress( ipAddr,
session.port,
session.ttl);
} else {
localAddr= new SessionAddress( InetAddress.getLocalHost(),
session.port);
destAddr = new SessionAddress( ipAddr, session.port);
}
mgrs[i].initialize( localAddr);
// You can try out some other buffer size to see
// if you can get better smoothness.
BufferControl bc = (BufferControl)mgrs[i]. getControl("javax.media.control.
BufferControl");
if (bc != null)
bc.setBufferLength(350);
mgrs[i].addTarget(destAddr);
}
} catch (Exception e){
System.err.println("Cannot create the RTP Session: " + e.getMessage());
return false;
}
// Wait for data to arrive before moving on.
long then = System.currentTimeMillis();
long waitingPeriod = 30000;
try{
synchronized (dataSync) {
while (!dataReceived &&
System.currentTimeMillis() - then < waitingPeriod) {
if (!dataReceived)
System.err.println(" - Waiting for RTP data to arrive...");
dataSync.wait(1000);
}
}
} catch (Exception e) {}
if (!dataReceived) {
System.err.println("No RTP data was received.");
//close();
return false;
}
return true;
}
public synchronized void update(SessionEvent evt) {
if (evt instanceof NewParticipantEvent) {
Participant p = ((NewParticipantEvent)evt).getParticipant();
System.err.println(" - A new participant had just joined: "
+ p.getCNAME());
}
}
private BranchGroup createVCube(DataSource ds,
double scale,
double xpos,
double ypos,
double zpos){
BranchGroup newG = new BranchGroup();
Transform3D t = new Transform3D();
t.set(scale, new Vector3d(xpos, ypos, zpos));
TransformGroup objTrans = new TransformGroup(t);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
objTrans.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
// Create a second transform group node and initialize it to the
// identity. Enable the TRANSFORM_WRITE capability so that
// our behavior code can modify it at runtime.
TransformGroup spinTg = new TransformGroup();
spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
spinTg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
spinTg.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
Appearance app = new Appearance();
app.setCapability(Appearance.ALLOW_TEXTURE_WRITE);
//determine which platform code is running on
JMFTexture2D jtex = new JMFTexture2D(c,
128,
128,
144,
176,
platformSpecificImageType,
platformSpecificYUP);
jtex.setMedia(ds);
jtex.openMedia();
jtex.init();
app.setTexture(jtex);
BoundingSphere b = new BoundingSphere(new Point3d(xpos,ypos,zpos), 1.0);
Box stream = new Box(1.f,1.f,1.f,
Box.GENERATE_TEXTURE_COORDS |
Box.ENABLE_GEOMETRY_PICKING, app);
spinTg.addChild(stream);
// add it to the scene graph.
objTrans.addChild(spinTg);
newG.addChild(objTrans);
return newG;
}
///end of createObject
public synchronized void update( ReceiveStreamEvent evt) {
RTPManager mgr = (RTPManager)evt.getSource();
Participant participant = evt.getParticipant(); // could be null.
ReceiveStream stream = evt.getReceiveStream(); // could be null.
if (evt instanceof RemotePayloadChangeEvent) {
System.err.println(" - Received an RTP PayloadChangeEvent.");
System.err.println("Sorry, cannot handle payload change.");
System.exit(0);
}
else if (evt instanceof NewReceiveStreamEvent) {
try {
stream = ((NewReceiveStreamEvent)evt).getReceiveStream();
DataSource ds = stream.getDataSource();
iter=iter+10;
// Find out the formats.
RTPControl ctl = (RTPControl)ds.
getControl("javax.media.rtp.RTPControl");
if (ctl != null){
System.err.println(" - Received new RTP stream: "
+ ctl.getFormat());
} else
System.err.println(" - Received new RTP stream");
if (participant == null)
System.err.println(" The sender of this stream had yet to be identified.");
else {
System.err.println(" The stream comes from: " +
participant.getCNAME());
}
scene.addChild(createVCube(ds, 0.5, 0.0, 0.0,iter));
System.out.println("creating cube " );
synchronized (dataSync) {
dataReceived = true;
dataSync.notifyAll();
}
} catch (Exception e) {
System.err.println("NewReceiveStreamEvent exception " + e.getMessage());
return;
}
}
else if (evt instanceof StreamMappedEvent) {
if (stream != null && stream.getDataSource() != null) {
DataSource ds = stream.getDataSource();
// Find out the formats.
RTPControl ctl = (RTPControl)ds.
getControl("javax.media.rtp.RTPControl");
System.err.println(" - The previously unidentified stream ");
if (ctl != null)
System.err.println(" " + ctl.getFormat());
System.err.println(" has now been identified as sent by: "
+ participant.getCNAME());
}
}
else if (evt instanceof ByeEvent) {
System.err.println(" - Got "bye" from: " + participant.getCNAME());
}
}
private Group createStructuralElement(double scale,
Vector3d pos, Color3f color,
float xdim, float ydim, float zdim,
int tnumber) {
// Create a transform group node to scale and position the object.
Transform3D t = new Transform3D();
t.set(scale, pos);
TransformGroup objTrans = new TransformGroup(t);
Appearance app = new Appearance();
ColoringAttributes ca =
new ColoringAttributes(color,ColoringAttributes.
SHADE_GOURAUD);
app.setColoringAttributes(ca);
Box structelem = new Box(xdim, ydim, zdim, app);
objTrans.addChild(structelem);
return objTrans;
}
public BranchGroup createSceneGraph(Canvas3D canvas) {
// Create the root of the branch graph
BranchGroup objRoot = new BranchGroup();
//add walls, floors etc.
Group rightwall =
createStructuralElement(1.f,
new Vector3d( 50.0, 0.0, 0.0),
new Color3f(1.f,0.f,0.f),
2.0f, 14.0f, 100.0f, 1);
objRoot.addChild(rightwall);
. . .
behavior1 = new PickRotateBehavior(objRoot, canvas, bounds);
objRoot.addChild(behavior1);
behavior2 = new PickZoomBehavior(objRoot, canvas, bounds);
objRoot.addChild(behavior2);
behavior3 = new PickTranslateBehavior(objRoot, canvas, bounds);
objRoot.addChild(behavior3);
// Let Java 3D perform optimizations on this scene graph.
objRoot.compile();
return objRoot;
}
public synchronized void controllerUpdate(ControllerEvent evt) {
if ( evt instanceof ConfigureCompleteEvent ||
evt instanceof RealizeCompleteEvent ||
evt instanceof PrefetchCompleteEvent ) {
synchronized (waitSync) {
stateTransOK = true;
waitSync.notifyAll();
}
} else if ( evt instanceof ResourceUnavailableEvent) {
synchronized (waitSync) {
stateTransOK = false;
waitSync.notifyAll();
}
}
}
/*
A utility class to parse the session addresses.
*/
class SessionLabel {
public String addr = null;
public int port;
public int ttl = 1;
SessionLabel(String session) throws IllegalArgumentException {
int off;
String portStr = null, ttlStr = null;
if (session != null && session.length() > 0) {
while (session.length() > 1 && session.charAt(0) == '/')
session = session.substring(1);
// Now see if there's a addr specified.
off = session.indexOf('/'),
if (off == -1) {
if (!session.equals(""))
addr = session;
} else {
addr = session.substring(0, off);
session = session.substring(off + 1);
// Now see if there's a port specified
off = session.indexOf('/'),
if (off == -1) {
if (!session.equals(""))
portStr = session;
} else {
portStr = session.substring(0, off);
session = session.substring(off + 1);
// Now see if there's a ttl specified
off = session.indexOf('/'),
if (off == -1) {
if (!session.equals(""))
ttlStr = session;
} else {
ttlStr = session.substring(0, off);
}
}
}
}
if (addr == null)
throw new IllegalArgumentException();
if (portStr != null) {
try {
Integer integer = Integer.valueOf(portStr);
if (integer != null)
port = integer.intValue();
} catch (Throwable t) {
throw new IllegalArgumentException();
}
} else
throw new IllegalArgumentException();
if (ttlStr != null) {
try {
Integer integer = Integer.valueOf(ttlStr);
if (integer != null)
ttl = integer.intValue();
} catch (Throwable t) {
throw new IllegalArgumentException();
}
}
}
}
public static void main(String argv[]) {
if (argv.length == 0)
prUsage();
BranchGroup group;
VideoCubes cubes = new VideoCubes(argv);
new MainFrame(cubes,750,550);
if (!cubes.initialize()) {
System.err.println("Failed to initialize the sessions.");
System.exit(-1);
}
}
static void prUsage() {
System.err.println("Usage: VideoCubes <session> <session> ...");
System.err.println(" <session>: <address>/<port>/<ttl>");
System.exit(0);
}
}// end of VideoCubes
|