Package edu.ups.gamedev.terrain

Source Code of edu.ups.gamedev.terrain.MaterialTerrainBlock

/*
* License goes here.
* GPL?
*/

package edu.ups.gamedev.terrain;

import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.VBOInfo;
import com.jme.scene.batch.TriangleBatch;
import com.jme.util.geom.BufferUtils;
import com.jmex.terrain.TerrainBlock;
import java.nio.FloatBuffer;
import java.util.Random;

/**
*
* @author scanfield
*/
public class MaterialTerrainBlock extends TerrainBlock {

  public MaterialMap materialMap;

  public MaterialTerrainBlock(String name, int size, Vector3f stepScale,
      int[] heightMap, Vector3f origin, boolean clod, int totalSize,
      Vector2f offset, float offsetAmount, MaterialMap matMap) {
    setUseClod(clod);
    setSize(size);
    setStepScale(stepScale);
    setTotalSize(totalSize);
    setOffsetAmount(offsetAmount);
    setOffset(offset);
    setHeightMap(heightMap);
    this.materialMap = matMap;

    setLocalTranslation(origin);

    buildVertices();
    buildTextureCoordinates();
    buildNormals();
    TriangleBatch batch = getBatch(0);

    VBOInfo vbo = new VBOInfo(true);
    batch.setVBOInfo(vbo);

    if (isUseClod()) {
      this.create(null);
      this.setTrisPerPixel(0.02f);
    }
  }

  int draw;
  public MaterialTerrainBlock(String name, int getSize,
      Vector3f getStepScale, int[] getHeightMap, Vector3f origin,
      boolean clod, MaterialMap matMap) {
    super(name, getSize, getStepScale, getHeightMap, origin, clod);
    this.materialMap = matMap;
  }

  public MaterialTerrainBlock(String name) {
    super(name);
  }

  public MaterialTerrainBlock() {
    super();
  }

  private int TILE_SIZE = 32;
   
  @Override
  public void buildTextureCoordinates() {
    float offsetX = getOffset().x + (getOffsetAmount() * getStepScale().x);
    float offsetY = getOffset().y + (getOffsetAmount() * getStepScale().z);
    TriangleBatch batch = getBatch(0);

    FloatBuffer texs = BufferUtils.createVector2Buffer(batch
        .getTextureBuffers().get(0), batch.getVertexCount());
    batch.getTextureBuffers().set(0, texs);
    texs.clear();

    batch.getVertexBuffer().rewind();
    float firstX = -1.0f;
    float firstY = -1.0f;
    for (int i = 0; i < batch.getVertexCount(); i++) {
      Vector2f mapCoord = new Vector2f();
      mapCoord.x = (batch.getVertexBuffer().get() + offsetX) / (getStepScale().x);
      batch.getVertexBuffer().get(); // ignore vert y coord.
      mapCoord.y = (batch.getVertexBuffer().get() + offsetY) / (getStepScale().z);
   
      if( firstX == -1.0f ) {
        firstX = mapCoord.x;
      }
      if( firstY == -1.0f ) {
        firstY = mapCoord.y;
      }
   
      float up = 1.0f;//((float)TILE_SIZE+1.0f) / (float)TILE_SIZE;
      float tileIndexX = (mapCoord.x % TILE_SIZE) / TILE_SIZE;
      float tileIndexY = (mapCoord.y % TILE_SIZE) / TILE_SIZE;
     
     
     
      float oX = tileIndexX * up;
      float oY = tileIndexY * up;

      if( tileIndexX == 0.0f ) {
        ifmapCoord.x != firstX ) {
          oX = 1.0f;
        } else {
          oX = 0.00f;
        }
      }
     
      if( tileIndexY == 0.0f ) {
        if( mapCoord.y != firstY ) {
          oY = 1.0f;
        } else {
          oY = 0.00f;
        }
      }
           
      Vector2f texCoord = materialMap.textureForMap(mapCoord);

     
      float fX = texCoord.x + (0.5f * oX);
      float fY = texCoord.y + (0.5f * oY);
      texs.put(fX);
      texs.put(fY);
    }
  }

  private void buildVertices() {
    TriangleBatch batch = getBatch(0);
    batch.setVertexCount(getHeightMap().length);
    batch.setVertexBuffer(BufferUtils.createVector3Buffer(batch
        .getVertexBuffer(), batch.getVertexCount()));
    Vector3f point = new Vector3f();
    for (int x = 0; x < getSize(); x++) {
      for (int y = 0; y < getSize(); y++) {
        point.set(x * getStepScale().x,
            getHeightMap()[x + (y * getSize())] * getStepScale().y,
            y * getStepScale().z);
        BufferUtils.setInBuffer(point, batch.getVertexBuffer(),
            (x + (y * getSize())));
      }
    }
   
    FloatBuffer fb = BufferUtils.createVector3Buffer( null, batch.getVertexCount());

    float offsetX = getOffset().x + (getOffsetAmount() * getStepScale().x);
    float offsetY = getOffset().y + (getOffsetAmount() * getStepScale().z);

    for (int x = 0; x < getSize(); x++) {
      for (int y = 0; y < getSize(); y++) {
       
        Vector3f newPoint = new Vector3f();
        Vector2f mapCoord = new Vector2f( x + offsetX, y + offsetY );
        int indexMain = (x + (y * getSize()));
        Vector2f texCoord = materialMap.textureForMap(mapCoord);
       
       
        BufferUtils.populateFromBuffer( newPoint, batch.getVertexBuffer(), indexMain);
        newPoint.y = averageHeight( batch, x, y );
        BufferUtils.setInBuffer( newPoint, fb, indexMain);
      }
    }
   
    batch.setVertexBuffer( fb );

    for (int x = 0; x < getSize(); x++) {
      for (int y = 0; y < getSize(); y++) {
    //    fixAllPoint( batch ,x,y);
      }
    }

   
    // set up the indices
    batch.setTriangleQuantity(((getSize() - 1) * (getSize() - 1)) * 2);
    batch.setIndexBuffer(BufferUtils.createIntBuffer(batch
        .getTriangleCount() * 3));

    // go through entire array up to the second to last column.
    for (int i = 0; i < (getSize() * (getSize() - 1)); i++) {
      // we want to skip the top row.
      if (i % ((getSize() * (i / getSize() + 1)) - 1) == 0 && i != 0) {
        continue;
      }

      int x = i % getSize();
      int y = i / getSize();
     
      // set the top left corner.
      batch.getIndexBuffer().put(i);

      // set the bottom right corner.
      batch.getIndexBuffer().put((1 + getSize()) + i);

      // set the top right corner.
      batch.getIndexBuffer().put(1 + i);

      // set the top left corner
      batch.getIndexBuffer().put(i);

      // set the bottom left corner
      batch.getIndexBuffer().put(getSize() + i);

      // set the bottom right corner
      batch.getIndexBuffer().put((1 + getSize()) + i);
    }
  }
 
  public void fixAllPoint( TriangleBatch tb, int x, int y ) {
    int i = 0;
    int j = 0;
    fori = -1; i < 2; i++ ) {
      for( j = -1; j < 2; j++ ) {
        fixPoint( tb, x,y, x+i, y+j);
      }
    }
  }
 
  public void fixPoint( TriangleBatch tb, int x, int y, int x2, int y2 ) {
    //System.out.println( x + " , " + y + " , " + x2 + " , " + y2);
    float offsetX = getOffset().x + (getOffsetAmount() * getStepScale().x);
    float offsetY = getOffset().y + (getOffsetAmount() * getStepScale().z);

    if( y2 < getSize() && y2 > 0 && x2 > 0 && x2 < getSize() ) {
      Vector3f here = new Vector3f();
      int indexMain = (x + (y * getSize()));
      BufferUtils.populateFromBuffer( here, tb.getVertexBuffer(), indexMain);

      Vector3f above = new Vector3f();
      int indexAbove = (x2 + ((y2) * getSize()));
      BufferUtils.populateFromBuffer( above, tb.getVertexBuffer(), indexAbove);

      Vector2f mapHere = new Vector2f( x + offsetX, y + offsetY );
      Vector2f mapAbove = new Vector2f( x2 + offsetX, y2 + offsetY );

      Vector2f textureHere = materialMap.textureForMap( mapHere );
      Vector2f textureAbove = materialMap.textureForMap( mapAbove );
     
     
      if( ! textureHere.equals( textureAbove )) {
        System.out.println("The points " + here.toString() + "and " + above.toString() + " are on different textures " );
        Vector3f avg = new Vector3f();
        avg = avg.add( here  );
        avg = avg.add( above );
        avg = avg.divide( 2.0f );
        BufferUtils.setInBuffer( avg, tb.getVertexBuffer(), indexMain );
        BufferUtils.setInBuffer( avg, tb.getVertexBuffer(), indexAbove );
      }
     
    }
  }

 
  public float averageHeight( TriangleBatch tb, int x, int y ) {
    int numPoints = 0;
    Vector3f accum = new Vector3f();
    Vector3f store = new Vector3f();
   
    ifx == 0 || x == getSize()-1 || y == 0 || y == getSize()-1) {
      BufferUtils.populateFromBuffer( store , tb.getVertexBuffer(), indexForPoint( x, y ) );
      return store.y;
    }
   
    if( x+1 < getSize() ) {
      BufferUtils.populateFromBuffer( store , tb.getVertexBuffer(), indexForPoint( x+1, y ) );
      numPoints++;
      accum = accum.add( store );
    }
   
    if( x-1 > 0 ) {
      BufferUtils.populateFromBuffer( store , tb.getVertexBuffer(), indexForPoint( x-1, y ) );
      numPoints++;
      accum = accum.add( store );     
    }
   
    if( y+1 < getSize() ) {
      BufferUtils.populateFromBuffer( store , tb.getVertexBuffer(), indexForPoint( x, y+1 ) );
      numPoints++;
      accum = accum.add( store );     
    }

    if( y-1 > 0) {
      BufferUtils.populateFromBuffer( store , tb.getVertexBuffer(), indexForPoint( x, y-1 ) );
      numPoints++;
      accum = accum.add( store );     
    }
   
    BufferUtils.populateFromBuffer( store , tb.getVertexBuffer(), indexForPoint( x, y ) );
    numPoints++;
    accum = accum.add( store );
   
    accum = accum.divide( numPoints );
    return accum.y;
  }
 
  public int indexForPoint( int x, int y ) {
    return (x + (y * getSize()));
  }
 
  /**
   * <code>buildNormals</code> calculates the normals of each vertex that makes up the block of terrain.
   */
  private void buildNormals() {
    TriangleBatch batch = getBatch(0);
    batch.setNormalBuffer(BufferUtils.createVector3Buffer(batch
        .getNormalBuffer(), batch.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 < getSize(); row++) {
      for (int col = 0; col < getSize(); col++) {
        BufferUtils.populateFromBuffer(rootPoint, batch
            .getVertexBuffer(), normalIndex);
        if (row == getSize() - 1) {
          if (col == getSize() - 1) { // last row, last col
            // up cross left
            adj = normalIndex - getSize();
            opp = normalIndex - 1;
          } else { // last row, except for last col
            // right cross up
            adj = normalIndex + 1;
            opp = normalIndex - getSize();
          }
        } else {
          if (col == getSize() - 1) { // last column except for last row
            // left cross down
            adj = normalIndex - 1;
            opp = normalIndex + getSize();
          } else { // most cases
            // down cross right
            adj = normalIndex + getSize();
            opp = normalIndex + 1;
          }
        }
        BufferUtils.populateFromBuffer(adjacentPoint, batch
            .getVertexBuffer(), adj);
        BufferUtils.populateFromBuffer(oppositePoint, batch
            .getVertexBuffer(), opp);
        tempNorm.set(adjacentPoint).subtractLocal(rootPoint)
            .crossLocal(oppositePoint.subtractLocal(rootPoint))
            .normalizeLocal();
        BufferUtils.setInBuffer(tempNorm, batch.getNormalBuffer(),
            normalIndex);
        normalIndex++;
      }
    }
  }
}
TOP

Related Classes of edu.ups.gamedev.terrain.MaterialTerrainBlock

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.