GPWiki.org
GPWiki.org
It is currently Tue May 21, 2013 7:07 am

All times are UTC




Post new topic Reply to topic  [ 1 post ] 
Author Message
PostPosted: Wed Aug 24, 2011 9:42 am 
Hello guys,

I am newbie in Java3D and I am facing some problems while designing a 3d shape. Actually I have to design a 3d shape of a 'Carpet' placed on the ground in such a way, it looks like a Road or Pathway from "First-Person-View". That is, like a Trapezoid. The Carpet itself is made up of several segments or pieces, each of different color, width and height. Finally, exporting the final Carpet-shape as Buffered Image. Though I am able to do the later part very easily, that is, creating an image using BufferdImage from JFrame, On & Off Screen Canvas but the designing part is where I am facing some difficulties.

I am creating a Group (carpetShapeGroup) of Polygons (with QuadArray: 4) for each segment/piece and place them one over another. so it looks like Rectangular Boxes placed one over another. Then with the Transformation3D (rot), I rotate this carpetShapeGroup with rot.rotX(-Math.PI/4) to make it like a Trapezoid shape. However, I am able to draw the image but there are several problems which I am not able to solve anymore and I need some help. I had uploaded the code on Pastie and attached it here as well with inline comments to illustrate the details.

Problem-1. I can create a Carpet with 3 segments/pieces successfully but as soon as I add fourth segment, the image gets distorted and the segments overlaps each other. I don't know why is it happening and how to resolve this issue. (Uncomment line:227)

Please let me know if something is unclear here, I will try to explain my problem again. Looking forward to see your replies.

thanks and regards

Code:
    package me.mmw.test.java3d; 
    import java.awt.BorderLayout; 
    import java.awt.Color; 
    import java.awt.GraphicsConfiguration; 
    import java.awt.GraphicsEnvironment; 
    import java.awt.image.BufferedImage; 
    import java.io.File; 
    import java.io.IOException; 
    import javax.imageio.ImageIO; 
    import javax.media.j3d.AmbientLight; 
    import javax.media.j3d.Appearance; 
    import javax.media.j3d.BoundingSphere; 
    import javax.media.j3d.BranchGroup; 
    import javax.media.j3d.Canvas3D; 
    import javax.media.j3d.ColoringAttributes; 
    import javax.media.j3d.DirectionalLight; 
    import javax.media.j3d.Group; 
    import javax.media.j3d.ImageComponent; 
    import javax.media.j3d.ImageComponent2D; 
    import javax.media.j3d.QuadArray; 
    import javax.media.j3d.Screen3D; 
    import javax.media.j3d.Shape3D; 
    import javax.media.j3d.Transform3D; 
    import javax.media.j3d.TransformGroup; 
    import javax.swing.JFrame; 
    import javax.vecmath.Color3f; 
    import javax.vecmath.Point3d; 
    import javax.vecmath.Vector3f; 
       
    import com.sun.j3d.utils.universe.SimpleUniverse; 
    import com.sun.j3d.utils.universe.ViewingPlatform; 
       
    public class CarpetImageRenderer { 
       
    private double screenWidth; 
    private double screenHeight; 
    private SimpleUniverse universe; 
       
    public double getScreenWidth() { 
    return screenWidth; 
    } 
       
    public void setScreenWidth(double screenWidth) { 
    this.screenWidth = screenWidth; 
    } 
       
    public double getScreenHeight() { 
    return screenHeight; 
    } 
       
    public void setScreenHeight(int screenHeight) { 
    this.screenHeight = screenHeight; 
    } 
       
    public BufferedImage render(int width, int height, PolygonDetails[] polygonDetails) { 
    setScreenWidth(width); 
    setScreenHeight(height); 
       
    BranchGroup scene = createSceneGraph(polygonDetails); 
    Canvas3D onScreenCanvas = new Canvas3D( 
    SimpleUniverse.getPreferredConfiguration()); 
       
    universe = new SimpleUniverse(onScreenCanvas); 
    ViewingPlatform viewingPlatform = universe.getViewingPlatform(); 
    viewingPlatform.setNominalViewingTransform(); 
    scene.compile(); 
    universe.addBranchGraph(scene); 
       
    OffScreenCanvas3D offScreenCanvas = createOffScreenCanvas(); 
       
    JFrame frame = new JFrame(); 
    frame.setLayout(new BorderLayout()); 
    frame.setLocation(GraphicsEnvironment.getLocalGraphicsEnvironment().getCenterPoint()); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
    frame.setTitle("3D Carpet Renderer"); 
    frame.add(onScreenCanvas); 
       
    BufferedImage output = offScreenCanvas.doRender((int)getScreenWidth(), (int)getScreenHeight()); 
    frame.setSize(output.getWidth(), output.getHeight()); 
    setScreenWidth(output.getWidth()); 
    setScreenHeight(output.getHeight()); 
       
    return output; 
    } 
       
    private OffScreenCanvas3D createOffScreenCanvas() { 
    /**
    * Setup graphics
    */ 
    GraphicsConfiguration configuration = SimpleUniverse 
    .getPreferredConfiguration(); 
       
    /**
    * Create the capturing canvas
    */ 
    OffScreenCanvas3D canvas = new OffScreenCanvas3D(configuration); 
       
    /**
    * Set the size, width and height so that off-screen renderer knows at
    * what dimensions it needs to render.
    */ 
    Screen3D screen3D = canvas.getScreen3D(); 
    screen3D.setSize((int)screenWidth, (int)screenHeight); 
       
    /**
    * Physical dimension of the Screen3D is supposed to be size of the physical screen in meters.
    * The values are from the top of the Screen3D physical screen in meters.
    * The values are from the top of the Screen3D.
    * Setting the wrong physical dimension may also change the aspect ratio of the rendered image
    * and you are end up with a Blackboard
    */ 
    screen3D.setPhysicalScreenWidth(0.0254 / 90.0 * screenWidth); 
    screen3D.setPhysicalScreenHeight(0.0254 / 90.0 * screenHeight); 
       
    universe.getViewer().getView().addCanvas3D(canvas); 
       
    return canvas; 
    } 
       
    public BranchGroup createSceneGraph(PolygonDetails[] polygonDetails) { 
       
    BranchGroup objRoot = new BranchGroup(); 
    Group carpetShapeGroup = new Group(); 
    /**
    * Setting Transformation/Postion Vector to display the Carpet from the Bottom of the screen
    * Problem-2: Not able to derive a constant factor for positioning the Carpet with
    * different Width and Height of Screen
    */ 
       
    final float TRANSFORMATION_VECTOR_Y = -0.0014f; 
       
    Vector3f vector = new Vector3f(0.0f, (float)(TRANSFORMATION_VECTOR_Y * getScreenHeight()), 0.0f); 
       
    double previousElementHeight = 0.0d; 
    double baseCoordinateY = 0.0d; 
       
    double elementHeight = 0.0d; 
    double elementWidth = 1.0d; 
       
    for (PolygonDetails element : polygonDetails) { 
    elementHeight = (double) getScreenHeight()/100 * element.getPercentage() /100 /2; 
    previousElementHeight += elementHeight; 
       
    //System.out.println("baseCoordinateY:"+baseCoordinateY+" previousElementHeight"+previousElementHeight); 
       
    QuadArray polygon = new QuadArray(4, QuadArray.COORDINATES); 
    // X:WIDTH, Y:HEIGHT, Z:LENGTH 
    polygon.setCoordinate(0, new Point3d(-elementWidth, baseCoordinateY, 0d)); 
    polygon.setCoordinate(1, new Point3d(elementWidth, baseCoordinateY, 0d)); 
    polygon.setCoordinate(2, new Point3d(elementWidth, previousElementHeight, 0d)); 
    polygon.setCoordinate(3, new Point3d(-elementWidth, previousElementHeight, 0d)); 
       
    Shape3D polygonShape = new Shape3D(polygon, createAppearance(element.getColor())); 
    polygonShape.setGeometry(polygon); 
    //System.out.println(polygonShape.getBounds()); 
    polygonShape.setCollidable(false); 
    /**
    * Adding each polygon-shape in a group and finally add this group in the BranchGroup
    * Problem-3: Is there any way I can create set of polygons as One Shape?
    */ 
    carpetShapeGroup.addChild(polygonShape); 
    baseCoordinateY = elementHeight; 
    } 
    TransformGroup tg = new TransformGroup(); 
    Transform3D transform = new Transform3D(); 
    Transform3D rot = new Transform3D(); 
    /**
    * transforming the final shape as Trapezoid
    */ 
    rot.rotX(-Math.PI / 7); 
    transform.mul(rot); 
    //transform.setScale(0.7); 
       
    transform.setTranslation(vector); 
    tg.setTransform(transform); 
    tg.addChild(carpetShapeGroup); 
       
    objRoot.addChild(tg); 
       
    createLights(objRoot); 
    return objRoot; 
    } 
    private Appearance createAppearance(Color color){ 
       
    Appearance polygon2Appearance = new Appearance(); 
    Color3f c = new Color3f (); 
    c.set(color); 
    ColoringAttributes yellowCA = new ColoringAttributes (c, 1); 
    polygon2Appearance.setColoringAttributes(yellowCA); 
    return polygon2Appearance; 
       
    } 
    private void createLights(BranchGroup branchGroup) { 
       
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 
    100.0); 
       
    Color3f ambientLightColour = new Color3f(0.9f, 0.9f, 0.9f); 
    AmbientLight ambientLight = new AmbientLight(ambientLightColour); 
    ambientLight.setInfluencingBounds(bounds); 
       
    Color3f directionLightColour = new Color3f(1.0f, 1.0f, 1.0f); 
    Vector3f directionLightDir = new Vector3f(4.0f, -7.0f, -12.0f);// (-1.0f, 
    // -100.0f, 
    // -1.0f); 
    DirectionalLight directionLight = new DirectionalLight( 
    directionLightColour, directionLightDir); 
    directionLight.setInfluencingBounds(bounds); 
       
    branchGroup.addChild(ambientLight); 
    branchGroup.addChild(directionLight); 
    } 
       
    public static void main(String... args) { 
    /**
    * Segments/Pieces of Carpet
    * 1st arg: size of segment as %tage value
    * 2nd arg: Color of segment
    * Problem-1: when I add Fourth segment, the Image gets weird
    */ 
    PolygonDetails[] polygonDetails = new PolygonDetails[] { 
    new PolygonDetails(10, Color.YELLOW), 
    new PolygonDetails(60, Color.GREEN), 
    new PolygonDetails(5, Color.RED), 
    new PolygonDetails(5, Color.YELLOW), 
    //new PolygonDetails(10, Color.GREEN), 
    }; 
    /**
    * Create a Scene, render the Carpet and finally return a buffered image.
    * Takes screen width, height and set of carpet-segments as args
    */ 
    BufferedImage bi = new CarpetImageRenderer().render(400, 400, polygonDetails); 
       
    try { 
    ImageIO.write(bi, "PNG", new File("carpet3d.png")); 
    } catch (IOException e) { 
    e.printStackTrace(); 
    } 
    } 
    } 
       
    @SuppressWarnings("serial") 
    class OffScreenCanvas3D extends Canvas3D { 
    public OffScreenCanvas3D(GraphicsConfiguration graphicsConfiguration) { 
    super(graphicsConfiguration, true); 
    } 
       
    public BufferedImage doRender(int width, int height) { 
       
    BufferedImage bImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 
       
    ImageComponent2D buffer = new ImageComponent2D( 
    ImageComponent.FORMAT_RGB, bImage); 
    buffer.setCapability(ImageComponent.ALLOW_FORMAT_READ); 
       
    setOffScreenBuffer(buffer); 
    renderOffScreenBuffer(); 
    waitForOffScreenRendering(); 
    bImage = getOffScreenBuffer().getImage(); 
       
    // Release the buffer 
    setOffScreenBuffer(null); 
       
    return bImage; 
    } 
    } 
       
    class PolygonDetails { 
       
    private Color color; 
    private double percentage; 
       
    public PolygonDetails(double percentage, Color color) { 
    super(); 
    this.color = color; 
    this.percentage = percentage; 
    } 
       
    public PolygonDetails() { 
    } 
       
    public double getPercentage() { 
    return percentage; 
    } 
       
    public Color getColor() { 
    return color; 
    } 
    } 


Top
  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 1 post ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group