mirror of
https://github.com/webbukkit/dynmap.git
synced 2024-12-01 06:33:38 +01:00
Merge pull request #305 from mikeprimm/hdrender
Make subblock rendering of scaled down models more accurate (esp for torches, small stuff)
This commit is contained in:
commit
0e6dfc1adf
@ -32,7 +32,7 @@ public class Color {
|
|||||||
return ((val >> 24) & 0xFF);
|
return ((val >> 24) & 0xFF);
|
||||||
}
|
}
|
||||||
public final boolean isTransparent() {
|
public final boolean isTransparent() {
|
||||||
return (val == TRANSPARENT);
|
return ((val & 0xFF000000) == TRANSPARENT);
|
||||||
}
|
}
|
||||||
public final void setTransparent() {
|
public final void setTransparent() {
|
||||||
val = TRANSPARENT;
|
val = TRANSPARENT;
|
||||||
|
@ -189,6 +189,7 @@ public class HDBlockModels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Now, use weights and indices to fill in scaled map */
|
/* Now, use weights and indices to fill in scaled map */
|
||||||
|
long accum[] = new long[map.length];
|
||||||
for(int y = 0; y < nativeres; y++) {
|
for(int y = 0; y < nativeres; y++) {
|
||||||
int ind_y = offsets[y];
|
int ind_y = offsets[y];
|
||||||
int wgt_y = weights[y];
|
int wgt_y = weights[y];
|
||||||
@ -208,7 +209,7 @@ public class HDBlockModels {
|
|||||||
for(int zz = 0; zz < 2; zz++) {
|
for(int zz = 0; zz < 2; zz++) {
|
||||||
int wz = (zz==0)?wgt_z:(res-wgt_z);
|
int wz = (zz==0)?wgt_z:(res-wgt_z);
|
||||||
if(wz == 0) continue;
|
if(wz == 0) continue;
|
||||||
map[(ind_y+yy)*res*res + (ind_z+zz)*res + (ind_x+xx)] +=
|
accum[(ind_y+yy)*res*res + (ind_z+zz)*res + (ind_x+xx)] +=
|
||||||
wx*wy*wz;
|
wx*wy*wz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -218,7 +219,7 @@ public class HDBlockModels {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(int i = 0; i < map.length; i++) {
|
for(int i = 0; i < map.length; i++) {
|
||||||
map[i] = (short)(255*map[i]/(nativeres*nativeres*nativeres));
|
map[i] = (short)(accum[i]*255/nativeres/nativeres/nativeres);
|
||||||
if(map[i] > 255) map[i] = 255;
|
if(map[i] > 255) map[i] = 255;
|
||||||
if(map[i] < 0) map[i] = 0;
|
if(map[i] < 0) map[i] = 0;
|
||||||
}
|
}
|
||||||
@ -249,6 +250,18 @@ public class HDBlockModels {
|
|||||||
if((m.databits & (1 << i)) != 0) {
|
if((m.databits & (1 << i)) != 0) {
|
||||||
if(smod == null) smod = m.getScaledMap(scale);
|
if(smod == null) smod = m.getScaledMap(scale);
|
||||||
row[i] = smod;
|
row[i] = smod;
|
||||||
|
/* if((m.blockid == 50) && (i == 5)) {
|
||||||
|
String v0 = "";
|
||||||
|
String v = "";
|
||||||
|
for(int x = 0; x < m.blockflags.length; x++)
|
||||||
|
v0 = v0 + " " + m.blockflags[x];
|
||||||
|
for(int x = 0; x < smod.length; x++) {
|
||||||
|
v = v + " " + smod[x];
|
||||||
|
if((x%scale) == (scale-1)) v += "|";
|
||||||
|
}
|
||||||
|
Log.info("src=" + v0);
|
||||||
|
Log.info("scaled=" + v);
|
||||||
|
} */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,8 +89,18 @@ public class IsoHDPerspective implements HDPerspective {
|
|||||||
int x_inc, y_inc, z_inc;
|
int x_inc, y_inc, z_inc;
|
||||||
double t_next_y, t_next_x, t_next_z;
|
double t_next_y, t_next_x, t_next_z;
|
||||||
boolean nonairhit;
|
boolean nonairhit;
|
||||||
|
/* Subblock tracer state */
|
||||||
|
int mx, my, mz;
|
||||||
|
double xx, yy, zz;
|
||||||
|
double mdt_dx;
|
||||||
|
double mdt_dy;
|
||||||
|
double mdt_dz;
|
||||||
|
double togo;
|
||||||
|
double mt_next_x, mt_next_y, mt_next_z;
|
||||||
int subalpha;
|
int subalpha;
|
||||||
double mt;
|
double mt;
|
||||||
|
double mtend;
|
||||||
|
|
||||||
int[] subblock_xyz = new int[3];
|
int[] subblock_xyz = new int[3];
|
||||||
MapIterator mapiter;
|
MapIterator mapiter;
|
||||||
boolean isnether;
|
boolean isnether;
|
||||||
@ -325,19 +335,31 @@ public class IsoHDPerspective implements HDPerspective {
|
|||||||
else if(blocktypeid == 54) { /* Special case for chest - need to fake data so we can render */
|
else if(blocktypeid == 54) { /* Special case for chest - need to fake data so we can render */
|
||||||
blockdata = generateChestBlockData(mapiter);
|
blockdata = generateChestBlockData(mapiter);
|
||||||
}
|
}
|
||||||
boolean missed = false;
|
|
||||||
|
|
||||||
/* Look up to see if block is modelled */
|
/* Look up to see if block is modelled */
|
||||||
short[] model = scalemodels.getScaledModel(blocktypeid, blockdata);
|
short[] model = scalemodels.getScaledModel(blocktypeid, blockdata);
|
||||||
if(model != null) {
|
if(model != null) {
|
||||||
missed = raytraceSubblock(model);
|
boolean firststep = true;
|
||||||
|
|
||||||
|
while(!raytraceSubblock(model, firststep)) {
|
||||||
|
boolean done = true;
|
||||||
|
skylevel = emitlevel = -1;
|
||||||
|
for(int i = 0; i < shaderstate.length; i++) {
|
||||||
|
if(!shaderdone[i])
|
||||||
|
shaderdone[i] = shaderstate[i].processBlock(this);
|
||||||
|
done = done && shaderdone[i];
|
||||||
|
}
|
||||||
|
/* If all are done, we're out */
|
||||||
|
if(done)
|
||||||
|
return true;
|
||||||
|
nonairhit = true;
|
||||||
|
firststep = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
subalpha = -1;
|
|
||||||
}
|
|
||||||
if(!missed) {
|
|
||||||
boolean done = true;
|
boolean done = true;
|
||||||
skylevel = emitlevel = -1;
|
skylevel = emitlevel = -1;
|
||||||
|
subalpha = -1;
|
||||||
for(int i = 0; i < shaderstate.length; i++) {
|
for(int i = 0; i < shaderstate.length; i++) {
|
||||||
if(!shaderdone[i])
|
if(!shaderdone[i])
|
||||||
shaderdone[i] = shaderstate[i].processBlock(this);
|
shaderdone[i] = shaderstate[i].processBlock(this);
|
||||||
@ -411,45 +433,53 @@ public class IsoHDPerspective implements HDPerspective {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean raytraceSubblock(short[] model) {
|
private boolean raytraceSubblock(short[] model, boolean firsttime) {
|
||||||
int mx = 0, my = 0, mz = 0;
|
if(firsttime) {
|
||||||
double xx, yy, zz;
|
mt = t + 0.0000001;
|
||||||
mt = t + 0.0000001;
|
xx = top.x + mt *(bottom.x - top.x);
|
||||||
xx = top.x + mt *(bottom.x - top.x);
|
yy = top.y + mt *(bottom.y - top.y);
|
||||||
yy = top.y + mt *(bottom.y - top.y);
|
zz = top.z + mt *(bottom.z - top.z);
|
||||||
zz = top.z + mt *(bottom.z - top.z);
|
mx = (int)((xx - Math.floor(xx)) * modscale);
|
||||||
mx = (int)((xx - Math.floor(xx)) * modscale);
|
my = (int)((yy - Math.floor(yy)) * modscale);
|
||||||
my = (int)((yy - Math.floor(yy)) * modscale);
|
mz = (int)((zz - Math.floor(zz)) * modscale);
|
||||||
mz = (int)((zz - Math.floor(zz)) * modscale);
|
mdt_dx = dt_dx / modscale;
|
||||||
double mdt_dx = dt_dx / modscale;
|
mdt_dy = dt_dy / modscale;
|
||||||
double mdt_dy = dt_dy / modscale;
|
mdt_dz = dt_dz / modscale;
|
||||||
double mdt_dz = dt_dz / modscale;
|
mt_next_x = t_next_x;
|
||||||
double togo;
|
mt_next_y = t_next_y;
|
||||||
double mt_next_x = t_next_x, mt_next_y = t_next_y, mt_next_z = t_next_z;
|
mt_next_z = t_next_z;
|
||||||
if(mt_next_x != Double.MAX_VALUE) {
|
if(mt_next_x != Double.MAX_VALUE) {
|
||||||
togo = ((t_next_x - t) / mdt_dx);
|
togo = ((t_next_x - t) / mdt_dx);
|
||||||
mt_next_x = mt + (togo - Math.floor(togo)) * mdt_dx;
|
mt_next_x = mt + (togo - Math.floor(togo)) * mdt_dx;
|
||||||
}
|
|
||||||
if(mt_next_y != Double.MAX_VALUE) {
|
|
||||||
togo = ((t_next_y - t) / mdt_dy);
|
|
||||||
mt_next_y = mt + (togo - Math.floor(togo)) * mdt_dy;
|
|
||||||
}
|
|
||||||
if(mt_next_z != Double.MAX_VALUE) {
|
|
||||||
togo = ((t_next_z - t) / mdt_dz);
|
|
||||||
mt_next_z = mt + (togo - Math.floor(togo)) * mdt_dz;
|
|
||||||
}
|
|
||||||
double mtend = Math.min(t_next_x, Math.min(t_next_y, t_next_z));
|
|
||||||
subalpha = -1;
|
|
||||||
while(mt < mtend) {
|
|
||||||
try {
|
|
||||||
int blkalpha = model[modscale*modscale*my + modscale*mz + mx];
|
|
||||||
if(blkalpha > 0) {
|
|
||||||
subalpha = blkalpha;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (ArrayIndexOutOfBoundsException aioobx) { /* We're outside the model, so miss */
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
if(mt_next_y != Double.MAX_VALUE) {
|
||||||
|
togo = ((t_next_y - t) / mdt_dy);
|
||||||
|
mt_next_y = mt + (togo - Math.floor(togo)) * mdt_dy;
|
||||||
|
}
|
||||||
|
if(mt_next_z != Double.MAX_VALUE) {
|
||||||
|
togo = ((t_next_z - t) / mdt_dz);
|
||||||
|
mt_next_z = mt + (togo - Math.floor(togo)) * mdt_dz;
|
||||||
|
}
|
||||||
|
mtend = Math.min(t_next_x, Math.min(t_next_y, t_next_z));
|
||||||
|
}
|
||||||
|
subalpha = -1;
|
||||||
|
boolean skip = !firsttime; /* Skip first block on continue */
|
||||||
|
while(mt < mtend) {
|
||||||
|
if(!skip) {
|
||||||
|
try {
|
||||||
|
int blkalpha = model[modscale*modscale*my + modscale*mz + mx];
|
||||||
|
if(blkalpha > 0) {
|
||||||
|
subalpha = blkalpha;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (ArrayIndexOutOfBoundsException aioobx) { /* We're outside the model, so miss */
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
skip = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* If X step is next best */
|
/* If X step is next best */
|
||||||
if((mt_next_x <= mt_next_y) && (mt_next_x <= mt_next_z)) {
|
if((mt_next_x <= mt_next_y) && (mt_next_x <= mt_next_z)) {
|
||||||
mx += x_inc;
|
mx += x_inc;
|
||||||
|
@ -148,10 +148,13 @@ public class TexturePackHDShader implements HDShader {
|
|||||||
}
|
}
|
||||||
/* Handle light level, if needed */
|
/* Handle light level, if needed */
|
||||||
lighting.applyLighting(ps, this, c, tmpcolor);
|
lighting.applyLighting(ps, this, c, tmpcolor);
|
||||||
/* If we got alpha from subblock model, use it instead */
|
/* If we got alpha from subblock model, use it instead if it is lower */
|
||||||
if(subalpha >= 0) {
|
if(subalpha >= 0) {
|
||||||
for(Color clr : tmpcolor)
|
for(Color clr : tmpcolor) {
|
||||||
clr.setAlpha(Math.max(subalpha,clr.getAlpha()));
|
int a = clr.getAlpha();
|
||||||
|
if(subalpha < a)
|
||||||
|
clr.setAlpha(subalpha);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* If no previous color contribution, use new color */
|
/* If no previous color contribution, use new color */
|
||||||
if(color[0].isTransparent()) {
|
if(color[0].isTransparent()) {
|
||||||
@ -164,10 +167,15 @@ public class TexturePackHDShader implements HDShader {
|
|||||||
int alpha = color[0].getAlpha();
|
int alpha = color[0].getAlpha();
|
||||||
int alpha2 = tmpcolor[0].getAlpha() * (255-alpha) / 255;
|
int alpha2 = tmpcolor[0].getAlpha() * (255-alpha) / 255;
|
||||||
int talpha = alpha + alpha2;
|
int talpha = alpha + alpha2;
|
||||||
for(int i = 0; i < color.length; i++)
|
if(talpha > 0)
|
||||||
color[i].setRGBA((tmpcolor[i].getRed()*alpha2 + color[i].getRed()*alpha) / talpha,
|
for(int i = 0; i < color.length; i++)
|
||||||
|
color[i].setRGBA((tmpcolor[i].getRed()*alpha2 + color[i].getRed()*alpha) / talpha,
|
||||||
(tmpcolor[i].getGreen()*alpha2 + color[i].getGreen()*alpha) / talpha,
|
(tmpcolor[i].getGreen()*alpha2 + color[i].getGreen()*alpha) / talpha,
|
||||||
(tmpcolor[i].getBlue()*alpha2 + color[i].getBlue()*alpha) / talpha, talpha);
|
(tmpcolor[i].getBlue()*alpha2 + color[i].getBlue()*alpha) / talpha, talpha);
|
||||||
|
else
|
||||||
|
for(int i = 0; i < color.length; i++)
|
||||||
|
color[i].setTransparent();
|
||||||
|
|
||||||
return (talpha >= 254); /* If only one short, no meaningful contribution left */
|
return (talpha >= 254); /* If only one short, no meaningful contribution left */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user