dynmap/DynmapCore/src/main/java/org/dynmap/hdmap/renderer/CuboidRenderer.java

103 lines
4.4 KiB
Java

package org.dynmap.hdmap.renderer;
import java.util.ArrayList;
import java.util.BitSet;
import java.util.Map;
import org.dynmap.Log;
import org.dynmap.renderer.CustomRenderer;
import org.dynmap.renderer.MapDataContext;
import org.dynmap.renderer.RenderPatch;
import org.dynmap.renderer.RenderPatchFactory;
import org.dynmap.renderer.RenderPatchFactory.SideVisible;
/**
* Renderer for allowing creation of a set of one or more cuboid or crossed-patch blocks, with independent textures for each
* Each cuboid is provided with two corner offsets within the cube (xmin,ymin,zmin) and (xmax,ymax,zmax), and a list of 6 patch indexes (default is 0,1,2,3,4,5 - order is bottom,top,xmin,xmax,zmin,zmax)
* Each crossed-patch is provided with two corner offsets within the cube (xmin,ymin,zmin) and (xmax,ymax,zmax), and a single patch index (default is 0)
*/
public class CuboidRenderer extends CustomRenderer {
private RenderPatch[] model;
private int textureCount;
private static final int[] crossedPatchDefault = { 0 };
private static final int[] cuboidPatchDefault = { 0, 1, 2, 3, 4, 5 };
private static final double clamp(double f) {
if (f < 0.0) { f = 0.0; }
if (f > 1.0) { f = 1.0; }
return f;
}
@Override
public boolean initializeRenderer(RenderPatchFactory rpf, String blkname, BitSet blockdatamask, Map<String,String> custparm) {
if(!super.initializeRenderer(rpf, blkname, blockdatamask, custparm))
return false;
ArrayList<RenderPatch> list = new ArrayList<RenderPatch>();
// Loop through parameters
for (String key : custparm.keySet()) {
String v = custparm.get(key);
if (key.startsWith("cuboid") || key.startsWith("cross")) {
boolean isCrossed = key.startsWith("cross");
String[] toks = v.split("/");
if (toks.length < 2) { // Must be at least two
Log.severe("Invalid cuboid token value: " + v);
return false;
}
String[] mins = toks[0].split(":");
String[] maxs = toks[1].split(":");
if ((mins.length < 3) || (maxs.length < 3)) {
Log.severe("Invalid number of fields: " + v);
return false;
}
double xmin = clamp(Double.parseDouble(mins[0]));
double ymin = clamp(Double.parseDouble(mins[1]));
double zmin = clamp(Double.parseDouble(mins[2]));
double xmax = clamp(Double.parseDouble(maxs[0]));
double ymax = clamp(Double.parseDouble(maxs[1]));
double zmax = clamp(Double.parseDouble(maxs[2]));
int[] patches = (isCrossed)?crossedPatchDefault:cuboidPatchDefault;
if (toks.length > 2) {
patches = new int[isCrossed?1:6];
String[] pidx = toks[2].split(":");
for (int j = 0; j < patches.length; j++) {
if (j >= pidx.length) {
patches[j] = Integer.parseInt(pidx[pidx.length-1]);
}
else {
patches[j] = Integer.parseInt(pidx[j]);
}
if (patches[j] >= textureCount) {
textureCount= patches[j] + 1;
}
}
}
// Build crossed patches
if (isCrossed) {
RenderPatch VertX1Z0ToX0Z1 = rpf.getPatch(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, Math.min(xmin, zmin), Math.max(xmax, zmax),
ymin, ymax, SideVisible.FLIP, patches[0]);
RenderPatch VertX1Z0ToX0Z1_90 = rpf.getRotatedPatch(VertX1Z0ToX0Z1, 0, 90, 0, patches[0]);
list.add(VertX1Z0ToX0Z1);
list.add(VertX1Z0ToX0Z1_90);
}
else {
CustomRenderer.addBox(rpf, list, xmin, xmax, ymin, ymax, zmin, zmax, patches);
}
}
}
model = list.toArray(new RenderPatch[list.size()]);
return true;
}
@Override
public int getMaximumTextureCount() {
return textureCount;
}
@Override
public RenderPatch[] getRenderPatchList(MapDataContext ctx) {
return model;
}
}