Hello everyone.
I hate having to post questions :) but I have spent
enough time trying to solve this problem myself to mitigate my guilty feelings
asking for help.
I am building a large outdoor terrain for use in a
RPG game. I have looked carefully at everquest and asheron's call (two VR
rpg's) to see how they are doing landscapes and have observed they are doing
them quite differently from each other. Anyway, I have built a HeightMap
class that can load some terrain formats. There are several methods in my
class which can return geometries. For the purpose of this dicusssion I am
using one which returns a triangle mesh. The heightmap is 100x100,
yielding 20,000 triangles and some 9k verticies. I am mapping 15 units (15
meters?) per X,Z coord which should create a triangle mesh 1,500 meters wide by
1,500 meters deep. During triangle generation you can specify the unit
size and the max height of the terrain. I am using GeometryInfo.
Then I normalize it and stripify it (using the Java3d geometry
classes).
When I render this as lines, the mesh looks
perfect. The problem begins when I start mapping a texture. I have a
texture that is tileable and what I want to do is map this onto my
terrain. The end result I am looking for would be the equivelent of taking
a sheet (that is covered all over with the tiled texture) and draping it over my
terrain. In other words, I do not want distortion of my
texture.
I am using TexCoordGeneration and that is probably
where my problem is. Here is what I am observing. My texture is
indeed tiled across the terrain, but in a weird fashion. It seems to be
"ringed" around the contours. This means that as I walk over the terrain
it appears that there are bands of circles around hills and valleys. When
I look closely what I see is the textures are being mapped radially to high and
low points, kind as if you took the texture, stretched it like bubble gum, fixed
one end in the bottom of the valley and then rotated it about that point. (I
will attach a picture of this).
So is there a way to solve this problem? A
way to generate the texture coordinates automatically so that the texture is
tiled and draped over the landscape without distortion? I did try
decreasing my crease angle during normal generation so that all triangles would
not be smoothed, but that did not help.
BTW: The performance rendering a few with
20,000 triangles (many culled im sure) is quite good. I can move over this
terrain very fast.
Thanks in advance,
Dave Yazel
Here is the relevant code:
public Shape3D getTerrain( String
textureName ) {
Shape3D
shape;
// set up the rendering attributes
RenderingAttributes ra = new RenderingAttributes();
ra.setDepthBufferEnable(true);
ra.setIgnoreVertexColors(true);
// set the polygon attributes
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
pa.setPolygonMode(pa.POLYGON_FILL);
// create the texture for the terrain
Texture tex =
TextureFactory.tf.getWrappableTexture("tex18.jpg");
// create the texture attributes
// create the texture attributes
TextureAttributes ta
= new TextureAttributes();
ta.setTextureMode(ta.MODULATE);
Transform3D trans = new Transform3D( );
trans.setScale( 5.0 );
ta.setTextureTransform( trans );
// Setup the automatic texture coordinate generation
ta.setTextureMode(ta.MODULATE);
Transform3D trans = new Transform3D( );
trans.setScale( 5.0 );
ta.setTextureTransform( trans );
// Setup the automatic texture coordinate generation
Vector4f planeS =
new Vector4f(1,0,0,0);
Vector4f planeT = new Vector4f(0,1,0,0);
TexCoordGeneration texCoord = new TexCoordGeneration(
texCoord.TEXTURE_COORDINATE_2, texCoord.OBJECT_LINEAR, planeS, planeT);
// Create line attributes for when we want to show the terrain as lines
Vector4f planeT = new Vector4f(0,1,0,0);
TexCoordGeneration texCoord = new TexCoordGeneration(
texCoord.TEXTURE_COORDINATE_2, texCoord.OBJECT_LINEAR, planeS, planeT);
// Create line attributes for when we want to show the terrain as lines
LineAttributes la =
new LineAttributes();
la.setLineWidth(1);
la.setLinePattern(la.PATTERN_SOLID);
// create the material
la.setLineWidth(1);
la.setLinePattern(la.PATTERN_SOLID);
// create the material
Material material =
new Material();
material.setLightingEnable(true);
// material.setShininess(10.0);
material.setEmissiveColor(5,5,5);
Appearance a = new Appearance();
a.setRenderingAttributes(ra);
a.setPolygonAttributes(pa);
a.setTexture(tex);
a.setTextureAttributes(ta);
a.setMaterial(material);
a.setTexCoordGeneration(texCoord);
GeometryArray geometry = info.getIndexedGeometryArray(true);
int vc = geometry.getVertexCount();
Log.log.println(LogType.EXHAUSTIVE,"There are "+vc+" verticies in the terrain");
// set up
shape = new Shape3D(geometry,a);
return shape;
material.setLightingEnable(true);
// material.setShininess(10.0);
material.setEmissiveColor(5,5,5);
Appearance a = new Appearance();
a.setRenderingAttributes(ra);
a.setPolygonAttributes(pa);
a.setTexture(tex);
a.setTextureAttributes(ta);
a.setMaterial(material);
a.setTexCoordGeneration(texCoord);
GeometryArray geometry = info.getIndexedGeometryArray(true);
int vc = geometry.getVertexCount();
Log.log.println(LogType.EXHAUSTIVE,"There are "+vc+" verticies in the terrain");
// set up
shape = new Shape3D(geometry,a);
return shape;
}
And here is a pic:
