Enhance patch definition - allow for triangles, trapezoids

This commit is contained in:
Mike Primm 2018-09-02 11:38:17 -05:00
parent d6f43206d1
commit 28bb9eea87
10 changed files with 150 additions and 29 deletions

View File

@ -113,7 +113,7 @@ public class OBJExport {
for (BlockStep s : BlockStep.values()) {
double[] p = pp[s.getFaceEntered()];
int ord = s.ordinal();
defaultPathces[ord] = fact.getPatch(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], 0, 1, 0, 1, 100, SideVisible.TOP, ord);
defaultPathces[ord] = fact.getPatch(p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7], p[8], 0, 1, 0, 0, 1, 1, SideVisible.TOP, ord);
}
vertices = new IndexedVector3DList(new IndexedVector3DList.ListCallback() {
@Override

View File

@ -611,7 +611,9 @@ public class HDBlockModels {
double p_xv = 1.0, p_yv = 0.0, p_zv = 0.0;
double p_umin = 0.0, p_umax = 1.0;
double p_vmin = 0.0, p_vmax = 1.0;
double p_uplusvmax = 100.0;
double p_vmaxatumax = -1.0;
double p_vminatumax = -1.0;
double p_uplusvmax = -1.0;
SideVisible p_sidevis = SideVisible.BOTH;
for(String a : args) {
@ -660,8 +662,15 @@ public class HDBlockModels {
p_vmax = Double.parseDouble(av[1]);
}
else if(av[0].equals("UplusVmax")) {
Log.warning("UplusVmax deprecated - use VmaxAtUMax - line " + rdr.getLineNumber() + " of " + fname);
p_uplusvmax = Double.parseDouble(av[1]);
}
else if(av[0].equals("VmaxAtUMax")) {
p_vmaxatumax = Double.parseDouble(av[1]);
}
else if(av[0].equals("VminAtUMax")) {
p_vminatumax = Double.parseDouble(av[1]);
}
else if(av[0].equals("visibility")) {
if(av[1].equals("top"))
p_sidevis = SideVisible.TOP;
@ -673,9 +682,23 @@ public class HDBlockModels {
p_sidevis = SideVisible.BOTH;
}
}
// Deprecated: If set, compute umax, vmax, and vmaxatumax
if (p_uplusvmax >= 0.0) {
p_umax = p_uplusvmax;
p_vmax = p_uplusvmax;
p_vmaxatumax = 0.0;
}
// If not set, match p_vmax by default
if (p_vmaxatumax < 0.0) {
p_vmaxatumax = p_vmax;
}
// If not set, match p_vmin by default
if (p_vminatumax < 0.0) {
p_vminatumax = p_vmin;
}
/* If completed, add to map */
if(patchid != null) {
PatchDefinition pd = pdf.getPatch(p_x0, p_y0, p_z0, p_xu, p_yu, p_zu, p_xv, p_yv, p_zv, p_umin, p_umax, p_vmin, p_vmax, p_uplusvmax, p_sidevis, 0);
PatchDefinition pd = pdf.getPatch(p_x0, p_y0, p_z0, p_xu, p_yu, p_zu, p_xv, p_yv, p_zv, p_umin, p_umax, p_vmin, p_vminatumax, p_vmax, p_vmaxatumax, p_sidevis, 0);
if(pd != null) {
patchdefs.put(patchid, pd);
}

View File

@ -439,14 +439,19 @@ public class IsoHDPerspective implements HDPerspective {
vS.subtract(v0);
/* Compute u - slope times inner product of offset and cross product */
double u = inv_det * vS.innerProduct(d_cross_uv);
if((u <= pd.umin) || (u >= pd.umax)) {
if ((u <= pd.umin) || (u >= pd.umax)) {
return hitcnt;
}
/* Compute cross product of offset and U */
vS.crossProduct(pd.u);
/* Compute V using slope times inner product of direction and cross product */
double v = inv_det * direction.innerProduct(vS);
if((v <= pd.vmin) || (v >= pd.vmax) || ((u + v) >= pd.uplusvmax)) {
// Check constrains: v must be below line from (0, vmax) to (umax, vmaxatumax)
double urel = (u > pd.umin) ? ((pd.umax - pd.umin) / (u - pd.umin)) : 0.0;
double vmaxatu = pd.vmax + (pd.vmaxatumax - pd.vmax) * urel;
// Check constrains: v must be above line from (0, vmin) to (umax, vminatumax)
double vminatu = pd.vmin + (pd.vminatumax - pd.vmin) * urel;
if ((v <= vminatu) || (v >= vmaxatu)) {
return hitcnt;
}
/* Compute parametric value of intercept */

View File

@ -193,8 +193,8 @@ public class ModModelDefinitionImpl implements ModModelDefinition {
public String getPatchID(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) {
PatchDefinition pd = pdf.getPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vmax, uplusvmax, sidevis, 0);
double umax, double vmin, double vminatumax, double vmax, double vmaxatumax, SideVisible sidevis) {
PatchDefinition pd = pdf.getPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vminatumax, vmax, vmaxatumax, sidevis, 0);
if (pd == null)
return null; // Invalid patch
for (int i = 0; i < blkPatch.size(); i++) {
@ -247,8 +247,8 @@ public class ModModelDefinitionImpl implements ModModelDefinition {
// Loop through patch definitions
for (int i = 0; i < blkPatch.size(); i++) {
PatchDefinition pd = blkPatch.get(i);
String line = String.format(Locale.US, "patch:id=patch%d,Ox=%f,Oy=%f,Oz=%f,Ux=%f,Uy=%f,Uz=%f,Vx=%f,Vy=%f,Vz=%f,Umin=%f,Umax=%f,Vmin=%f,Vmax=%f,UplusVmax=%f",
i, pd.x0, pd.y0, pd.z0, pd.xu, pd.yu, pd.zu, pd.xv, pd.yv, pd.zv, pd.umin, pd.umax, pd.vmin, pd.vmax, pd.uplusvmax);
String line = String.format(Locale.US, "patch:id=patch%d,Ox=%f,Oy=%f,Oz=%f,Ux=%f,Uy=%f,Uz=%f,Vx=%f,Vy=%f,Vz=%f,Umin=%f,Umax=%f,Vmin=%f,Vmax=%f,VmaxAtUMax=%f,VminAtUMax=%f",
i, pd.x0, pd.y0, pd.z0, pd.xu, pd.yu, pd.zu, pd.xv, pd.yv, pd.zv, pd.umin, pd.umax, pd.vmin, pd.vmax, pd.vmaxatumax, pd.vminatumax);
switch (pd.sidevis) {
case BOTTOM:
line += ",visibility=bottom";

View File

@ -39,23 +39,32 @@ public class PatchBlockModelImpl extends BlockModelImpl implements PatchBlockMod
@Override
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,
double umax, double vmin, double vminatumax, double vmax, double vmaxatumax,
SideVisible sidevis) {
String pi = mdf.getPatchID(x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vmax, uplusvmax, sidevis);
String pi = mdf.getPatchID(x0, y0, z0, xu, yu, zu, xv, yv, zv, umin, umax, vmin, vminatumax, vmax, vmaxatumax, sidevis);
patches.add(pi);
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) {
return addPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, 0.0, 1.0, 0.0, 1.0, 100.0, sidevis);
return addPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, sidevis);
}
@Override
public String addPatch(double x0, double y0, double z0, double xu, double yu,
double zu, double xv, double yv, double zv) {
return addPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, 0.0, 1.0, 0.0, 1.0, 100.0, SideVisible.BOTH);
return addPatch(x0, y0, z0, xu, yu, zu, xv, yv, zv, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, SideVisible.BOTH);
}
@Override

View File

@ -8,11 +8,11 @@ public class PlantBlockModelImpl extends BlockModelImpl implements PlantBlockMod
public PlantBlockModelImpl(int blkid, ModModelDefinitionImpl mdf) {
super(blkid, mdf);
patch0 = mdf.getPatchID(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 100.0, SideVisible.FLIP);
patch0 = mdf.getPatchID(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, SideVisible.FLIP);
}
public PlantBlockModelImpl(String blkname, ModModelDefinitionImpl mdf) {
super(blkname, mdf);
patch0 = mdf.getPatchID(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 100.0, SideVisible.FLIP);
patch0 = mdf.getPatchID(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, SideVisible.FLIP);
}

View File

@ -11,7 +11,8 @@ public class PatchDefinition implements RenderPatch {
public double xv, yv, zv; /* Coordinates of end of V vector (relative to origin) - corresponds to v=1.0 (upper left corner) */
public double umin, umax; /* Limits of patch - minimum and maximum u value */
public double vmin, vmax; /* Limits of patch - minimum and maximum v value */
public double uplusvmax; /* Limits of patch - max of u+v (triangle) */
public double vmaxatumax; /* Limits of patch - max v value at max u (allows triangle or trapezoid) */
public double vminatumax; /* Limits of patch - min v value at max u (allows triangle or trapezoid) */
public Vector3D u, v; /* U and V vector, relative to origin */
public SideVisible sidevis; /* Which side is visible */
public int textureindex;
@ -26,7 +27,8 @@ public class PatchDefinition implements RenderPatch {
yv = zv = 0.0; xv = 1.0;
umin = vmin = 0.0;
umax = vmax = 1.0;
uplusvmax = 100.0;
vmaxatumax = 1.0;
vminatumax = 0.0;
u = new Vector3D();
v = new Vector3D();
sidevis = SideVisible.BOTH;
@ -47,7 +49,8 @@ public class PatchDefinition implements RenderPatch {
this.vmin = pd.vmin;
this.umax = pd.umax;
this.vmax = pd.vmax;
this.uplusvmax = pd.uplusvmax;
this.vmaxatumax = pd.vmaxatumax;
this.vminatumax = pd.vminatumax;
this.u = new Vector3D(pd.u);
this.v = new Vector3D(pd.v);
this.sidevis = pd.sidevis;
@ -75,7 +78,8 @@ public class PatchDefinition implements RenderPatch {
xv = vec.x; yv = vec.y; zv = vec.z;
umin = orig.umin; vmin = orig.vmin;
umax = orig.umax; vmax = orig.vmax;
uplusvmax = orig.uplusvmax;
vmaxatumax = orig.vmaxatumax;
vminatumax = orig.vminatumax;
sidevis = orig.sidevis;
this.textureindex = textureindex;
u = new Vector3D();
@ -104,8 +108,8 @@ public class PatchDefinition implements RenderPatch {
}
public void update(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,
int textureids) {
double umax, double vmin, double vmax, SideVisible sidevis,
int textureids, double vminatumax, double vmaxatumax) {
this.x0 = x0;
this.y0 = y0;
this.z0 = z0;
@ -119,7 +123,8 @@ public class PatchDefinition implements RenderPatch {
this.umax = umax;
this.vmin = vmin;
this.vmax = vmax;
this.uplusvmax = uplusvmax;
this.vmaxatumax = vmaxatumax;
this.vminatumax = vminatumax;
this.sidevis = sidevis;
this.textureindex = textureids;
update();
@ -131,7 +136,7 @@ public class PatchDefinition implements RenderPatch {
hc = (int)((Double.doubleToLongBits(x0 + xu + xv) >> 32) ^
(Double.doubleToLongBits(y0 + yu + yv) >> 34) ^
(Double.doubleToLongBits(z0 + yu + yv) >> 36) ^
(Double.doubleToLongBits(umin + umax + vmin + vmax + uplusvmax) >> 38)) ^
(Double.doubleToLongBits(umin + umax + vmin + vmax + vmaxatumax) >> 38)) ^
(sidevis.ordinal() << 8) ^ textureindex;
/* Now compute normal of surface - U cross V */
double crossx = (u.y*v.z) - (u.z*v.y);
@ -229,6 +234,14 @@ public class PatchDefinition implements RenderPatch {
Log.severe("Invalid vmax=" + vmax);
good = false;
}
if ((vminatumax < 0.0) || (vminatumax > vmaxatumax)) {
Log.severe("Invalid vminatumax=" + vminatumax);
good = false;
}
if(vmaxatumax > 1.0) {
Log.severe("Invalid vmaxatumax=" + vmaxatumax);
good = false;
}
return good;
}
@ -244,7 +257,8 @@ public class PatchDefinition implements RenderPatch {
(xv == p.xv) && (yv == p.yv) && (zv == p.zv) &&
(umin == p.umin) && (umax == p.umax) &&
(vmin == p.vmin) && (vmax == p.vmax) &&
(uplusvmax == p.uplusvmax) && (sidevis == p.sidevis)) {
(vmaxatumax == p.vmaxatumax) &&
(vminatumax == p.vminatumax) && (sidevis == p.sidevis)) {
return true;
}
}

View File

@ -26,23 +26,30 @@ public class PatchDefinitionFactory implements RenderPatchFactory {
double yu, double zu, double xv, double yv, double zv, double umin,
double umax, double vmin, double vmax, SideVisible sidevis,
int textureids) {
return getPatch(x0, y0, z0, xu, yu, zu,xv, yv, zv, umin, umax, vmin, vmax, 100.0, sidevis, textureids);
return getPatch(x0, y0, z0, xu, yu, zu,xv, yv, zv, umin, umax, vmin, vmax, sidevis, textureids, vmin, vmax);
}
@Override
public RenderPatch getPatch(double x0, double y0, double z0, double xu,
double yu, double zu, double xv, double yv, double zv,
double uplusvmax, SideVisible sidevis, int textureids) {
return getPatch(x0, y0, z0, xu, yu, zu,xv, yv, zv, 0.0, 1.0, 0.0, 1.0, uplusvmax, sidevis, textureids);
return getPatch(x0, y0, z0, xu, yu, zu,xv, yv, zv, 0.0, uplusvmax, 0.0, uplusvmax, sidevis, textureids, 0.0, 0.0);
}
@Override
public PatchDefinition getPatch(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,
double umax, double vmin, double vminatumax, double vmax, double vmaxatumax, SideVisible sidevis,
int textureids) {
return getPatch(x0, y0, z0, xu, yu, zu,xv, yv, zv, umin, umax, vmin, vmax, sidevis, textureids, vminatumax, vmaxatumax);
}
public PatchDefinition getPatch(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, SideVisible sidevis,
int textureids, double vminatumax, double vmaxatumax) {
synchronized(lock) {
lookup.update(x0, y0, z0, xu, yu, zu, xv, yv, zv, umin,
umax, vmin, vmax, uplusvmax, sidevis, textureids);
umax, vmin, vmax, sidevis, textureids, vminatumax, vmaxatumax);
if(lookup.validate() == false)
return null;
PatchDefinition pd2 = patches.get(lookup); /* See if in cache already */

View File

@ -32,9 +32,40 @@ public interface PatchBlockModel extends BlockModel {
* @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.
*
* Definition is a 2D parallelogram surface, with origin &lt;x0,y0,z0&gt; within the block, and defined by two edge vectors -
* one with and end point of &lt;xu,yu,zu&gt;, and a second with an end point of &lt;xv,yv,zv&gt;. 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 at u=umin (use 0.0 by default)
* @param vminatumax - lower bound for visibility along V vector at u=umax (use 0.0 by default)
* @param vmax - upper bound for visibility along V vector at u=umin (use 1.0 by default)
* @param vmaxatumax - upper bound for visibility along V vector at u=umax (use 1.0 by default)
* @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
*/
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 vminatumax, double vmax, double vmaxatumax, SideVisible sidevis);
/**
* Add patch with given attributes.
*

View File

@ -30,6 +30,37 @@ public interface RenderPatchFactory {
* @param textureidx - texture index to be used for patch
*/
public RenderPatch getPatch(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, SideVisible sidevis, int textureidx);
/**
* Get/create patch with given attributes.
*
* Definition is a 2D parallelogram surface, with origin &lt;x0,y0,z0&gt; within the block, and defined by two edge vectors -
* one with and end point of &lt;xu,yu,zu&gt;, and a second with an end point of &lt;xv,yv,zv&gt;. The patch is
* defined within the unit vector range umin to umax (parallel to the U vector) and vmin to vmax
* (parallel to the V vector).
* vmaxatumax allows for a triangle or trapezoid, specifying the max v value at umax (with vmax treated as the max v at u=umin)
* vminatumax allows for a triangle or trapezoid, specifying the min v value at umax (with vmin treated as the min v at u=umin)
* The surface can be visible via one side (SideVisible.TOP, SideVisible.BOTTOM) or both sides (SideVisible.BOTH).
* The surface also needs to define the index of the texture to be used for shading the surface.
*
* @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 at u=umin (use 0.0 by default)
* @param vminatumax - lower bound for visibility along V vector at u=umax (use 0.0 by default)
* @param vmax - upper bound for visibility along V vector at u=umin (use 1.0 by default)
* @param vmaxatumax - upper bound for visibility along V vector at u=umax (use 1.0 by default)
* @param sidevis - Controls which sides of the surface are visible (U cross V defines normal - TOP is from that side, BOTTOM is opposite side)
* @param textureidx - texture index to be used for patch
*/
public RenderPatch getPatch(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 vminatumax, double vmax, double vmaxatumax, SideVisible sidevis, int textureidx);
/**
* Get/create patch with given attributes.
*
@ -52,6 +83,7 @@ public interface RenderPatchFactory {
* @param sidevis - Controls which sides of the surface are visible (U cross V defines normal - TOP is from that side, BOTTOM is opposite side)
* @param textureidx - texture index to be used for patch
*/
@Deprecated
public RenderPatch getPatch(double x0, double y0, double z0, double xu, double yu, double zu, double xv, double yv, double zv, double uplusvmax, SideVisible sidevis, int textureidx);
/**
* Get/create patch with given attributes.