> From: [EMAIL PROTECTED] (Krishna Gadepalli)
>
> 1. 3D Texture mapping :
>
>   Has anyone attempted 3D texture mapping with Java3D ?
>
>   If anyone has a simple working example I would really appreciate it

A simple example of 3D texture mapping is attached below.

Doug Gehringer
Sun Microsystems
/*
 *      @(#)Texture3DTest.java 1.1 99/01/05 16:14:11
 *
 * Copyright (c) 1996-1998 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use,
 * modify and redistribute this software in source and binary code form,
 * provided that i) this copyright notice and license appear on all copies of
 * the software; and ii) Licensee does not utilize the software in a manner
 * which is disparaging to Sun.
 *
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGES.
 *
 * This software is not designed or intended for use in on-line control of
 * aircraft, air traffic, aircraft navigation or aircraft communications; or in
 * the design, construction, operation or maintenance of any nuclear
 * facility. Licensee represents and warrants that it will not use or
 * redistribute the Software for such purposes.
 */


/**
 * Draws two squares using a 3D texture map.  The first square uses explicit
 * texture coordinates.  The second uses texture coordinate generation to 
 * set up texture coordinates which line up with the first square.
 */


import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.event.*;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.Box;
import javax.media.j3d.*;
import javax.vecmath.*;
import java.awt.image.BufferedImage;
import java.awt.image.ComponentColorModel;
import java.awt.image.WritableRaster;
import java.awt.image.DataBufferByte;
import java.awt.color.ColorSpace;
import java.awt.Transparency;


public class Texture3DTest extends Applet {

    public BranchGroup createSceneGraph() {

        // Create the root of the branch graph
        BranchGroup objRoot = new BranchGroup();

        // Create a transform group to center the object
        TransformGroup objOrient = new TransformGroup();
        Transform3D orient = new Transform3D();
        orient.set(new Vector3d(-0.25, -0.0, -0.0), 0.5);
        objOrient.setTransform(orient);
        objRoot.addChild(objOrient);

        // Create a transform group node and initialize it to the identity.
        // Enable the TRANSFORM_WRITE capability so that our behavior code
        // can modify it at runtime.  Add it to the root of the subgraph.
        //
        TransformGroup objTrans = new TransformGroup();

        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objOrient.addChild(objTrans);

        //
        // Create a 3D texture
        //
        int width = 16;
        int height = 16;
        int depth = 16;

        ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB); 
        int[] nBits = {8, 8, 8}; 
        ComponentColorModel colorModel = new ComponentColorModel(cs, nBits, 
                false, false, Transparency.OPAQUE, 0); 
        WritableRaster raster = 
          colorModel.createCompatibleWritableRaster(width, height); 
 
        BufferedImage bImage =                                   
            new BufferedImage(colorModel, raster, false, null); 
 
        byte[] byteData = ((DataBufferByte)raster.getDataBuffer()).getData(); 
 
        ImageComponent3D pArray = new ImageComponent3D(
                ImageComponent.FORMAT_RGB, width, height, depth);

        // set up a volume with the color intensities corresponding to the 
        // s,t,r values: s = red, t = green, r == blue
        for (int k = 0; k < depth; k++) {
            for (int j = 0;j < height;j++){
                for (int i = 0;i < width;i++){ 

                    double s = (double) i / width;
                    double t = (double) j / height;
                    double r = (double) k / depth;

                    // Note: Java3D flips the s coordinate to match the 2D 
                    // image sematics, which put s=0 at the "top" of the image.
                    // Since most 3D data puts the origin at the lower left 
                    // corner, we flip the "s" coordinate
                    s = 1.0 - s;
                    
                    int index = ((j * width) + i) * 3; 
                    byteData[index] =   (byte)(255 * s);
                    byteData[index+1] = (byte)(255 * t);
                    byteData[index+2] = (byte)(255 * r);
                } 
            } 
            pArray.set(k, bImage);
        }
 

        Texture3D tex = new Texture3D(Texture.BASE_LEVEL,
                                           Texture.RGB, width, height, depth);
        tex.setImage(0, pArray);
        tex.setEnable(true);
        tex.setMinFilter(Texture.BASE_LEVEL_LINEAR);
        tex.setMagFilter(Texture.BASE_LEVEL_LINEAR);
        tex.setBoundaryModeS(Texture.CLAMP);
        tex.setBoundaryModeT(Texture.CLAMP);
        tex.setBoundaryModeR(Texture.CLAMP);

        // turn off face culling and lighting so we an see just the texture
        PolygonAttributes p = new PolygonAttributes();
        p.setCullFace(PolygonAttributes.CULL_NONE);
        Material m = new Material();
        m.setLightingEnable(false);

        // Create two squares, one with texture coordinates, and the 
        // other with generated texture coordinates

        Point3f[]       coords = new Point3f[4];
        coords[0] = new Point3f(0.0f, 0.0f, 0.0f);
        coords[1] = new Point3f(1.0f, 1.0f, 0.0f);
        coords[2] = new Point3f(1.0f, 1.0f, 1.0f);
        coords[3] = new Point3f(0.0f, 0.0f, 1.0f);

        // Note that the texture coordinates match the coords: s=x, t=y, r=z
        Point3f[]       texCoords = new Point3f[4];
        texCoords[0] = coords[0];
        texCoords[1] = coords[1];
        texCoords[2] = coords[2];
        texCoords[3] = coords[3];

        QuadArray coordsSquare = new QuadArray(4, 
                QuadArray.COORDINATES | QuadArray.TEXTURE_COORDINATE_3 );
        coordsSquare.setCoordinates(0, coords);
        coordsSquare.setTextureCoordinates(0, texCoords);

        // create an appearance with the texture but no tex coord gen
        Appearance coordsAppearance = new Appearance();
        coordsAppearance.setTexture(tex);
        coordsAppearance.setMaterial(m);
        coordsAppearance.setPolygonAttributes(p);

        Shape3D coordsShape = new Shape3D(coordsSquare, coordsAppearance); 

        objTrans.addChild(coordsShape);

        // Now the square with generated tex coords.  This crosses the first
        // square, but it has texture coordinates which match up with the
        // the first quad

        // First the shape...
        Point3f[]       genCoords = new Point3f[4];
        genCoords[0] = new Point3f(1.0f, 0.0f, 0.0f);
        genCoords[1] = new Point3f(1.0f, 0.0f, 1.0f);
        genCoords[2] = new Point3f(0.0f, 1.0f, 1.0f);
        genCoords[3] = new Point3f(0.0f, 1.0f, 0.0f);

        QuadArray genSquare = new QuadArray(4, QuadArray.COORDINATES);
        genSquare.setCoordinates(0, genCoords);

        // setup the tex coord gen.  This is just s = x, t = y, r = z
        TexCoordGeneration tg = new TexCoordGeneration();
        tg.setFormat(TexCoordGeneration.TEXTURE_COORDINATE_3);
        tg.setPlaneS(new Vector4f(1.0f, 0.0f, 0.0f, 0.0f));
        tg.setPlaneT(new Vector4f(0.0f, 1.0f, 0.0f, 0.0f));
        tg.setPlaneR(new Vector4f(0.0f, 0.0f, 1.0f, 0.0f));

        // create an appearance with the texture and tex coord gen
        Appearance genAppearance = new Appearance();
        genAppearance.setTexture(tex);
        genAppearance.setTexCoordGeneration(tg);
        genAppearance.setMaterial(m);
        genAppearance.setPolygonAttributes(p);

        Shape3D genShape = new Shape3D(genSquare, genAppearance); 

        objTrans.addChild(genShape);

        BoundingSphere bounds =
            new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);

        // Create a new Behavior object that will perform the desired
        // operation on the specified transform object and add it into the
        // scene graph.
        //
        Transform3D yAxis = new Transform3D();
        Alpha rotorAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
                                     0, 0,
                                     4000, 0, 0,
                                     0, 0, 0);
        RotationInterpolator rotator =
            new RotationInterpolator(rotorAlpha,
                                     objTrans,
                                     yAxis,
                                     0.0f, (float) Math.PI*2.0f);
        rotator.setSchedulingBounds(bounds);
        objTrans.addChild(rotator);

        // Have Java 3D perform optimizations on this scene graph.
        objRoot.compile();

        return objRoot;
    }

    public Texture3DTest() {
        setLayout(new BorderLayout());
        Canvas3D c = new Canvas3D(null);
        add("Center", c);

        // Create a simple scene and attach it to the virtual universe
        BranchGroup scene = createSceneGraph();
        SimpleUniverse u = new SimpleUniverse(c);

        // This will move the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        u.getViewingPlatform().setNominalViewingTransform();

        u.addBranchGraph(scene);
    }

    //
    // The following allows Texture3DTest to be run as an application
    // as well as an applet
    //
    public static void main(String[] args) {
        new MainFrame(new Texture3DTest(), 256, 256);
    }

}

Reply via email to