`
ilovezhurong
  • 浏览: 43269 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

jme学习笔记例13---创建地形

阅读更多

 本程序介绍JME的的地形实用工具类。您将学习如何使用ProceduralTextureGenerator,ImageBasedHeightMap,MidPointHeightMap和TerrainBlock对象。
这一切都将允许看毫不费力地创建地形。

 

import com.jme.app.SimpleGame;
import com.jme.terrain.TerrainBlock;
import com.jme.terrain.util.MidPointHeightMap;
import com.jme.terrain.util.ImageBasedHeightMap;
import com.jme.terrain.util.ProceduralTextureGenerator;
import com.jme.math.Vector3f;
import com.jme.bounding.BoundingBox;
import com.jme.scene.state.TextureState;
import com.jme.util.TextureManager;
import com.jme.image.Texture;
import java.net.URL;
import javax.swing.*;
/**
* Started Date: Aug 19, 2004<br><br>
*
* This program introduces jME's terrain utility classes and how
* they are used. It
* goes over ProceduralTextureGenerator,
* ImageBasedHeightMap, MidPointHeightMap, and
* TerrainBlock.
*
* @author Jack Lindamood
*/
public class HelloTerrain extends SimpleGame {
public static void main(String[] args) {
HelloTerrain app = new HelloTerrain();
app.setDialogBehaviour(SimpleGame.ALWAYS_SHOW_PROPS_DIALOG);
app.start();
}
protected void simpleInitGame() {
// First a hand made terrain
homeGrownHeightMap();
// Next an automatically generated terrain with a texture
generatedHeightMap();
// Finally a terrain loaded from a greyscale image with
// fancy textures on it.
complexTerrain();
}
private void homeGrownHeightMap() {
// The map for our terrain. Each value is a height on the terrain
int[] map=new int[]{
1,2,3,4,
89
2,1,2,3,
3,2,1,2,
4,3,2,1
};
// Create a terrain block. Our integer height values will
// scale on the map 2x larger x,
// and 2x larger z. Our map's origin will be the regular
// origin, and it won't create an
// AreaClodMesh from it.
TerrainBlock tb=new TerrainBlock("block",4,
new Vector3f(2,1,2),
map,
new Vector3f(0,0,0),
false);
// Give the terrain a bounding box.
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// Attach the terrain TriMesh to our rootNode
rootNode.attachChild(tb);
}
private void generatedHeightMap() {
// This will be the texture for the terrain.
URL grass=HelloTerrain.class.getClassLoader().getResource(
"jmetest/data/texture/grassb.png");
// Use the helper class to create a terrain for us. The
// terrain will be 64x64
MidPointHeightMap mph=new MidPointHeightMap(64,1.5f);
// Create a terrain block from the created terrain map.
TerrainBlock tb=new TerrainBlock("midpoint block",mph.getSize(),
new Vector3f(1,.11f,1),
mph.getHeightMap(),
new Vector3f(0,-25,0),false);
// Add the texture
TextureState ts=display.getRenderer().createTextureState();
ts.setTexture(
TextureManager.loadTexture(grass,
Texture.MM_LINEAR,Texture.FM_LINEAR,true)
);
tb.setRenderState(ts);
// Give the terrain a bounding box.
tb.setModelBound(new BoundingBox());
tb.updateModelBound();
// Attach the terrain TriMesh to rootNode
rootNode.attachChild(tb);
}
private void complexTerrain() {

// This grayscale image will be our terrain
URL grayscale = HelloTerrain.
class.getClassLoader(). getResource("jmetest/data/texture/bubble.jpg");
// These will be the textures of our terrain.
URL waterImage=HelloTerrain.
class.getClassLoader().
getResource("jmetest/data/texture/water.png");
URL dirtImage=HelloTerrain.
class.getClassLoader().
getResource("jmetest/data/texture/dirt.jpg");
URL highest=HelloTerrain.
class.getClassLoader(). getResource("jmetest/data/texture/highest.jpg");
// Create an image height map based on the gray scale of our image.
ImageBasedHeightMap ib=new ImageBasedHeightMap( new ImageIcon(grayScale).getImage()
);
// Create a terrain block from the image's grey scale
TerrainBlock tb=new TerrainBlock("image icon",ib.getSize(),
new Vector3f(.5f,.05f,.5f),ib.getHeightMap(), new Vector3f(0,0,0),false); // Create an object to generate textured terrain from the
// image based height map.
ProceduralTextureGenerator pg=new ProceduralTextureGenerator(ib);
// Look like water from height 0-60 with the strongest
// "water look" at 30
pg.addTexture(new ImageIcon(waterImage),0,30,60);
// Look like dirt from height 40-120 with the strongest
// "dirt look" at 80
pg.addTexture(new ImageIcon(dirtImage),40,80,120); // Look like highest (pure white) from height 110-256
// with the strongest "white look" at 130 pg.addTexture(new ImageIcon(highest),110,130,256);
// Tell pg to create a texture from the ImageIcon's it has recieved.
pg.createTexture(256);
TextureState ts=display.getRenderer().createTextureState();
// Load the texture and assign it.
ts.setTexture(
TextureManager.loadTexture(
pg.getImageIcon().getImage(),
Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR,
true, true )
); tb.setRenderState(ts);
// Give the terrain a bounding box tb.setModelBound(new BoundingBox());

tb.updateModelBound();
// Move the terrain in front of the camera
tb.setLocalTranslation(new Vector3f(0,0,-50));
// Attach the terrain to our rootNode. rootNode.attachChild(tb); } }

这个程序演示了jme的地形如何工作,所有的地形来自基类
TerrainBlock。这个类也是一个TriMesh,此类用一个整数
数组创建地形,这个程序创建了3个不同类型的地形,
第一个始手工的,第2个使用工具创建,第3个是从某地形文件创建,我们开始第一个先
// The map for our terrain. Each value is a height on the terrain
int[] map=new int[]{
1,2,3,4,
2,1,2,3,
3,2,1,2,
4,3,2,1
};
// Create a terrain block. Our integer height values will
// scale on the map 2x larger x,
// and 2x larger z. Our map's origin will be the regular
// origin, and it won't create an
// AreaClodMesh from it.
TerrainBlock tb=new TerrainBlock("block",4,
new Vector3f(2,1,2),
map,
new Vector3f(0,0,0),
false);

这个地图数组就是整数值,每个整数代表一个高度
这地形是一个正方形,如果你用map数组创建每个高度
他看起来就是这样的,这就是在terrainblock如何生成的
TerrainBlock第一个参数是地形块的名字(每个spatial对象必须有名字),接着块的尺寸是4*4.3rd是地形的scale值,我们定义了地形的整数值但如果我们要浮点的高度,
scale值把地形沿x和z轴拉长了两倍。通过这个值可以控制
地形的大小,最后两个参数是地形的原点(0,0,00
如果我们要用areaclodmesh创建地形,地形将占用更大的内存可是会有更快的刷新率
   下面,看这个地形的生成
// Use the helper class to create a terrain for us. The
// terrain will be 64x64
MidPointHeightMap mph=new MidPointHeightMap(64,1.5f);
// Create a terrain block from the created terrain map.
TerrainBlock tb=new TerrainBlock("midpoint block",mph.getSize(),
new Vector3f(1,.11f,1),
mph.getHeightMap(),
new Vector3f(0,-25,0),false);
这里我们使用midpointheightmap去生成一个地形,
地形是64*64的,我们给他的粗糙度是1.5,这个值让
地形变得平滑,你可以把它设成你期望的效果,
terrainblock对象从midpointheightmap中读取地形大小。
 
 最后我们创建一个灰色图片的地形。

你要注意地形图片的明暗度,imagebasedheightmap创建的地形从高到低由亮到暗,
// Create an image height map based on the gray scale of our image.
ImageBasedHeightMap ib=new ImageBasedHeightMap(
new ImageIcon(grayScale).getImage() );

我必须传递imagebasedheightmap一个图片对象,为此
我创建imageicon获取url资源的图片,在height map和
terrainblock创建之后,下一步是创建strange地形,
首先,看这三个地形
第一个是water,第2个是dirt最后一个是highest.jpg
注意highest.jpg是相似白,现在另一个要关注的是复杂
地形的尺寸
// Create an object to generate textured terrain from the
// image based height map.
ProceduralTextureGenerator pg=new ProceduralTextureGenerator(ib);
// Look like water from height 0-60 with the strongest
// "water look" at 30
pg.addTexture(new ImageIcon(waterImage),0,30,60);
// Look like dirt from height 40-120 with the strongest
// "dirt look" at 80
pg.addTexture(new ImageIcon(dirtImage),40,80,120);
// Look like highest (pure white) from height 110-256
// with the strongest "white look" at 130
pg.addTexture(new ImageIcon(highest),110,130,256);

当我创建pd时传递它一个height map(实际height map
对象不是int[]数组),它使用height map创建纹理
下面我传递3个图片给地形的3个部分,让我们看其中一个
另外两个是同样的道理
// Look like water from height 0-60 with the strongest
// "water look" at 30
pg.addTexture(new ImageIcon(waterImage),0,30,60);

这个方法调用pg从高0-60存放water图片,water图片融合
0-30之间,这个融合的最大强度是30,同样处理其他两个纹理,通知pg需要创建纹理
// Tell pg to create a texture from the ImageIcon's it has recieved.
pg.createTexture(256);

你将注意当我创建纹理对象需要使用texturestate,
我从pg获得texture
TextureState ts=display.getRenderer().createTextureState();
// Load the texture and assign it.
ts.setTexture(
TextureManager.loadTexture(
pg.getImageIcon().getImage(),
Texture.MM_LINEAR_LINEAR,
Texture.FM_LINEAR,
true,
true
)
);
全部的工作完成了,一个terrain类创建地形并把它拆分到
不同的约束盒所以你看不到地形被包裹
 
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics