Quadrics in Xith3D

I noticed that spheres and cylinders are created with triangles in Xith3D. So, I’m wondering if anyone knows how performance would be affected if quadrics were used instead. I’m going to be developing an application that could have thousands of spheres and cylinders, and so this is why I’m interested.

I know that quadrics are used with OpenGL, and so if you added Sphere and Cylinder classes then maybe you could allow someone to specify how the shape is rendered, having the default be triangles in case the renderer doesn’t support quadrics?

Java3D has Sphere and Cylinder classes in the com.sun.j3d.util.geometry package, so they are not part of the standard Java3D API. Maybe these classes could go in the com.xith3d.scenegraph package or maybe com.xith3d.scenegraph.utility.geometry?

I was able to render spheres and cylinders in JOGL, and have attached some code if it would help out.

Thanks,

Jason

import net.java.games.jogl.GL;
import net.java.games.jogl.GLU;
import net.java.games.jogl.GLUquadric;
public class QuadricCylinderGeometry{
private static GLUquadric cylinderObject;
private static boolean m_instantiated = false;
private double baseRadius;
private double topRadius;
private double height;
private int slices;
private int stacks;
public void render(GL gl, GLU glu) {
if(!m_instantiated)
{
m_instantiated = true;
cylinderObject = glu.gluNewQuadric();
}
glu.gluQuadricNormals(cylinderObject, GLU.GLU_SMOOTH);
glu.gluQuadricDrawStyle(cylinderObject,GLU.GLU_FILL);
glu.gluQuadricOrientation(cylinderObject, GLU.GLU_INSIDE);

        gl.glPushMatrix();
        gl.glRotatef(-90.0f, 1.0f, 0.0f, 0.0f);
              gl.glPushMatrix();
                    gl.glTranslatef( 0.0f,  0.0f,-(float)(height/2));
                    glu.gluDisk(cylinderObject, 0.0, topRadius, slices, 4);
                    
                    gl.glTranslatef( 0.0f,  0.0f,(float)(height));
                    
                    glu.gluQuadricOrientation(cylinderObject, GLU.GLU_OUTSIDE);
                    glu.gluDisk(cylinderObject, 0.0, baseRadius, slices, 4);
              gl.glPopMatrix();
        gl.glTranslatef( 0.0f,  0.0f,-(float)(height/2));
        glu.gluQuadricOrientation(cylinderObject, GLU.GLU_INSIDE);
        glu.gluCylinder(cylinderObject,baseRadius, topRadius, height, slices, stacks);
        glu.gluQuadricOrientation( cylinderObject, GLU.GLU_OUTSIDE);
        glu.gluCylinder(cylinderObject,baseRadius, topRadius, height, slices, stacks);
        gl.glPopMatrix();            
  }
  
  public QuadricCylinderGeometry(double b, double t, double h, int sl, int st)
  {
        baseRadius = b;
        topRadius = t;
        height = h;
        slices = sl;
        stacks = st;      
  }

}
import net.java.games.jogl.GL;
import net.java.games.jogl.GLU;
import net.java.games.jogl.GLUquadric;
public class QuadricSphereGeometry{
protected double radius;
private static GLUquadric sphereObject;
private static boolean m_instantiated = false;
protected int stacks = 35;
protected int slices = 35;
public void render(GL gl, GLU glu) {
if(!m_instantiated)
{
m_instantiated = true;
sphereObject = glu.gluNewQuadric();
}
glu.gluQuadricNormals(sphereObject, GLU.GLU_SMOOTH);
glu.gluQuadricDrawStyle(sphereObject,GLU.GLU_FILL);
glu.gluQuadricOrientation(sphereObject, GLU.GLU_OUTSIDE);
glu.gluSphere(sphereObject, radius, slices, stacks);

  }
  public QuadricSphereGeometry(double r)
  {
        radius = r;
  }

}

Hello again,

First off, I’d like to thank everyone involved in the Xith3D project, it is really cool to be able to look at the source code and see how everything works. Great job!

So, I’ve been thinking how to implement rendering quadrics, and here are some ideas:

The ShapeAtomPeer has the renderAtom method, and that is where the objects are rendered.

public void renderAtom(CanvasPeer canvas, RenderAtom atom)
{

Shape3D shape = (Shape3D) ((ShapeAtom) atom).getNode();

Geometry geometry = shape.getGeometry();

GeometryArray geoArray = null;
if (geometry instanceof GeometryArray) {
geoArray = (GeometryArray) geometry;
} else if (geometry instanceof GeometryTranslocator) {
geoArray = ((GeometryTranslocator) geometry).getGeometry();
} else {…

and so in this method it is assumed that geoArray will be set to a GeometryArray.

Later on this.drawGeometry(canvas, gl, geoArray); is called, but I think that this method should be renamed to be:
drawGeometryArray(canvas, gl, geoArray); since it is passing a GeometryArray.

So maybe you could add an else if:
else if(geometry instanceof PrimitiveGeometry)
{
this.drawPrimitiveGeometry(canvas, gl, (PrimitiveGeometry)geometry);
}

then add the

drawPrimitiveGeometry(CanvasPeer canvas, GL gl, PrimitiveGeometry primitiveGeometry)
{
if(primitiveGeometry instanceof Sphere)
{
Sphere sphere = (Sphere)primitiveGeometry;
if(sphere.getRenderingPreference() == Sphere.RENDER_WITH_TRIANGLES)
{

        }
        else if(sphere.getRenderingPreference() == Sphere.RENDER_WITH_QUADRICS)
        {

        }

  }
  else if(PrimitiveGeometry instanceof Cylinder)
  {
        ...
  }

}
Just an idea, so let me know if you think this may be worth doing.

Thanks,

Jason Cheatham