📄 landscape.java
字号:
shape.setAppearance(app);
}
} // end of addLandTexture()
private Texture2D loadLandTexture(String fname)
// load texture for colouring the landscape
{
String fn = new String("models/" + fname + ".jpg");
TextureLoader texLoader = new TextureLoader(fn, null);
Texture2D tex = (Texture2D) texLoader.getTexture();
if (tex == null)
System.out.println("Cannot load land texture from " + fn);
else {
System.out.println("Loaded land texture from " + fn);
tex.setMagFilter(Texture.BASE_LEVEL_LINEAR);
tex.setEnable(true);
}
return tex;
} // end of loadLandTexture()
private TexCoordGeneration stampTexCoords(Shape3D shape)
/* Adjust the genration planes so that the texture is
'stetched' over the entire mesh.
The mesh has equal X- and Y- axis sides of landLength,
and the mesh's lower left-hand corner starts at (0,0), so the
stretching is quite simple.
*/
{ /* Adjust the generation planes so the mesh's XY plane is mapped
to texture coordinates [0,0] and [1,1].
*/
Vector4f planeS =
new Vector4f( (float)(1.0/landLength), 0.0f, 0.0f, 0.0f);
Vector4f planeT =
new Vector4f( 0.0f, (float)(1.0/landLength), 0.0f, 0.0f);
// generate new texture coordinates for GeometryArray
TexCoordGeneration texGen = new TexCoordGeneration();
texGen.setPlaneS(planeS);
texGen.setPlaneT(planeT);
return texGen;
} // end of stampTexCoords()
// --------------------- load scenery -------------------
private void makeScenery(BranchGroup landBG, String fname)
/* The scenery file (models/fname.txt) has the format:
start x y z
<object file> x y z scale
<object file> x y z scale
:
The start line must be included -- it says where the user
is placed in the landscape.
The scenery objects are optional.
Each scenery object is loaded with a PropManager object; we assume
the existence of "coords" data files for the models.
The (x,y,z) values are in landscape coordinates, and scale
makes the model the 'right' size for the landscape.
*/
{
boolean startSet = false;
String sceneryFile = new String("models/" + fname + ".txt");
System.out.println("Loading scenery file: " + sceneryFile);
try {
BufferedReader br = new BufferedReader( new FileReader(sceneryFile) );
String line, token, modelFnm;
StringTokenizer tokens;
double xCoord, yCoord, zCoord, scale;
PropManager propMan;
while((line = br.readLine()) != null) {
// System.out.println(line);
tokens = new StringTokenizer(line);
modelFnm = tokens.nextToken(); // may be a filename or 'start'
xCoord = Double.parseDouble( tokens.nextToken() );
yCoord = Double.parseDouble( tokens.nextToken() );
zCoord = Double.parseDouble( tokens.nextToken() );
if (!modelFnm.equals("start"))
scale = Double.parseDouble( tokens.nextToken() );
else
scale = 0.0; // no scale for the start line
System.out.println("\nAdding: " + modelFnm + " (" + xCoord +
", " + yCoord + ", " + zCoord + "), scale: " + scale);
if (modelFnm.equals("start")) { // user's starting point
originVec = landToWorld(xCoord, yCoord, zCoord); // in world coords
startSet = true;
}
else {
propMan = new PropManager(modelFnm, true); // load scenery
placeScenery( landBG, propMan.getTG(), xCoord, yCoord, zCoord, scale );
}
}
br.close();
System.out.println();
if (!startSet) {
System.out.println("No starting position specified");
System.exit(0); // give up if no starting position
}
}
catch (Exception e)
{ System.out.println(e);
System.exit(0);
}
} // end of makeScenery()
private Vector3d landToWorld(double xCoord, double yCoord, double zCoord)
/* Converting land to world coordinates involves scaling,
translation, and rotation. The rotation is achieved by switching
the y- and z- values.
*/
{
double x = (xCoord * scaleLen) - LAND_LEN/2;
double y = zCoord * scaleLen; // z-axis --> y-axis
double z = (-yCoord * scaleLen) + LAND_LEN/2; // y-axis --> z-axis
return new Vector3d(x, y, z);
} // end of landToWorld()
private void placeScenery(BranchGroup landBG, TransformGroup modelTG,
double x, double y, double z, double scale)
/* Add a scenery object to landBG using landscape coords.
The object is translated, then rotated and scaled.
*/
{
modelTG.setPickable(false); // so not pickable in scene
Transform3D t3d = new Transform3D();
t3d.rotX( Math.PI/2.0 ); // to counter the -ve rotation of land
// since using XY as floor
t3d.setScale( new Vector3d(scale, scale, scale) ); // scaled
TransformGroup scaleTG = new TransformGroup(t3d);
scaleTG.addChild( modelTG );
Transform3D t3d1 = new Transform3D();
t3d1.set( new Vector3d(x,y,z)); // translated
TransformGroup posTG = new TransformGroup(t3d1);
posTG.addChild( scaleTG );
landBG.addChild( posTG );
} // end of placeScenery()
private void addWalls()
/* Add 4 textured walls around the landscape.
Each wall is a TexturedPlane object, which are placed using world
coordinates, and so linked to sceneBG, not landBG.
The texture is hardwired to be WALL_PIC.
*/
{ // heights used for the walls, in world coords
double minH = minHeight * scaleLen;
double maxH = maxHeight * scaleLen;
// the eight corner points
// back, left
Point3d p1 = new Point3d(-LAND_LEN/2.0f, minH, -LAND_LEN/2.0f);
Point3d p2 = new Point3d(-LAND_LEN/2.0f, maxH, -LAND_LEN/2.0f);
// front, left
Point3d p3 = new Point3d(-LAND_LEN/2.0f, minH, LAND_LEN/2.0f);
Point3d p4 = new Point3d(-LAND_LEN/2.0f, maxH, LAND_LEN/2.0f);
// front, right
Point3d p5 = new Point3d(LAND_LEN/2.0f, minH, LAND_LEN/2.0f);
Point3d p6 = new Point3d(LAND_LEN/2.0f, maxH, LAND_LEN/2.0f);
// back, right
Point3d p7 = new Point3d(LAND_LEN/2.0f, minH, -LAND_LEN/2.0f);
Point3d p8 = new Point3d(LAND_LEN/2.0f, maxH, -LAND_LEN/2.0f);
// load and set the texture; set mag filter since the image is enlarged
TextureLoader loader = new TextureLoader(WALL_PIC, null);
Texture2D texture = (Texture2D) loader.getTexture();
if (texture == null)
System.out.println("Cannot load wall image from " + WALL_PIC);
else {
System.out.println("Loaded wall image: " + WALL_PIC);
texture.setMagFilter(Texture2D.BASE_LEVEL_LINEAR);
}
// left wall; counter-clockwise
sceneBG.addChild( new TexturedPlane(p3, p1, p2, p4, texture));
// front wall; counter-clockwise from back
sceneBG.addChild( new TexturedPlane(p5, p3, p4, p6, texture));
// right wall
sceneBG.addChild( new TexturedPlane(p7, p5, p6, p8, texture));
// back wall
sceneBG.addChild( new TexturedPlane(p1, p7, p8, p2, texture));
} // end of addWalls()
// ------------- public methods ------------------
public Vector3d getOriginVec()
// used by KeyBehavior
{ return originVec; }
public BranchGroup getLandBG()
// used by HeightFinder
{ return landBG; }
public double getScaleLen()
// used by HeightFinder
{ return scaleLen; }
public boolean inLandscape(double x, double z)
// is world (x,z) in the landscape? Used by KeyBehavior
{
Vector3d landVec = worldToLand( new Vector3d(x, 0, z));
if ((landVec.x <= 0) || (landVec.x >= landLength) ||
(landVec.y <= 0) || (landVec.y >= landLength))
return false;
return true;
} // end of inLandscape()
public Vector3d worldToLand(Vector3d worldVec)
/* Used by KeyBehavior
Converting world to land coordinates involves translation, scaling,
and rotation. The rotation is achieved by switching
the y- and z- values. */
{
double xCoord = (worldVec.x + LAND_LEN/2) / scaleLen;
double yCoord = (-worldVec.z + LAND_LEN/2) / scaleLen; // z-axis --> y-axis
double zCoord = worldVec.y / scaleLen; // y-axis --> z-axis
return new Vector3d(xCoord, yCoord, zCoord);
} // end of worldToLand()
} // end of Landscape class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -