Java Programing

January 31, 2007

A vertex s position is defined using three dimensions

Filed under: Java 3D Programming — webmaster @ 11:15 pm

Figure 14.8 Using OBJECT_LINEAR texture coordinate generation That is, the t texture coordinate is equal to a scaled version of the y vertex coordinate plus an offset of 0.5. We use an offset of 0.5 because we defined the midpoint of the texture image as the elevation = 0 contour. From the equation you can see that: Vertex y = yMaxHeight, s = 1.0 Vertex y = 0.0, s = 0.5 Vertex y = yMaxHeight, s = 0.0 That is, we have successfully defined a mapping from vertex y coordinate in the range yMaxHeight to s texture coordinates in the range 0.0 to 1.0. The texture coordinate is independent of a vertex s x and z coordinates. Using the OBJECT_LINEARmode, the landscape has texture coordinates automatically calculated, coloring areas above sea level green (light gray) and areas below sea level blue (dark gray). As the landscape as a whole is rotated and translated, the texture coordinates are unaffected. The vertex coordinates in the local coordinate system of the landscape are unchanged, despite the origin of the landscape s coordinate being shifted. EYE_LINEAR mode The EYE_LINEARtexture coordinate generation mode is very similar to the OBJECT_LINEARmode with one important difference. The positions of vertices in their local coordinate system are no longer used; rather the positions of vertices in the world coordinate system are used instead. This has major consequences as the landscape is moved within the VirtualUniverse, the texture coordinates of the vertices within the landscape are recomputed, for example, in the TexCoordTestexample, by simply modifying the construction of the TexCoordGenerationobject to be: TexCoordGeneration texGen = new TexCoordGeneration( TexCoordGeneration.EYE_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2, new Vector4f( 0, (float) (1.0/(2 * yMaxHeight)), 0, 0.5f ), new Vector4f( 0,0,0,0 ), new Vector4f( 0,0,0,0 ) ); We define a VirtualUniversewhere the texture coordinate of the landscape is calculated from the y coordinate of the landscape in the VirtualUniverse s coordinate system. In essence we have defined a band of texture coordinates (color) that ranges from yMaxHeight to +yMaxHeight. When the landscape falls inside this range, it will have a texture coordinate applied to it. In mathematical terms, this is equivalent to multiplying each vertex coordinate by the result of calling Shape3D.getLocalToVworldbefore computing the texture coordinate using: s texture coordinate = (0.0 * vertex x) + (1.0/ 2 * yMaxHeight * vertex y) + (0.0 * vertex z) + 0.5; 241

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

A vertex s position is defined using three dimensions

Filed under: Java 3D Programming — webmaster @ 11:15 pm

A vertex s position is defined using three dimensions (x,y,z), while a texture coordinate can potentially be expressed in three dimensions (although typically only s and t are used). We define a plane for each of the texture coordinates (s, t, and sometimes r). The s texture coordinate is given by a vertex s position relative to the s plane, the t coordinate is given by a vertex s position relative to the t plane, and so on. Planes are defined by specifying the direction of the vector perpendicular (normal) to the plane. For example, to create our mapping from y vertex coordinate to s texture coordinate: TexCoordGeneration texGen = new TexCoordGeneration( TexCoordGeneration.OBJECT_LINEAR, TexCoordGeneration.TEXTURE_COORDINATE_2, new Vector4f( 0, (float) (1.0/(2 * yMaxHeight)), 0, 0.5f ), new Vector4f( 0,0,0,0 ), new Vector4f( 0,0,0,0 ) ); The parameters to the TexCoordGenerationconstructor do the following: 1. Specify the texture coordinate generation mode that we are using, in this case, OBJECT_LINEAR. 2. Specify that we are generating 2D texture coordinates (s and t). 3. Define the mapping from vertex coordinate to s coordinate. 4. Define the mapping from vertex coordinate to t coordinate. 5. Define the mapping from vertex coordinate to r coordinate (which is unused when 2D texture coordinates are used). The mapping from vertex coordinates to s coordinates we defined was: (0, (float) (1.0/ (2 * yMaxHeight)), 0, 0.5f) This equates to: s texture coordinate = (0.0 * vertex x) + (1.0/ 2 * yMaxHeight * vertex y) + (0.0 * vertex z) + 0.5; 240

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

Texture coordinates themselves are usually manually calculated or

Filed under: Java 3D Programming — webmaster @ 6:36 pm

Figure 14.6 The TexCoordTest example application in action. The vertices in the undulating landscape do not have assigned texture coordinates, but rather a TexCoordGeneration object is used to calculate texture coordinates dynamically OBJECT_LINEAR mode The OBJECT_LINEAR texture coordinate generation mode calculates texture coordinates based on the relative positions of vertices. The TexCoordTestexample creates a simulated landscape that has contours automatically mapped onto the landscape Everything above the y = 0 plane is texture-mapped green, while everything below is texture-mapped blue. Figure 14.7 illustrates the texture image used in the TexCoordTestexample for dynamic texture mapping. The texture image is 64 x 64 pixels and merely contains a single row of pixels that is of interest the rest of the image is ignored. The bottom row of the image (t = 0) defines the colors to be dynamically applied to the landscape. The midpoint of the row (s = 0.5) defines the elevation = 0 (sea level) contour, while everything to the left of the midpoint is used for elevations below sea level, and everything to the right is used for elevations above sea level. Different colored pixels for contours are evenly spaced from the midpoint. Figure 14.7 The texture image used to perform dynamic mapping of texture coordinates in the TexCoordTest example application To map contours onto the landscape we merely need to define a mapping from the y coordinate of the landscape to the s coordinate of the texture image. That is, we are defining a 1D-to-1D mapping from vertex coordinates to texture coordinates. 239

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

Texture coordinates themselves are usually manually calculated or

Filed under: Java 3D Programming — webmaster @ 6:36 pm

Texture coordinates themselves are usually manually calculated or are the product of an automated texture-mapping process (such as 3D model capture or model editor). Note that although we have called this section static mapping, there is nothing to prevent you from modifying the texture coordinates within a GeometryArrayat runtime. Very interesting dynamic effects can be achieved through reassigning texture coordinates. Care must be taken to ensure that texture images do not become too pixilated as they become enlarged and stretched by the sampling algorithm. The MIPMAP technique covered in detail in Section 14.3.4 is useful in this regard in that different sizes of different texture images can be specified. Needless to say, texture images consume memory, and using large 24-bit texture images is an easy way to place a heavy strain on the renderer and push up total memory footprint. Of course, the larger the texture image, the less susceptible it is to becoming pixilated so a comfortable balance must be found between rendering quality, rendering speed, and memory footprint. You should also be very aware that different 3D rendering hardware performs texture mapping in hardware only if the texture image falls within certain criteria. Modern 3D rendering cards typically have 16 MB or more of texture memory, and 64 MB is now not uncommon. Most rendering hardware will render texture images of up to 512 x 512 pixels. You should consult the documentation for the 3D rendering cards that your application considers important. 14.1.2 Dynamic mapping using TexCoordGeneration In contrast to a hard-coded static mapping between vertex coordinates and texture coordinates, dynamic texture mapping enables the application developer to define a mapping that is resolved by the renderer at runtime. Dynamic mapping is fairly unusual but is very useful for certain scientific visualization applications where the position of a vertex in 3D space should correlate with its texture coordinate. Rather than having to manually update the texture coordinate whenever a vertex moves, the application developer defines a series of planes that the renderer uses to calculate a texture coordinate. The TexCoordTestexample application explores the three texture coordinate generation options in Java 3D. These are TexCoordGeneration.EYE_LINEAR, TexCoordGeneration.OBJECT_LINEAR, and TexCoordGeneration.SPHERE_MAP(figures 14.6 14.11). Each will be described in turn in the sections that follow. 238

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

gi.setContourCounts( countourCountArray ); gi.setStripCounts( stripCountArray ); Triangulator triangulator

Filed under: Java 3D Programming — webmaster @ 12:26 pm

java.util.StringTokenizer tokenizer = new java.util.StringTokenizer( szBufferData.toString() ); //read the name of the texture image texInfo.m_szImage = tokenizer.nextToken(); //read the size of the generated geometry in the X dimension sizeGeometryX = Float.parseFloat( tokenizer.nextToken() ); //read the Y scale factor factorY = Float.parseFloat( tokenizer.nextToken() ); //read the number of texture coordinates nNumPoints = Integer.parseInt( tokenizer.nextToken() ); //read each texture coordinate texInfo.m_TexCoordArray = new Point2f[nNumPoints]; Point2f texPoint2f = null; for( int n = 0; n < nNumPoints; n++ ) { texPoint2f = new Point2f( Float.parseFloat( tokenizer.nextToken() ), Float.parseFloat( tokenizer.nextToken() ) ); texInfo.m_TexCoordArray[n] = texPoint2f; //keep an eye on the extents of the texture coordinates // so we can automatically center the geometry if( n == 0 || texPoint2f.x > boundsPoint.x ) boundsPoint.x = texPoint2f.x; if( n == 0 || texPoint2f.y > boundsPoint.y ) boundsPoint.y = texPoint2f.y; } } catch( Exception e ) { System.err.println( e.toString() ); return null; } //build the array of coordinates texInfo.m_CoordArray = new Point3f[nNumPoints]; for( int n = 0; n < nNumPoints; n++ ) { //scale and center the geometry based on the texture coordinates texInfo.m_CoordArray[n] = new Point3f( sizeGeometryX * texInfo.m_TexCoordArray[n].x - boundsPoint.x/2), factorY * sizeGeometryX * (texInfo.m_TexCoordArray[n].y - boundsPoint.y/2), 0 ); } return texInfo; } As the TextureTestexample illustrates, using a static mapping from vertex coordinates is relatively straightforward. Texture coordinates are assigned to each vertex, much like vertex coordinates or per-vertex colors. The renderer will take care of all the messy details of interpolating the texture image between projected vertex coordinates using projection and sampling algorithms. 237

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

gi.setContourCounts( countourCountArray ); gi.setStripCounts( stripCountArray ); Triangulator triangulator

Filed under: Java 3D Programming — webmaster @ 12:26 pm

gi.setContourCounts( countourCountArray ); gi.setStripCounts( stripCountArray ); Triangulator triangulator = new Triangulator(); triangulator.triangulate( gi ); //Generate normal vectors for the triangles, not strictly necessary //as we are not lighting the scene, but generally useful. NormalGenerator normalGenerator = new NormalGenerator(); normalGenerator.generateNormals( gi ); //wrap the GeometryArray in a Shape3D and assign appearance return new Shape3D( gi.getGeometryArray(), app ); } /* * Handle the nitty-gritty details of loading the input file * and reading (in order): * - texture file image name * - size of the geometry in the X direction * - Y direction scale factor * - number of texture coordinates * - each texture coordinate (X Y) * This could all be easily accomplished using a scenegraph loader, * but this simple code is included for reference. */ protected TextureGeometryInfo createTextureCoordinates( String szFile ) { //create a simple wrapper class to package our return values TextureGeometryInfo texInfo = new TextureGeometryInfo(); //allocate a temporary buffer to store the input file StringBuffer szBufferData = new StringBuffer(); float sizeGeometryX = 0; float factorY = 1; int nNumPoints = 0; Point2f boundsPoint = new Point2f(); try { //attach a reader to the input file FileReader fileIn = new FileReader( szFile ); int nChar = 0; //read the entire file into the StringBuffer while( true ) { nChar = fileIn.read(); //if we have not hit the end of file //add the character to the StringBuffer if( nChar != -1 ) szBufferData.append( (char) nChar ); else //hit EOF break; } //create a tokenizer to tokenize the input file at whitespace 236

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Tomcat Web Hosting services

assign to an Appearance. //load the texture image

Filed under: Java 3D Programming — webmaster @ 7:35 am

} //return a Shape3D that is a triangulated texture-mapped polygon //based on the texture coordinates and name of texture image in the //input file protected Shape3D createTextureGeometry( String szFile, boolean bWireframe ) { //load all the texture data from the file and //create the geometry coordinates TextureGeometryInfo texInfo = createTextureCoordinates( szFile ); if( texInfo == null ) { System.err.println( “Could not load texture info for file:” + szFile ); return null; } //print some stats on the loaded file System.out.println( “Loaded File: ” + szFile ); System.out.println( ” Texture image: ” + texInfo.m_szImage ); System.out.println( ” Texture coordinates: ” + texInfo.m_TexCoordArray.length ); //create an Appearance and assign a Material Appearance app = new Appearance(); PolygonAttributes polyAttribs = null; //create the PolygonAttributes and attach to the Appearance, //note that we use CULL_NONE so that the “rear” side //of the geometry is visible with the applied texture image if( bWireframe == false ) { polyAttribs = new PolygonAttributes( PolygonAttributes.POLYGON_FILL, PolygonAttributes.CULL_NONE, 0 ); } else { polyAttribs = new PolygonAttributes( PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0 ); } app.setPolygonAttributes( polyAttribs ); //load the texture image and assign to the appearance TextureLoader texLoader = new TextureLoader( texInfo.m_szImage, Texture.RGB, this ); Texture tex = texLoader.getTexture(); app.setTexture( tex ); //create a GeometryInfo for the QuadArray that was populated. GeometryInfo gi = new GeometryInfo( GeometryInfo.POLYGON_ARRAY ); gi.setCoordinates( texInfo.m_CoordArray ); gi.setTextureCoordinates( texInfo.m_TexCoordArray ); //use the triangulator utility to triangulate the polygon int[] stripCountArray = {texInfo.m_CoordArray.length}; int[] countourCountArray = {stripCountArray.length}; 235

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

assign to an Appearance. //load the texture image

Filed under: Java 3D Programming — webmaster @ 7:35 am

assign to an Appearance. //load the texture image and assign to the appearance TextureLoader texLoader = new TextureLoader( texInfo.m_szImage, Texture.RGB, this ); Texture tex = texLoader.getTexture(); app.setTexture( tex ); 4. Create a GeometryInfoobject to store the texture and vertex coordinates (POYGON_ARRAY). //create a GeometryInfo for the QuadArray that was populated. GeometryInfo gi = new GeometryInfo( GeometryInfo.POLYGON_ARRAY ); 5. Assign the texture and vertex coordinates to the GeometryInfoobject. //assign coordinates gi.setCoordinates( texInfo.m_CoordArray ); gi.setTextureCoordinates( texInfo.m_TexCoordArray ); 6. Triangulate the GeometryInfoobject. //use the triangulator utility to triangulate the polygon int[] stripCountArray = {texInfo.m_CoordArray.length}; int[] countourCountArray = {stripCountArray.length}; gi.setContourCounts( countourCountArray ); gi.setStripCounts( stripCountArray ); Triangulator triangulator = new Triangulator(); triangulator.triangulate( gi ); 7. Generate Normal vectors for the GeometryInfoobject. //generate normal vectors for the triangles, //not strictly necessary as we are not lighting the scene //but generally useful NormalGenerator normalGenerator = new NormalGenerator(); normalGenerator.generateNormals( gi ); 8. Create a Shape3Dobject based on the GeometryInfoobject. //wrap the GeometryArray in a Shape3D and assign appearance new Shape3D( gi.getGeometryArray(), app ); Please refer to TextureTest.java for the full example. The important methods are listed in full next. //create a TransformGroup, position it, and add the texture //geometry as a child node protected TransformGroup createTextureGroup( String szFile, double x, double y, double z, boolean bWireframe ) { TransformGroup tg = new TransformGroup(); Transform3D t3d = new Transform3D(); t3d.setTranslation( new Vector3d( x,y,z ) ); tg.setTransform( t3d ); Shape3D texShape = createTextureGeometry( szFile, bWireframe ); if( texShape != null ) tg.addChild( texShape ); return tg; 234

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

January 30, 2007

Figure 14.4 The TextureTest example loads an image

Filed under: Java 3D Programming — webmaster @ 11:30 pm

Figure 14.5 The TextureTest example in action. Four texture-mapped TriangleArrays have been created from two sets of texture coordinate data and images. The TriangleArrays are rotated using an Interpolator The texture coordinates are specified in IMPORTANT counterclockwise order. This is a requirement imposed by the com.sun.j3d.utils.geometry.Triangulator utility, which converts the polygon created from the texture coordinates into a TriangleArray. The createTextureGeometrymethod performs most of the work related to assigning texture coordinates to vertices. There are eight basic steps: 1. Read Texture coordinates from file. 2. Generate vertex coordinates based on scaling and translating texture coordinates. 3. Load the texture image using the com.sun.j3d.utils.image.TextureLoaderclass and 233

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

Figure 14.4 The TextureTest example loads an image

Filed under: Java 3D Programming — webmaster @ 11:30 pm

Figure 14.4 The TextureTest example loads an image and a list of texture coordinates and displays a portion of the image in a 3D scene by texture mapping it onto a TriangleArray The x, y columns are the pixel locations in the image that are returned by a bitmap editor. The origin for these 2D coordinates is at the top-left of the image. The x’ and y’ coordinates compensate for this by flipping the y coordinate (y’ = height y). The texture coordinates tx and ty are suitable for Java 3D (tx = x’/width and ty = y’/height). It is very easy to perform the coordinate conversions using a spreadsheet. The ASCII file is therefore: daniel.gif (name of the image file) 5 (size in the x direction) 1.0 (y scale factor) 13 (number of texture coordinates) 0.40 0.75 (texture coordinate 1, x y) 0.31 0.69 0.28 0.59 0.26 0.39 0.30 0.24 0.45 0.09 0.55 0.09 0.66 0.16 0.72 0.28 0.74 0.49 0.70 0.67 0.63 0.74 0.52 0.76 (texture coordinate 13, x y) The Microsoft Excel spread sheet file daniel coords.xls with the TextureTestexample contains the formulae necessary for the coordinate transformation (figure 14.5). 232

Note: If you are looking for good and high quality web space to host and run your application check Lunarwebhost Java Web Hosting services

Next Page »

Powered by Java Web Hosting