final Vector3 sxIn = tmpV3.set(tangentX, tangentY, tangentZ).scl(innerWidth * 0.5f); final Vector3 syIn = tmpV4.set(binormalX, binormalY, binormalZ).scl(innerHeight * 0.5f); VertexInfo currIn = vertTmp3.set(null, null, null, null); currIn.hasUV = currIn.hasPosition = currIn.hasNormal = true; currIn.uv.set(.5f, .5f); currIn.position.set(centerX, centerY, centerZ); currIn.normal.set(normalX, normalY, normalZ); VertexInfo currEx = vertTmp4.set(null, null, null, null); currEx.hasUV = currEx.hasPosition = currEx.hasNormal = true; currEx.uv.set(.5f, .5f);
float bottomV1 = 0; float bottomV2 = 1; MeshPartBuilder.VertexInfo bottomLeftBack = new MeshPartBuilder.VertexInfo().setPos(x1, y1, z1).setUV(sideU1, sideV2); MeshPartBuilder.VertexInfo bottomRightBack = new MeshPartBuilder.VertexInfo().setPos(x2, y1, z1).setUV(sideU2, sideV2); MeshPartBuilder.VertexInfo bottomRightFront = new MeshPartBuilder.VertexInfo().setPos(x2, y1, z2).setUV(sideU1, sideV2); MeshPartBuilder.VertexInfo bottomLeftFront = new MeshPartBuilder.VertexInfo().setPos(x1, y1, z2).setUV(sideU2, sideV2); MeshPartBuilder.VertexInfo topLeftBack = new MeshPartBuilder.VertexInfo().setPos(x1, y2, z1).setUV(sideU1, sideV1); MeshPartBuilder.VertexInfo topRightBack = new MeshPartBuilder.VertexInfo().setPos(x2, y2, z1).setUV(sideU2, sideV1); MeshPartBuilder.VertexInfo topRightFront = new MeshPartBuilder.VertexInfo().setPos(x2, y2, z2).setUV(sideU1, sideV1); MeshPartBuilder.VertexInfo topLeftFront = new MeshPartBuilder.VertexInfo().setPos(x1, y2, z2).setUV(sideU2, sideV1); builder.rect(topLeftBack.setUV(topU1, topV1), topRightBack.setUV(topU2, topV1), topRightFront.setUV(topU2, topV2), topLeftFront.setUV(topU1, topV2)); builder.rect(bottomLeftFront.setUV(bottomU1, bottomV2), bottomRightFront.setUV(bottomU2, bottomV2), bottomRightBack.setUV(bottomU2, bottomV1), bottomLeftBack.setUV(bottomU1, bottomV1)); Mesh skybox = builder.end();
float angleU = 0f; float angleV = 0f; VertexInfo curr1 = vertTmp3.set(null, null, null, null); curr1.hasUV = curr1.hasPosition = curr1.hasNormal = true;
float u = 0f; float angle = 0f; VertexInfo curr1 = vertTmp3.set(null, null, null, null); curr1.hasUV = curr1.hasPosition = curr1.hasNormal = true; VertexInfo curr2 = vertTmp4.set(null, null, null, null).setPos(0, hh, 0).setNor(0, 1, 0).setUV(0.5f, 0); final short base = builder.vertex(curr2); short i1, i2 = 0;
@Override public void renderTop(int atlasIndex, float x1, float z1, float x2, float z2, float y, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); MeshPartBuilder.VertexInfo c00 = new MeshPartBuilder.VertexInfo().setPos(x1, y, z1).setNor(0, 1, 0); MeshPartBuilder.VertexInfo c01 = new MeshPartBuilder.VertexInfo().setPos(x1, y, z2).setNor(0, 1, 0); MeshPartBuilder.VertexInfo c10 = new MeshPartBuilder.VertexInfo().setPos(x2, y, z1).setNor(0, 1, 0); MeshPartBuilder.VertexInfo c11 = new MeshPartBuilder.VertexInfo().setPos(x2, y, z2).setNor(0, 1, 0); IChunk chunk = RadixClient.getInstance().getWorld().getChunk((int) x1, (int) z1); Biome biome; if(chunk != null) { biome = chunk.getBiome(); } else { biome = RadixAPI.instance.getBiomeByID(0); } int[] color = biome.getGrassColor((int) y - 1); float r = color[0]/255f; float g = color[1]/255f; float b = color[2]/255f; if(pcld == null) { builder.setColor(r*lightLevel, g*lightLevel, b*lightLevel, 1); } else { c00.setCol(r*pcld.l00, g*pcld.l00, b*pcld.l00, 1); c01.setCol(r*pcld.l01, g*pcld.l01, b*pcld.l01, 1); c10.setCol(r*pcld.l10, g*pcld.l10, b*pcld.l10, 1); c11.setCol(r*pcld.l11, g*pcld.l11, b*pcld.l11, 1); } builder.rect(c01, c11, c10, c00); }
@Override public void renderEast(int atlasIndex, float z1, float y1, float z2, float y2, float x, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { // POSITIVE X float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); c00.setPos(x, y1, z1).setNor(1, 0, 0); c01.setPos(x, y1, z2).setNor(1, 0, 0); c10.setPos(x, y2, z1).setNor(1, 0, 0); c11.setPos(x, y2, z2).setNor(1, 0, 0); Color c = getColor((int) x - 1, (int) y1, (int) z1); if(pcld == null) { builder.setColor(c.r*lightLevel, c.g*lightLevel, c.b*lightLevel, c.a); } else { c00.setCol(c.r*pcld.l00, c.g*pcld.l00, c.b*pcld.l00, c.a); c01.setCol(c.r*pcld.l01, c.g*pcld.l01, c.b*pcld.l01, c.a); c10.setCol(c.r*pcld.l10, c.g*pcld.l10, c.b*pcld.l10, c.a); c11.setCol(c.r*pcld.l11, c.g*pcld.l11, c.b*pcld.l11, c.a); } builder.rect(c00, c10, c11, c01); }
@Override public void renderWest(int atlasIndex, float z1, float y1, float z2, float y2, float x, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { // NEGATIVE X float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); c00.setPos(x, y1, z1).setNor(-1, 0, 0); c01.setPos(x, y1, z2).setNor(-1, 0, 0); c10.setPos(x, y2, z1).setNor(-1, 0, 0); c11.setPos(x, y2, z2).setNor(-1, 0, 0); Color c = getColor((int) x, (int) y1, (int) z1); if(pcld == null) { builder.setColor(c.r*lightLevel, c.g*lightLevel, c.b*lightLevel, c.a); } else { c00.setCol(c.r*pcld.l00, c.g*pcld.l00, c.b*pcld.l00, c.a); c01.setCol(c.r*pcld.l01, c.g*pcld.l01, c.b*pcld.l01, c.a); c10.setCol(c.r*pcld.l10, c.g*pcld.l10, c.b*pcld.l10, c.a); c11.setCol(c.r*pcld.l11, c.g*pcld.l11, c.b*pcld.l11, c.a); } builder.rect(c01, c11, c10, c00); }
/** Add a box. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ public static void build (MeshPartBuilder builder, Vector3 corner000, Vector3 corner010, Vector3 corner100, Vector3 corner110, Vector3 corner001, Vector3 corner011, Vector3 corner101, Vector3 corner111) { if ((builder.getAttributes().getMask() & (Usage.Normal | Usage.BiNormal | Usage.Tangent | Usage.TextureCoordinates)) == 0) { build(builder, vertTmp1.set(corner000, null, null, null), vertTmp2.set(corner010, null, null, null), vertTmp3.set(corner100, null, null, null), vertTmp4.set(corner110, null, null, null), vertTmp5.set(corner001, null, null, null), vertTmp6.set(corner011, null, null, null), vertTmp7.set(corner101, null, null, null), vertTmp8.set(corner111, null, null, null)); } else { builder.ensureVertices(24); builder.ensureRectangleIndices(6); Vector3 nor = tmpV1.set(corner000).lerp(corner110, 0.5f).sub(tmpV2.set(corner001).lerp(corner111, 0.5f)).nor(); builder.rect(corner000, corner010, corner110, corner100, nor); builder.rect(corner011, corner001, corner101, corner111, nor.scl(-1)); nor = tmpV1.set(corner000).lerp(corner101, 0.5f).sub(tmpV2.set(corner010).lerp(corner111, 0.5f)).nor(); builder.rect(corner001, corner000, corner100, corner101, nor); builder.rect(corner010, corner011, corner111, corner110, nor.scl(-1)); nor = tmpV1.set(corner000).lerp(corner011, 0.5f).sub(tmpV2.set(corner100).lerp(corner111, 0.5f)).nor(); builder.rect(corner001, corner011, corner010, corner000, nor); builder.rect(corner100, corner110, corner111, corner101, nor.scl(-1)); } }
@Override public void renderSouth(int atlasIndex, float x1, float y1, float x2, float y2, float z, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { // NEGATIVE Z float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); c00.setPos(x1, y1, z).setNor(0, 0, -1); c01.setPos(x1, y2, z).setNor(0, 0, -1); c10.setPos(x2, y1, z).setNor(0, 0, -1); c11.setPos(x2, y2, z).setNor(0, 0, -1); Color c = getColor((int) x1, (int) y1, (int) z); if(pcld == null) { builder.setColor(c.r*lightLevel, c.g*lightLevel, c.b*lightLevel, c.a); } else { c00.setCol(c.r*pcld.l00, c.g*pcld.l00, c.b*pcld.l00, c.a); c01.setCol(c.r*pcld.l01, c.g*pcld.l01, c.b*pcld.l01, c.a); c10.setCol(c.r*pcld.l10, c.g*pcld.l10, c.b*pcld.l10, c.a); c11.setCol(c.r*pcld.l11, c.g*pcld.l11, c.b*pcld.l11, c.a); } builder.rect(c01, c11, c10, c00); }
@Override public void renderTop(int atlasIndex, float x1, float z1, float x2, float z2, float y, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { // POSITIVE Y float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); c00.setPos(x1, y, z1).setNor(0, 1, 0); c01.setPos(x1, y, z2).setNor(0, 1, 0); c10.setPos(x2, y, z1).setNor(0, 1, 0); c11.setPos(x2, y, z2).setNor(0, 1, 0); Color c = getColor((int) x1, (int) y - 1, (int) z1); if(pcld == null) { builder.setColor(c.r*lightLevel, c.g*lightLevel, c.b*lightLevel, c.a); } else { c00.setCol(c.r*pcld.l00, c.g*pcld.l00, c.b*pcld.l00, c.a); c01.setCol(c.r*pcld.l01, c.g*pcld.l01, c.b*pcld.l01, c.a); c10.setCol(c.r*pcld.l10, c.g*pcld.l10, c.b*pcld.l10, c.a); c11.setCol(c.r*pcld.l11, c.g*pcld.l11, c.b*pcld.l11, c.a); } builder.rect(c01, c11, c10, c00); }
@Override public void renderNorth(int atlasIndex, float x1, float y1, float x2, float y2, float z, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { // POSITIVE Z float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); c00.setPos(x1, y1, z).setNor(0, 0, 1); c01.setPos(x1, y2, z).setNor(0, 0, 1); c10.setPos(x2, y1, z).setNor(0, 0, 1); c11.setPos(x2, y2, z).setNor(0, 0, 1); Color c = getColor((int) x1, (int) y1, (int) z - 1); if(pcld == null) { builder.setColor(c.r*lightLevel, c.g*lightLevel, c.b*lightLevel, c.a); } else { c00.setCol(c.r*pcld.l00, c.g*pcld.l00, c.b*pcld.l00, c.a); c01.setCol(c.r*pcld.l01, c.g*pcld.l01, c.b*pcld.l01, c.a); c10.setCol(c.r*pcld.l10, c.g*pcld.l10, c.b*pcld.l10, c.a); c11.setCol(c.r*pcld.l11, c.g*pcld.l11, c.b*pcld.l11, c.a); } builder.rect(c00, c10, c11, c01); }
@Override public void renderBottom(int atlasIndex, float x1, float z1, float x2, float z2, float y, float lightLevel, PerCornerLightData pcld, MeshBuilder builder) { // NEGATIVE Y float u = getU(atlasIndex); float v = getV(atlasIndex); builder.setUVRange(u, v, u, v); c00.setPos(x1, y, z1).setNor(0, -1, 0); c01.setPos(x1, y, z2).setNor(0, -1, 0); c10.setPos(x2, y, z1).setNor(0, -1, 0); c11.setPos(x2, y, z2).setNor(0, -1, 0); Color c = getColor((int) x1, (int) y, (int) z1); if(pcld == null) { builder.setColor(c.r*lightLevel, c.g*lightLevel, c.b*lightLevel, c.a); } else { c00.setCol(c.r*pcld.l00, c.g*pcld.l00, c.b*pcld.l00, c.a); c01.setCol(c.r*pcld.l01, c.g*pcld.l01, c.b*pcld.l01, c.a); c10.setCol(c.r*pcld.l10, c.g*pcld.l10, c.b*pcld.l10, c.a); c11.setCol(c.r*pcld.l11, c.g*pcld.l11, c.b*pcld.l11, c.a); } builder.rect(c00, c10, c11, c01); }
/** Build a patch shape. Requires GL_POINTS, GL_LINES or GL_TRIANGLES primitive type. */ public static void build (MeshPartBuilder builder, VertexInfo corner00, VertexInfo corner10, VertexInfo corner11, VertexInfo corner01, int divisionsU, int divisionsV) { if (divisionsU < 1 || divisionsV < 1) { throw new GdxRuntimeException("divisionsU and divisionV must be > 0, u,v: " + divisionsU + ", " + divisionsV); } builder.ensureVertices((divisionsV + 1) * (divisionsU + 1)); builder.ensureRectangleIndices(divisionsV * divisionsU); for (int u = 0; u <= divisionsU; u++) { final float alphaU = (float)u / (float)divisionsU; vertTmp5.set(corner00).lerp(corner10, alphaU); vertTmp6.set(corner01).lerp(corner11, alphaU); for (int v = 0; v <= divisionsV; v++) { final short idx = builder.vertex(vertTmp7.set(vertTmp5).lerp(vertTmp6, (float)v / (float)divisionsV)); if (u > 0 && v > 0) builder.rect((short)(idx - divisionsV - 2), (short)(idx - 1), idx, (short)(idx - divisionsV - 1)); } } }