/** * Request the triangles (in world coord space) of a TerrainBlock that correspond to the given * grid location. The triangles are stored in the class fields _gridTriA and _gridTriB. * * @param gridX grid row * @param gridY grid column * @param block the TerrainBlock we are working with * @return true if the grid point is valid for the given block, false if it is off the block. */ protected boolean getTriangles(float gridX, float gridY, TerrainBlock block) { _calcVec1.set(gridX, 0, gridY); int index = findClosestHeightIndex(_calcVec1, block); if (index == -1) return false; float h3 = block.getHeightMap()[index + block.getSize()]; float h4 = block.getHeightMap()[index + block.getSize() + 1]; float h1 = block.getHeightMap()[index]; float h2 = block.getHeightMap()[index + 1]; final Vector3f scaleVec = _calcVec1.set(_tracer.getGridSpacing()).multLocal(block.getWorldScale()); _gridTriA.get(0).x = (gridX); _gridTriA.get(0).y = (h1); _gridTriA.get(0).z = (gridY); _gridTriA.get(0).multLocal(scaleVec).addLocal(_tracer.getGridOrigin()); _gridTriA.get(1).x = (gridX); _gridTriA.get(1).y = (h3); _gridTriA.get(1).z = (gridY + 1); _gridTriA.get(1).multLocal(scaleVec).addLocal(_tracer.getGridOrigin()); _gridTriA.get(2).x = (gridX + 1); _gridTriA.get(2).y = (h2); _gridTriA.get(2).z = (gridY); _gridTriA.get(2).multLocal(scaleVec).addLocal(_tracer.getGridOrigin()); _gridTriB.get(0).x = (gridX + 1); _gridTriB.get(0).y = (h2); _gridTriB.get(0).z = (gridY); _gridTriB.get(0).multLocal(scaleVec).addLocal(_tracer.getGridOrigin()); _gridTriB.get(1).x = (gridX); _gridTriB.get(1).y = (h3); _gridTriB.get(1).z = (gridY + 1); _gridTriB.get(1).multLocal(scaleVec).addLocal(_tracer.getGridOrigin()); _gridTriB.get(2).x = (gridX + 1); _gridTriB.get(2).y = (h4); _gridTriB.get(2).z = (gridY + 1); _gridTriB.get(2).multLocal(scaleVec).addLocal(_tracer.getGridOrigin()); return true; }