Suggestion: Add methods to facilitate Mesh class

The last reply to this topic was 10 months ago . But my solution (no matter if good or bad) fits exactly to this question.

I wanted to cut a mesh so that I get a part exactly above the water surface and a part exactly below the water - the last has to colored blue.

The following can happen to the triangles:

A college programmer would collapse because of the triple copy of the source code, but sometimes it is practical and more pleasant to simply write down the thoughts one after the other.

My calculator:


public class JaReWaterLevelCalculator extends JaReMeshCalculator {

	private final float level;

	public JaReWaterLevelCalculator(final float level) {
		this.level = level;
	}

	public void calculate(final short[] indexbuffer, final float[] texCoord, final float[] vertexbuffer,
			final float[] colorbuffer, final JaReWaterLevelConsumer consumer) {
		final ArrayList<Short> overIndex = new ArrayList<>(indexbuffer.length + 6);
		final ArrayList<Short> underIndex = new ArrayList<>(indexbuffer.length + 6);
		final ArrayList<Float> newTexCord = filledList(texCoord);
		final ArrayList<Float> newColorbuffer = filledList(colorbuffer);
		final ArrayList<Float> newVertex = filledList(vertexbuffer);
		for (int i = 0; i < indexbuffer.length; i = i + 3) {
			final int j = i + 1;
			final int k = j + 1;
			final short index_i = indexbuffer[i];
			final short index_j = indexbuffer[j];
			final short index_k = indexbuffer[k];
			final float ah = vertexbuffer[index_i * 3 + 1];
			final float bh = vertexbuffer[index_j * 3 + 1];
			final float ch = vertexbuffer[index_k * 3 + 1];
			if (ah + EPSILON >= level && bh + EPSILON >= level && ch + EPSILON >= level) {
				overIndex.add(index_i);
				overIndex.add(index_j);
				overIndex.add(index_k);
			} else if (ah - EPSILON <= level && bh - EPSILON <= level && ch - EPSILON <= level) {
				underIndex.add(index_i);
				underIndex.add(index_j);
				underIndex.add(index_k);
			} else if (ah + EPSILON >= level && ah - EPSILON <= level) {
				// splitt 2
				final float b_c = (level - bh) / (ch - bh);
				final float bch = level;
				final short index_bc = (short) (newTexCord.size() / TEX_COORD_COMP);
				newVertex.add(vertexbuffer[index_j * 3 + 0] * (1.0f - b_c) //
						+ vertexbuffer[index_k * 3 + 0] * b_c);
				newVertex.add(bch);
				newVertex.add(vertexbuffer[index_j * 3 + 2] * (1.0f - b_c) //
						+ vertexbuffer[index_k * 3 + 2] * b_c);
				newTexCord.add(texCoord[index_j * TEX_COORD_COMP + 0] * (1.0f - b_c) //
						+ texCoord[index_k * TEX_COORD_COMP + 0] * b_c);
				newTexCord.add(texCoord[index_j * TEX_COORD_COMP + 1] * (1.0f - b_c) //
						+ texCoord[index_k * TEX_COORD_COMP + 1] * b_c);
				newTexCord.add(texCoord[index_j * TEX_COORD_COMP + 2]);
				newColorbuffer.add(colorbuffer[index_j * 4 + 0] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 0] * b_c);
				newColorbuffer.add(colorbuffer[index_j * 4 + 1] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 1] * b_c);
				newColorbuffer.add(colorbuffer[index_j * 4 + 2] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 2] * b_c);
				newColorbuffer.add(colorbuffer[index_j * 4 + 3] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 3] * b_c);
				if (bh < level) {
					underIndex.add(index_i);
					underIndex.add(index_j);
					underIndex.add(index_bc);
				} else {
					overIndex.add(index_i);
					overIndex.add(index_j);
					overIndex.add(index_bc);
				}
				if (ch < level) {
					underIndex.add(index_k);
					underIndex.add(index_i);
					underIndex.add(index_bc);
				} else {
					overIndex.add(index_k);
					overIndex.add(index_i);
					overIndex.add(index_bc);
				}
			} else if (bh + EPSILON >= level && bh - EPSILON <= level) {
				// splitt 2
				final float c_a = (level - ch) / (ah - ch);
				final float cah = level;
				final short index_ca = (short) (newTexCord.size() / TEX_COORD_COMP);
				newVertex.add(vertexbuffer[index_k * 3 + 0] * (1.0f - c_a) //
						+ vertexbuffer[index_i * 3 + 0] * c_a);
				newVertex.add(cah);
				newVertex.add(vertexbuffer[index_k * 3 + 2] * (1.0f - c_a) //
						+ vertexbuffer[index_i * 3 + 2] * c_a);
				newTexCord.add(texCoord[index_k * TEX_COORD_COMP + 0] * (1.0f - c_a) //
						+ texCoord[index_i * TEX_COORD_COMP + 0] * c_a);
				newTexCord.add(texCoord[index_k * TEX_COORD_COMP + 1] * (1.0f - c_a) //
						+ texCoord[index_i * TEX_COORD_COMP + 1] * c_a);
				newTexCord.add(texCoord[index_k * TEX_COORD_COMP + 2]);
				newColorbuffer.add(colorbuffer[index_k * 4 + 0] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 0] * c_a);
				newColorbuffer.add(colorbuffer[index_k * 4 + 1] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 1] * c_a);
				newColorbuffer.add(colorbuffer[index_k * 4 + 2] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 2] * c_a);
				newColorbuffer.add(colorbuffer[index_k * 4 + 3] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 3] * c_a);
				if (ah < level) {
					underIndex.add(index_i);
					underIndex.add(index_j);
					underIndex.add(index_ca);
				} else {
					overIndex.add(index_i);
					overIndex.add(index_j);
					overIndex.add(index_ca);
				}
				if (ch < level) {
					underIndex.add(index_j);
					underIndex.add(index_k);
					underIndex.add(index_ca);
				} else {
					overIndex.add(index_j);
					overIndex.add(index_k);
					overIndex.add(index_ca);
				}
			} else if (ch + EPSILON >= level && ch - EPSILON <= level) {
				// splitt 2
				float a_b = (level - ah) / (bh - ah);
				float abh = level;
				if ((ah > level && bh < level) || (ah < level && bh > level)) {
					a_b = (level - ah) / (bh - ah);
					abh = level;
				}
				final short index_ab = (short) (newTexCord.size() / TEX_COORD_COMP);
				newVertex.add(vertexbuffer[index_i * 3 + 0] * (1.0f - a_b) //
						+ vertexbuffer[index_j * 3 + 0] * a_b);
				newVertex.add(abh);
				newVertex.add(vertexbuffer[index_i * 3 + 2] * (1.0f - a_b) //
						+ vertexbuffer[index_j * 3 + 2] * a_b);
				newTexCord.add(texCoord[index_i * TEX_COORD_COMP + 0] * (1.0f - a_b) //
						+ texCoord[index_j * TEX_COORD_COMP + 0] * a_b);
				newTexCord.add(texCoord[index_i * TEX_COORD_COMP + 1] * (1.0f - a_b) //
						+ texCoord[index_j * TEX_COORD_COMP + 1] * a_b);
				newTexCord.add(texCoord[index_i * TEX_COORD_COMP + 2]);
				newColorbuffer.add(colorbuffer[index_i * 4 + 0] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 0] * a_b);
				newColorbuffer.add(colorbuffer[index_i * 4 + 1] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 1] * a_b);
				newColorbuffer.add(colorbuffer[index_i * 4 + 2] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 2] * a_b);
				newColorbuffer.add(colorbuffer[index_i * 4 + 3] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 3] * a_b);
				if (ah < level) {
					underIndex.add(index_k);
					underIndex.add(index_i);
					underIndex.add(index_ab);
				} else {
					overIndex.add(index_k);
					overIndex.add(index_i);
					overIndex.add(index_ab);
				}
				if (bh < level) {
					underIndex.add(index_j);
					underIndex.add(index_k);
					underIndex.add(index_ab);
				} else {
					overIndex.add(index_j);
					overIndex.add(index_k);
					overIndex.add(index_ab);
				}
			} else {
				// splitt 4
				float a_b = 0.5f;
				float b_c = 0.5f;
				float c_a = 0.5f;
				float abh = (ah + bh) / 2;
				float bch = (bh + ch) / 2;
				float cah = (ch + ah) / 2;
				if ((ah > level && bh < level) || (ah < level && bh > level)) {
					a_b = (level - ah) / (bh - ah);
					abh = level;
				}
				if ((bh > level && ch < level) || (bh < level && ch > level)) {
					b_c = (level - bh) / (ch - bh);
					bch = level;
				}
				if ((ch > level && ah < level) || (ch < level && ah > level)) {
					c_a = (level - ch) / (ah - ch);
					cah = level;
				}
				final short index_ab = (short) (newTexCord.size() / TEX_COORD_COMP);
				newVertex.add(vertexbuffer[index_i * 3 + 0] * (1.0f - a_b) //
						+ vertexbuffer[index_j * 3 + 0] * a_b);
				newVertex.add(abh);
				newVertex.add(vertexbuffer[index_i * 3 + 2] * (1.0f - a_b) //
						+ vertexbuffer[index_j * 3 + 2] * a_b);
				newTexCord.add(texCoord[index_i * TEX_COORD_COMP + 0] * (1.0f - a_b) //
						+ texCoord[index_j * TEX_COORD_COMP + 0] * a_b);
				newTexCord.add(texCoord[index_i * TEX_COORD_COMP + 1] * (1.0f - a_b) //
						+ texCoord[index_j * TEX_COORD_COMP + 1] * a_b);
				newTexCord.add(texCoord[index_i * TEX_COORD_COMP + 2]);
				newColorbuffer.add(colorbuffer[index_i * 4 + 0] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 0] * a_b);
				newColorbuffer.add(colorbuffer[index_i * 4 + 1] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 1] * a_b);
				newColorbuffer.add(colorbuffer[index_i * 4 + 2] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 2] * a_b);
				newColorbuffer.add(colorbuffer[index_i * 4 + 3] * (1.0f - a_b) //
						+ colorbuffer[index_j * 4 + 3] * a_b);

				final short index_bc = (short) (newTexCord.size() / TEX_COORD_COMP);
				newVertex.add(vertexbuffer[index_j * 3 + 0] * (1.0f - b_c) //
						+ vertexbuffer[index_k * 3 + 0] * b_c);
				newVertex.add(bch);
				newVertex.add(vertexbuffer[index_j * 3 + 2] * (1.0f - b_c) //
						+ vertexbuffer[index_k * 3 + 2] * b_c);
				newTexCord.add(texCoord[index_j * TEX_COORD_COMP + 0] * (1.0f - b_c) //
						+ texCoord[index_k * TEX_COORD_COMP + 0] * b_c);
				newTexCord.add(texCoord[index_j * TEX_COORD_COMP + 1] * (1.0f - b_c) //
						+ texCoord[index_k * TEX_COORD_COMP + 1] * b_c);
				newTexCord.add(texCoord[index_j * TEX_COORD_COMP + 2]);
				newColorbuffer.add(colorbuffer[index_j * 4 + 0] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 0] * b_c);
				newColorbuffer.add(colorbuffer[index_j * 4 + 1] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 1] * b_c);
				newColorbuffer.add(colorbuffer[index_j * 4 + 2] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 2] * b_c);
				newColorbuffer.add(colorbuffer[index_j * 4 + 3] * (1.0f - b_c) //
						+ colorbuffer[index_k * 4 + 3] * b_c);

				final short index_ca = (short) (newTexCord.size() / TEX_COORD_COMP);
				newVertex.add(vertexbuffer[index_k * 3 + 0] * (1.0f - c_a) //
						+ vertexbuffer[index_i * 3 + 0] * c_a);
				newVertex.add(cah);
				newVertex.add(vertexbuffer[index_k * 3 + 2] * (1.0f - c_a) //
						+ vertexbuffer[index_i * 3 + 2] * c_a);
				newTexCord.add(texCoord[index_k * TEX_COORD_COMP + 0] * (1.0f - c_a) //
						+ texCoord[index_i * TEX_COORD_COMP + 0] * c_a);
				newTexCord.add(texCoord[index_k * TEX_COORD_COMP + 1] * (1.0f - c_a) //
						+ texCoord[index_i * TEX_COORD_COMP + 1] * c_a);
				newTexCord.add(texCoord[index_k * TEX_COORD_COMP + 2]);
				newColorbuffer.add(colorbuffer[index_k * 4 + 0] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 0] * c_a);
				newColorbuffer.add(colorbuffer[index_k * 4 + 1] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 1] * c_a);
				newColorbuffer.add(colorbuffer[index_k * 4 + 2] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 2] * c_a);
				newColorbuffer.add(colorbuffer[index_k * 4 + 3] * (1.0f - c_a) //
						+ colorbuffer[index_i * 4 + 3] * c_a);

				if (ah <= level && abh <= level && cah <= level) {
					underIndex.add(index_i);
					underIndex.add(index_ab);
					underIndex.add(index_ca);
				} else {
					overIndex.add(index_i);
					overIndex.add(index_ab);
					overIndex.add(index_ca);
				}
				if (bh <= level && bch <= level && abh <= level) {
					underIndex.add(index_j);
					underIndex.add(index_bc);
					underIndex.add(index_ab);
				} else {
					overIndex.add(index_j);
					overIndex.add(index_bc);
					overIndex.add(index_ab);
				}
				if (ch <= level && cah <= level && bch <= level) {
					underIndex.add(index_k);
					underIndex.add(index_ca);
					underIndex.add(index_bc);
				} else {
					overIndex.add(index_k);
					overIndex.add(index_ca);
					overIndex.add(index_bc);
				}
				if (abh <= level && bch <= level && cah <= level) {
					underIndex.add(index_ab);
					underIndex.add(index_bc);
					underIndex.add(index_ca);
				} else {
					overIndex.add(index_ab);
					overIndex.add(index_bc);
					overIndex.add(index_ca);
				}
			}
		}
		consumer.setIndexbufferUnder(toShortArray(underIndex));
		consumer.setIndexbufferOver(toShortArray(overIndex));
		consumer.setTexCoord(toFloatArray(newTexCord));
		consumer.setColorBuffer(toFloatArray(newColorbuffer));
		consumer.setVertexBuffer(toFloatArray(newVertex));
	}

	public float getLevel() {
		return level;
	}

}

with:


public abstract class JaReMeshCalculator {

	public static final float EPSILON = 0.001f;

	protected ArrayList<Float> filledList(final float[] array) {
		final int size = array.length;
		final ArrayList<Float> arrayList = new ArrayList<>(size + 9);
		for (int i = 0; i < size; i++) {
			arrayList.add(array[i]);
		}
		return arrayList;
	}

	protected short[] toShortArray(final ArrayList<Short> list) {
		final int size = list.size();
		final short[] ret = new short[size];
		for (int i = 0; i < size; i++) {
			ret[i] = list.get(i);
		}
		return ret;
	}

	protected float[] toFloatArray(final ArrayList<Float> list) {
		final int size = list.size();
		final float[] ret = new float[size];
		for (int i = 0; i < size; i++) {
			ret[i] = list.get(i);
		}
		return ret;
	}
}

with
TEX_COORD_COMP = 3;

Note: The Vertrex and TexCord are still duplicated in both meshes! Only the indices are divided.

I still have to revise that.

1 Like