summaryrefslogtreecommitdiffstats
path: root/src/classes
diff options
context:
space:
mode:
authorChien Yang <[email protected]>2007-04-23 23:11:22 +0000
committerChien Yang <[email protected]>2007-04-23 23:11:22 +0000
commitcdf0d5d0cb795de2d1ae4b5ac0daf8580f94107f (patch)
tree1ecf3f4ef37dfa164fd677ec80564e5ae0d70a47 /src/classes
parent6e794f18042c13a0e7755477dd6ed17eb02d6c75 (diff)
1) Fix to Issue 411 : Add Primitive flag to reverse Y for tex coords
2) Remove dead code. git-svn-id: https://svn.java.net/svn/j3d-core-utils~svn/trunk@163 9497e636-51bd-65ba-982d-a4982e1767a5
Diffstat (limited to 'src/classes')
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/Box.java21
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/Cone.java7
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/Cylinder.java7
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/GeomBuffer.java54
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/Primitive.java6
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/Quadrics.java1124
-rw-r--r--src/classes/share/com/sun/j3d/utils/geometry/Sphere.java97
7 files changed, 603 insertions, 713 deletions
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/Box.java b/src/classes/share/com/sun/j3d/utils/geometry/Box.java
index 8a1627a..04dac4d 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/Box.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/Box.java
@@ -167,12 +167,14 @@ public class Box extends Primitive {
zDim = zdim;
flags = primflags;
numTexUnit = numTexUnit;
-
+ boolean texCoordYUp = (flags & GENERATE_TEXTURE_COORDS_YUP) != 0;
+
//Depending on whether normal inward bit is set.
if ((flags & GENERATE_NORMALS_INWARD) != 0)
- sign = -1.0;
+ sign = -1.0;
else sign = 1.0;
+
// TransformGroup objTrans = new TransformGroup();
// objTrans.setCapability(ALLOW_CHILDREN_READ);
// this.addChild(objTrans);
@@ -200,7 +202,13 @@ public class Box extends Primitive {
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]);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(tcoords[i*8 + j*2], 1.0 - tcoords[i*8 + j*2 + 1]);
+ }
+ else {
+ 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 );
@@ -209,7 +217,12 @@ public class Box extends Primitive {
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]);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(tcoords[i*8 + j*2], 1.0 - tcoords[i*8 + j*2 + 1]);
+ }
+ else {
+ 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 );
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/Cone.java b/src/classes/share/com/sun/j3d/utils/geometry/Cone.java
index 2097931..c98cae9 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/Cone.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/Cone.java
@@ -211,6 +211,7 @@ public class Cone extends Primitive {
ydivisions = ydivision;
flags = primflags;
boolean outside = (flags & GENERATE_NORMALS_INWARD) == 0;
+ boolean texCoordYUp = (flags & GENERATE_TEXTURE_COORDS_YUP) != 0;
Quadrics q = new Quadrics();
GeomBuffer gbuf = null;
@@ -229,7 +230,7 @@ public class Cone extends Primitive {
gbuf = q.coneTop((double)(height/2.0 - height/ydivisions),
(double)(radius/ydivisions), height/ydivisions,
xdivisions, 1.0-1.0/(double)ydivisions,
- outside);
+ outside, texCoordYUp);
shape[BODY] = new Shape3D(gbuf.getGeom(flags));
numVerts += gbuf.getNumVerts();
numTris += gbuf.getNumTris();
@@ -255,7 +256,7 @@ public class Cone extends Primitive {
(double)(height/2.0-height/ydivisions),
(double)radius, (double)(radius/ydivisions),
xdivisions, ydivisions-1, 1.0/(double)ydivisions,
- outside);
+ outside, texCoordYUp);
shape[BODY].addGeometry(gbuf.getGeom(flags));
numVerts += gbuf.getNumVerts();
numTris += gbuf.getNumTris();
@@ -289,7 +290,7 @@ public class Cone extends Primitive {
}
else {
gbuf = q.disk((double)radius, xdivision, -(double)height/2.0,
- !outside);
+ !outside, texCoordYUp);
shape[CAP] = new Shape3D(gbuf.getGeom(flags));
numVerts += gbuf.getNumVerts();
numTris += gbuf.getNumTris();
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/Cylinder.java b/src/classes/share/com/sun/j3d/utils/geometry/Cylinder.java
index 1be3d98..26b0cec 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/Cylinder.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/Cylinder.java
@@ -212,6 +212,7 @@ public class Cylinder extends Primitive{
this.ydivisions = ydivision;
flags = primflags;
boolean outside = (flags & GENERATE_NORMALS_INWARD) == 0;
+ boolean texCoordYUp = (flags & GENERATE_TEXTURE_COORDS_YUP) != 0;
// Create many body of the cylinder.
Quadrics q = new Quadrics();
GeomBuffer gbuf = null;
@@ -228,7 +229,7 @@ public class Cylinder extends Primitive{
}
else {
gbuf = q.cylinder((double)height, (double)radius,
- xdivision, ydivision, outside);
+ xdivision, ydivision, outside, texCoordYUp);
shape[BODY] = new Shape3D(gbuf.getGeom(flags));
numVerts += gbuf.getNumVerts();
numTris += gbuf.getNumTris();
@@ -260,7 +261,7 @@ public class Cylinder extends Primitive{
}
else {
gbuf = q.disk((double)radius, xdivision, height/2.0,
- outside);
+ outside, texCoordYUp);
shape[TOP] = new Shape3D(gbuf.getGeom(flags));
numVerts += gbuf.getNumVerts();
numTris += gbuf.getNumTris();
@@ -293,7 +294,7 @@ public class Cylinder extends Primitive{
numTris += cache.getNumTris();
}
else {
- gbuf = q.disk((double)radius, xdivision, -height/2.0, !outside);
+ gbuf = q.disk((double)radius, xdivision, -height/2.0, !outside, texCoordYUp);
shape[BOTTOM] = new Shape3D(gbuf.getGeom(flags));
numVerts += gbuf.getNumVerts();
numTris += gbuf.getNumTris();
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/GeomBuffer.java b/src/classes/share/com/sun/j3d/utils/geometry/GeomBuffer.java
index 897a79c..890f989 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/GeomBuffer.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/GeomBuffer.java
@@ -96,8 +96,6 @@ class GeomBuffer extends Object{
static final int TRIANGLE_STRIP = 0x20;
private int flags;
- static final int GENERATE_NORMALS = 0x01;
- static final int GENERATE_TEXTURE_COORDS = 0x02;
Point3f[] pts = null;
Vector3f[] normals = null;
@@ -285,9 +283,9 @@ class GeomBuffer extends Object{
if (debug >= 1) System.out.println("totalVerts " + totalVerts);
int tsaFlags = TriangleStripArray.COORDINATES;
- if ((flags & GENERATE_NORMALS) != 0)
+ if ((flags & Primitive.GENERATE_NORMALS) != 0)
tsaFlags |= TriangleStripArray.NORMALS;
- if ((flags & GENERATE_TEXTURE_COORDS) != 0)
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)
tsaFlags |= TriangleStripArray.TEXTURE_COORDINATE_2;
// Create GeometryArray to pass back
@@ -314,9 +312,9 @@ class GeomBuffer extends Object{
numTris += totalVerts - currPrimCnt * 2;
obj.setCoordinates(0, newpts);
- if ((flags & GENERATE_NORMALS) != 0)
+ if ((flags & Primitive.GENERATE_NORMALS) != 0)
obj.setNormals(0, newnormals);
- if ((flags & GENERATE_TEXTURE_COORDS) != 0)
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)
obj.setTextureCoordinates(0, 0, newtcoords);
geometry = obj;
@@ -335,8 +333,8 @@ class GeomBuffer extends Object{
if (debug >= 1) System.out.println("totalVerts " + totalVerts);
- if (((flags & GENERATE_NORMALS) != 0) &&
- ((flags & GENERATE_TEXTURE_COORDS) != 0)){
+ if (((flags & Primitive.GENERATE_NORMALS) != 0) &&
+ ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)){
obj = new QuadArray(totalVerts,
QuadArray.COORDINATES |
QuadArray.NORMALS |
@@ -344,16 +342,16 @@ class GeomBuffer extends Object{
1, texCoordSetMap);
}
else
- if (((flags & GENERATE_NORMALS) == 0) &&
- ((flags & GENERATE_TEXTURE_COORDS) != 0)){
+ if (((flags & Primitive.GENERATE_NORMALS) == 0) &&
+ ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)){
obj = new QuadArray(totalVerts,
QuadArray.COORDINATES |
QuadArray.TEXTURE_COORDINATE_2,
1, texCoordSetMap);
}
else
- if (((flags & GENERATE_NORMALS) != 0) &&
- ((flags & GENERATE_TEXTURE_COORDS) == 0)){
+ if (((flags & Primitive.GENERATE_NORMALS) != 0) &&
+ ((flags & Primitive.GENERATE_TEXTURE_COORDS) == 0)){
obj = new QuadArray(totalVerts,
QuadArray.COORDINATES |
QuadArray.NORMALS);
@@ -388,9 +386,9 @@ class GeomBuffer extends Object{
numVerts = currVert;
obj.setCoordinates(0, newpts);
- if ((flags & GENERATE_NORMALS) != 0)
+ if ((flags & Primitive.GENERATE_NORMALS) != 0)
obj.setNormals(0, newnormals);
- if ((flags & GENERATE_TEXTURE_COORDS) != 0)
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)
obj.setTextureCoordinates(0, 0, newtcoords);
geometry = obj;
@@ -409,8 +407,8 @@ class GeomBuffer extends Object{
if (debug >= 1) System.out.println("totalVerts " + totalVerts);
- if (((flags & GENERATE_NORMALS) != 0) &&
- ((flags & GENERATE_TEXTURE_COORDS) != 0)){
+ if (((flags & Primitive.GENERATE_NORMALS) != 0) &&
+ ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)){
obj = new TriangleArray(totalVerts,
TriangleArray.COORDINATES |
TriangleArray.NORMALS |
@@ -418,16 +416,16 @@ class GeomBuffer extends Object{
1, texCoordSetMap);
}
else
- if (((flags & GENERATE_NORMALS) == 0) &&
- ((flags & GENERATE_TEXTURE_COORDS) != 0)){
+ if (((flags & Primitive.GENERATE_NORMALS) == 0) &&
+ ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)){
obj = new TriangleArray(totalVerts,
TriangleArray.COORDINATES |
TriangleArray.TEXTURE_COORDINATE_2,
1, texCoordSetMap);
}
else
- if (((flags & GENERATE_NORMALS) != 0) &&
- ((flags & GENERATE_TEXTURE_COORDS) == 0)){
+ if (((flags & Primitive.GENERATE_NORMALS) != 0) &&
+ ((flags & Primitive.GENERATE_TEXTURE_COORDS) == 0)){
obj = new TriangleArray(totalVerts,
TriangleArray.COORDINATES |
TriangleArray.NORMALS);
@@ -456,9 +454,9 @@ class GeomBuffer extends Object{
numVerts = currVert;
obj.setCoordinates(0, newpts);
- if ((flags & GENERATE_NORMALS) != 0)
+ if ((flags & Primitive.GENERATE_NORMALS) != 0)
obj.setNormals(0, newnormals);
- if ((flags & GENERATE_TEXTURE_COORDS) != 0)
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0)
obj.setTextureCoordinates(0, 0, newtcoords);
geometry = obj;
@@ -483,10 +481,10 @@ class GeomBuffer extends Object{
// figure out what flags we need
int tfFlags = TriangleFanArray.COORDINATES;
- if ((flags & GENERATE_NORMALS) != 0) {
+ if ((flags & Primitive.GENERATE_NORMALS) != 0) {
tfFlags |= TriangleFanArray.NORMALS;
}
- if ((flags & GENERATE_TEXTURE_COORDS) != 0) {
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0) {
tfFlags |= TriangleFanArray.TEXTURE_COORDINATE_2;
}
@@ -520,10 +518,10 @@ class GeomBuffer extends Object{
obj.setCoordinates(0, newpts);
// set the normals and tex coords if necessary
- if ((flags & GENERATE_NORMALS) != 0) {
+ if ((flags & Primitive.GENERATE_NORMALS) != 0) {
obj.setNormals(0, newnormals);
}
- if ((flags & GENERATE_TEXTURE_COORDS) != 0) {
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0) {
obj.setTextureCoordinates(0, 0, newtcoords);
}
geometry = obj;
@@ -545,10 +543,10 @@ class GeomBuffer extends Object{
dpts[dloc] = new Point3f(spts[sloc]);
- if ((flags & GENERATE_NORMALS) != 0){
+ if ((flags & Primitive.GENERATE_NORMALS) != 0){
dnormals[dloc] = new Vector3f(snormals[sloc]);
}
- if ((flags & GENERATE_TEXTURE_COORDS) != 0){
+ if ((flags & Primitive.GENERATE_TEXTURE_COORDS) != 0){
if (debug >= 2) System.out.println("final out tcoord");
dtcoords[dloc] = new TexCoord2f(stcoords[sloc]);
}
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/Primitive.java b/src/classes/share/com/sun/j3d/utils/geometry/Primitive.java
index bb14dce..4ba8094 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/Primitive.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/Primitive.java
@@ -80,6 +80,12 @@ public abstract class Primitive extends Group {
*/
public static final int GENERATE_NORMALS_INWARD = 0x04;
+ /**
+ * Specifies that texture coordinates are to be Y up.
+ */
+ public static final int GENERATE_TEXTURE_COORDS_YUP = 0x08;
+
+
/**
* Specifies that the geometry being created will not be shared by
* another scene graph node. By default all primitives created with
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/Quadrics.java b/src/classes/share/com/sun/j3d/utils/geometry/Quadrics.java
index 929de37..015e506 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/Quadrics.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/Quadrics.java
@@ -52,671 +52,499 @@ import javax.vecmath.*;
import java.math.*;
class Quadrics extends Object {
-
- Quadrics (){ }
-
- // do not use this to make a cone. It uses too many triangles. The top of
- // cone can be a triangle fan array
-
- GeomBuffer cylinder(double lowr, double highr,
- double height, int xdivisions, int ydivisions,
- boolean outside)
- {
- double r, sign;
-
- /*
- * Cylinder is created by extruding the unit circle along the Z+
- * axis. The number of layers is controlled by ydivisions (which is
- * actually zdivisions). For each consecutive sample points along the
- * unit circle, we also sample along the height of the cylinder. Quads
- * are created along the Z direction. When the unit circle at the base is
- * completed, we also obtain the layers of quads along the height of the
- * cylinder.
- *
- * Texture coordinates are created in a straight forward cylindrical
- * mapping of the texture map. The texture is wrapped from the back of
- * the cylinder.
- */
-
- if (outside)
- sign = 1.0;
- else
- sign = -1.0;
- //Compute the deltas
- double dtheta = 2.0*Math.PI / xdivisions;
- double dr = (highr - lowr) / ydivisions;
- double dz = height / ydivisions;
- double znormal = (lowr - highr) / height;
- double du = 1.0 / xdivisions;
- double dv = 1.0 / ydivisions;
-
- //Initialize geometry buffer.
- GeomBuffer gbuf = new GeomBuffer(xdivisions*ydivisions*4);
-
- double s = 0.0, t = 0.0;
- for (int i=0;i<xdivisions;i++) {
- double px, py, qx, qy, z;
- // (px,py) and (qx,qy) are consecutive sample points along the
- // unit circle. We will create quads along the Z+ direction.
- // we have to start at the back of the sphere, so add 90 degrees
- px = Math.cos(i*dtheta + Math.PI/2.0);
- py = Math.sin(i*dtheta + Math.PI/2.0);
- qx = Math.cos((i+1)*dtheta + Math.PI/2.0);
- qy = Math.sin((i+1)*dtheta + Math.PI/2.0);
- // Initialize z,r,t
- z = -1.0*height/2.0; r = lowr; t = 0.0;
-
- gbuf.begin( GeomBuffer.QUAD_STRIP );
- // For each consecutive two unit circle points,
- // we obtain the layers of quads along the Z direction. Number of
- // layers depends on ydivisions.
- for (int j=0; j<=ydivisions; j++,z += dz,r += dr,t += dv){
- if ((j == ydivisions) && (highr == 0)) {
- if (outside) {
- gbuf.normal3d( 0.0, 0.0, znormal*sign );
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d( px*r, py*r, z );
- gbuf.normal3d( 0.0, 0.0, znormal*sign );
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d( qx*r, qy*r, z );
- }
- else {
- gbuf.normal3d( 0.0, 0.0, znormal*sign );
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d( qx*r, qy*r, z );
- gbuf.normal3d( 0.0, 0.0, znormal*sign );
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d( px*r, py*r, z );
- }
- } else {
- if (outside) {
- gbuf.normal3d( px*sign, py*sign, znormal*sign );
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d( px*r, py*r, z );
- gbuf.normal3d( qx*sign, qy*sign, znormal*sign );
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d( qx*r, qy*r, z );
- }
- else {
- gbuf.normal3d( qx*sign, qy*sign, znormal*sign );
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d( qx*r, qy*r, z );
- gbuf.normal3d( px*sign, py*sign, znormal*sign );
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d( px*r, py*r, z );
- }
- }
- }
- gbuf.end();
- s += du;
- }
- return gbuf;
- }
-
- GeomBuffer disk(double r, int xdivisions, boolean outside)
- {
- double theta, dtheta, sign, sinTheta, cosTheta;
- int i;
-
- /*
- * Disk is created by evaluating points along the unit circle. Let
- * theta be the angle about the Z axis. Then, for each theta, we
- * obtain (cos(theta), sin(theta)) = (x,y) sample points. We create quad
- * strips (or fan strips) from these sample points.
- *
- * Texture coordinates of the disk is gotten from a unit circle
- * centered at (0.5, 0.5) in s,t space. Thus, portions of a texture is not
- * used.
- */
-
- if (outside)
- sign = 1.0;
- else sign = -1.0;
+ Quadrics(){ }
- dtheta = 2.0*Math.PI / xdivisions;
- GeomBuffer gbuf = new GeomBuffer(xdivisions*4);
-
- // gbuf.begin(GeomBuffer.QUAD_STRIP);
- gbuf.begin(GeomBuffer.TRIANGLE_FAN);
- // the first point to add is the center of the fan
- gbuf.normal3d( 0.0, 0.0, 1.0*sign );
- gbuf.texCoord2d(0.5,0.5);
- gbuf.vertex3d(0.0, 0.0, 0.0);
- if (outside) {
- for (i = 0;i <= xdivisions;i++) {
- theta = i * dtheta;
- // add 90 degrees to theta so lines up with the body
- sinTheta = Math.sin(theta + Math.PI/2.0);
- cosTheta = Math.cos(theta + Math.PI/2.0);
- // First point of quad
- gbuf.normal3d( 0.0, 0.0, 1.0*sign );
- // Texture coord is centered at (0.5, 0.5) in s,t space.
- gbuf.texCoord2d(0.5+cosTheta*0.5,0.5+sinTheta*0.5);
- gbuf.vertex3d( r*cosTheta, r*sinTheta , 0.0);
-
- }
- }
- else {
- for (i=xdivisions;i>=0;i--) {
- theta = i * dtheta;
- // add 90 degrees to theta so lines up with the body
- sinTheta = Math.sin(theta + Math.PI/2.0);
- cosTheta = Math.cos(theta + Math.PI/2.0);
- gbuf.normal3d( 0.0, 0.0, 1.0*sign );
- // if not outside, texture coordinates need to be upside down
- // to conform with VRML spec
-// gbuf.texCoord2d(0.5-cosTheta*0.5, 0.5+sinTheta*0.5);
- gbuf.texCoord2d(0.5+cosTheta*0.5, 0.5-sinTheta*0.5);
- gbuf.vertex3d( r*cosTheta, r*sinTheta, 0.0 );
- }
+ // new disk code to remove transforms in the primitive code
+ GeomBuffer disk(double r, int xdiv, double y, boolean outside, boolean texCoordYUp) {
+
+ double theta, dtheta, sign, sinTheta, cosTheta;
+
+ if (outside) sign = 1.0;
+ else sign = -1.0;
+
+ dtheta = 2.0*Math.PI / xdiv;
+
+ GeomBuffer gbuf = new GeomBuffer(xdiv+2);
+
+ gbuf.begin(GeomBuffer.TRIANGLE_FAN);
+ gbuf.normal3d(0.0, 1.0*sign, 0.0);
+ gbuf.texCoord2d(0.5, 0.5);
+ gbuf.vertex3d(0.0, y, 0.0);
+
+ // create the disk by evaluating points along the unit circle.
+ // theta is the angle around the y-axis. Then we obtain
+ // (cos(theta), sin(theta)) = (x,z) sample points. The y value
+ // was passed in as a parameter.
+ // texture coordinates are obtain from the unit circle centered at
+ // (.5, .5) in s, t space. thus portions of the texture are not used.
+
+ if (!outside) {
+ for (int i = 0; i <= xdiv; i++) {
+ theta = i * dtheta;
+ // add 90 degrees to theta so lines up wtih the body
+ sinTheta = Math.sin(theta - Math.PI/2.0);
+ cosTheta = Math.cos(theta - Math.PI/2.0);
+ gbuf.normal3d(0.0, 1.0*sign, 0.0);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(0.5+cosTheta*0.5, 1.0 - (0.5+sinTheta*0.5));
+ }
+ else {
+ gbuf.texCoord2d(0.5+cosTheta*0.5, 0.5+sinTheta*0.5);
+ }
+ gbuf.vertex3d(r*cosTheta, y, r*sinTheta);
+ }
+ } else {
+ for (int i = xdiv; i >= 0; i--) {
+ theta = i * dtheta;
+ // add 90 degrees to theta so lines up with the body
+ sinTheta = Math.sin(theta - Math.PI/2.0);
+ cosTheta = Math.cos(theta - Math.PI/2.0);
+ gbuf.normal3d(0.0, 1.0*sign, 0.0);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(0.5+cosTheta*0.5, 1.0 - (0.5-sinTheta*0.5));
+ }
+ else {
+ gbuf.texCoord2d(0.5+cosTheta*0.5, 0.5-sinTheta*0.5);
+ }
+ gbuf.vertex3d(cosTheta*r, y, sinTheta*r);
+ }
+ }
+
+ gbuf.end();
+ return gbuf;
}
- gbuf.end();
- return gbuf;
- }
-
- // use this to make the top of the cone. It uses a triangle fan so there
- // aren't extra triangles
-
- GeomBuffer coneTop(double coneRadius, double coneHeight, int xdivisions,
- int ydivisions, boolean outside) {
-
- double sign;
- double radius = coneRadius/(double)ydivisions;
-
- double bottom = coneHeight/2.0 - coneHeight/(double)ydivisions;
- double top = coneHeight/2.0;
-
- if (outside) sign = 1.0;
- else sign = -1.0;
-
- // compute the deltas
- double dtheta = 2.0 * Math.PI / (double)xdivisions;
- double znormal = radius/(top-bottom);
- double du = 1.0/(double)xdivisions;
-
- // initialize geometry buffer
- GeomBuffer gbuf = new GeomBuffer(xdivisions + 2);
- gbuf.begin(GeomBuffer.TRIANGLE_FAN);
- // add the tip, which is the center of the fan
- gbuf.normal3d(0.0, 0.0, znormal*sign);
- gbuf.texCoord2d(.5, 1);
- gbuf.vertex3d(0.0, 0.0, top);
-
- // go around the circle and add the rest of the fan
- double s = 0.0;
- double t = 1.0 - 1.0/(double)ydivisions;
- double px, py;
- if (outside) {
- for (int i = 0; i <= xdivisions; i++) {
- // we have to start at the back of the sphere, so add 90 degrees
- px = Math.cos(i*dtheta + Math.PI/2.0);
- py = Math.sin(i*dtheta + Math.PI/2.0);
- gbuf.normal3d(px*sign, py*sign, znormal*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, py*radius, bottom);
- s += du;
- }
- }
- else {
- for (int i = xdivisions; i >= 0; i--) {
- px = Math.cos(i*dtheta + Math.PI/2.0);
- py = Math.sin(i*dtheta + Math.PI/2.0);
- gbuf.normal3d(px*sign, py*sign, znormal*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, py*radius, bottom);
- s += du;
- }
- }
- gbuf.end();
- return gbuf;
- }
-
- // use this to make the body of the cone. similar to cylinder, only allows
- // you to leave off the top.
-
- GeomBuffer coneBody(double coneRadius, double height,
- int xdivisions, int ydivisions,
- boolean outside)
- {
- double r, sign;
-
- double bottom = -height/2.0;
- double topRadius = coneRadius/(double)ydivisions;
-
- /*
- * The cone body is created by extruding the unit circle along the Z+
- * axis. The number of layers is controlled by ydivisions (which is
- * actually zdivisions). For each consecutive sample points along the
- * unit circle, we also sample along the height of the cone. Quads
- * are created along the Z direction. When the unit circle at the base is
- * completed, we also obtain the layers of quads along the height of the
- * cylinder.
- *
- * Texture coordinates are created in a straight forward cylindrical
- * mapping of the texture map. The texture is wrapped from the back of
- * the cylinder.
- */
-
- if (outside)
- sign = 1.0;
- else
- sign = -1.0;
- //Compute the deltas
- double dtheta = 2.0*Math.PI / xdivisions;
- double dr = -coneRadius / ydivisions;
- double dz = height / ydivisions;
- double znormal = coneRadius / height;
- double du = 1.0 / xdivisions;
- double dv = 1.0 / ydivisions;
-
- //Initialize geometry buffer.
- GeomBuffer gbuf = new GeomBuffer(xdivisions*ydivisions*4);
-
- double s = 0.0, t = 0.0;
- for (int i=0;i<xdivisions;i++) {
- double px, py, qx, qy, z;
- // (px,py) and (qx,qy) are consecutive sample points along the
- // unit circle. We will create quads along the Z+ direction.
- // we have to start at the back of the sphere, so add 90 degrees
- px = Math.cos(i*dtheta + Math.PI/2.0);
- py = Math.sin(i*dtheta + Math.PI/2.0);
- qx = Math.cos((i+1)*dtheta + Math.PI/2.0);
- qy = Math.sin((i+1)*dtheta + Math.PI/2.0);
- // Initialize z,r,t
- //z = -1.0*height/2.0;
- r = coneRadius; t = 0.0;
- z = bottom;
-
- gbuf.begin( GeomBuffer.QUAD_STRIP );
- // For each consecutive two unit circle points,
- // we obtain the layers of quads along the Z direction. Number of
- // layers depends on ydivisions.
- for (int j=0; j<=ydivisions-1; j++,z += dz,r += dr,t += dv){
- if (outside) {
- gbuf.normal3d( px*sign, py*sign, znormal*sign );
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d( px*r, py*r, z );
- gbuf.normal3d( qx*sign, qy*sign, znormal*sign );
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d( qx*r, qy*r, z );
- }
- else {
- gbuf.normal3d( qx*sign, qy*sign, znormal*sign );
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d( qx*r, qy*r, z );
- gbuf.normal3d( px*sign, py*sign, znormal*sign );
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d( px*r, py*r, z );
- }
- }
- gbuf.end();
- s += du;
- }
- return gbuf;
- }
-
- // new disk code to remove transforms in the primitive code
- GeomBuffer disk(double r, int xdiv, double y, boolean outside) {
-
- double theta, dtheta, sign, sinTheta, cosTheta;
-
- if (outside) sign = 1.0;
- else sign = -1.0;
-
- dtheta = 2.0*Math.PI / xdiv;
-
- GeomBuffer gbuf = new GeomBuffer(xdiv+2);
-
- gbuf.begin(GeomBuffer.TRIANGLE_FAN);
- gbuf.normal3d(0.0, 1.0*sign, 0.0);
- gbuf.texCoord2d(0.5, 0.5);
- gbuf.vertex3d(0.0, y, 0.0);
-
- // create the disk by evaluating points along the unit circle.
- // theta is the angle around the y-axis. Then we obtain
- // (cos(theta), sin(theta)) = (x,z) sample points. The y value
- // was passed in as a parameter.
- // texture coordinates are obtain from the unit circle centered at
- // (.5, .5) in s, t space. thus portions of the texture are not used.
-
- if (!outside) {
- for (int i = 0; i <= xdiv; i++) {
- theta = i * dtheta;
- // add 90 degrees to theta so lines up wtih the body
- sinTheta = Math.sin(theta - Math.PI/2.0);
- cosTheta = Math.cos(theta - Math.PI/2.0);
- gbuf.normal3d(0.0, 1.0*sign, 0.0);
- gbuf.texCoord2d(0.5+cosTheta*0.5, 0.5+sinTheta*0.5);
- gbuf.vertex3d(r*cosTheta, y, r*sinTheta);
- }
- }
- else {
- for (int i = xdiv; i >= 0; i--) {
- theta = i * dtheta;
- // add 90 degrees to theta so lines up with the body
- sinTheta = Math.sin(theta - Math.PI/2.0);
- cosTheta = Math.cos(theta - Math.PI/2.0);
- gbuf.normal3d(0.0, 1.0*sign, 0.0);
- gbuf.texCoord2d(0.5+cosTheta*0.5, 0.5-sinTheta*0.5);
- gbuf.vertex3d(cosTheta*r, y, sinTheta*r);
- }
- }
-
- gbuf.end();
- return gbuf;
- }
-
-
// new cylinder to remove transforms in the cylinder code and to optimize
// by using triangle strip
GeomBuffer cylinder(double height, double radius,
- int xdiv, int ydiv, boolean outside) {
-
- double sign;
-
- if (outside) sign = 1.0;
- else sign = -1.0;
-
- // compute the deltas
- double dtheta = 2.0*Math.PI / (double)xdiv;
- double dy = height / (double)ydiv;
- double du = 1.0/(double)xdiv;
- double dv = 1.0/(double)ydiv;
-
- GeomBuffer gbuf = new GeomBuffer(ydiv*2*(xdiv+1));
-
- double s = 0.0, t = 0.0;
- double px, pz, qx, qz;
- double py = -height/2.0;
- double qy;
-
-// int c;
-// if (outside) c = ydiv*2*(xdiv+1) - 1;
-// else c = 0;
-
- gbuf.begin(GeomBuffer.QUAD_STRIP);
-
- for (int i = 0; i < ydiv; i++) {
- qy = py+dy;
- if (outside) {
- px = Math.cos(xdiv*dtheta - Math.PI/2.0);
- pz = Math.sin(xdiv*dtheta - Math.PI/2.0);
- qx = Math.cos((xdiv-1)*dtheta - Math.PI/2.0);
- qz = Math.sin((xdiv-1)*dtheta - Math.PI/2.0);
-
- // vert 2
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*radius, qy, pz*radius);
-
- // vert 1
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, py, pz*radius);
-
- // vert 4
- gbuf.normal3d(qx*sign, 0.0, qz*sign);
- gbuf.texCoord2d(s+du, t+dv);
- gbuf.vertex3d(qx*radius, qy, qz*radius);
-
- // vert 3
- gbuf.normal3d(qx*sign, 0.0, qz*sign);
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d(qx*radius, py, qz*radius);
-
- s += (du*2.0);
-
- for (int j = xdiv-2; j >=0; j--) {
- px = Math.cos(j*dtheta - Math.PI/2.0);
- pz = Math.sin(j*dtheta - Math.PI/2.0);
-
- // vert 6
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*radius, qy, pz*radius);
-
- // vert 5
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, py, pz*radius);
-
- s += du;
- }
-
- }
- else {
+ int xdiv, int ydiv, boolean outside, boolean texCoordYUp) {
+
+ double sign;
+
+ if (outside) sign = 1.0;
+ else sign = -1.0;
+
+ // compute the deltas
+ double dtheta = 2.0*Math.PI / (double)xdiv;
+ double dy = height / (double)ydiv;
+ double du = 1.0/(double)xdiv;
+ double dv = 1.0/(double)ydiv;
+
+ GeomBuffer gbuf = new GeomBuffer(ydiv*2*(xdiv+1));
+
+ double s = 0.0, t = 0.0;
+ double px, pz, qx, qz;
+ double py = -height/2.0;
+ double qy;
+
+ gbuf.begin(GeomBuffer.QUAD_STRIP);
+
+ for (int i = 0; i < ydiv; i++) {
+ qy = py+dy;
+ if (outside) {
+ px = Math.cos(xdiv*dtheta - Math.PI/2.0);
+ pz = Math.sin(xdiv*dtheta - Math.PI/2.0);
+ qx = Math.cos((xdiv-1)*dtheta - Math.PI/2.0);
+ qz = Math.sin((xdiv-1)*dtheta - Math.PI/2.0);
+
+ // vert 2
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*radius, qy, pz*radius);
+
+ // vert 1
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ } else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*radius, py, pz*radius);
+
+ // vert 4
+ gbuf.normal3d(qx*sign, 0.0, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t+dv);
+ }
+ gbuf.vertex3d(qx*radius, qy, qz*radius);
+
+ // vert 3
+ gbuf.normal3d(qx*sign, 0.0, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t);
+ }
+ gbuf.vertex3d(qx*radius, py, qz*radius);
+
+ s += (du*2.0);
+
+ for (int j = xdiv-2; j >=0; j--) {
+ px = Math.cos(j*dtheta - Math.PI/2.0);
+ pz = Math.sin(j*dtheta - Math.PI/2.0);
+
+ // vert 6
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*radius, qy, pz*radius);
+
+ // vert 5
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*radius, py, pz*radius);
+
+ s += du;
+ }
+
+ } else {
// c = 0;
- px = Math.cos(-Math.PI/2.0);
- pz = Math.sin(-Math.PI/2.0);
- qx = Math.cos(dtheta - Math.PI/2.0);
- qz = Math.sin(dtheta - Math.PI/2.0);
-
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*radius, qy, pz*radius);
-
- // vert 1
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, py, pz*radius);
-
- gbuf.normal3d(qx*sign, 0.0, qz*sign);
- gbuf.texCoord2d(s+du, t+dv);
- gbuf.vertex3d(qx*radius, qy, qz*radius);
-
- gbuf.normal3d(qx*sign, 0.0, qz*sign);
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d(qx*radius, py, qz*radius);
-
- s += (du*2.0);
-
- for (int j = 2; j <= xdiv; j++) {
- px = Math.cos(j*dtheta - Math.PI/2.0);
- pz = Math.sin(j*dtheta - Math.PI/2.0);
-
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*radius, qy, pz*radius);
-
- gbuf.normal3d(px*sign, 0.0, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, py, pz*radius);
-
- s += du;
- }
-
- }
- s = 0.0;
- t += dv;
- py += dy;
- }
-
- gbuf.end();
-
- return gbuf;
+ px = Math.cos(-Math.PI/2.0);
+ pz = Math.sin(-Math.PI/2.0);
+ qx = Math.cos(dtheta - Math.PI/2.0);
+ qz = Math.sin(dtheta - Math.PI/2.0);
+
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*radius, qy, pz*radius);
+
+ // vert 1
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*radius, py, pz*radius);
+
+ gbuf.normal3d(qx*sign, 0.0, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t+dv);
+ }
+ gbuf.vertex3d(qx*radius, qy, qz*radius);
+
+ gbuf.normal3d(qx*sign, 0.0, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t);
+ }
+ gbuf.vertex3d(qx*radius, py, qz*radius);
+
+ s += (du*2.0);
+
+ for (int j = 2; j <= xdiv; j++) {
+ px = Math.cos(j*dtheta - Math.PI/2.0);
+ pz = Math.sin(j*dtheta - Math.PI/2.0);
+
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*radius, qy, pz*radius);
+
+ gbuf.normal3d(px*sign, 0.0, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*radius, py, pz*radius);
+
+ s += du;
+ }
+
+ }
+ s = 0.0;
+ t += dv;
+ py += dy;
+ }
+
+ gbuf.end();
+
+ return gbuf;
}
-
+
// new coneBody method to remove transform in the Cone primitive
// and to optimize by using triangle strip
GeomBuffer coneBody(double bottom, double top, double bottomR, double topR,
- int xdiv, int ydiv, double dv, boolean outside) {
-
- double r, sign;
-
- if (outside) sign = 1.0;
- else sign = -1.0;
-
- // compute the deltas
- double dtheta = 2.0*Math.PI/(double)xdiv;
- double dr = (topR-bottomR)/(double)ydiv;
- double height = top-bottom;
- double dy = height/(double)ydiv;
- double ynormal = (bottomR-topR)/height;
- double du = 1.0/(double)xdiv;
+ int xdiv, int ydiv, double dv, boolean outside, boolean texCoordYUp) {
+
+ double r, sign;
+
+ if (outside) sign = 1.0;
+ else sign = -1.0;
+
+ // compute the deltas
+ double dtheta = 2.0*Math.PI/(double)xdiv;
+ double dr = (topR-bottomR)/(double)ydiv;
+ double height = top-bottom;
+ double dy = height/(double)ydiv;
+ double ynormal = (bottomR-topR)/height;
+ double du = 1.0/(double)xdiv;
// double dv = 1.0/(double)(ydiv+1);
-
- GeomBuffer gbuf = new GeomBuffer(ydiv*2*(xdiv+1));
-
- double s = 0.0, t = 0.0;
- double px, pz, qx, qz;
- double py = bottom;
- double qy;
- r = bottomR;
-
- gbuf.begin(GeomBuffer.QUAD_STRIP);
-
- for (int i = 0; i < ydiv; i++) {
- qy = py+dy;
- if (outside) {
- px = Math.cos(xdiv*dtheta - Math.PI/2.0);
- pz = Math.sin(xdiv*dtheta - Math.PI/2.0);
- qx = Math.cos((xdiv-1)*dtheta - Math.PI/2.0);
- qz = Math.sin((xdiv-1)*dtheta - Math.PI/2.0);
-
- // vert2
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
-
- // vert1
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*r, py, pz*r);
-
- // vert4
- gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
- gbuf.texCoord2d(s+du, t+dv);
- gbuf.vertex3d(qx*(r+dr), qy, qz*(r+dr));
-
- // vert3
- gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d(qx*r, py, qz*r);
-
- s += (du*2.0);
-
- for (int j = xdiv-2; j >= 0; j--) {
- px = Math.cos(j*dtheta - Math.PI/2.0);
- pz = Math.sin(j*dtheta - Math.PI/2.0);
-
- // vert 6
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
-
- // vert 5
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*r, py, pz*r);
-
- s += du;
- }
- }
- else {
- px = Math.cos(-Math.PI/2.0);
- pz = Math.sin(-Math.PI/2.0);
- qx = Math.cos(dtheta - Math.PI/2.0);
- qz = Math.sin(dtheta - Math.PI/2.0);
-
- // vert1
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
-
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*r, py, pz*r);
-
- gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
- gbuf.texCoord2d(s+du, t+dv);
- gbuf.vertex3d(qx*(r+dr), qy, qz*(r+dr));
-
- gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
- gbuf.texCoord2d(s+du, t);
- gbuf.vertex3d(qx*r, py, qz*r);
-
- s += (du*2.0);
-
- for (int j = 2; j <= xdiv; j++) {
- px = Math.cos(j*dtheta - Math.PI/2.0);
- pz = Math.sin(j*dtheta - Math.PI/2.0);
-
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t+dv);
- gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
-
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*r, py, pz*r);
-
- s += du;
- }
- }
- s = 0.0;
- t += dv;
- py += dy;
- r += dr;
- }
- gbuf.end();
-
- return gbuf;
+
+ GeomBuffer gbuf = new GeomBuffer(ydiv*2*(xdiv+1));
+
+ double s = 0.0, t = 0.0;
+ double px, pz, qx, qz;
+ double py = bottom;
+ double qy;
+ r = bottomR;
+
+ gbuf.begin(GeomBuffer.QUAD_STRIP);
+
+ for (int i = 0; i < ydiv; i++) {
+ qy = py+dy;
+ if (outside) {
+ px = Math.cos(xdiv*dtheta - Math.PI/2.0);
+ pz = Math.sin(xdiv*dtheta - Math.PI/2.0);
+ qx = Math.cos((xdiv-1)*dtheta - Math.PI/2.0);
+ qz = Math.sin((xdiv-1)*dtheta - Math.PI/2.0);
+
+ // vert2
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
+
+ // vert1
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*r, py, pz*r);
+
+ // vert4
+ gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t+dv);
+ }
+ gbuf.vertex3d(qx*(r+dr), qy, qz*(r+dr));
+
+ // vert3
+ gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t);
+ }
+ gbuf.vertex3d(qx*r, py, qz*r);
+
+ s += (du*2.0);
+
+ for (int j = xdiv-2; j >= 0; j--) {
+ px = Math.cos(j*dtheta - Math.PI/2.0);
+ pz = Math.sin(j*dtheta - Math.PI/2.0);
+
+ // vert 6
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ } else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
+
+ // vert 5
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*r, py, pz*r);
+
+ s += du;
+ }
+ } else {
+ px = Math.cos(-Math.PI/2.0);
+ pz = Math.sin(-Math.PI/2.0);
+ qx = Math.cos(dtheta - Math.PI/2.0);
+ qz = Math.sin(dtheta - Math.PI/2.0);
+
+ // vert1
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
+
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*r, py, pz*r);
+
+ gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t+dv);
+ }
+ gbuf.vertex3d(qx*(r+dr), qy, qz*(r+dr));
+
+ gbuf.normal3d(qx*sign, ynormal*sign, qz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s+du, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s+du, t);
+ }
+ gbuf.vertex3d(qx*r, py, qz*r);
+
+ s += (du*2.0);
+
+ for (int j = 2; j <= xdiv; j++) {
+ px = Math.cos(j*dtheta - Math.PI/2.0);
+ pz = Math.sin(j*dtheta - Math.PI/2.0);
+
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t + dv);
+ }
+ else {
+ gbuf.texCoord2d(s, t+dv);
+ }
+ gbuf.vertex3d(px*(r+dr), qy, pz*(r+dr));
+
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*r, py, pz*r);
+
+ s += du;
+ }
+ }
+ s = 0.0;
+ t += dv;
+ py += dy;
+ r += dr;
+ }
+ gbuf.end();
+
+ return gbuf;
}
-
+
// new coneTop method to remove transforms in the cone code
GeomBuffer coneTop(double bottom, double radius, double height,
- int xdiv,double t, boolean outside) {
-
- double sign;
-
- if (outside) sign = 1.0;
- else sign = -1.0;
-
- // compute the deltas
- double dtheta = 2.0*Math.PI/(double)xdiv;
- double ynormal = radius/height;
- double du = 1.0/(double)xdiv;
- double top = bottom + height;
-
- // initialize the geometry buffer
- GeomBuffer gbuf = new GeomBuffer(xdiv + 2);
- gbuf.begin(GeomBuffer.TRIANGLE_FAN);
-
- // add the tip, which is the center of the fan
- gbuf.normal3d(0.0, ynormal*sign, 0.0);
- gbuf.texCoord2d(.5, 1.0);
- gbuf.vertex3d(0.0, top, 0.0);
-
- // go around the circle and add the rest of the fan
- double s = 0.0;
- double px, pz;
- if (outside) {
-// for (int i = 0; i <= xdiv; i++) {
- for (int i = xdiv; i >= 0; i--) {
- px = Math.cos(i*dtheta - Math.PI/2.0);
- pz = Math.sin(i*dtheta - Math.PI/2.0);
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, bottom, pz*radius);
-
- s += du;
- }
- }
- else {
-// for (int i = xdiv; i >= 0; i--) {
- for (int i = 0; i <= xdiv; i++) {
- px = Math.cos(i*dtheta - Math.PI/2.0);
- pz = Math.sin(i*dtheta - Math.PI/2.0);
- gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
- gbuf.texCoord2d(s, t);
- gbuf.vertex3d(px*radius, bottom, pz*radius);
- s += du;
- }
- }
- gbuf.end();
- return gbuf;
+ int xdiv,double t, boolean outside, boolean texCoordYUp) {
+
+ double sign;
+
+ if (outside) sign = 1.0;
+ else sign = -1.0;
+
+ // compute the deltas
+ double dtheta = 2.0*Math.PI/(double)xdiv;
+ double ynormal = radius/height;
+ double du = 1.0/(double)xdiv;
+ double top = bottom + height;
+
+ // initialize the geometry buffer
+ GeomBuffer gbuf = new GeomBuffer(xdiv + 2);
+ gbuf.begin(GeomBuffer.TRIANGLE_FAN);
+
+ // add the tip, which is the center of the fan
+ gbuf.normal3d(0.0, ynormal*sign, 0.0);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(.5, 0.0);
+ }
+ else {
+ gbuf.texCoord2d(.5, 1.0);
+ }
+ gbuf.vertex3d(0.0, top, 0.0);
+
+ // go around the circle and add the rest of the fan
+ double s = 0.0;
+ double px, pz;
+ if (outside) {
+ for (int i = xdiv; i >= 0; i--) {
+ px = Math.cos(i*dtheta - Math.PI/2.0);
+ pz = Math.sin(i*dtheta - Math.PI/2.0);
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ } else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*radius, bottom, pz*radius);
+
+ s += du;
+ }
+ } else {
+ for (int i = 0; i <= xdiv; i++) {
+ px = Math.cos(i*dtheta - Math.PI/2.0);
+ pz = Math.sin(i*dtheta - Math.PI/2.0);
+ gbuf.normal3d(px*sign, ynormal*sign, pz*sign);
+ if (texCoordYUp) {
+ gbuf.texCoord2d(s, 1.0 - t);
+ } else {
+ gbuf.texCoord2d(s, t);
+ }
+ gbuf.vertex3d(px*radius, bottom, pz*radius);
+ s += du;
+ }
+ }
+ gbuf.end();
+ return gbuf;
}
}
diff --git a/src/classes/share/com/sun/j3d/utils/geometry/Sphere.java b/src/classes/share/com/sun/j3d/utils/geometry/Sphere.java
index 90dbab8..95327e4 100644
--- a/src/classes/share/com/sun/j3d/utils/geometry/Sphere.java
+++ b/src/classes/share/com/sun/j3d/utils/geometry/Sphere.java
@@ -206,14 +206,15 @@ public class Sphere extends Primitive {
*/
flags = primflags;
-
+ boolean texCoordYUp = (flags & GENERATE_TEXTURE_COORDS_YUP) != 0;
+
//Depending on whether normal inward bit is set.
if ((flags & GENERATE_NORMALS_INWARD) != 0) {
sign = -1;
} else {
sign = 1;
}
-
+
if (divisions < 4) {
nstep = 1;
n = 4;
@@ -244,8 +245,8 @@ public class Sphere extends Primitive {
GeomBuffer gbuf = new GeomBuffer(8*nstep*(nstep+2));
for (int i=0; i < 4; i++) {
- buildQuadrant(gbuf, i*Math.PI/2, (i+1)*Math.PI/2, sign, nstep, n, true);
- buildQuadrant(gbuf, i*Math.PI/2, (i+1)*Math.PI/2, sign, nstep, n, false);
+ buildQuadrant(gbuf, i*Math.PI/2, (i+1)*Math.PI/2, sign, texCoordYUp, nstep, n, true);
+ buildQuadrant(gbuf, i*Math.PI/2, (i+1)*Math.PI/2, sign, texCoordYUp, nstep, n, false);
}
shape = new Shape3D(gbuf.getGeom(flags));
@@ -354,7 +355,7 @@ public class Sphere extends Primitive {
}
void buildQuadrant(GeomBuffer gbuf, double startDelta, double endDelta,
- int sign, int nstep, int n, boolean upperSphere)
+ int sign, boolean texCoordYUp, int nstep, int n, boolean upperSphere)
{
double ds, dt, theta, delta;
@@ -415,17 +416,32 @@ public class Sphere extends Primitive {
texCoord = gbuf.tcoords[index];
// connect with correspondent vertices from previous row
gbuf.normal3d(norm.x, norm.y, norm.z);
- gbuf.texCoord2d(texCoord.x, texCoord.y);
+ if(texCoordYUp) {
+ gbuf.texCoord2d(texCoord.x, 1.0 - texCoord.y);
+ }
+ else {
+ gbuf.texCoord2d(texCoord.x, texCoord.y);
+ }
gbuf.vertex3d(pt.x, pt.y, pt.z);
} else {
gbuf.normal3d(0, sign*starth, 0);
- if (sign > 0) {
- gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
- 1.0 - (theta - dt)/Math.PI);
- } else {
- gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
- (theta - dt)/Math.PI);
- }
+ if (sign > 0) {
+ if (texCoordYUp) {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ (theta - dt)/Math.PI);
+ } else {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ 1.0 - (theta - dt)/Math.PI);
+ }
+ } else {
+ if (texCoordYUp) {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ 1.0 - (theta - dt)/Math.PI);
+ } else {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ (theta - dt)/Math.PI);
+ }
+ }
gbuf.vertex3d( 0, starth*radius, 0);
}
@@ -439,7 +455,12 @@ public class Sphere extends Primitive {
vx = r*Math.cos(delta);
vz = r*Math.sin(delta);
gbuf.normal3d( vx*sign, h*sign, vz*sign );
- gbuf.texCoord2d(0.75 - delta/(2*Math.PI), t);
+ if(texCoordYUp) {
+ gbuf.texCoord2d(0.75 - delta/(2*Math.PI), 1.0 - t);
+ }
+ else {
+ gbuf.texCoord2d(0.75 - delta/(2*Math.PI), t);
+ }
gbuf.vertex3d( vx*radius, h*radius, vz*radius);
} else {
delta = endDelta;
@@ -451,7 +472,11 @@ public class Sphere extends Primitive {
gbuf.normal3d( vx*sign, h*sign, vz*sign );
// Convert texture coordinate back to one
// set in previous version
- gbuf.texCoord2d(0.75 - delta/(2*Math.PI), t);
+ if(texCoordYUp) {
+ gbuf.texCoord2d(0.75 - delta/(2*Math.PI), 1.0 - t);
+ } else {
+ gbuf.texCoord2d(0.75 - delta/(2*Math.PI), t);
+ }
gbuf.vertex3d( vx*radius, h*radius, vz*radius );
if (i > 1) {
// get previous vertex from buffer
@@ -460,17 +485,31 @@ public class Sphere extends Primitive {
norm = gbuf.normals[index];
texCoord = gbuf.tcoords[index];
gbuf.normal3d(norm.x, norm.y, norm.z);
- gbuf.texCoord2d(texCoord.x, texCoord.y);
+ if(texCoordYUp) {
+ gbuf.texCoord2d(texCoord.x, 1.0 - texCoord.y);
+ } else {
+ gbuf.texCoord2d(texCoord.x, texCoord.y);
+ }
gbuf.vertex3d(pt.x, pt.y, pt.z);
} else {
gbuf.normal3d(0, sign*starth, 0);
if (sign > 0) {
- gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
- 1.0 - (theta - dt)/Math.PI);
- } else {
- gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
- (theta - dt)/Math.PI);
- }
+ if (texCoordYUp) {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ (theta - dt)/Math.PI);
+ } else {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ 1.0 - (theta - dt)/Math.PI);
+ }
+ } else {
+ if (texCoordYUp) {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ 1.0 - (theta - dt)/Math.PI);
+ } else {
+ gbuf.texCoord2d(0.75 - (startDelta + endDelta)/(4*Math.PI),
+ (theta - dt)/Math.PI);
+ }
+ }
gbuf.vertex3d( 0, starth*radius, 0);
}
@@ -481,11 +520,15 @@ public class Sphere extends Primitive {
// for numerical accuracy we don't use delta
// compute from above.
delta = startDelta;
- vx = r*Math.cos(delta);
- vz = r*Math.sin(delta);
- gbuf.normal3d( vx*sign, h*sign, vz*sign );
- gbuf.texCoord2d(0.75 - delta/(2*Math.PI), t);
- gbuf.vertex3d( vx*radius, h*radius, vz*radius );
+ vx = r*Math.cos(delta);
+ vz = r*Math.sin(delta);
+ gbuf.normal3d( vx*sign, h*sign, vz*sign );
+ if(texCoordYUp) {
+ gbuf.texCoord2d(0.75 - delta/(2*Math.PI), 1.0 - t);
+ } else {
+ gbuf.texCoord2d(0.75 - delta/(2*Math.PI), t);
+ }
+ gbuf.vertex3d( vx*radius, h*radius, vz*radius );
}