* Here is a sample code that use this utility to create some quads. *
*
* *Notice, that you only need to specify some upperbound on the * number of points you'll use at the beginning (100 in this case). ** * * OldGeomBuffer gbuf = new OldGeomBuffer(100); * gbuf.begin(OldGeomBuffer.QUADS); * * for (int i = 0; i < 5; i++) { * gbuf.normal3d(0.0, 1.0, 0.0); * gbuf.vertex3d(1.0, 1.0, 0.0); * * gbuf.normal3d(0.0, 1.0, 0.0); * gbuf.vertex3d(0.0, 1.0, 0.0); * * gbuf.normal3d(0.0, 1.0, 0.0); * gbuf.vertex3d(0.0, 0.0, 0.0); * * gbuf.normal3d(0.0, 1.0, 0.0); * gbuf.vertex3d(1.0, 0.0, 0.0); * } * gbuf.end(); * Shape3D shape = new Shape3D(gbuf.getGeom(OldGeomBuffer.GENERATE_NORMALS)); ** *
* Currently, you are limited to one primitive type per geom buffer. Future
* versions will add support for mixed primitive types.
*
*/
class OldGeomBuffer extends Object {
//Supported Primitives
static final int QUAD_STRIP = 0x01;
static final int TRIANGLES = 0x02;
static final int QUADS = 0x04;
private int flags;
static final int GENERATE_NORMALS = 0x01;
static final int GENERATE_TEXTURE_COORDS = 0x02;
Point3f[] pts = null;
Vector3f[] normals = null;
Point2f[] tcoords = null;
int currVertCnt;
int currPrimCnt;
int[] currPrimType = null, currPrimStartVertex = null,
currPrimEndVertex = null;
GeometryArray geometry;
int numVerts = 0;
int numTris = 0;
static final int debug = 0;
/**
* Creates a geometry buffer of given number of vertices
*
* @param numVerts
* total number of vertices to allocate by this buffer. This is
* an upper bound estimate.
*/
OldGeomBuffer(int numVerts) {
pts = new Point3f[numVerts];
normals = new Vector3f[numVerts];
tcoords = new Point2f[numVerts];
// max primitives is numV/3
currPrimType = new int[numVerts / 3];
currPrimStartVertex = new int[numVerts / 3];
currPrimEndVertex = new int[numVerts / 3];
currVertCnt = 0;
currPrimCnt = 0;
}
/*
* Returns a Java 3D geometry array from the geometry buffer. You need to
* call begin, vertex3d, end, etc. before calling this, of course.
*
* @param format vertex format.
*/
GeometryArray getGeom(int format) {
GeometryArray obj;
flags = format;
numTris = 0;
//Switch based on first primitive.
switch (currPrimType[0]) {
case TRIANGLES:
obj = processTriangles();
obj.setCapability(Geometry.ALLOW_INTERSECT);
return obj;
case QUADS:
obj = processQuads();
obj.setCapability(Geometry.ALLOW_INTERSECT);
return obj;
case QUAD_STRIP:
obj = processQuadStrips();
obj.setCapability(Geometry.ALLOW_INTERSECT);
return obj;
}
return null;
}
/**
* Begins a new primitive given the primitive type.
*
* @param prim
* the primitive type (listed above).
*
*/
void begin(int prim) {
if (debug >= 1)
System.out.println("quad");
currPrimType[currPrimCnt] = prim;
currPrimStartVertex[currPrimCnt] = currVertCnt;
}
/**
* End of primitive.
*
*
*/
void end() {
if (debug >= 1)
System.out.println("end");
currPrimEndVertex[currPrimCnt] = currVertCnt;
currPrimCnt++;
}
void vertex3d(double x, double y, double z) {
if (debug >= 2)
System.out.println("v " + x + " " + y + " " + z);
pts[currVertCnt] = new Point3f();
pts[currVertCnt].x = (float) x;
pts[currVertCnt].y = (float) y;
pts[currVertCnt].z = (float) z;
currVertCnt++;
}
void normal3d(double x, double y, double z) {
if (debug >= 2)
System.out.println("n " + x + " " + y + " " + z);
double sum = x * x + y * y + z * z;
if (Math.abs(sum - 1.0) > 0.001) {
if (debug >= 2)
System.out.println("normalizing");
double root = Math.sqrt(sum) + 0.0000001;
x /= root;
y /= root;
z /= root;
}
normals[currVertCnt] = new Vector3f();
normals[currVertCnt].x = (float) x;
normals[currVertCnt].y = (float) y;
normals[currVertCnt].z = (float) z;
}
void texCoord2d(double s, double t) {
if (debug >= 2)
System.out.println("t " + s + " " + t);
tcoords[currVertCnt] = new Point2f();
tcoords[currVertCnt].x = (float) s;
tcoords[currVertCnt].y = (float) t;
}
/**
* Returns the Java 3D geometry gotten from calling getGeom.
*
*/
GeometryArray getComputedGeometry() {
return geometry;
}
int getNumTris() {
return numTris;
}
int getNumVerts() {
return numVerts;
}
private GeometryArray processQuadStrips() {
GeometryArray obj = null;
int i;
int totalVerts = 0;
for (i = 0; i < currPrimCnt; i++) {
int numQuadStripVerts;
numQuadStripVerts = currPrimEndVertex[i] - currPrimStartVertex[i];
totalVerts += (numQuadStripVerts / 2 - 1) * 4;
}
if (debug >= 1)
System.out.println("totalVerts " + totalVerts);
if (((flags & GENERATE_NORMALS) != 0)
&& ((flags & GENERATE_TEXTURE_COORDS) != 0)) {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES
| QuadArray.NORMALS | QuadArray.TEXTURE_COORDINATE_2);
} else if (((flags & GENERATE_NORMALS) == 0)
&& ((flags & GENERATE_TEXTURE_COORDS) != 0)) {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES
| QuadArray.TEXTURE_COORDINATE_2);
} else if (((flags & GENERATE_NORMALS) != 0)
&& ((flags & GENERATE_TEXTURE_COORDS) == 0)) {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES
| QuadArray.NORMALS);
} else {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES);
}
Point3f[] newpts = new Point3f[totalVerts];
Vector3f[] newnormals = new Vector3f[totalVerts];
TexCoord2f[] newtcoords = new TexCoord2f[totalVerts];
int currVert = 0;
for (i = 0; i < currPrimCnt; i++) {
for (int j = currPrimStartVertex[i] + 2; j < currPrimEndVertex[i]; j += 2) {
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j - 2);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j - 1);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j + 1);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j);
numTris += 2;
}
}
numVerts = currVert;
obj.setCoordinates(0, newpts);
if ((flags & GENERATE_NORMALS) != 0)
obj.setNormals(0, newnormals);
if ((flags & GENERATE_TEXTURE_COORDS) != 0)
obj.setTextureCoordinates(0, 0, newtcoords);
geometry = obj;
return obj;
}
private GeometryArray processQuads() {
GeometryArray obj = null;
int i;
int totalVerts = 0;
for (i = 0; i < currPrimCnt; i++) {
totalVerts += currPrimEndVertex[i] - currPrimStartVertex[i];
}
if (debug >= 1)
System.out.println("totalVerts " + totalVerts);
if (((flags & GENERATE_NORMALS) != 0)
&& ((flags & GENERATE_TEXTURE_COORDS) != 0)) {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES
| QuadArray.NORMALS | QuadArray.TEXTURE_COORDINATE_2);
} else if (((flags & GENERATE_NORMALS) == 0)
&& ((flags & GENERATE_TEXTURE_COORDS) != 0)) {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES
| QuadArray.TEXTURE_COORDINATE_2);
} else if (((flags & GENERATE_NORMALS) != 0)
&& ((flags & GENERATE_TEXTURE_COORDS) == 0)) {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES
| QuadArray.NORMALS);
} else {
obj = new QuadArray(totalVerts, QuadArray.COORDINATES);
}
Point3f[] newpts = new Point3f[totalVerts];
Vector3f[] newnormals = new Vector3f[totalVerts];
TexCoord2f[] newtcoords = new TexCoord2f[totalVerts];
int currVert = 0;
if (debug > 1)
System.out.println("total prims " + currPrimCnt);
for (i = 0; i < currPrimCnt; i++) {
if (debug > 1)
System.out.println("start " + currPrimStartVertex[i] + " end "
+ currPrimEndVertex[i]);
for (int j = currPrimStartVertex[i]; j < currPrimEndVertex[i] - 3; j += 4) {
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j + 1);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j + 2);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j + 3);
numTris += 2;
}
}
numVerts = currVert;
obj.setCoordinates(0, newpts);
if ((flags & GENERATE_NORMALS) != 0)
obj.setNormals(0, newnormals);
if ((flags & GENERATE_TEXTURE_COORDS) != 0)
obj.setTextureCoordinates(0, 0, newtcoords);
geometry = obj;
return obj;
}
private GeometryArray processTriangles() {
GeometryArray obj = null;
int i;
int totalVerts = 0;
for (i = 0; i < currPrimCnt; i++) {
totalVerts += currPrimEndVertex[i] - currPrimStartVertex[i];
}
if (debug >= 1)
System.out.println("totalVerts " + totalVerts);
if (((flags & GENERATE_NORMALS) != 0)
&& ((flags & GENERATE_TEXTURE_COORDS) != 0)) {
obj = new TriangleArray(totalVerts, TriangleArray.COORDINATES
| TriangleArray.NORMALS
| TriangleArray.TEXTURE_COORDINATE_2);
} else if (((flags & GENERATE_NORMALS) == 0)
&& ((flags & GENERATE_TEXTURE_COORDS) != 0)) {
obj = new TriangleArray(totalVerts, TriangleArray.COORDINATES
| TriangleArray.TEXTURE_COORDINATE_2);
} else if (((flags & GENERATE_NORMALS) != 0)
&& ((flags & GENERATE_TEXTURE_COORDS) == 0)) {
obj = new TriangleArray(totalVerts, TriangleArray.COORDINATES
| TriangleArray.NORMALS);
} else {
obj = new TriangleArray(totalVerts, TriangleArray.COORDINATES);
}
Point3f[] newpts = new Point3f[totalVerts];
Vector3f[] newnormals = new Vector3f[totalVerts];
TexCoord2f[] newtcoords = new TexCoord2f[totalVerts];
int currVert = 0;
for (i = 0; i < currPrimCnt; i++) {
for (int j = currPrimStartVertex[i]; j < currPrimEndVertex[i] - 2; j += 3) {
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j + 1);
outVertex(newpts, newnormals, newtcoords, currVert++, pts,
normals, tcoords, j + 2);
numTris += 1;
}
}
numVerts = currVert;
obj.setCoordinates(0, newpts);
if ((flags & GENERATE_NORMALS) != 0)
obj.setNormals(0, newnormals);
if ((flags & GENERATE_TEXTURE_COORDS) != 0)
obj.setTextureCoordinates(0, 0, newtcoords);
geometry = obj;
return obj;
}
void outVertex(Point3f[] dpts, Vector3f[] dnormals, TexCoord2f[] dtcoords,
int dloc, Point3f[] spts, Vector3f[] snormals, Point2f[] stcoords,
int sloc) {
if (debug >= 1)
System.out.println("v " + spts[sloc].x + " " + spts[sloc].y + " "
+ spts[sloc].z);
dpts[dloc] = new Point3f();
dpts[dloc].x = spts[sloc].x;
dpts[dloc].y = spts[sloc].y;
dpts[dloc].z = spts[sloc].z;
if ((flags & GENERATE_NORMALS) != 0) {
dnormals[dloc] = new Vector3f();
dnormals[dloc].x = snormals[sloc].x;
dnormals[dloc].y = snormals[sloc].y;
dnormals[dloc].z = snormals[sloc].z;
}
if ((flags & GENERATE_TEXTURE_COORDS) != 0) {
if (debug >= 2)
System.out.println("final out tcoord");
dtcoords[dloc] = new TexCoord2f();
dtcoords[dloc].x = stcoords[sloc].x;
dtcoords[dloc].y = stcoords[sloc].y;
}
}
}
//Based on Sun's Box.java 1.13 98/11/23 10:23:02
//Work around for the Box bug when rendered in Wireframe mode.
/**
* Cuboid is a geometry primitive created with a given length, width, and
* height. It is centered at the origin. By default, it lies within the bounding
* Cuboid, [-1,-1,-1] and [1,1,1].
*
* When a texture is applied to a Cuboid, it is map CCW like on a Cylinder. A
* texture is mapped CCW from the back of the body. The top and bottom faces are
* mapped such that the texture appears front facing when the faces are rotated
* 90 toward the viewer.
*/
class Cuboid extends Primitive {
protected int numTris = 0;
protected int numVerts = 0;
/**
* Primitive flags.
*/
protected int flags;
/**
* Used to designate the front side of the Cuboid when using getShape().
*
* @see Cuboid#getShape
*/
public static final int FRONT = 0;
/**
* Used to designate the back side of the Cuboid when using getShape().
*
* @see Cuboid#getShape
*/
public static final int BACK = 1;
/**
* Used to designate the right side of the Cuboid when using getShape().
*
* @see Cuboid#getShape
*/
public static final int RIGHT = 2;
/**
* Used to designate the left side of the Cuboid when using getShape().
*
* @see Cuboid#getShape
*/
public static final int LEFT = 3;
/**
* Used to designate the top side of the Cuboid when using getShape().
*
* @see Cuboid#getShape
*/
public static final int TOP = 4;
/**
* Used to designate the bottom side of the Cuboid when using getShape().
*
* @see Cuboid#getShape
*/
public static final int BOTTOM = 5;
float xDim, yDim, zDim;
/**
* Constructs a default Cuboid of 1.0 in all dimensions.
*/
public Cuboid() {
this(1.0f, 1.0f, 1.0f, GENERATE_NORMALS, null);
}
public Appearance getAppearance(int index) {
return null;
}
/**
* Constructs a Cuboid of a given dimension and appearance.
*
* @param xdim
* X-dimension size.
* @param ydim
* Y-dimension size.
* @param zdim
* Z-dimension size.
* @param ap
* Appearance
*/
public Cuboid(float xdim, float ydim, float zdim, Appearance ap) {
this(xdim, ydim, zdim, GENERATE_NORMALS, ap);
}
/**
* Constructs a Cuboid of a given dimension, flags, and appearance.
*
* @param xdim
* X-dimension size.
* @param ydim
* Y-dimension size.
* @param zdim
* Z-dimension size.
* @param primflags
* primitive flags.
* @param ap
* Appearance
*/
public Cuboid(float xdim, float ydim, float zdim, int primflags,
Appearance ap) {
int i;
double sign;
xDim = xdim;
yDim = ydim;
zDim = zdim;
flags = primflags;
//Depending on whether normal inward bit is set.
if ((flags & GENERATE_NORMALS_INWARD) != 0)
sign = -1.0;
else
sign = 1.0;
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(ALLOW_CHILDREN_READ);
this.addChild(objTrans);
Shape3D shape[] = new Shape3D[6];
for (i = FRONT; i <= BOTTOM; i++) {
OldGeomBuffer gbuf = new OldGeomBuffer(4);
gbuf.begin(OldGeomBuffer.QUAD_STRIP);
for (int j = 0; j < 2; j++) {
gbuf.normal3d((double) normals[i].x * sign,
(double) normals[i].y * sign, (double) normals[i].z
* sign);
gbuf.texCoord2d(tcoords[i * 8 + j * 2], tcoords[i * 8 + j * 2
+ 1]);
gbuf.vertex3d((double) verts[i * 12 + j * 3] * xdim,
(double) verts[i * 12 + j * 3 + 1] * ydim,
(double) verts[i * 12 + j * 3 + 2] * zdim);
}
for (int j = 3; j > 1; j--) {
gbuf.normal3d((double) normals[i].x * sign,
(double) normals[i].y * sign, (double) normals[i].z
* sign);
gbuf.texCoord2d(tcoords[i * 8 + j * 2], tcoords[i * 8 + j * 2
+ 1]);
gbuf.vertex3d((double) verts[i * 12 + j * 3] * xdim,
(double) verts[i * 12 + j * 3 + 1] * ydim,
(double) verts[i * 12 + j * 3 + 2] * zdim);
}
gbuf.end();
shape[i] = new Shape3D(gbuf.getGeom(flags));
numVerts = gbuf.getNumVerts();
numTris = gbuf.getNumTris();
if ((flags & ENABLE_APPEARANCE_MODIFY) != 0) {
(shape[i]).setCapability(Shape3D.ALLOW_APPEARANCE_READ);
(shape[i]).setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
}
objTrans.addChild(shape[i]);
}
if (ap == null) {
setAppearance();
} else
setAppearance(ap);
}
/**
* Gets one of the faces (Shape3D) from the Cuboid that contains the
* geometry and appearance. This allows users to modify the appearance or
* geometry of individual parts.
*
* @param partId
* The part to return.
* @return The Shape3D object associated with the partID. If an invalid
* partId is passed in, null is returned.
*/
public Shape3D getShape(int partId) {
if ((partId >= FRONT) && (partId <= BOTTOM))
return (Shape3D) (((Group) getChild(0)).getChild(partId));
return null;
}
/**
* Sets appearance of the Cuboid. This will set each face of the Cuboid to
* the same appearance. To set each face's appearance separately, use
* getShape(partId) to get the individual shape and call
* shape.setAppearance(ap).
*/
public void setAppearance(Appearance ap) {
((Shape3D) ((Group) getChild(0)).getChild(TOP)).setAppearance(ap);
((Shape3D) ((Group) getChild(0)).getChild(LEFT)).setAppearance(ap);
((Shape3D) ((Group) getChild(0)).getChild(RIGHT)).setAppearance(ap);
((Shape3D) ((Group) getChild(0)).getChild(FRONT)).setAppearance(ap);
((Shape3D) ((Group) getChild(0)).getChild(BACK)).setAppearance(ap);
((Shape3D) ((Group) getChild(0)).getChild(BOTTOM)).setAppearance(ap);
}
private static final float[] verts = {
// front face
1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f,
-1.0f, 1.0f,
// back face
-1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f,
-1.0f, -1.0f,
// right face
1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
-1.0f, 1.0f,
// left face
-1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
-1.0f, -1.0f,
// top face
1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f,
1.0f, 1.0f,
// bottom face
-1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f,
-1.0f, 1.0f, };
private static final double[] tcoords = {
// front
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
// back
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
//right
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
// left
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
// top
1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
// bottom
0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0 };
private static final Vector3f[] normals = { new Vector3f(0.0f, 0.0f, 1.0f), // front
// face
new Vector3f(0.0f, 0.0f, -1.0f), // back face
new Vector3f(1.0f, 0.0f, 0.0f), // right face
new Vector3f(-1.0f, 0.0f, 0.0f), // left face
new Vector3f(0.0f, 1.0f, 0.0f), // top face
new Vector3f(0.0f, -1.0f, 0.0f), // bottom face
};
/**
* Used to create a new instance of the node. This routine is called by
* cloneTree
to duplicate the current node.
* cloneNode
should be overridden by any user subclassed
* objects. All subclasses must have their cloneNode
method
* consist of the following lines:
*
*
* ** * @param forceDuplicate * when set to* public Node cloneNode(boolean forceDuplicate) { * UserSubClass usc = new UserSubClass(); * usc.duplicateNode(this, forceDuplicate); * return usc; * } ** *
true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines
* whether NodeComponent data is duplicated or copied.
*
* @see Node#cloneTree
* @see Node#duplicateNode
* @see NodeComponent#setDuplicateOnCloneTree
*/
public Node cloneNode(boolean forceDuplicate) {
Cuboid b = new Cuboid(xDim, yDim, zDim, flags, getAppearance());
b.duplicateNode(this, forceDuplicate);
return b;
}
/**
* Copies all node information from originalNode
into the
* current node. This method is called from the cloneNode
* method which is, in turn, called by the cloneTree
method.
*
* For any NodeComponent objects contained by the object being
* duplicated, each NodeComponent object's
* duplicateOnCloneTree
value is used to determine whether
* the NodeComponent should be duplicated in the new node or if just
* a reference to the current node should be placed in the new node. This
* flag can be overridden by setting the forceDuplicate
* parameter in the cloneTree
method to true
.
*
* @param originalNode
* the original node to duplicate.
* @param forceDuplicate
* when set to true
, causes the
* duplicateOnCloneTree
flag to be ignored. When
* false
, the value of each node's
* duplicateOnCloneTree
variable determines
* whether NodeComponent data is duplicated or copied.
*
* @see Node#cloneTree
* @see Node#cloneNode
* @see NodeComponent#setDuplicateOnCloneTree
*/
public void duplicateNode(Node originalNode, boolean forceDuplicate) {
super.duplicateNode(originalNode, forceDuplicate);
}
}
/*******************************************************************************
* Copyright (C) 2001 Daniel Selman
*
* First distributed with the book "Java 3D Programming" by Daniel Selman and
* published by Manning Publications. http://manning.com/selman
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation, version 2.
*
* This program 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 General Public License for more
* details.
*
* The license can be found on the WWW at: http://www.fsf.org/copyleft/gpl.html
*
* Or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite
* 330, Boston, MA 02111-1307, USA.
*
* Authors can be contacted at: Daniel Selman: daniel@selman.org
*
* If you make changes you think others would like, please contact one of the
* authors or someone at the www.j3d.org web site.
******************************************************************************/
//*****************************************************************************
/**
* Java3dApplet
*
* Base class for defining a Java 3D applet. Contains some useful methods for
* defining views and scenegraphs etc.
*
* @author Daniel Selman
* @version 1.0
*/
//*****************************************************************************
abstract class Java3dApplet extends Applet {
public static int m_kWidth = 300;
public static int m_kHeight = 300;
protected String[] m_szCommandLineArray = null;
protected VirtualUniverse m_Universe = null;
protected BranchGroup m_SceneBranchGroup = null;
protected Bounds m_ApplicationBounds = null;
// protected com.tornadolabs.j3dtree.Java3dTree m_Java3dTree = null;
public Java3dApplet() {
}
public boolean isApplet() {
try {
System.getProperty("user.dir");
System.out.println("Running as Application.");
return false;
} catch (Exception e) {
}
System.out.println("Running as Applet.");
return true;
}
public URL getWorkingDirectory() throws java.net.MalformedURLException {
URL url = null;
try {
File file = new File(System.getProperty("user.dir"));
System.out.println("Running as Application:");
System.out.println(" " + file.toURL());
return file.toURL();
} catch (Exception e) {
}
System.out.println("Running as Applet:");
System.out.println(" " + getCodeBase());
return getCodeBase();
}
public VirtualUniverse getVirtualUniverse() {
return m_Universe;
}
//public com.tornadolabs.j3dtree.Java3dTree getJ3dTree() {
//return m_Java3dTree;
// }
public Locale getFirstLocale() {
java.util.Enumeration e = m_Universe.getAllLocales();
if (e.hasMoreElements() != false)
return (Locale) e.nextElement();
return null;
}
protected Bounds getApplicationBounds() {
if (m_ApplicationBounds == null)
m_ApplicationBounds = createApplicationBounds();
return m_ApplicationBounds;
}
protected Bounds createApplicationBounds() {
m_ApplicationBounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
100.0);
return m_ApplicationBounds;
}
protected Background createBackground() {
Background back = new Background(new Color3f(0.9f, 0.9f, 0.9f));
back.setApplicationBounds(createApplicationBounds());
return back;
}
public void initJava3d() {
// m_Java3dTree = new com.tornadolabs.j3dtree.Java3dTree();
m_Universe = createVirtualUniverse();
Locale locale = createLocale(m_Universe);
BranchGroup sceneBranchGroup = createSceneBranchGroup();
ViewPlatform vp = createViewPlatform();
BranchGroup viewBranchGroup = createViewBranchGroup(
getViewTransformGroupArray(), vp);
createView(vp);
Background background = createBackground();
if (background != null)
sceneBranchGroup.addChild(background);
// m_Java3dTree.recursiveApplyCapability(sceneBranchGroup);
// m_Java3dTree.recursiveApplyCapability(viewBranchGroup);
locale.addBranchGraph(sceneBranchGroup);
addViewBranchGroup(locale, viewBranchGroup);
onDoneInit();
}
protected void onDoneInit() {
// m_Java3dTree.updateNodes(m_Universe);
}
protected double getScale() {
return 1.0;
}
public TransformGroup[] getViewTransformGroupArray() {
TransformGroup[] tgArray = new TransformGroup[1];
tgArray[0] = new TransformGroup();
// move the camera BACK a little...
// note that we have to invert the matrix as
// we are moving the viewer
Transform3D t3d = new Transform3D();
t3d.setScale(getScale());
t3d.setTranslation(new Vector3d(0.0, 0.0, -20.0));
t3d.invert();
tgArray[0].setTransform(t3d);
return tgArray;
}
protected void addViewBranchGroup(Locale locale, BranchGroup bg) {
locale.addBranchGraph(bg);
}
protected Locale createLocale(VirtualUniverse u) {
return new Locale(u);
}
protected BranchGroup createSceneBranchGroup() {
m_SceneBranchGroup = new BranchGroup();
return m_SceneBranchGroup;
}
protected View createView(ViewPlatform vp) {
View view = new View();
PhysicalBody pb = createPhysicalBody();
PhysicalEnvironment pe = createPhysicalEnvironment();
AudioDevice audioDevice = createAudioDevice(pe);
if (audioDevice != null) {
pe.setAudioDevice(audioDevice);
audioDevice.initialize();
}
view.setPhysicalEnvironment(pe);
view.setPhysicalBody(pb);
if (vp != null)
view.attachViewPlatform(vp);
view.setBackClipDistance(getBackClipDistance());
view.setFrontClipDistance(getFrontClipDistance());
Canvas3D c3d = createCanvas3D();
view.addCanvas3D(c3d);
addCanvas3D(c3d);
return view;
}
protected PhysicalBody createPhysicalBody() {
return new PhysicalBody();
}
protected AudioDevice createAudioDevice(PhysicalEnvironment pe) {
JavaSoundMixer javaSoundMixer = new JavaSoundMixer(pe);
if (javaSoundMixer == null)
System.out.println("create of audiodevice failed");
return javaSoundMixer;
}
protected PhysicalEnvironment createPhysicalEnvironment() {
return new PhysicalEnvironment();
}
protected float getViewPlatformActivationRadius() {
return 100;
}
protected ViewPlatform createViewPlatform() {
ViewPlatform vp = new ViewPlatform();
vp.setViewAttachPolicy(View.RELATIVE_TO_FIELD_OF_VIEW);
vp.setActivationRadius(getViewPlatformActivationRadius());
return vp;
}
protected Canvas3D createCanvas3D() {
GraphicsConfigTemplate3D gc3D = new GraphicsConfigTemplate3D();
gc3D.setSceneAntialiasing(GraphicsConfigTemplate.PREFERRED);
GraphicsDevice gd[] = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getScreenDevices();
Canvas3D c3d = new Canvas3D(gd[0].getBestConfiguration(gc3D));
c3d.setSize(getCanvas3dWidth(c3d), getCanvas3dHeight(c3d));
return c3d;
}
protected int getCanvas3dWidth(Canvas3D c3d) {
return m_kWidth;
}
protected int getCanvas3dHeight(Canvas3D c3d) {
return m_kHeight;
}
protected double getBackClipDistance() {
return 100.0;
}
protected double getFrontClipDistance() {
return 1.0;
}
protected BranchGroup createViewBranchGroup(TransformGroup[] tgArray,
ViewPlatform vp) {
BranchGroup vpBranchGroup = new BranchGroup();
if (tgArray != null && tgArray.length > 0) {
Group parentGroup = vpBranchGroup;
TransformGroup curTg = null;
for (int n = 0; n < tgArray.length; n++) {
curTg = tgArray[n];
parentGroup.addChild(curTg);
parentGroup = curTg;
}
tgArray[tgArray.length - 1].addChild(vp);
} else
vpBranchGroup.addChild(vp);
return vpBranchGroup;
}
protected void addCanvas3D(Canvas3D c3d) {
setLayout(new BorderLayout());
add(c3d, BorderLayout.CENTER);
doLayout();
}
protected VirtualUniverse createVirtualUniverse() {
return new VirtualUniverse();
}
protected void saveCommandLineArguments(String[] szArgs) {
m_szCommandLineArray = szArgs;
}
protected String[] getCommandLineArguments() {
return m_szCommandLineArray;
}
}