mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-25 10:07:37 +01:00
Add more vanilla model friendly modellist type for model file, use for
comparator
This commit is contained in:
parent
9247b7ec2f
commit
4452777585
@ -22,6 +22,7 @@ import org.dynmap.DynmapCore;
|
||||
import org.dynmap.Log;
|
||||
import org.dynmap.MapManager;
|
||||
import org.dynmap.debug.Debug;
|
||||
import org.dynmap.modsupport.BlockSide;
|
||||
import org.dynmap.renderer.CustomRenderer;
|
||||
import org.dynmap.renderer.DynmapBlockState;
|
||||
import org.dynmap.renderer.RenderPatch;
|
||||
@ -320,6 +321,29 @@ public class HDBlockModels {
|
||||
int yrot = 0;
|
||||
int[] patches = new int[6]; // Default all to patch0
|
||||
}
|
||||
|
||||
private static class ModelBoxSide {
|
||||
BlockSide side;
|
||||
int textureid;
|
||||
double[] uv;
|
||||
};
|
||||
|
||||
private static class ModelBox {
|
||||
double[] from = new double[3];
|
||||
double[] to = new double[3];
|
||||
ArrayList<ModelBoxSide> sides = new ArrayList<ModelBoxSide>();
|
||||
};
|
||||
|
||||
private static HashMap<String, BlockSide> toBlockSide = new HashMap<String, BlockSide>();
|
||||
static {
|
||||
toBlockSide.put("u", BlockSide.TOP);
|
||||
toBlockSide.put("d", BlockSide.BOTTOM);
|
||||
toBlockSide.put("n", BlockSide.NORTH);
|
||||
toBlockSide.put("s", BlockSide.SOUTH);
|
||||
toBlockSide.put("w", BlockSide.WEST);
|
||||
toBlockSide.put("e", BlockSide.EAST);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load models from file
|
||||
* @param core
|
||||
@ -964,6 +988,125 @@ public class HDBlockModels {
|
||||
Log.severe("Box list block model missing required parameters = line " + rdr.getLineNumber() + " of " + fname);
|
||||
}
|
||||
}
|
||||
// Shortcur for building JSON model style
|
||||
else if(line.startsWith("modellist:")) {
|
||||
ArrayList<String> blknames = new ArrayList<String>();
|
||||
databits.clear();
|
||||
line = line.substring(10);
|
||||
String[] args = line.split(",");
|
||||
ArrayList<ModelBox> boxes = new ArrayList<ModelBox>();
|
||||
for(String a : args) {
|
||||
String[] av = a.split("=");
|
||||
if(av.length < 2) continue;
|
||||
if(av[0].equals("id")) {
|
||||
blknames.add(getBlockName(modname,av[1]));
|
||||
}
|
||||
else if(av[0].equals("data")) {
|
||||
if(av[1].equals("*")) {
|
||||
databits.clear();
|
||||
}
|
||||
else if (av[1].indexOf('-') > 0) {
|
||||
String[] sp = av[1].split("-");
|
||||
int m0 = getIntValue(varvals, sp[0]);
|
||||
int m1 = getIntValue(varvals, sp[1]);
|
||||
for (int m = m0; m <= m1; m++) {
|
||||
databits.set(m);
|
||||
}
|
||||
}
|
||||
else
|
||||
databits.set(getIntValue(varvals,av[1]));
|
||||
}
|
||||
else if(av[0].equals("box")) {
|
||||
// box=fromx/y/z:tox/y/z:<side - upnsew>/<txtidx>/umin/vmin/umax/vmax>:...
|
||||
String[] prms = av[1].split(":");
|
||||
|
||||
ModelBox box = new ModelBox();
|
||||
if (prms.length > 0) { // Handle from
|
||||
String[] xyz = prms[0].split("/");
|
||||
if (xyz.length == 3) {
|
||||
box.from[0] = Double.parseDouble(xyz[0]);
|
||||
box.from[1] = Double.parseDouble(xyz[1]);
|
||||
box.from[2] = Double.parseDouble(xyz[2]);
|
||||
}
|
||||
else {
|
||||
Log.severe("Invalid modellist FROM value (" + prms[0] + " at line " + rdr.getLineNumber());
|
||||
}
|
||||
}
|
||||
if (prms.length > 1) { // Handle to
|
||||
String[] xyz = prms[1].split("/");
|
||||
if (xyz.length == 3) {
|
||||
box.to[0] = Double.parseDouble(xyz[0]);
|
||||
box.to[1] = Double.parseDouble(xyz[1]);
|
||||
box.to[2] = Double.parseDouble(xyz[2]);
|
||||
}
|
||||
else {
|
||||
Log.severe("Invalid modellist TO value (" + prms[1] + " at line " + rdr.getLineNumber());
|
||||
}
|
||||
}
|
||||
// Rest are faces (<side - upnsew>/<txtidx>/umin/vmin/umax/vmax> or <<side - upnsew>/<txtidx>)
|
||||
for (int faceidx = 2; faceidx < prms.length; faceidx++) {
|
||||
String v = prms[faceidx];
|
||||
String[] flds = v.split("/");
|
||||
ModelBoxSide side = new ModelBoxSide();
|
||||
if (flds.length > 0) {
|
||||
String face = flds[0];
|
||||
side.side = toBlockSide.get(face);
|
||||
if (side.side == null) {
|
||||
Log.severe("Invalid modellist side value (" + face + " at line " + rdr.getLineNumber());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (flds.length > 1) {
|
||||
side.textureid = getIntValue(varvals, flds[1]);
|
||||
}
|
||||
if (flds.length >= 6) {
|
||||
side.uv = new double[4];
|
||||
side.uv[0] = Double.parseDouble(flds[2]);
|
||||
side.uv[1] = Double.parseDouble(flds[3]);
|
||||
side.uv[2] = Double.parseDouble(flds[4]);
|
||||
side.uv[3] = Double.parseDouble(flds[5]);
|
||||
}
|
||||
box.sides.add(side);
|
||||
}
|
||||
boxes.add(box);
|
||||
}
|
||||
}
|
||||
/* If we have everything, build block */
|
||||
pmodlist.clear();
|
||||
if (blknames.size() > 0) {
|
||||
ArrayList<PatchDefinition> pd = new ArrayList<PatchDefinition>();
|
||||
|
||||
for (ModelBox bl : boxes) {
|
||||
// Loop through faces
|
||||
for (ModelBoxSide side : bl.sides) {
|
||||
PatchDefinition patch = pdf.getModelFace(bl.from, bl.to, side.side, side.uv, side.textureid);
|
||||
if (patch != null) {
|
||||
pd.add(patch);
|
||||
Log.info("patch=" + patch);
|
||||
}
|
||||
}
|
||||
}
|
||||
PatchDefinition[] patcharray = new PatchDefinition[pd.size()];
|
||||
for (int i = 0; i < patcharray.length; i++) {
|
||||
patcharray[i] = pd.get(i);
|
||||
}
|
||||
if (patcharray.length > max_patches)
|
||||
max_patches = patcharray.length;
|
||||
for(String nm : blknames) {
|
||||
DynmapBlockState bs = DynmapBlockState.getBaseStateByName(nm);
|
||||
if (bs.isNotAir()) {
|
||||
pmodlist.add(new HDBlockPatchModel(bs, databits, patcharray, blockset));
|
||||
cnt++;
|
||||
}
|
||||
else {
|
||||
Log.severe("Invalid modellist block name " + nm + " at line " + rdr.getLineNumber());
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
Log.severe("Model list block model missing required parameters = line " + rdr.getLineNumber() + " of " + fname);
|
||||
}
|
||||
}
|
||||
else if(line.startsWith("customblock:")) {
|
||||
ArrayList<String> blknames = new ArrayList<String>();
|
||||
HashMap<String,String> custargs = new HashMap<String,String>();
|
||||
|
@ -8,11 +8,13 @@ import java.util.LinkedHashMap;
|
||||
import java.util.Locale;
|
||||
|
||||
import org.dynmap.hdmap.HDBlockModels;
|
||||
import org.dynmap.modsupport.BlockSide;
|
||||
import org.dynmap.modsupport.BoxBlockModel;
|
||||
import org.dynmap.modsupport.CuboidBlockModel;
|
||||
import org.dynmap.modsupport.DoorBlockModel;
|
||||
import org.dynmap.modsupport.ModModelDefinition;
|
||||
import org.dynmap.modsupport.ModTextureDefinition;
|
||||
import org.dynmap.modsupport.ModelBlockModel;
|
||||
import org.dynmap.modsupport.PaneBlockModel;
|
||||
import org.dynmap.modsupport.PatchBlockModel;
|
||||
import org.dynmap.modsupport.PlantBlockModel;
|
||||
@ -190,6 +192,19 @@ public class ModModelDefinitionImpl implements ModModelDefinition {
|
||||
blkModel.add(mod);
|
||||
return mod;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ModelBlockModel addModelBlockModel(String blockname) {
|
||||
ModelBlockModelImpl mod = new ModelBlockModelImpl(blockname, this);
|
||||
blkModel.add(mod);
|
||||
return mod;
|
||||
}
|
||||
@Override
|
||||
public ModelBlockModel addRotatedModelBlockModel(String blockname, ModelBlockModel model, int xrot, int yrot, int zrot) {
|
||||
ModelBlockModelImpl mod = new ModelBlockModelImpl(blockname, this, model, xrot, yrot, zrot);
|
||||
blkModel.add(mod);
|
||||
return mod;
|
||||
}
|
||||
|
||||
public String getPatchID(double x0, double y0, double z0, double xu,
|
||||
double yu, double zu, double xv, double yv, double zv, double umin,
|
||||
@ -207,6 +222,21 @@ public class ModModelDefinitionImpl implements ModModelDefinition {
|
||||
blkPatchMap.put(id, pd);
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getModelFacePatchID(double[] from, double[] to, BlockSide face, double[] uv, int textureid) {
|
||||
PatchDefinition pd = pdf.getModelFace(from, to, face, uv, textureid);
|
||||
if (pd == null)
|
||||
return null; // Invalid patch
|
||||
for (int i = 0; i < blkPatch.size(); i++) {
|
||||
if (blkPatch.get(i) == pd) {
|
||||
return "patch" + i;
|
||||
}
|
||||
}
|
||||
blkPatch.add(pd);
|
||||
String id = "patch" + (blkPatch.size() - 1);
|
||||
blkPatchMap.put(id, pd);
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getRotatedPatchID(String patchid, int xrot, int yrot, int zrot) {
|
||||
PatchDefinition pd = blkPatchMap.get(patchid);
|
||||
|
@ -0,0 +1,120 @@
|
||||
package org.dynmap.modsupport.impl;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
|
||||
import org.dynmap.modsupport.BlockSide;
|
||||
import org.dynmap.modsupport.ModelBlockModel;
|
||||
|
||||
public class ModelBlockModelImpl extends BlockModelImpl implements ModelBlockModel {
|
||||
|
||||
private static class ModelSide {
|
||||
private double[] uv;
|
||||
int textureid;
|
||||
};
|
||||
private static class ModelBlockImpl implements ModelBlock {
|
||||
private HashMap<BlockSide, ModelSide> sides = new HashMap<BlockSide, ModelSide>();
|
||||
private double[] from = { 0, 0, 0 };
|
||||
private double[] to = { 16, 16, 16 };
|
||||
@Override
|
||||
public void addBlockSide(BlockSide side, double[] uv, int textureid) {
|
||||
ModelSide ms = new ModelSide();
|
||||
ms.textureid = textureid;
|
||||
if (uv != null) {
|
||||
ms.uv = Arrays.copyOf(uv, uv.length);
|
||||
}
|
||||
if (side == BlockSide.FACE_0 || side == BlockSide.Y_MINUS) side = BlockSide.BOTTOM;
|
||||
if (side == BlockSide.FACE_1 || side == BlockSide.Y_PLUS) side = BlockSide.TOP;
|
||||
if (side == BlockSide.FACE_2 || side == BlockSide.Z_MINUS) side = BlockSide.NORTH;
|
||||
if (side == BlockSide.FACE_3 || side == BlockSide.Z_PLUS) side = BlockSide.SOUTH;
|
||||
if (side == BlockSide.FACE_4 || side == BlockSide.X_MINUS) side = BlockSide.WEST;
|
||||
if (side == BlockSide.FACE_5 || side == BlockSide.X_PLUS) side = BlockSide.EAST;
|
||||
|
||||
sides.put(side, ms);
|
||||
}
|
||||
}
|
||||
private ArrayList<ModelBlockImpl> boxes = new ArrayList<ModelBlockImpl>();
|
||||
private String rotsourceblockname;
|
||||
private int rotsourcemetaindex;
|
||||
private int xrot, yrot, zrot;
|
||||
|
||||
public ModelBlockModelImpl(String blkname, ModModelDefinitionImpl mdf) {
|
||||
super(blkname, mdf);
|
||||
}
|
||||
|
||||
public ModelBlockModelImpl(String blkname, ModModelDefinitionImpl mdf, ModelBlockModel mod, int xrot, int yrot, int zrot) {
|
||||
super(blkname, mdf);
|
||||
this.rotsourceblockname = mod.getBlockNames()[0];
|
||||
this.rotsourcemetaindex = Integer.numberOfTrailingZeros(mod.getMetaValueMask());
|
||||
this.xrot = xrot; this.yrot = yrot; this.zrot = zrot;
|
||||
}
|
||||
|
||||
private static HashMap<BlockSide, String> fromBlockSide = new HashMap<BlockSide, String>();
|
||||
static {
|
||||
fromBlockSide.put(BlockSide.TOP, "u");
|
||||
fromBlockSide.put(BlockSide.BOTTOM, "d");
|
||||
fromBlockSide.put(BlockSide.NORTH, "n");
|
||||
fromBlockSide.put(BlockSide.SOUTH, "s");
|
||||
fromBlockSide.put(BlockSide.WEST, "e");
|
||||
fromBlockSide.put(BlockSide.EAST, "w");
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getLine() {
|
||||
String ids = this.getIDsAndMeta();
|
||||
if (ids == null) return null;
|
||||
String line = String.format("patchblock:%s", ids);
|
||||
// If rotating another model
|
||||
if (rotsourceblockname != null) {
|
||||
line += "\npatchrotate:id=" + rotsourceblockname + ",data=" + rotsourcemetaindex;
|
||||
if (xrot != 0) {
|
||||
line += ",rotx=" + xrot;
|
||||
}
|
||||
if (yrot != 0) {
|
||||
line += ",roty=" + yrot;
|
||||
}
|
||||
if (zrot != 0) {
|
||||
line += ",rotz=" + yrot;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (ModelBlockImpl mb: boxes) {
|
||||
line += String.format(",box=%f/%f/%f:%f/%f/%f", mb.from[0], mb.from[1], mb.from[2], mb.to[0], mb.to[1], mb.to[2]);
|
||||
for (BlockSide bs : fromBlockSide.keySet()) {
|
||||
String side = fromBlockSide.get(bs);
|
||||
ModelSide mside = mb.sides.get(bs);
|
||||
if (mside != null) {
|
||||
if (mside.uv != null) {
|
||||
line += String.format(":%s/%d/%f/%f/%f/%f", side, mside.textureid, mside.uv[0], mside.uv[1], mside.uv[2], mside.uv[3]);
|
||||
}
|
||||
else {
|
||||
line += String.format(":%s/%d", side, mside.textureid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return line;
|
||||
}
|
||||
/**
|
||||
* Factory method to build a block of patches relative to a typical element in a MC model file.
|
||||
* Specifically, all coordinates are relative to 0-16 range for
|
||||
* side of a cube, and relative to 0-16 range for U,V within a texture:
|
||||
*
|
||||
* from, to in model drive 'from', 'to' inputs
|
||||
*
|
||||
* face, uv of face, and texture in model drives face, uv, textureid (added using addBlockSide)
|
||||
*
|
||||
* @param from - vector of lower left corner of box (0-16 range for coordinates - min x, y, z)
|
||||
* @param to - vector of upper right corner of box (0-16 range for coordinates max x, y, z)
|
||||
* @return model block to add faces to
|
||||
*/
|
||||
public ModelBlock addModelBlock(double[] from, double[] to) {
|
||||
ModelBlockImpl mbi = new ModelBlockImpl();
|
||||
if (from != null) { mbi.from[0] = from[0]; mbi.from[1] = from[1]; mbi.from[2] = from[2]; }
|
||||
if (to != null) { mbi.to[0] = to[0]; mbi.to[1] = to[1]; mbi.to[2] = to[2]; }
|
||||
boxes.add(mbi);
|
||||
return mbi;
|
||||
}
|
||||
}
|
@ -46,15 +46,6 @@ public class PatchBlockModelImpl extends BlockModelImpl implements PatchBlockMod
|
||||
return pi;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public String addPatch(double x0, double y0, double z0, double xu, double yu,
|
||||
double zu, double xv, double yv, double zv, double umin,
|
||||
double umax, double vmin, double vmax, double uplusvmax,
|
||||
SideVisible sidevis) {
|
||||
return addPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vmin, vmax, ((uplusvmax - umax) < vmax) ? uplusvmax - umax : vmax, sidevis);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String addPatch(double x0, double y0, double z0, double xu, double yu,
|
||||
double zu, double xv, double yv, double zv, SideVisible sidevis) {
|
||||
|
@ -1,9 +1,20 @@
|
||||
package org.dynmap.utils;
|
||||
|
||||
import org.dynmap.Log;
|
||||
import org.dynmap.modsupport.BlockSide;
|
||||
import org.dynmap.renderer.RenderPatch;
|
||||
import org.dynmap.renderer.RenderPatchFactory.SideVisible;
|
||||
|
||||
//
|
||||
// (v = 1) umin umax
|
||||
// x0+xv,y0+yv,z0+zv *-----|-------|--------* (u=1, v=1) x0,y0,z0 = lower left corner relative to cube origin (0,0,0 to 1,1,1)
|
||||
// | | | | length of xu,yu,zu = width of whole texture (u=0 to u=1)
|
||||
// |-----+=======+--------| vmax length of xv,yv,zv = height of whole texture (v=0 to v=1)
|
||||
// | [visible] | umin to umax = clipping (visible portion of texture) horizontally
|
||||
// |-----+=======+--------| vmin vmin to vmax = clipping (visible portion of texture) vertically
|
||||
// (u=0,v=0)| | | |
|
||||
// x0,y0,z0 *----|-------|--------* x0+xu, y0+yu, z0+zu (u = 1)
|
||||
//
|
||||
/* Define patch in surface-based models - origin (xyz), u-vector (xyz) v-vector (xyz), u limits and v limits */
|
||||
public class PatchDefinition implements RenderPatch {
|
||||
public double x0, y0, z0; /* Origin of patch (lower left corner of texture) */
|
||||
@ -280,4 +291,112 @@ public class PatchDefinition implements RenderPatch {
|
||||
return String.format("xyz0=%f/%f/%f,xyzU=%f/%f/%f,xyzV=%f/%f/%f,minU=%f,maxU=%f,vMin=%f/%f,vmax=%f/%f,side=%s,txtidx=%d",
|
||||
x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vminatumax, vmax, vmaxatumax, sidevis, textureindex);
|
||||
}
|
||||
|
||||
//
|
||||
// Update patch relative to typical parameters found in
|
||||
// minecraft model files. Specifically, all coordinates are relative to 0-16 range for
|
||||
// side of a cube, and relative to 0-16 range for U,V within a texture:
|
||||
//
|
||||
// from, to in model drive 'from', 'to' inputs
|
||||
// face, uv of face, and texture in model drives face, uv, textureid
|
||||
//
|
||||
// @param from - vector of lower left corner of box (0-16 range for coordinates - min x, y, z)
|
||||
// @param to - vector of upper right corner of box (0-16 range for coordinates max x, y, z)
|
||||
// @param face - which face (determines use of xyz-min vs xyz-max
|
||||
// @param uv - bounds on UV (umin, vmin, umax, vmax): if undefined, default based on face range (minecraft UV is relative to top left corner of texture)
|
||||
// @param textureid - texture ID
|
||||
public void updateModelFace(double[] from, double[] to, BlockSide face, double[] uv, int textureid) {
|
||||
// Based on face, figure out coordinates of face corner (lower left for x0, y0, z0 - lower right for xu, yu, zy - top left for xv, yv, zv)
|
||||
double x0 = 0, xu = 1, xv = 0, y0 = 0, yu = 0, yv = 1, z0 = 0, zu = 0, zv = 0;
|
||||
double umin = 0, vmin = 0, umax = 1, vmax = 1;
|
||||
switch (face) {
|
||||
case BOTTOM:
|
||||
case FACE_0:
|
||||
case Y_MINUS:
|
||||
// Bottom - Y-negative (top towards south (+Z), right towards east (+x))
|
||||
x0 = xv = from[0] / 16.0; xu = to[0] / 16.0;
|
||||
y0 = yu = yv = from[1] / 16.0; // Bottom
|
||||
z0 = zu = from[2] / 16.0; zv = to[2] / 16.0;
|
||||
umin = x0; umax = xu;
|
||||
vmin = z0; vmax = zv;
|
||||
break;
|
||||
case TOP:
|
||||
case FACE_1:
|
||||
case Y_PLUS:
|
||||
// Top - Y-positive (top towards north (-Z), right towards east (+x))
|
||||
x0 = xv = from[0] / 16.0; xu = to[0] / 16.0;
|
||||
y0 = yu = yv = to[1] / 16.0; // Top
|
||||
z0 = zu = to[2] / 16.0; zv = from[2] / 16.0;
|
||||
umin = x0; umax = xu;
|
||||
vmin = 1 - z0; vmax = 1 - zv;
|
||||
break;
|
||||
case NORTH:
|
||||
case FACE_2:
|
||||
case Z_MINUS:
|
||||
// North - Z-negative (top towards up (+Y), right towards west (-X))
|
||||
x0 = xv = to[0] / 16.0; xu = from[0] / 16.0;
|
||||
y0 = yu = from[1] / 16.0; yv = to[1] / 16.0;
|
||||
z0 = zu = zv = from[2] / 16.0;
|
||||
umin = 1 - x0; umax = 1 - xu;
|
||||
vmin = y0; vmax = yv;
|
||||
break;
|
||||
case SOUTH:
|
||||
case FACE_3:
|
||||
case Z_PLUS:
|
||||
// South - Z-positive (top towards up (+Y), right towards east (+X))
|
||||
x0 = xv = from[0] / 16.0; xu = to[0] / 16.0;
|
||||
y0 = yu = from[1] / 16.0; yv = to[1] / 16.0;
|
||||
z0 = zu = zv = to[2] / 16.0;
|
||||
umin = x0; umax = xu;
|
||||
vmin = y0; vmax = yv;
|
||||
break;
|
||||
case WEST:
|
||||
case FACE_4:
|
||||
case X_MINUS:
|
||||
// West - X-negative (top towards up (+Y), right towards south (+Z))
|
||||
x0 = xu = xv = from[0] / 16.0;
|
||||
y0 = yu = from[1] / 16.0; yv = to[1] / 16.0;
|
||||
z0 = zv = from[2] / 16.0; zu = to[2] / 16.0;
|
||||
umin = z0; umax = zu;
|
||||
vmin = y0; vmax = yv;
|
||||
break;
|
||||
case EAST:
|
||||
case FACE_5:
|
||||
case X_PLUS:
|
||||
// East - X-positive (top towards up (+Y), right towards north (-Z))
|
||||
x0 = xu = xv = to[0] / 16.0;
|
||||
y0 = yu = from[1] / 16.0; yv = to[1] / 16.0;
|
||||
z0 = zv = to[2] / 16.0; zu = from[2] / 16.0;
|
||||
umin = 1 - z0; umax = 1 - zu;
|
||||
vmin = y0; vmax = yv;
|
||||
break;
|
||||
default:
|
||||
Log.severe("Invalid side: " + face);
|
||||
return;
|
||||
}
|
||||
// If uv provided, use it to override
|
||||
if ((uv != null) && (uv.length == 4)) {
|
||||
umin = uv[0] / 16.0;
|
||||
vmin = 1 - (uv[3] / 16.0); // MC V is inverted from our V
|
||||
umax = uv[2] / 16.0;
|
||||
vmax = 1 - (uv[1] / 16.0); // MC V is inverted from our V
|
||||
}
|
||||
// Compute texture origin for u,y = 0,0, based on coordinates
|
||||
// x0,y0,z0 = u=umin,v=vmin; xu,yu,zu = u=umax,v=vmin; xv,yv,zv = u=umin,v=vmax
|
||||
// Compute U vector (based on proportion of umax-umin versus U offset
|
||||
double uvectx = (xu - x0) / (umax - umin);
|
||||
double uvecty = (yu - y0) / (umax - umin);
|
||||
double uvectz = (zu - z0) / (umax - umin);
|
||||
// Compute V vector (based on proportion of vmax-vmin versus V offset
|
||||
double vvectx = (xv - x0) / (vmax - vmin);
|
||||
double vvecty = (yv - y0) / (vmax - vmin);
|
||||
double vvectz = (zv - z0) / (vmax - vmin);
|
||||
// Compute origin based on U vector and umin and V vector and vmin vs x0,y0,z0
|
||||
double ovectx = x0 - (uvectx * umin) - (vvectx * vmin);
|
||||
double ovecty = y0 - (uvecty * umin) - (vvecty * vmin);
|
||||
double ovectz = z0 - (uvectz * umin) - (vvectz * vmin);
|
||||
|
||||
update(ovectx, ovecty, ovectz, uvectx + ovectx, uvecty + ovecty, uvectz + ovectz, vvectx + ovectx, vvecty + ovecty, vvectz + ovectz,
|
||||
umin, umax, vmin, vmax, SideVisible.TOP, textureid, vmin, vmax);
|
||||
}
|
||||
}
|
||||
|
@ -4,8 +4,11 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.dynmap.hdmap.TexturePack;
|
||||
import org.dynmap.modsupport.BlockSide;
|
||||
import org.dynmap.renderer.RenderPatch;
|
||||
import org.dynmap.renderer.RenderPatchFactory;
|
||||
import org.dynmap.renderer.RenderPatchFactory.SideVisible;
|
||||
import org.dynmap.Log;
|
||||
|
||||
public class PatchDefinitionFactory implements RenderPatchFactory {
|
||||
private HashMap<PatchDefinition,PatchDefinition> patches = new HashMap<PatchDefinition,PatchDefinition>();
|
||||
@ -62,6 +65,22 @@ public class PatchDefinitionFactory implements RenderPatchFactory {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public PatchDefinition getModelFace(double[] from, double[] to, BlockSide face, double[] uv, int textureid) {
|
||||
synchronized(lock) {
|
||||
lookup.updateModelFace(from, to, face, uv, textureid);
|
||||
if(lookup.validate() == false)
|
||||
return null;
|
||||
PatchDefinition pd2 = patches.get(lookup); /* See if in cache already */
|
||||
if(pd2 == null) {
|
||||
PatchDefinition pd = new PatchDefinition(lookup);
|
||||
patches.put(pd, pd);
|
||||
pd2 = pd;
|
||||
}
|
||||
return pd2;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderPatch getRotatedPatch(RenderPatch patch, int xrot, int yrot,
|
||||
int zrot, int textureindex) {
|
||||
@ -163,4 +182,30 @@ public class PatchDefinitionFactory implements RenderPatchFactory {
|
||||
return TexturePack.getTextureMapLength(id);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
PatchDefinitionFactory fact = new PatchDefinitionFactory();
|
||||
BlockSide[] faces = { BlockSide.BOTTOM, BlockSide.TOP, BlockSide.NORTH, BlockSide.SOUTH, BlockSide.WEST, BlockSide.EAST };
|
||||
double[] from = { 0,0,0 };
|
||||
double[] to = { 16,16,16 };
|
||||
|
||||
// Do normal faces, default limits
|
||||
PatchDefinition pd = new PatchDefinition();
|
||||
for (BlockSide face : faces) {
|
||||
pd.updateModelFace(from, to, face, null, 0);
|
||||
System.out.println("Full cube " + face + ": " + pd);
|
||||
}
|
||||
|
||||
double[] toquarter = { 8,8,8 };
|
||||
for (BlockSide face : faces) {
|
||||
pd.updateModelFace(from, toquarter, face, null, 0);
|
||||
System.out.println("8x8x8 cube " + face + ": " + pd);
|
||||
}
|
||||
|
||||
|
||||
for (BlockSide face : faces) {
|
||||
pd.updateModelFace(from, toquarter, face, new double[] { 4, 4, 12, 12 }, 0);
|
||||
System.out.println("Full cube, middle half of texture " + face + ": " + pd);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -946,66 +946,38 @@ patchrotate:id=anvil,data=1,rot=180
|
||||
# Daylight Sensor
|
||||
boxblock:id=daylight_detector,ymax=0.375
|
||||
|
||||
# (149) Redstone Comparator (inactive)
|
||||
# (150) Redstone Comparator (active)
|
||||
block:id=comparator,data=0,data=1,data=2,data=3,scale=16
|
||||
layer:0,1
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
****************
|
||||
layer:2,3
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
---**-----------
|
||||
---**-----------
|
||||
----------------
|
||||
------------**--
|
||||
------------**--
|
||||
----------------
|
||||
---**-----------
|
||||
---**-----------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
layer:4,5,6
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
---**-----------
|
||||
---**-----------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
---**-----------
|
||||
---**-----------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
----------------
|
||||
block:id=comparator,data=4,data=5,data=6,data=7,scale=16
|
||||
rotate:id=comparator,data=0,rot=90
|
||||
block:id=comparator,,data=8,data=9,data=10,data=11,scale=16
|
||||
rotate:id=comparator,data=0,rot=180
|
||||
block:id=comparator,data=12,data=13,data=14,data=15,scale=16
|
||||
rotate:id=comparator,data=0,rot=270
|
||||
# Comparator (compare mode, off) - slab, comparator, unlit, lit, comparator_on
|
||||
modellist:id=comparator,data=5,box=0/0/0:16/2/16:d/0/0/0/16/16:u/1/0/0/16/16:n/0/0/14/16/16:s/0/0/14/16/16:w/0/0/14/16/16:e/0/0/14/16/16,box=4/2/11:6/7/13:d/2/7/13/9/15:u/2/7/6/9/8:n/2/7/6/9/11:s/2/7/6/9/11:w/2/7/6/9/11:e/2/7/6/9/11,box=10/2/11:12/7/13:d/2/7/13/9/15:u/2/7/6/9/8:n/2/7/6/9/11:s/2/7/6/9/11:w/2/7/6/9/11:e/2/7/6/9/11,box=7/2/2:9/4/4:d/2/7/13/9/15:u/2/7/6/9/8:n/2/7/6/9/8:s/2/7/6/9/8:w/2/7/6/9/8:e/2/7/6/9/8
|
||||
patchblock:id=comparator,data=1
|
||||
patchrotate:id=comparator,data=5,rot=180
|
||||
patchblock:id=comparator,data=9
|
||||
patchrotate:id=comparator,data=5,rot=90
|
||||
patchblock:id=comparator,data=13
|
||||
patchrotate:id=comparator,data=5,rot=270
|
||||
# Comparator (compare mode, on) - slab, comparator, unlit, lit, comparator_on
|
||||
modellist:id=comparator,data=4,box=0/0/0:16/2/16:d/0/0/0/16/16:u/4/0/0/16/16:n/0/0/14/16/16:s/0/0/14/16/16:w/0/14/16/16:e/0/14/16/16,box=4/7/11:6/7/13:u/3/7/6/9/8,box=4/2/10:6/8/14:w/3/6/5/10/11:e/3/6/5/10/11,box=3/2/11:7/8/13:n/3/6/5/10/11:s/3/6/5/10/11,box=10/7/11:12/7/13:u/3/7/6/9/8,box=10/1/10:12/8/14:w/3/6/5/10/11:e/3/6/5/10/11,box=9/2/11:13/8/13:n/3/6/5/10/11:s/3/6/5/10/11,box=7/2/2:9/4/4:d/2/7/13/9/15:u/2/7/6/9/8:n/2/7/6/9/8:s/2/7/6/9/8:w/2/7/6/9/8:e/2/7/6/9/8
|
||||
patchblock:id=comparator,data=0
|
||||
patchrotate:id=comparator,data=4,rot=180
|
||||
patchblock:id=comparator,data=8
|
||||
patchrotate:id=comparator,data=4,rot=90
|
||||
patchblock:id=comparator,data=12
|
||||
patchrotate:id=comparator,data=4,rot=270
|
||||
# Comparator (subtract mode, off) - slab, comparator, unlit, lit, comparator_on
|
||||
modellist:id=comparator,data=7,box=0/0/0:16/2/16:d/0/0/0/16/16:u/1/0/0/16/16:n/0/0/14/16/16:s/0/0/14/16/16:e/0/0/14/16/16:w/0/0/14/16/16,box=4/2/11:6/7/13:d/2/7/13/9/15:u/2/7/6/9/8:n/2/7/6/9/11:s/2/7/6/9/11:w/2/7/6/9/11:e/2/7/6/9/11,box=10/2/11:12/7/13:d/2/7/13/9/15:u/2/7/6/9/8:n/2/7/6/9/11:s/2/7/6/9/11:w/2/7/6/9/11:e/2/7/6/9/11,box=7/5/2:9/5/4:u/3/7/6/9/8,box=7/2/1:9/6/5:w/3/6/5/10/9:e/3/6/5/10/9,box=6/2/2:10/6/4:n/3/6/5/10/9:s/3/6/5/10/9
|
||||
patchblock:id=comparator,data=3
|
||||
patchrotate:id=comparator,data=7,rot=180
|
||||
patchblock:id=comparator,data=11
|
||||
patchrotate:id=comparator,data=7,rot=90
|
||||
patchblock:id=comparator,data=15
|
||||
patchrotate:id=comparator,data=7,rot=270
|
||||
# Comparator (subtract mode, on) - slab, comparator, unlit, lit, comparator_on
|
||||
modellist:id=comparator,data=6,box=0/0/0:16/2/16:d/0/0/0/16/16:u/4/0/0/16/16:n/0/0/14/16/16:s/0/0/14/16/16:w/0/0/14/16/16:e/0/0/14/16/16,box=4/7/11:6/7/13:u/3/7/6/9/8,box=4/2/10:6/8/14:w/3/6/5/10/11:e/3/6/5/10/11,box=3/2/11:7/8/13:n/3/6/5/10/11:s/3/6/5/10/11,box=10/7/11:12/7/13:u/3/7/6/9/8,box=10/2/10:12/8/14:w/3/6/5/10/11:e/3/6/5/10/11,box=9/2/11:13/8/13:n/3/6/5/10/11:s/3/6/5/10/11,box=7/5/2:9/5/4:u/3/7/6/9/8,box=7/2/1:9/6/5:w/3/6/5/10/9:e/3/6/5/10/9,box=6/2/2:10/6/4:n/3/6/5/10/9:s/3/6/5/10/9
|
||||
patchblock:id=comparator,data=2
|
||||
patchrotate:id=comparator,data=6,rot=180
|
||||
patchblock:id=comparator,data=10
|
||||
patchrotate:id=comparator,data=6,rot=90
|
||||
patchblock:id=comparator,data=14
|
||||
patchrotate:id=comparator,data=6,rot=270
|
||||
|
||||
# (154) Hopper
|
||||
block:id=hopper,scale=16
|
||||
|
@ -88,6 +88,7 @@ texture:id=dropper_front
|
||||
texture:id=dropper_front_vertical
|
||||
texture:id=hopper_inside
|
||||
texture:id=hopper_outside
|
||||
texture:id=smooth_stone
|
||||
texture:id=black_terracotta
|
||||
texture:id=blue_terracotta
|
||||
texture:id=brown_terracotta
|
||||
@ -1358,16 +1359,8 @@ block:id=light_weighted_pressure_plate,allfaces=0:gold_block,stdrot=true,transpa
|
||||
# Heavy weighted pressure plate
|
||||
block:id=heavy_weighted_pressure_plate,allfaces=0:iron_block,stdrot=true,transparency=TRANSPARENT
|
||||
|
||||
# Redstone Comparator (active)
|
||||
block:id=comparator,data=0,data=2,top=6000:comparator_on,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
block:id=comparator,data=4,data=6,top=5000:comparator_on,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
block:id=comparator,data=8,data=10,top=4000:comparator_on,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
block:id=comparator,data=12,data=14,top=0:comparator_on,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
# Redstone Comparator (inactive)
|
||||
block:id=comparator,data=1,data=3,top=6000:comparator,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
block:id=comparator,data=5,data=7,top=5000:comparator,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
block:id=comparator,data=9,data=11,top=4000:comparator,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
block:id=comparator,data=13,data=15,top=0:comparator,allsides=0:stone,bottom=0:stone,transparency=TRANSPARENT
|
||||
# Comparator (on)
|
||||
block:id=comparator,data=*,patch0=0:smooth_stone,patch1=0:comparator,patch2=0:redstone_torch_off,patch3=0:redstone_torch,patch4=0:comparator_on,transparency=TRANSPARENT
|
||||
|
||||
# Daylight Sensor
|
||||
# Inverted Daylight Sensor
|
||||
@ -2132,7 +2125,6 @@ block:id=black_banner,id=black_wall_banner,data=*,patch0=0:oak_planks,patch1=0:b
|
||||
[1.14-]texture:id=wither_rose
|
||||
[1.14-]texture:id=lily_of_the_valley
|
||||
[1.14-]texture:id=smooth_stone_slab_side
|
||||
[1.14-]texture:id=smooth_stone
|
||||
[1.14-]texture:id=bamboo_stage0
|
||||
[1.14-]texture:id=bamboo_stalk
|
||||
[1.14-]texture:id=scaffolding_top
|
||||
|
@ -151,6 +151,22 @@ public interface ModModelDefinition {
|
||||
* @return block model record
|
||||
*/
|
||||
public PatchBlockModel addRotatedPatchModel(String blockname, PatchBlockModel model, int xrot, int yrot, int zrot);
|
||||
/**
|
||||
* Add model block model: default assumes all metadata values are matching
|
||||
* @param blockname - block name
|
||||
* @return block model record
|
||||
*/
|
||||
public ModelBlockModel addModelBlockModel(String blockname);
|
||||
/**
|
||||
* Add rotated model block model, based on existing model : default assumes all metadata values are matching
|
||||
* @param blockname - block name
|
||||
* @param model - existing model to be rotated
|
||||
* @param xrot - x rotation in degrees (0, 90, 180, 270)
|
||||
* @param yrot - y rotation in degrees (0, 90, 180, 270)
|
||||
* @param zrot - z rotation in degrees (0, 90, 180, 270)
|
||||
* @return block model record
|
||||
*/
|
||||
public ModelBlockModel addRotatedModelBlockModel(String blockname, ModelBlockModel model, int xrot, int yrot, int zrot);
|
||||
/**
|
||||
* Final call for model definition: publishes definiiton to Dynmap to be used for the mod
|
||||
* @return true if successful, false if error
|
||||
|
@ -0,0 +1,32 @@
|
||||
package org.dynmap.modsupport;
|
||||
|
||||
// Model for more direct translation of MC models
|
||||
// All coordinates are 0-16 range per block, and 0-16 range for UV
|
||||
|
||||
public interface ModelBlockModel extends BlockModel {
|
||||
|
||||
public interface ModelBlock {
|
||||
/**
|
||||
* Factory method for adding a side to a model block started using addModelBlock.
|
||||
*
|
||||
* @param face - which face (determines use of xyz-min vs xyz-max
|
||||
* @param uv - bounds on UV (umin, vmin, umax, vmax): if null, default based on face range
|
||||
* @param textureid - texture ID
|
||||
*/
|
||||
public void addBlockSide(BlockSide side, double[] uv, int textureid);
|
||||
}
|
||||
/**
|
||||
* Factory method to build a block of patches relative to a typical element in a MC model file.
|
||||
* Specifically, all coordinates are relative to 0-16 range for
|
||||
* side of a cube, and relative to 0-16 range for U,V within a texture:
|
||||
*
|
||||
* from, to in model drive 'from', 'to' inputs
|
||||
*
|
||||
* face, uv of face, and texture in model drives face, uv, textureid (added using addBlockSide)
|
||||
*
|
||||
* @param from - vector of lower left corner of box (0-16 range for coordinates - min x, y, z)
|
||||
* @param to - vector of upper right corner of box (0-16 range for coordinates max x, y, z)
|
||||
* @return model block to add faces to
|
||||
*/
|
||||
public ModelBlock addModelBlock(double[] from, double[] to);
|
||||
}
|
@ -6,36 +6,6 @@ import org.dynmap.renderer.RenderPatchFactory.SideVisible;
|
||||
* Patch block model
|
||||
*/
|
||||
public interface PatchBlockModel extends BlockModel {
|
||||
/**
|
||||
* Add patch with given attributes.
|
||||
*
|
||||
* Definition is a 2D parallelogram surface, with origin <x0,y0,z0> within the block, and defined by two edge vectors -
|
||||
* one with and end point of <xu,yu,zu>, and a second with an end point of <xv,yv,zv>. The patch is
|
||||
* defined within the unit vector range umin to umax (parallel to the U vecotr) and vmin to vmax
|
||||
* (parallel to the V vector).
|
||||
* The surface can be visible via one side (SideVisible.TOP, SideVisible.BOTTOM) or both sides (SideVisible.BOTH).
|
||||
*
|
||||
* @param x0 - X coordinate of origin of patch
|
||||
* @param y0 - Y coordinate of origin of patch
|
||||
* @param z0 - Z coordinate of origin of patch
|
||||
* @param xu - X coordinate of end of U vector
|
||||
* @param yu - Y coordinate of end of U vector
|
||||
* @param zu - Z coordinate of end of U vector
|
||||
* @param xv - X coordinate of end of V vector
|
||||
* @param yv - Y coordinate of end of V vector
|
||||
* @param zv - Z coordinate of end of V vector
|
||||
* @param umin - lower bound for visibility along U vector (use 0.0 by default)
|
||||
* @param umax - upper bound for visibility along U vector (use 1.0 by default)
|
||||
* @param vmin - lower bound for visibility along V vector (use 0.0 by default)
|
||||
* @param vmax - upper bound for visibility along V vector (use 1.0 by default)
|
||||
* @param uplusvmax - upper bound for visibility for U+V (use 100.0 by default: <=1.0 for triangle)
|
||||
* @param sidevis - Controls which sides of the surface are visible (U cross V defines normal - TOP is from that side, BOTTOM is opposite side)
|
||||
* @return patch ID
|
||||
*/
|
||||
@Deprecated
|
||||
public String addPatch(double x0, double y0, double z0, double xu,
|
||||
double yu, double zu, double xv, double yv, double zv, double umin,
|
||||
double umax, double vmin, double vmax, double uplusvmax, SideVisible sidevis);
|
||||
/**
|
||||
* Add patch with given attributes.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user