📄 terrainblock.java
字号:
focalSpot + size + 1);
// Use linear interpolation to find the height.
topLeft.interpolate(topRight, intOnX);
bottomLeft.interpolate(bottomRight, intOnX);
topLeft.interpolate(bottomLeft, intOnZ);
return topLeft.normalizeLocal();
}
/**
* <code>buildVertices</code> sets up the vertex and index arrays of the
* TriMesh.
*/
private void buildVertices() {
setVertexCount(heightMap.length);
setVertexBuffer(BufferUtils.createVector3Buffer(getVertexBuffer(),
getVertexCount()));
Vector3f point = new Vector3f();
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
point.set(x * stepScale.x, heightMap[x + (y * size)]
* stepScale.y, y * stepScale.z);
BufferUtils.setInBuffer(point, getVertexBuffer(),
(x + (y * size)));
}
}
// set up the indices
setTriangleQuantity(((size - 1) * (size - 1)) * 2);
setIndexBuffer(BufferUtils.createIntBuffer(getTriangleCount() * 3));
// go through entire array up to the second to last column.
for (int i = 0; i < (size * (size - 1)); i++) {
// we want to skip the top row.
if (i % ((size * (i / size + 1)) - 1) == 0 && i != 0) {
continue;
}
// set the top left corner.
getIndexBuffer().put(i);
// set the bottom right corner.
getIndexBuffer().put((1 + size) + i);
// set the top right corner.
getIndexBuffer().put(1 + i);
// set the top left corner
getIndexBuffer().put(i);
// set the bottom left corner
getIndexBuffer().put(size + i);
// set the bottom right corner
getIndexBuffer().put((1 + size) + i);
}
}
/**
* <code>buildTextureCoordinates</code> calculates the texture coordinates
* of the terrain.
*/
public void buildTextureCoordinates() {
float offsetX = offset.x + (offsetAmount * stepScale.x);
float offsetY = offset.y + (offsetAmount * stepScale.z);
setTextureCoords(new TexCoords(BufferUtils.createVector2Buffer(getVertexCount())));
FloatBuffer texs = getTextureCoords(0).coords;
texs.clear();
getVertexBuffer().rewind();
for (int i = 0; i < getVertexCount(); i++) {
texs.put((getVertexBuffer().get() + offsetX)
/ (stepScale.x * (totalSize - 1)));
getVertexBuffer().get(); // ignore vert y coord.
texs.put((getVertexBuffer().get() + offsetY)
/ (stepScale.z * (totalSize - 1)));
}
}
/**
* <code>buildNormals</code> calculates the normals of each vertex that
* makes up the block of terrain.
*/
private void buildNormals() {
setNormalBuffer(BufferUtils.createVector3Buffer(getNormalBuffer(),
getVertexCount()));
Vector3f oppositePoint = new Vector3f();
Vector3f adjacentPoint = new Vector3f();
Vector3f rootPoint = new Vector3f();
Vector3f tempNorm = new Vector3f();
int adj = 0, opp = 0, normalIndex = 0;
for (int row = 0; row < size; row++) {
for (int col = 0; col < size; col++) {
BufferUtils.populateFromBuffer(rootPoint, getVertexBuffer(),
normalIndex);
if (row == size - 1) {
if (col == size - 1) { // last row, last col
// up cross left
adj = normalIndex - size;
opp = normalIndex - 1;
} else { // last row, except for last col
// right cross up
adj = normalIndex + 1;
opp = normalIndex - size;
}
} else {
if (col == size - 1) { // last column except for last row
// left cross down
adj = normalIndex - 1;
opp = normalIndex + size;
} else { // most cases
// down cross right
adj = normalIndex + size;
opp = normalIndex + 1;
}
}
BufferUtils.populateFromBuffer(adjacentPoint,
getVertexBuffer(), adj);
BufferUtils.populateFromBuffer(oppositePoint,
getVertexBuffer(), opp);
tempNorm.set(adjacentPoint).subtractLocal(rootPoint)
.crossLocal(oppositePoint.subtractLocal(rootPoint))
.normalizeLocal();
BufferUtils.setInBuffer(tempNorm, getNormalBuffer(),
normalIndex);
normalIndex++;
}
}
}
/**
* Returns the height map this terrain block is using.
*
* @return This terrain block's height map.
*/
public float[] getHeightMap() {
return heightMap;
}
/**
* Returns the offset amount this terrain block uses for textures.
*
* @return The current offset amount.
*/
public float getOffsetAmount() {
return offsetAmount;
}
/**
* Returns the step scale that stretches the height map.
*
* @return The current step scale.
*/
public Vector3f getStepScale() {
return stepScale;
}
/**
* Returns the total size of the terrain.
*
* @return The terrain's total size.
*/
public int getTotalSize() {
return totalSize;
}
/**
* Returns the size of this terrain block.
*
* @return The current block size.
*/
public int getSize() {
return size;
}
/**
* Returns the current offset amount. This is used when building texture
* coordinates.
*
* @return The current offset amount.
*/
public Vector2f getOffset() {
return offset;
}
/**
* Sets the value for the current offset amount to use when building texture
* coordinates. Note that this does <b>NOT </b> rebuild the terrain at all.
* This is mostly used for outside constructors of terrain blocks.
*
* @param offset
* The new texture offset.
*/
public void setOffset(Vector2f offset) {
this.offset = offset;
}
/**
* Sets the size of this terrain block. Note that this does <b>NOT </b>
* rebuild the terrain at all. This is mostly used for outside constructors
* of terrain blocks.
*
* @param size
* The new size.
*/
public void setSize(int size) {
this.size = size;
}
/**
* Sets the total size of the terrain . Note that this does <b>NOT </b>
* rebuild the terrain at all. This is mostly used for outside constructors
* of terrain blocks.
*
* @param totalSize
* The new total size.
*/
public void setTotalSize(int totalSize) {
this.totalSize = totalSize;
}
/**
* Sets the step scale of this terrain block's height map. Note that this
* does <b>NOT </b> rebuild the terrain at all. This is mostly used for
* outside constructors of terrain blocks.
*
* @param stepScale
* The new step scale.
*/
public void setStepScale(Vector3f stepScale) {
this.stepScale = stepScale;
}
/**
* Sets the offset of this terrain texture map. Note that this does <b>NOT
* </b> rebuild the terrain at all. This is mostly used for outside
* constructors of terrain blocks.
*
* @param offsetAmount
* The new texture offset.
*/
public void setOffsetAmount(float offsetAmount) {
this.offsetAmount = offsetAmount;
}
/**
* Sets the terrain's height map. Note that this does <b>NOT </b> rebuild
* the terrain at all. This is mostly used for outside constructors of
* terrain blocks.
*
* @param heightMap
* The new height map.
*/
public void setHeightMap(float[] heightMap) {
this.heightMap = heightMap;
}
/**
* Updates the block's vertices and normals from the current height map
* values.
*/
public void updateFromHeightMap() {
if (!hasChanged())
return;
Vector3f point = new Vector3f();
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
point.set(x * stepScale.x, heightMap[x + (y * size)]
* stepScale.y, y * stepScale.z);
BufferUtils.setInBuffer(point, getVertexBuffer(),
(x + (y * size)));
}
}
buildNormals();
if (getVBOInfo() != null) {
getVBOInfo().setVBOVertexID(-1);
getVBOInfo().setVBONormalID(-1);
DisplaySystem.getDisplaySystem().getRenderer().deleteVBO(
getVertexBuffer());
DisplaySystem.getDisplaySystem().getRenderer().deleteVBO(
getNormalBuffer());
}
}
/**
* <code>setHeightMapValue</code> sets the value of this block's height
* map at the given coords
*
* @param x
* @param y
* @param newVal
*/
public void setHeightMapValue(int x, int y, float newVal) {
heightMap[x + (y * size)] = newVal;
}
/**
* <code>setHeightMapValue</code> adds to the value of this block's height
* map at the given coords
*
* @param x
* @param y
* @param toAdd
*/
public void addHeightMapValue(int x, int y, float toAdd) {
heightMap[x + (y * size)] += toAdd;
}
/**
* <code>setHeightMapValue</code> multiplies the value of this block's
* height map at the given coords by the value given.
*
* @param x
* @param y
* @param toMult
*/
public void multHeightMapValue(int x, int y, float toMult) {
heightMap[x + (y * size)] *= toMult;
}
public boolean hasChanged() {
boolean update = false;
if (oldHeightMap == null) {
oldHeightMap = new float[heightMap.length];
update = true;
}
for (int x = 0; x < oldHeightMap.length; x++)
if (oldHeightMap[x] != heightMap[x] || update) {
update = true;
oldHeightMap[x] = heightMap[x];
}
return update;
}
/**
* @return Returns the quadrant.
*/
public short getQuadrant() {
return quadrant;
}
/**
* @param quadrant
* The quadrant to set.
*/
public void setQuadrant(short quadrant) {
this.quadrant = quadrant;
}
public void write(JMEExporter e) throws IOException {
super.write(e);
OutputCapsule capsule = e.getCapsule(this);
capsule.write(size, "size", 0);
capsule.write(totalSize, "totalSize", 0);
capsule.write(quadrant, "quadrant", (short) 1);
capsule.write(stepScale, "stepScale", Vector3f.ZERO);
capsule.write(offset, "offset", new Vector2f());
capsule.write(offsetAmount, "offsetAmount", 0);
capsule.write(heightMap, "heightMap", null);
capsule.write(oldHeightMap, "oldHeightMap", null);
}
public void read(JMEImporter e) throws IOException {
super.read(e);
InputCapsule capsule = e.getCapsule(this);
size = capsule.readInt("size", 0);
totalSize = capsule.readInt("totalSize", 0);
quadrant = capsule.readShort("quadrant", (short) 1);
stepScale = (Vector3f) capsule.readSavable("stepScale", Vector3f.ZERO
.clone());
offset = (Vector2f) capsule.readSavable("offset", new Vector2f());
offsetAmount = capsule.readFloat("offsetAmount", 0);
heightMap = capsule.readFloatArray("heightMap", null);
oldHeightMap = capsule.readFloatArray("oldHeightMap", null);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -