Compare commits
15 Commits
master
...
falling-sa
Author | SHA1 | Date | |
---|---|---|---|
|
71250104ea | ||
|
51752f95f9 | ||
|
175f092673 | ||
|
59129f95c9 | ||
|
efff41a6db | ||
|
30879a1241 | ||
|
dccfcc9419 | ||
|
c2a2cc074a | ||
|
e58007ea11 | ||
|
ae2980c9de | ||
|
3879e5ffac | ||
|
47eb9fa5af | ||
|
bf49687ab6 | ||
|
b3ae829383 | ||
|
b374e9a736 |
@ -45,7 +45,7 @@ public class OpenSimplex2S {
|
|||||||
source[i] = i;
|
source[i] = i;
|
||||||
for (int i = PSIZE - 1; i >= 0; i--) {
|
for (int i = PSIZE - 1; i >= 0; i--) {
|
||||||
seed = seed * 6364136223846793005L + 1442695040888963407L;
|
seed = seed * 6364136223846793005L + 1442695040888963407L;
|
||||||
int r = (int)((seed + 31) % (i + 1));
|
int r = (int) ((seed + 31) % (i + 1));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
r += (i + 1);
|
r += (i + 1);
|
||||||
perm[i] = source[r];
|
perm[i] = source[r];
|
||||||
@ -72,9 +72,9 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D SuperSimplex noise, with Y pointing down the main diagonal.
|
* 2D SuperSimplex noise, with Y pointing down the main diagonal. Might be
|
||||||
* Might be better for a 2D sandbox style game, where Y is vertical.
|
* better for a 2D sandbox style game, where Y is vertical. Probably
|
||||||
* Probably slightly less optimal for heightmaps or continent maps.
|
* slightly less optimal for heightmaps or continent maps.
|
||||||
*/
|
*/
|
||||||
public double noise2_XBeforeY(double x, double y) {
|
public double noise2_XBeforeY(double x, double y) {
|
||||||
|
|
||||||
@ -86,8 +86,8 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 2D SuperSimplex noise base.
|
* 2D SuperSimplex noise base. Lookup table implementation inspired by
|
||||||
* Lookup table implementation inspired by DigitalShadow.
|
* DigitalShadow.
|
||||||
*/
|
*/
|
||||||
private double noise2_Base(double xs, double ys) {
|
private double noise2_Base(double xs, double ys) {
|
||||||
double value = 0;
|
double value = 0;
|
||||||
@ -97,11 +97,8 @@ public class OpenSimplex2S {
|
|||||||
double xsi = xs - xsb, ysi = ys - ysb;
|
double xsi = xs - xsb, ysi = ys - ysb;
|
||||||
|
|
||||||
// Index to point list
|
// Index to point list
|
||||||
int a = (int)(xsi + ysi);
|
int a = (int) (xsi + ysi);
|
||||||
int index =
|
int index = (a << 2) | (int) (xsi - ysi / 2 + 1 - a / 2.0) << 3 | (int) (ysi - xsi / 2 + 1 - a / 2.0) << 4;
|
||||||
(a << 2) |
|
|
||||||
(int)(xsi - ysi / 2 + 1 - a / 2.0) << 3 |
|
|
||||||
(int)(ysi - xsi / 2 + 1 - a / 2.0) << 4;
|
|
||||||
|
|
||||||
double ssi = (xsi + ysi) * -0.211324865405187;
|
double ssi = (xsi + ysi) * -0.211324865405187;
|
||||||
double xi = xsi + ssi, yi = ysi + ssi;
|
double xi = xsi + ssi, yi = ysi + ssi;
|
||||||
@ -112,7 +109,8 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
double dx = xi + c.dx, dy = yi + c.dy;
|
double dx = xi + c.dx, dy = yi + c.dy;
|
||||||
double attn = 2.0 / 3.0 - dx * dx - dy * dy;
|
double attn = 2.0 / 3.0 - dx * dx - dy * dy;
|
||||||
if (attn <= 0) continue;
|
if (attn <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK;
|
int pxm = (xsb + c.xsv) & PMASK, pym = (ysb + c.ysv) & PMASK;
|
||||||
Grad2 grad = permGrad2[perm[pxm] ^ pym];
|
Grad2 grad = permGrad2[perm[pxm] ^ pym];
|
||||||
@ -126,15 +124,16 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 3D Re-oriented 8-point BCC noise, classic orientation
|
* 3D Re-oriented 8-point BCC noise, classic orientation Proper substitute
|
||||||
* Proper substitute for what 3D SuperSimplex would be,
|
* for what 3D SuperSimplex would be, in light of Forbidden Formulae. Use
|
||||||
* in light of Forbidden Formulae.
|
* noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate.
|
||||||
* Use noise3_XYBeforeZ or noise3_XZBeforeY instead, wherever appropriate.
|
|
||||||
*/
|
*/
|
||||||
public double noise3_Classic(double x, double y, double z) {
|
public double noise3_Classic(double x, double y, double z) {
|
||||||
|
|
||||||
// Re-orient the cubic lattices via rotation, to produce the expected look on cardinal planar slices.
|
// Re-orient the cubic lattices via rotation, to produce the expected
|
||||||
// If texturing objects that don't tend to have cardinal plane faces, you could even remove this.
|
// look on cardinal planar slices.
|
||||||
|
// If texturing objects that don't tend to have cardinal plane faces,
|
||||||
|
// you could even remove this.
|
||||||
// Orthonormal rotation. Not a skew transform.
|
// Orthonormal rotation. Not a skew transform.
|
||||||
double r = (2.0 / 3.0) * (x + y + z);
|
double r = (2.0 / 3.0) * (x + y + z);
|
||||||
double xr = r - x, yr = r - y, zr = r - z;
|
double xr = r - x, yr = r - y, zr = r - z;
|
||||||
@ -145,15 +144,17 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y).
|
* 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Y).
|
||||||
* Recommended for 3D terrain and time-varied animations.
|
* Recommended for 3D terrain and time-varied animations. The Z coordinate
|
||||||
* The Z coordinate should always be the "different" coordinate in your use case.
|
* should always be the "different" coordinate in your use case. If Y is
|
||||||
* If Y is vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use noise3_XZBeforeY.
|
* vertical in world coordinates, call noise3_XYBeforeZ(x, z, Y) or use
|
||||||
* If Z is vertical in world coordinates, call noise3_XYBeforeZ(x, y, Z).
|
* noise3_XZBeforeY. If Z is vertical in world coordinates, call
|
||||||
* For a time varied animation, call noise3_XYBeforeZ(x, y, T).
|
* noise3_XYBeforeZ(x, y, Z). For a time varied animation, call
|
||||||
|
* noise3_XYBeforeZ(x, y, T).
|
||||||
*/
|
*/
|
||||||
public double noise3_XYBeforeZ(double x, double y, double z) {
|
public double noise3_XYBeforeZ(double x, double y, double z) {
|
||||||
|
|
||||||
// Re-orient the cubic lattices without skewing, to make X and Y triangular like 2D.
|
// Re-orient the cubic lattices without skewing, to make X and Y
|
||||||
|
// triangular like 2D.
|
||||||
// Orthonormal rotation. Not a skew transform.
|
// Orthonormal rotation. Not a skew transform.
|
||||||
double xy = x + y;
|
double xy = x + y;
|
||||||
double s2 = xy * -0.211324865405187;
|
double s2 = xy * -0.211324865405187;
|
||||||
@ -167,20 +168,23 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z).
|
* 3D Re-oriented 8-point BCC noise, with better visual isotropy in (X, Z).
|
||||||
* Recommended for 3D terrain and time-varied animations.
|
* Recommended for 3D terrain and time-varied animations. The Y coordinate
|
||||||
* The Y coordinate should always be the "different" coordinate in your use case.
|
* should always be the "different" coordinate in your use case. If Y is
|
||||||
* If Y is vertical in world coordinates, call noise3_XZBeforeY(x, Y, z).
|
* vertical in world coordinates, call noise3_XZBeforeY(x, Y, z). If Z is
|
||||||
* If Z is vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use noise3_XYBeforeZ.
|
* vertical in world coordinates, call noise3_XZBeforeY(x, Z, y) or use
|
||||||
* For a time varied animation, call noise3_XZBeforeY(x, T, y) or use noise3_XYBeforeZ.
|
* noise3_XYBeforeZ. For a time varied animation, call noise3_XZBeforeY(x,
|
||||||
|
* T, y) or use noise3_XYBeforeZ.
|
||||||
*/
|
*/
|
||||||
public double noise3_XZBeforeY(double x, double y, double z) {
|
public double noise3_XZBeforeY(double x, double y, double z) {
|
||||||
|
|
||||||
// Re-orient the cubic lattices without skewing, to make X and Z triangular like 2D.
|
// Re-orient the cubic lattices without skewing, to make X and Z
|
||||||
|
// triangular like 2D.
|
||||||
// Orthonormal rotation. Not a skew transform.
|
// Orthonormal rotation. Not a skew transform.
|
||||||
double xz = x + z;
|
double xz = x + z;
|
||||||
double s2 = xz * -0.211324865405187;
|
double s2 = xz * -0.211324865405187;
|
||||||
double yy = y * 0.577350269189626;
|
double yy = y * 0.577350269189626;
|
||||||
double xr = x + s2 - yy; double zr = z + s2 - yy;
|
double xr = x + s2 - yy;
|
||||||
|
double zr = z + s2 - yy;
|
||||||
double yr = xz * 0.577350269189626 + yy;
|
double yr = xz * 0.577350269189626 + yy;
|
||||||
|
|
||||||
// Evaluate both lattices to form a BCC lattice.
|
// Evaluate both lattices to form a BCC lattice.
|
||||||
@ -188,10 +192,10 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate overlapping cubic lattices for 3D Re-oriented BCC noise.
|
* Generate overlapping cubic lattices for 3D Re-oriented BCC noise. Lookup
|
||||||
* Lookup table implementation inspired by DigitalShadow.
|
* table implementation inspired by DigitalShadow. It was actually faster to
|
||||||
* It was actually faster to narrow down the points in the loop itself,
|
* narrow down the points in the loop itself, than to build up the index
|
||||||
* than to build up the index with enough info to isolate 8 points.
|
* with enough info to isolate 8 points.
|
||||||
*/
|
*/
|
||||||
private double noise3_BCC(double xr, double yr, double zr) {
|
private double noise3_BCC(double xr, double yr, double zr) {
|
||||||
|
|
||||||
@ -199,9 +203,11 @@ public class OpenSimplex2S {
|
|||||||
int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr);
|
int xrb = fastFloor(xr), yrb = fastFloor(yr), zrb = fastFloor(zr);
|
||||||
double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb;
|
double xri = xr - xrb, yri = yr - yrb, zri = zr - zrb;
|
||||||
|
|
||||||
// Identify which octant of the cube we're in. This determines which cell
|
// Identify which octant of the cube we're in. This determines which
|
||||||
// in the other cubic lattice we're in, and also narrows down one point on each.
|
// cell
|
||||||
int xht = (int)(xri + 0.5), yht = (int)(yri + 0.5), zht = (int)(zri + 0.5);
|
// in the other cubic lattice we're in, and also narrows down one point
|
||||||
|
// on each.
|
||||||
|
int xht = (int) (xri + 0.5), yht = (int) (yri + 0.5), zht = (int) (zri + 0.5);
|
||||||
int index = (xht << 0) | (yht << 1) | (zht << 2);
|
int index = (xht << 0) | (yht << 1) | (zht << 2);
|
||||||
|
|
||||||
// Point contributions
|
// Point contributions
|
||||||
@ -230,9 +236,9 @@ public class OpenSimplex2S {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the 2D noise over a large area.
|
* Generate the 2D noise over a large area. Propagates by flood-fill instead
|
||||||
* Propagates by flood-fill instead of iterating over a range.
|
* of iterating over a range. Results may occasionally slightly exceed [-1,
|
||||||
* Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel.
|
* 1] due to the grid-snapped pre-generated kernel.
|
||||||
*/
|
*/
|
||||||
public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0) {
|
public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0) {
|
||||||
int height = buffer.length;
|
int height = buffer.length;
|
||||||
@ -241,11 +247,12 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the 2D noise over a large area.
|
* Generate the 2D noise over a large area. Propagates by flood-fill instead
|
||||||
* Propagates by flood-fill instead of iterating over a range.
|
* of iterating over a range. Results may occasionally slightly exceed [-1,
|
||||||
* Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel.
|
* 1] due to the grid-snapped pre-generated kernel.
|
||||||
*/
|
*/
|
||||||
public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0, int width, int height, int skipX, int skipY) {
|
public void generate2(GenerateContext2D context, double[][] buffer, int x0, int y0, int width, int height,
|
||||||
|
int skipX, int skipY) {
|
||||||
Queue<AreaGenLatticePoint2D> queue = new LinkedList<AreaGenLatticePoint2D>();
|
Queue<AreaGenLatticePoint2D> queue = new LinkedList<AreaGenLatticePoint2D>();
|
||||||
Set<AreaGenLatticePoint2D> seen = new HashSet<AreaGenLatticePoint2D>();
|
Set<AreaGenLatticePoint2D> seen = new HashSet<AreaGenLatticePoint2D>();
|
||||||
|
|
||||||
@ -260,16 +267,19 @@ public class OpenSimplex2S {
|
|||||||
// - Much faster than computing the kernel equation every time.
|
// - Much faster than computing the kernel equation every time.
|
||||||
// You can remove these lines if you find it's the opposite for you.
|
// You can remove these lines if you find it's the opposite for you.
|
||||||
// You'll have to double the bounds again in GenerateContext2D
|
// You'll have to double the bounds again in GenerateContext2D
|
||||||
kernel = new double[scaledRadiusY * 2][/*scaledRadiusX * 2*/];
|
kernel = new double[scaledRadiusY * 2][/* scaledRadiusX * 2 */];
|
||||||
for (int yy = 0; yy < scaledRadiusY; yy++) {
|
for (int yy = 0; yy < scaledRadiusY; yy++) {
|
||||||
kernel[2 * scaledRadiusY - yy - 1] = kernel[yy] = (double[]) context.kernel[yy].clone();
|
kernel[2 * scaledRadiusY - yy - 1] = kernel[yy] = (double[]) context.kernel[yy].clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get started with one point/vertex.
|
// Get started with one point/vertex.
|
||||||
// For some lattices, you might need to try a handful of points in the cell,
|
// For some lattices, you might need to try a handful of points in the
|
||||||
// or flip a couple of coordinates, to guarantee it or a neighbor contributes.
|
// cell,
|
||||||
|
// or flip a couple of coordinates, to guarantee it or a neighbor
|
||||||
|
// contributes.
|
||||||
// For An* lattices, the base coordinate seems fine.
|
// For An* lattices, the base coordinate seems fine.
|
||||||
double x0f = x0Skipped * context.xFrequency; double y0f = y0Skipped * context.yFrequency;
|
double x0f = x0Skipped * context.xFrequency;
|
||||||
|
double y0f = y0Skipped * context.yFrequency;
|
||||||
double x0s = context.orientation.s00 * x0f + context.orientation.s01 * y0f;
|
double x0s = context.orientation.s00 * x0f + context.orientation.s01 * y0f;
|
||||||
double y0s = context.orientation.s10 * x0f + context.orientation.s11 * y0f;
|
double y0s = context.orientation.s10 * x0f + context.orientation.s11 * y0f;
|
||||||
int x0sb = fastFloor(x0s), y0sb = fastFloor(y0s);
|
int x0sb = fastFloor(x0s), y0sb = fastFloor(y0s);
|
||||||
@ -287,11 +297,16 @@ public class OpenSimplex2S {
|
|||||||
Grad2 grad = context.orientation.gradients[perm[perm[pxm] ^ pym]];
|
Grad2 grad = context.orientation.gradients[perm[perm[pxm] ^ pym]];
|
||||||
double gx = grad.dx * context.xFrequency;
|
double gx = grad.dx * context.xFrequency;
|
||||||
double gy = grad.dy * context.yFrequency;
|
double gy = grad.dy * context.yFrequency;
|
||||||
double gOff = 0.5 * (gx + gy); // to correct for (0.5, 0.5)-offset kernel
|
double gOff = 0.5 * (gx + gy); // to correct for (0.5, 0.5)-offset
|
||||||
|
// kernel
|
||||||
|
|
||||||
// Contribution kernel bounds
|
// Contribution kernel bounds
|
||||||
int yy0 = destPointY - scaledRadiusY; if (yy0 < y0Skipped) yy0 = y0Skipped;
|
int yy0 = destPointY - scaledRadiusY;
|
||||||
int yy1 = destPointY + scaledRadiusY; if (yy1 > y0 + height) yy1 = y0 + height;
|
if (yy0 < y0Skipped)
|
||||||
|
yy0 = y0Skipped;
|
||||||
|
int yy1 = destPointY + scaledRadiusY;
|
||||||
|
if (yy1 > y0 + height)
|
||||||
|
yy1 = y0 + height;
|
||||||
|
|
||||||
// For each row of the contribution circle,
|
// For each row of the contribution circle,
|
||||||
for (int yy = yy0; yy < yy1; yy++) {
|
for (int yy = yy0; yy < yy1; yy++) {
|
||||||
@ -300,16 +315,22 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
// Set up bounds so we only loop over what we need to
|
// Set up bounds so we only loop over what we need to
|
||||||
int thisScaledRadiusX = context.kernelBounds[ky];
|
int thisScaledRadiusX = context.kernelBounds[ky];
|
||||||
int xx0 = destPointX - thisScaledRadiusX; if (xx0 < x0Skipped) xx0 = x0Skipped;
|
int xx0 = destPointX - thisScaledRadiusX;
|
||||||
int xx1 = destPointX + thisScaledRadiusX; if (xx1 > x0 + width) xx1 = x0 + width;
|
if (xx0 < x0Skipped)
|
||||||
|
xx0 = x0Skipped;
|
||||||
|
int xx1 = destPointX + thisScaledRadiusX;
|
||||||
|
if (xx1 > x0 + width)
|
||||||
|
xx1 = x0 + width;
|
||||||
|
|
||||||
// For each point on that row
|
// For each point on that row
|
||||||
for (int xx = xx0; xx < xx1; xx++) {
|
for (int xx = xx0; xx < xx1; xx++) {
|
||||||
int dx = xx - destPointX;
|
int dx = xx - destPointX;
|
||||||
int kx = dx + scaledRadiusX;
|
int kx = dx + scaledRadiusX;
|
||||||
|
|
||||||
// gOff accounts for our choice to offset the pre-generated kernel by (0.5, 0.5) to avoid the zero center.
|
// gOff accounts for our choice to offset the pre-generated
|
||||||
// I found almost no difference in performance using gOff vs not (under 1ns diff per value on my system)
|
// kernel by (0.5, 0.5) to avoid the zero center.
|
||||||
|
// I found almost no difference in performance using gOff vs
|
||||||
|
// not (under 1ns diff per value on my system)
|
||||||
double extrapolation = gx * dx + gy * dy + gOff;
|
double extrapolation = gx * dx + gy * dy + gOff;
|
||||||
buffer[yy - y0][xx - x0] += kernel[ky][kx] * extrapolation;
|
buffer[yy - y0][xx - x0] += kernel[ky][kx] * extrapolation;
|
||||||
|
|
||||||
@ -318,13 +339,14 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
// For each neighbor of the point
|
// For each neighbor of the point
|
||||||
for (int i = 0; i < NEIGHBOR_MAP_2D.length; i++) {
|
for (int i = 0; i < NEIGHBOR_MAP_2D.length; i++) {
|
||||||
AreaGenLatticePoint2D neighbor = new AreaGenLatticePoint2D(context,
|
AreaGenLatticePoint2D neighbor = new AreaGenLatticePoint2D(context, point.xsv + NEIGHBOR_MAP_2D[i][0],
|
||||||
point.xsv + NEIGHBOR_MAP_2D[i][0], point.ysv + NEIGHBOR_MAP_2D[i][1]);
|
point.ysv + NEIGHBOR_MAP_2D[i][1]);
|
||||||
|
|
||||||
// If it's in range of the buffer region and not seen before
|
// If it's in range of the buffer region and not seen before
|
||||||
if (neighbor.destPointX + scaledRadiusX >= x0Skipped && neighbor.destPointX - scaledRadiusX <= x0 + width - 1
|
if (neighbor.destPointX + scaledRadiusX >= x0Skipped
|
||||||
&& neighbor.destPointY + scaledRadiusY >= y0Skipped && neighbor.destPointY - scaledRadiusY <= y0 + height - 1
|
&& neighbor.destPointX - scaledRadiusX <= x0 + width - 1
|
||||||
&& !seen.contains(neighbor)) {
|
&& neighbor.destPointY + scaledRadiusY >= y0Skipped
|
||||||
|
&& neighbor.destPointY - scaledRadiusY <= y0 + height - 1 && !seen.contains(neighbor)) {
|
||||||
|
|
||||||
// Add it to the queue so we can process it at some point
|
// Add it to the queue so we can process it at some point
|
||||||
queue.add(neighbor);
|
queue.add(neighbor);
|
||||||
@ -337,9 +359,9 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the 3D noise over a large area/volume.
|
* Generate the 3D noise over a large area/volume. Propagates by flood-fill
|
||||||
* Propagates by flood-fill instead of iterating over a range.
|
* instead of iterating over a range. Results may occasionally slightly
|
||||||
* Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel.
|
* exceed [-1, 1] due to the grid-snapped pre-generated kernel.
|
||||||
*/
|
*/
|
||||||
public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0) {
|
public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0) {
|
||||||
int depth = buffer.length;
|
int depth = buffer.length;
|
||||||
@ -349,11 +371,12 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate the 3D noise over a large area/volume.
|
* Generate the 3D noise over a large area/volume. Propagates by flood-fill
|
||||||
* Propagates by flood-fill instead of iterating over a range.
|
* instead of iterating over a range. Results may occasionally slightly
|
||||||
* Results may occasionally slightly exceed [-1, 1] due to the grid-snapped pre-generated kernel.
|
* exceed [-1, 1] due to the grid-snapped pre-generated kernel.
|
||||||
*/
|
*/
|
||||||
public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0, int width, int height, int depth, int skipX, int skipY, int skipZ) {
|
public void generate3(GenerateContext3D context, double[][][] buffer, int x0, int y0, int z0, int width, int height,
|
||||||
|
int depth, int skipX, int skipY, int skipZ) {
|
||||||
Queue<AreaGenLatticePoint3D> queue = new LinkedList<AreaGenLatticePoint3D>();
|
Queue<AreaGenLatticePoint3D> queue = new LinkedList<AreaGenLatticePoint3D>();
|
||||||
Set<AreaGenLatticePoint3D> seen = new HashSet<AreaGenLatticePoint3D>();
|
Set<AreaGenLatticePoint3D> seen = new HashSet<AreaGenLatticePoint3D>();
|
||||||
|
|
||||||
@ -365,8 +388,10 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
// Quaternion multiplication for rotation.
|
// Quaternion multiplication for rotation.
|
||||||
// https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
|
// https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
|
||||||
double qx = context.orientation.qx, qy = context.orientation.qy, qz = context.orientation.qz, qw = context.orientation.qw;
|
double qx = context.orientation.qx, qy = context.orientation.qy, qz = context.orientation.qz,
|
||||||
double x0f = x0Skipped * context.xFrequency, y0f = y0Skipped * context.yFrequency, z0f = z0Skipped * context.zFrequency;
|
qw = context.orientation.qw;
|
||||||
|
double x0f = x0Skipped * context.xFrequency, y0f = y0Skipped * context.yFrequency,
|
||||||
|
z0f = z0Skipped * context.zFrequency;
|
||||||
double tx = 2 * (qy * z0f - qz * y0f);
|
double tx = 2 * (qy * z0f - qz * y0f);
|
||||||
double ty = 2 * (qz * x0f - qx * z0f);
|
double ty = 2 * (qz * x0f - qx * z0f);
|
||||||
double tz = 2 * (qx * y0f - qy * x0f);
|
double tz = 2 * (qx * y0f - qy * x0f);
|
||||||
@ -392,11 +417,16 @@ public class OpenSimplex2S {
|
|||||||
double gx = grad.dx * context.xFrequency;
|
double gx = grad.dx * context.xFrequency;
|
||||||
double gy = grad.dy * context.yFrequency;
|
double gy = grad.dy * context.yFrequency;
|
||||||
double gz = grad.dz * context.zFrequency;
|
double gz = grad.dz * context.zFrequency;
|
||||||
double gOff = 0.5 * (gx + gy + gz); // to correct for (0.5, 0.5, 0.5)-offset kernel
|
double gOff = 0.5 * (gx + gy + gz); // to correct for (0.5, 0.5,
|
||||||
|
// 0.5)-offset kernel
|
||||||
|
|
||||||
// Contribution kernel bounds.
|
// Contribution kernel bounds.
|
||||||
int zz0 = destPointZ - scaledRadiusZ; if (zz0 < z0Skipped) zz0 = z0Skipped;
|
int zz0 = destPointZ - scaledRadiusZ;
|
||||||
int zz1 = destPointZ + scaledRadiusZ; if (zz1 > z0 + depth) zz1 = z0 + depth;
|
if (zz0 < z0Skipped)
|
||||||
|
zz0 = z0Skipped;
|
||||||
|
int zz1 = destPointZ + scaledRadiusZ;
|
||||||
|
if (zz1 > z0 + depth)
|
||||||
|
zz1 = z0 + depth;
|
||||||
|
|
||||||
// For each x/y slice of the contribution sphere,
|
// For each x/y slice of the contribution sphere,
|
||||||
for (int zz = zz0; zz < zz1; zz++) {
|
for (int zz = zz0; zz < zz1; zz++) {
|
||||||
@ -405,8 +435,12 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
// Set up bounds so we only loop over what we need to
|
// Set up bounds so we only loop over what we need to
|
||||||
int thisScaledRadiusY = context.kernelBoundsY[kz];
|
int thisScaledRadiusY = context.kernelBoundsY[kz];
|
||||||
int yy0 = destPointY - thisScaledRadiusY; if (yy0 < y0Skipped) yy0 = y0Skipped;
|
int yy0 = destPointY - thisScaledRadiusY;
|
||||||
int yy1 = destPointY + thisScaledRadiusY; if (yy1 > y0 + height) yy1 = y0 + height;
|
if (yy0 < y0Skipped)
|
||||||
|
yy0 = y0Skipped;
|
||||||
|
int yy1 = destPointY + thisScaledRadiusY;
|
||||||
|
if (yy1 > y0 + height)
|
||||||
|
yy1 = y0 + height;
|
||||||
|
|
||||||
// For each row of the contribution circle,
|
// For each row of the contribution circle,
|
||||||
for (int yy = yy0; yy < yy1; yy++) {
|
for (int yy = yy0; yy < yy1; yy++) {
|
||||||
@ -415,15 +449,21 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
// Set up bounds so we only loop over what we need to
|
// Set up bounds so we only loop over what we need to
|
||||||
int thisScaledRadiusX = context.kernelBoundsX[kz][ky];
|
int thisScaledRadiusX = context.kernelBoundsX[kz][ky];
|
||||||
int xx0 = destPointX - thisScaledRadiusX; if (xx0 < x0Skipped) xx0 = x0Skipped;
|
int xx0 = destPointX - thisScaledRadiusX;
|
||||||
int xx1 = destPointX + thisScaledRadiusX; if (xx1 > x0 + width) xx1 = x0 + width;
|
if (xx0 < x0Skipped)
|
||||||
|
xx0 = x0Skipped;
|
||||||
|
int xx1 = destPointX + thisScaledRadiusX;
|
||||||
|
if (xx1 > x0 + width)
|
||||||
|
xx1 = x0 + width;
|
||||||
|
|
||||||
// For each point on that row
|
// For each point on that row
|
||||||
for (int xx = xx0; xx < xx1; xx++) {
|
for (int xx = xx0; xx < xx1; xx++) {
|
||||||
int dx = xx - destPointX;
|
int dx = xx - destPointX;
|
||||||
int kx = dx + scaledRadiusX;
|
int kx = dx + scaledRadiusX;
|
||||||
|
|
||||||
// gOff accounts for our choice to offset the pre-generated kernel by (0.5, 0.5, 0.5) to avoid the zero center.
|
// gOff accounts for our choice to offset the
|
||||||
|
// pre-generated kernel by (0.5, 0.5, 0.5) to avoid the
|
||||||
|
// zero center.
|
||||||
double extrapolation = gx * dx + gy * dy + gz * dz + gOff;
|
double extrapolation = gx * dx + gy * dy + gz * dz + gOff;
|
||||||
buffer[zz - z0][yy - y0][xx - x0] += kernel[kz][ky][kx] * extrapolation;
|
buffer[zz - z0][yy - y0][xx - x0] += kernel[kz][ky][kx] * extrapolation;
|
||||||
|
|
||||||
@ -435,13 +475,16 @@ public class OpenSimplex2S {
|
|||||||
for (int i = 0; i < NEIGHBOR_MAP_3D[0].length; i++) {
|
for (int i = 0; i < NEIGHBOR_MAP_3D[0].length; i++) {
|
||||||
int l = point.lattice;
|
int l = point.lattice;
|
||||||
AreaGenLatticePoint3D neighbor = new AreaGenLatticePoint3D(context,
|
AreaGenLatticePoint3D neighbor = new AreaGenLatticePoint3D(context,
|
||||||
point.xsv + NEIGHBOR_MAP_3D[l][i][0], point.ysv + NEIGHBOR_MAP_3D[l][i][1], point.zsv + NEIGHBOR_MAP_3D[l][i][2], 1 ^ l);
|
point.xsv + NEIGHBOR_MAP_3D[l][i][0], point.ysv + NEIGHBOR_MAP_3D[l][i][1],
|
||||||
|
point.zsv + NEIGHBOR_MAP_3D[l][i][2], 1 ^ l);
|
||||||
|
|
||||||
// If it's in range of the buffer region and not seen before
|
// If it's in range of the buffer region and not seen before
|
||||||
if (neighbor.destPointX + scaledRadiusX >= x0Skipped && neighbor.destPointX - scaledRadiusX <= x0 + width - 1
|
if (neighbor.destPointX + scaledRadiusX >= x0Skipped
|
||||||
&& neighbor.destPointY + scaledRadiusY >= y0Skipped && neighbor.destPointY - scaledRadiusY <= y0 + height - 1
|
&& neighbor.destPointX - scaledRadiusX <= x0 + width - 1
|
||||||
&& neighbor.destPointZ + scaledRadiusZ >= z0Skipped && neighbor.destPointZ - scaledRadiusZ <= z0 + depth - 1
|
&& neighbor.destPointY + scaledRadiusY >= y0Skipped
|
||||||
&& !seen.contains(neighbor)) {
|
&& neighbor.destPointY - scaledRadiusY <= y0 + height - 1
|
||||||
|
&& neighbor.destPointZ + scaledRadiusZ >= z0Skipped
|
||||||
|
&& neighbor.destPointZ - scaledRadiusZ <= z0 + depth - 1 && !seen.contains(neighbor)) {
|
||||||
|
|
||||||
// Add it to the queue so we can process it at some point
|
// Add it to the queue so we can process it at some point
|
||||||
queue.add(neighbor);
|
queue.add(neighbor);
|
||||||
@ -458,7 +501,7 @@ public class OpenSimplex2S {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
private static int fastFloor(double x) {
|
private static int fastFloor(double x) {
|
||||||
int xi = (int)x;
|
int xi = (int) x;
|
||||||
return x < xi ? xi - 1 : xi;
|
return x < xi ? xi - 1 : xi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -475,11 +518,35 @@ public class OpenSimplex2S {
|
|||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
int i1, j1, i2, j2;
|
int i1, j1, i2, j2;
|
||||||
if ((i & 1) == 0) {
|
if ((i & 1) == 0) {
|
||||||
if ((i & 2) == 0) { i1 = -1; j1 = 0; } else { i1 = 1; j1 = 0; }
|
if ((i & 2) == 0) {
|
||||||
if ((i & 4) == 0) { i2 = 0; j2 = -1; } else { i2 = 0; j2 = 1; }
|
i1 = -1;
|
||||||
|
j1 = 0;
|
||||||
} else {
|
} else {
|
||||||
if ((i & 2) != 0) { i1 = 2; j1 = 1; } else { i1 = 0; j1 = 1; }
|
i1 = 1;
|
||||||
if ((i & 4) != 0) { i2 = 1; j2 = 2; } else { i2 = 1; j2 = 0; }
|
j1 = 0;
|
||||||
|
}
|
||||||
|
if ((i & 4) == 0) {
|
||||||
|
i2 = 0;
|
||||||
|
j2 = -1;
|
||||||
|
} else {
|
||||||
|
i2 = 0;
|
||||||
|
j2 = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ((i & 2) != 0) {
|
||||||
|
i1 = 2;
|
||||||
|
j1 = 1;
|
||||||
|
} else {
|
||||||
|
i1 = 0;
|
||||||
|
j1 = 1;
|
||||||
|
}
|
||||||
|
if ((i & 4) != 0) {
|
||||||
|
i2 = 1;
|
||||||
|
j2 = 2;
|
||||||
|
} else {
|
||||||
|
i2 = 1;
|
||||||
|
j2 = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LOOKUP_2D[i * 4 + 0] = new LatticePoint2D(0, 0);
|
LOOKUP_2D[i * 4 + 0] = new LatticePoint2D(0, 0);
|
||||||
LOOKUP_2D[i * 4 + 1] = new LatticePoint2D(1, 1);
|
LOOKUP_2D[i * 4 + 1] = new LatticePoint2D(1, 1);
|
||||||
@ -489,10 +556,15 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++) {
|
||||||
int i1, j1, k1, i2, j2, k2;
|
int i1, j1, k1, i2, j2, k2;
|
||||||
i1 = (i >> 0) & 1; j1 = (i >> 1) & 1; k1 = (i >> 2) & 1;
|
i1 = (i >> 0) & 1;
|
||||||
i2 = i1 ^ 1; j2 = j1 ^ 1; k2 = k1 ^ 1;
|
j1 = (i >> 1) & 1;
|
||||||
|
k1 = (i >> 2) & 1;
|
||||||
|
i2 = i1 ^ 1;
|
||||||
|
j2 = j1 ^ 1;
|
||||||
|
k2 = k1 ^ 1;
|
||||||
|
|
||||||
// The two points within this octant, one from each of the two cubic half-lattices.
|
// The two points within this octant, one from each of the two cubic
|
||||||
|
// half-lattices.
|
||||||
LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0);
|
LatticePoint3D c0 = new LatticePoint3D(i1, j1, k1, 0);
|
||||||
LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1);
|
LatticePoint3D c1 = new LatticePoint3D(i1 + i2, j1 + j2, k1 + k2, 1);
|
||||||
|
|
||||||
@ -525,27 +597,36 @@ public class OpenSimplex2S {
|
|||||||
c1.nextOnFailure = c1.nextOnSuccess = c2;
|
c1.nextOnFailure = c1.nextOnSuccess = c2;
|
||||||
|
|
||||||
// If c2 is in range, then we know c3 and c4 are not.
|
// If c2 is in range, then we know c3 and c4 are not.
|
||||||
c2.nextOnFailure = c3; c2.nextOnSuccess = c5;
|
c2.nextOnFailure = c3;
|
||||||
c3.nextOnFailure = c4; c3.nextOnSuccess = c4;
|
c2.nextOnSuccess = c5;
|
||||||
|
c3.nextOnFailure = c4;
|
||||||
|
c3.nextOnSuccess = c4;
|
||||||
|
|
||||||
// If c4 is in range, then we know c5 is not.
|
// If c4 is in range, then we know c5 is not.
|
||||||
c4.nextOnFailure = c5; c4.nextOnSuccess = c6;
|
c4.nextOnFailure = c5;
|
||||||
|
c4.nextOnSuccess = c6;
|
||||||
c5.nextOnFailure = c5.nextOnSuccess = c6;
|
c5.nextOnFailure = c5.nextOnSuccess = c6;
|
||||||
|
|
||||||
// If c6 is in range, then we know c7 and c8 are not.
|
// If c6 is in range, then we know c7 and c8 are not.
|
||||||
c6.nextOnFailure = c7; c6.nextOnSuccess = c9;
|
c6.nextOnFailure = c7;
|
||||||
c7.nextOnFailure = c8; c7.nextOnSuccess = c8;
|
c6.nextOnSuccess = c9;
|
||||||
|
c7.nextOnFailure = c8;
|
||||||
|
c7.nextOnSuccess = c8;
|
||||||
|
|
||||||
// If c8 is in range, then we know c9 is not.
|
// If c8 is in range, then we know c9 is not.
|
||||||
c8.nextOnFailure = c9; c8.nextOnSuccess = cA;
|
c8.nextOnFailure = c9;
|
||||||
|
c8.nextOnSuccess = cA;
|
||||||
c9.nextOnFailure = c9.nextOnSuccess = cA;
|
c9.nextOnFailure = c9.nextOnSuccess = cA;
|
||||||
|
|
||||||
// If cA is in range, then we know cB and cC are not.
|
// If cA is in range, then we know cB and cC are not.
|
||||||
cA.nextOnFailure = cB; cA.nextOnSuccess = cD;
|
cA.nextOnFailure = cB;
|
||||||
cB.nextOnFailure = cC; cB.nextOnSuccess = cC;
|
cA.nextOnSuccess = cD;
|
||||||
|
cB.nextOnFailure = cC;
|
||||||
|
cB.nextOnSuccess = cC;
|
||||||
|
|
||||||
// If cC is in range, then we know cD is not.
|
// If cC is in range, then we know cD is not.
|
||||||
cC.nextOnFailure = cD; cC.nextOnSuccess = null;
|
cC.nextOnFailure = cD;
|
||||||
|
cC.nextOnSuccess = null;
|
||||||
cD.nextOnFailure = cD.nextOnSuccess = null;
|
cD.nextOnFailure = cD.nextOnSuccess = null;
|
||||||
|
|
||||||
LOOKUP_3D[i] = c0;
|
LOOKUP_3D[i] = c0;
|
||||||
@ -554,28 +635,24 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Hexagon surrounding each vertex.
|
// Hexagon surrounding each vertex.
|
||||||
private static final int[][] NEIGHBOR_MAP_2D = {
|
private static final int[][] NEIGHBOR_MAP_2D = { { 1, 0 }, { 1, 1 }, { 0, 1 }, { 0, -1 }, { -1, -1 }, { -1, 0 } };
|
||||||
{ 1, 0 }, { 1, 1 }, { 0, 1 }, { 0, -1 }, { -1, -1 }, { -1, 0 }
|
|
||||||
};
|
|
||||||
|
|
||||||
// Cube surrounding each vertex.
|
// Cube surrounding each vertex.
|
||||||
// Alternates between half-lattices.
|
// Alternates between half-lattices.
|
||||||
private static final int[][][] NEIGHBOR_MAP_3D = {
|
private static final int[][][] NEIGHBOR_MAP_3D = {
|
||||||
{
|
{ { 1024, 1024, 1024 }, { 1025, 1024, 1024 }, { 1024, 1025, 1024 }, { 1025, 1025, 1024 },
|
||||||
{ 1024, 1024, 1024 }, { 1025, 1024, 1024 }, { 1024, 1025, 1024 }, { 1025, 1025, 1024 },
|
{ 1024, 1024, 1025 }, { 1025, 1024, 1025 }, { 1024, 1025, 1025 }, { 1025, 1025, 1025 } },
|
||||||
{ 1024, 1024, 1025 }, { 1025, 1024, 1025 }, { 1024, 1025, 1025 }, { 1025, 1025, 1025 }
|
{ { -1024, -1024, -1024 }, { -1025, -1024, 1024 }, { -1024, -1025, -1024 }, { -1025, -1025, -1024 },
|
||||||
},
|
{ -1024, -1024, -1025 }, { -1025, -1024, -1025 }, { -1024, -1025, -1025 },
|
||||||
{
|
{ -1025, -1025, 1025 } }, };
|
||||||
{ -1024, -1024, -1024 }, { -1025, -1024, 1024 }, { -1024, -1025, -1024 }, { -1025, -1025, -1024 },
|
|
||||||
{ -1024, -1024, -1025 }, { -1025, -1024, -1025 }, { -1024, -1025, -1025 }, { -1025, -1025, 1025 }
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
private static class LatticePoint2D {
|
private static class LatticePoint2D {
|
||||||
int xsv, ysv;
|
int xsv, ysv;
|
||||||
double dx, dy;
|
double dx, dy;
|
||||||
|
|
||||||
public LatticePoint2D(int xsv, int ysv) {
|
public LatticePoint2D(int xsv, int ysv) {
|
||||||
this.xsv = xsv; this.ysv = ysv;
|
this.xsv = xsv;
|
||||||
|
this.ysv = ysv;
|
||||||
double ssv = (xsv + ysv) * -0.211324865405187;
|
double ssv = (xsv + ysv) * -0.211324865405187;
|
||||||
this.dx = -xsv - ssv;
|
this.dx = -xsv - ssv;
|
||||||
this.dy = -ysv - ssv;
|
this.dy = -ysv - ssv;
|
||||||
@ -586,29 +663,42 @@ public class OpenSimplex2S {
|
|||||||
public double dxr, dyr, dzr;
|
public double dxr, dyr, dzr;
|
||||||
public int xrv, yrv, zrv;
|
public int xrv, yrv, zrv;
|
||||||
LatticePoint3D nextOnFailure, nextOnSuccess;
|
LatticePoint3D nextOnFailure, nextOnSuccess;
|
||||||
|
|
||||||
public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) {
|
public LatticePoint3D(int xrv, int yrv, int zrv, int lattice) {
|
||||||
this.dxr = -xrv + lattice * 0.5; this.dyr = -yrv + lattice * 0.5; this.dzr = -zrv + lattice * 0.5;
|
this.dxr = -xrv + lattice * 0.5;
|
||||||
this.xrv = xrv + lattice * 1024; this.yrv = yrv + lattice * 1024; this.zrv = zrv + lattice * 1024;
|
this.dyr = -yrv + lattice * 0.5;
|
||||||
|
this.dzr = -zrv + lattice * 0.5;
|
||||||
|
this.xrv = xrv + lattice * 1024;
|
||||||
|
this.yrv = yrv + lattice * 1024;
|
||||||
|
this.zrv = zrv + lattice * 1024;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class AreaGenLatticePoint2D {
|
private static class AreaGenLatticePoint2D {
|
||||||
int xsv, ysv;
|
int xsv, ysv;
|
||||||
int destPointX, destPointY;
|
int destPointX, destPointY;
|
||||||
public AreaGenLatticePoint2D(GenerateContext2D context, int xsv, int ysv) {
|
|
||||||
this.xsv = xsv; this.ysv = ysv;
|
|
||||||
|
|
||||||
//Matrix multiplication for inverse rotation. Simplex skew transforms have always been shorthand for matrices.
|
public AreaGenLatticePoint2D(GenerateContext2D context, int xsv, int ysv) {
|
||||||
this.destPointX = (int)Math.ceil((context.orientation.t00 * xsv + context.orientation.t01 * ysv) * context.xFrequencyInverse);
|
this.xsv = xsv;
|
||||||
this.destPointY = (int)Math.ceil((context.orientation.t10 * xsv + context.orientation.t11 * ysv) * context.yFrequencyInverse);
|
this.ysv = ysv;
|
||||||
|
|
||||||
|
// Matrix multiplication for inverse rotation. Simplex skew
|
||||||
|
// transforms have always been shorthand for matrices.
|
||||||
|
this.destPointX = (int) Math
|
||||||
|
.ceil((context.orientation.t00 * xsv + context.orientation.t01 * ysv) * context.xFrequencyInverse);
|
||||||
|
this.destPointY = (int) Math
|
||||||
|
.ceil((context.orientation.t10 * xsv + context.orientation.t11 * ysv) * context.yFrequencyInverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return xsv * 7841 + ysv;
|
return xsv * 7841 + ysv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof AreaGenLatticePoint2D)) return false;
|
if (!(obj instanceof AreaGenLatticePoint2D))
|
||||||
|
return false;
|
||||||
AreaGenLatticePoint2D other = (AreaGenLatticePoint2D) obj;
|
AreaGenLatticePoint2D other = (AreaGenLatticePoint2D) obj;
|
||||||
return (other.xsv == this.xsv && other.ysv == this.ysv);
|
return (other.xsv == this.xsv && other.ysv == this.ysv);
|
||||||
}
|
}
|
||||||
@ -617,15 +707,20 @@ public class OpenSimplex2S {
|
|||||||
private static class AreaGenLatticePoint3D {
|
private static class AreaGenLatticePoint3D {
|
||||||
int xsv, ysv, zsv, lattice;
|
int xsv, ysv, zsv, lattice;
|
||||||
int destPointX, destPointY, destPointZ;
|
int destPointX, destPointY, destPointZ;
|
||||||
|
|
||||||
public AreaGenLatticePoint3D(GenerateContext3D context, int xsv, int ysv, int zsv, int lattice) {
|
public AreaGenLatticePoint3D(GenerateContext3D context, int xsv, int ysv, int zsv, int lattice) {
|
||||||
this.xsv = xsv; this.ysv = ysv; this.zsv = zsv; this.lattice = lattice;
|
this.xsv = xsv;
|
||||||
|
this.ysv = ysv;
|
||||||
|
this.zsv = zsv;
|
||||||
|
this.lattice = lattice;
|
||||||
double xr = (xsv - lattice * 1024.5);
|
double xr = (xsv - lattice * 1024.5);
|
||||||
double yr = (ysv - lattice * 1024.5);
|
double yr = (ysv - lattice * 1024.5);
|
||||||
double zr = (zsv - lattice * 1024.5);
|
double zr = (zsv - lattice * 1024.5);
|
||||||
|
|
||||||
// Quaternion multiplication for inverse rotation.
|
// Quaternion multiplication for inverse rotation.
|
||||||
// https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
|
// https://blog.molecular-matters.com/2013/05/24/a-faster-quaternion-vector-multiplication/
|
||||||
double qx = -context.orientation.qx, qy = -context.orientation.qy, qz = -context.orientation.qz, qw = context.orientation.qw;
|
double qx = -context.orientation.qx, qy = -context.orientation.qy, qz = -context.orientation.qz,
|
||||||
|
qw = context.orientation.qw;
|
||||||
double tx = 2 * (qy * zr - qz * yr);
|
double tx = 2 * (qy * zr - qz * yr);
|
||||||
double ty = 2 * (qz * xr - qx * zr);
|
double ty = 2 * (qz * xr - qx * zr);
|
||||||
double tz = 2 * (qx * yr - qy * xr);
|
double tz = 2 * (qx * yr - qy * xr);
|
||||||
@ -633,19 +728,23 @@ public class OpenSimplex2S {
|
|||||||
double yrr = yr + qw * ty + (qz * tx - qx * tz);
|
double yrr = yr + qw * ty + (qz * tx - qx * tz);
|
||||||
double zrr = zr + qw * tz + (qx * ty - qy * tx);
|
double zrr = zr + qw * tz + (qx * ty - qy * tx);
|
||||||
|
|
||||||
this.destPointX = (int)Math.ceil(xrr * context.xFrequencyInverse);
|
this.destPointX = (int) Math.ceil(xrr * context.xFrequencyInverse);
|
||||||
this.destPointY = (int)Math.ceil(yrr * context.yFrequencyInverse);
|
this.destPointY = (int) Math.ceil(yrr * context.yFrequencyInverse);
|
||||||
this.destPointZ = (int)Math.ceil(zrr * context.zFrequencyInverse);
|
this.destPointZ = (int) Math.ceil(zrr * context.zFrequencyInverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return xsv * 2122193 + ysv * 2053 + zsv * 2 + lattice;
|
return xsv * 2122193 + ysv * 2053 + zsv * 2 + lattice;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object obj) {
|
public boolean equals(Object obj) {
|
||||||
if (!(obj instanceof AreaGenLatticePoint3D)) return false;
|
if (!(obj instanceof AreaGenLatticePoint3D))
|
||||||
|
return false;
|
||||||
AreaGenLatticePoint3D other = (AreaGenLatticePoint3D) obj;
|
AreaGenLatticePoint3D other = (AreaGenLatticePoint3D) obj;
|
||||||
return (other.xsv == this.xsv && other.ysv == this.ysv && other.zsv == this.zsv && other.lattice == this.lattice);
|
return (other.xsv == this.xsv && other.ysv == this.ysv && other.zsv == this.zsv
|
||||||
|
&& other.lattice == this.lattice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -661,7 +760,8 @@ public class OpenSimplex2S {
|
|||||||
int[] kernelBounds;
|
int[] kernelBounds;
|
||||||
LatticeOrientation2D orientation;
|
LatticeOrientation2D orientation;
|
||||||
|
|
||||||
public GenerateContext2D(LatticeOrientation2D orientation, double xFrequency, double yFrequency, double amplitude) {
|
public GenerateContext2D(LatticeOrientation2D orientation, double xFrequency, double yFrequency,
|
||||||
|
double amplitude) {
|
||||||
|
|
||||||
// These will be used by every call to generate
|
// These will be used by every call to generate
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
@ -674,19 +774,18 @@ public class OpenSimplex2S {
|
|||||||
double preciseScaledRadiusY = Math.sqrt(2.0 / 3.0) * yFrequencyInverse;
|
double preciseScaledRadiusY = Math.sqrt(2.0 / 3.0) * yFrequencyInverse;
|
||||||
|
|
||||||
// 0.25 because we offset center by 0.5
|
// 0.25 because we offset center by 0.5
|
||||||
this.scaledRadiusX = (int)Math.ceil(preciseScaledRadiusX + 0.25);
|
this.scaledRadiusX = (int) Math.ceil(preciseScaledRadiusX + 0.25);
|
||||||
this.scaledRadiusY = (int)Math.ceil(preciseScaledRadiusY + 0.25);
|
this.scaledRadiusY = (int) Math.ceil(preciseScaledRadiusY + 0.25);
|
||||||
|
|
||||||
// So will these
|
// So will these
|
||||||
kernel = new double[scaledRadiusY/* * 2*/][];
|
kernel = new double[scaledRadiusY/* * 2 */][];
|
||||||
kernelBounds = new int[scaledRadiusY * 2];
|
kernelBounds = new int[scaledRadiusY * 2];
|
||||||
for (int yy = 0; yy < scaledRadiusY * 2; yy++) {
|
for (int yy = 0; yy < scaledRadiusY * 2; yy++) {
|
||||||
|
|
||||||
// Pre-generate boundary of circle
|
// Pre-generate boundary of circle
|
||||||
kernelBounds[yy] = (int)Math.ceil(
|
kernelBounds[yy] = (int) Math.ceil(Math.sqrt(
|
||||||
Math.sqrt(1.0
|
1.0 - (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) / (scaledRadiusY * scaledRadiusY))
|
||||||
- (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) / (scaledRadiusY * scaledRadiusY)
|
* scaledRadiusX);
|
||||||
) * scaledRadiusX);
|
|
||||||
|
|
||||||
if (yy < scaledRadiusY) {
|
if (yy < scaledRadiusY) {
|
||||||
kernel[yy] = new double[scaledRadiusX * 2];
|
kernel[yy] = new double[scaledRadiusX * 2];
|
||||||
@ -703,7 +802,7 @@ public class OpenSimplex2S {
|
|||||||
kernel[yy][xx] = 0.0;
|
kernel[yy][xx] = 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* else kernel[yy] = kernel[2 * scaledRadiusY - yy - 1];*/
|
} /* else kernel[yy] = kernel[2 * scaledRadiusY - yy - 1]; */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -724,7 +823,8 @@ public class OpenSimplex2S {
|
|||||||
int[][] kernelBoundsX;
|
int[][] kernelBoundsX;
|
||||||
LatticeOrientation3D orientation;
|
LatticeOrientation3D orientation;
|
||||||
|
|
||||||
public GenerateContext3D(LatticeOrientation3D orientation, double xFrequency, double yFrequency, double zFrequency, double amplitude) {
|
public GenerateContext3D(LatticeOrientation3D orientation, double xFrequency, double yFrequency,
|
||||||
|
double zFrequency, double amplitude) {
|
||||||
|
|
||||||
// These will be used by every call to generate
|
// These will be used by every call to generate
|
||||||
this.orientation = orientation;
|
this.orientation = orientation;
|
||||||
@ -740,9 +840,9 @@ public class OpenSimplex2S {
|
|||||||
double preciseScaledRadiusZ = Math.sqrt(0.75) * zFrequencyInverse;
|
double preciseScaledRadiusZ = Math.sqrt(0.75) * zFrequencyInverse;
|
||||||
|
|
||||||
// 0.25 because we offset center by 0.5
|
// 0.25 because we offset center by 0.5
|
||||||
this.scaledRadiusX = (int)Math.ceil(preciseScaledRadiusX + 0.25);
|
this.scaledRadiusX = (int) Math.ceil(preciseScaledRadiusX + 0.25);
|
||||||
this.scaledRadiusY = (int)Math.ceil(preciseScaledRadiusY + 0.25);
|
this.scaledRadiusY = (int) Math.ceil(preciseScaledRadiusY + 0.25);
|
||||||
this.scaledRadiusZ = (int)Math.ceil(preciseScaledRadiusZ + 0.25);
|
this.scaledRadiusZ = (int) Math.ceil(preciseScaledRadiusZ + 0.25);
|
||||||
|
|
||||||
// So will these
|
// So will these
|
||||||
kernel = new double[scaledRadiusZ * 2][][];
|
kernel = new double[scaledRadiusZ * 2][][];
|
||||||
@ -751,9 +851,9 @@ public class OpenSimplex2S {
|
|||||||
for (int zz = 0; zz < scaledRadiusZ * 2; zz++) {
|
for (int zz = 0; zz < scaledRadiusZ * 2; zz++) {
|
||||||
|
|
||||||
// Pre-generate boundary of sphere
|
// Pre-generate boundary of sphere
|
||||||
kernelBoundsY[zz] = (int)Math.ceil(
|
kernelBoundsY[zz] = (int) Math.ceil(Math.sqrt(
|
||||||
Math.sqrt(1.0 - (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ)
|
1.0 - (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ) / (scaledRadiusZ * scaledRadiusZ))
|
||||||
/ (scaledRadiusZ * scaledRadiusZ)) * scaledRadiusY);
|
* scaledRadiusY);
|
||||||
|
|
||||||
if (zz < scaledRadiusZ) {
|
if (zz < scaledRadiusZ) {
|
||||||
kernel[zz] = new double[scaledRadiusY * 2][];
|
kernel[zz] = new double[scaledRadiusY * 2][];
|
||||||
@ -767,11 +867,12 @@ public class OpenSimplex2S {
|
|||||||
for (int yy = 0; yy < scaledRadiusY * 2; yy++) {
|
for (int yy = 0; yy < scaledRadiusY * 2; yy++) {
|
||||||
|
|
||||||
// Pre-generate boundary of sphere
|
// Pre-generate boundary of sphere
|
||||||
kernelBoundsX[zz][yy] = (int)Math.ceil(
|
kernelBoundsX[zz][yy] = (int) Math.ceil(Math.sqrt(1.0
|
||||||
Math.sqrt(1.0
|
- (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY)
|
||||||
- (yy + 0.5 - scaledRadiusY) * (yy + 0.5 - scaledRadiusY) / (scaledRadiusY * scaledRadiusY)
|
/ (scaledRadiusY * scaledRadiusY)
|
||||||
- (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ) / (scaledRadiusZ * scaledRadiusZ)
|
- (zz + 0.5 - scaledRadiusZ) * (zz + 0.5 - scaledRadiusZ)
|
||||||
) * scaledRadiusX);
|
/ (scaledRadiusZ * scaledRadiusZ))
|
||||||
|
* scaledRadiusX);
|
||||||
|
|
||||||
if (yy < scaledRadiusY) {
|
if (yy < scaledRadiusY) {
|
||||||
kernel[zz][yy] = new double[scaledRadiusX * 2];
|
kernel[zz][yy] = new double[scaledRadiusX * 2];
|
||||||
@ -790,7 +891,8 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else kernel[zz][yy] = kernel[zz][2 * scaledRadiusY - yy - 1];
|
} else
|
||||||
|
kernel[zz][yy] = kernel[zz][2 * scaledRadiusY - yy - 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -798,40 +900,50 @@ public class OpenSimplex2S {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public enum LatticeOrientation2D {
|
public enum LatticeOrientation2D {
|
||||||
// Simplex skew transforms have always been shorthand for the matrices they represent.
|
// Simplex skew transforms have always been shorthand for the matrices
|
||||||
// But when we bake the rotation into the skew transform, we need to use the general form.
|
// they represent.
|
||||||
Standard(GRADIENTS_2D,
|
// But when we bake the rotation into the skew transform, we need to use
|
||||||
1.366025403784439, 0.366025403784439, 0.366025403784439, 1.366025403784439,
|
// the general form.
|
||||||
0.788675134594813, -0.211324865405187, -0.211324865405187, 0.788675134594813),
|
Standard(GRADIENTS_2D, 1.366025403784439, 0.366025403784439, 0.366025403784439, 1.366025403784439,
|
||||||
XBeforeY(GRADIENTS_2D_X_BEFORE_Y,
|
0.788675134594813, -0.211324865405187, -0.211324865405187,
|
||||||
0.7071067811865476, 1.224744871380249, -0.7071067811865476, 1.224744871380249,
|
0.788675134594813), XBeforeY(GRADIENTS_2D_X_BEFORE_Y, 0.7071067811865476, 1.224744871380249,
|
||||||
0.7071067811865476, -0.7071067811865476, 0.40824829046764305, 0.40824829046764305);
|
-0.7071067811865476, 1.224744871380249, 0.7071067811865476, -0.7071067811865476,
|
||||||
|
0.40824829046764305, 0.40824829046764305);
|
||||||
|
|
||||||
Grad2[] gradients;
|
Grad2[] gradients;
|
||||||
double s00, s01, s10, s11;
|
double s00, s01, s10, s11;
|
||||||
double t00, t01, t10, t11;
|
double t00, t01, t10, t11;
|
||||||
|
|
||||||
private LatticeOrientation2D(Grad2[] gradients,
|
private LatticeOrientation2D(Grad2[] gradients, double s00, double s01, double s10, double s11, double t00,
|
||||||
double s00, double s01, double s10, double s11,
|
double t01, double t10, double t11) {
|
||||||
double t00, double t01, double t10, double t11) {
|
|
||||||
this.gradients = gradients;
|
this.gradients = gradients;
|
||||||
this.s00 = s00; this.s01 = s01; this.s10 = s10; this.s11 = s11;
|
this.s00 = s00;
|
||||||
this.t00 = t00; this.t01 = t01; this.t10 = t10; this.t11 = t11;
|
this.s01 = s01;
|
||||||
|
this.s10 = s10;
|
||||||
|
this.s11 = s11;
|
||||||
|
this.t00 = t00;
|
||||||
|
this.t01 = t01;
|
||||||
|
this.t10 = t10;
|
||||||
|
this.t11 = t11;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum LatticeOrientation3D {
|
public enum LatticeOrientation3D {
|
||||||
// Quaternions for 3D. Could use matrices, but I already wrote this code before I moved them into here.
|
// Quaternions for 3D. Could use matrices, but I already wrote this code
|
||||||
Classic(GRADIENTS_3D_CLASSIC, 0.577350269189626, 0.577350269189626, 0.577350269189626, 0),
|
// before I moved them into here.
|
||||||
XYBeforeZ(GRADIENTS_3D_XY_BEFORE_Z, 0.3250575836718682, -0.3250575836718682, 0, 0.8880738339771154),
|
Classic(GRADIENTS_3D_CLASSIC, 0.577350269189626, 0.577350269189626, 0.577350269189626, 0), XYBeforeZ(
|
||||||
XZBeforeY(GRADIENTS_3D_XZ_BEFORE_Y, -0.3250575836718682, 0, 0.3250575836718682, 0.8880738339771154);
|
GRADIENTS_3D_XY_BEFORE_Z, 0.3250575836718682, -0.3250575836718682, 0, 0.8880738339771154), XZBeforeY(
|
||||||
|
GRADIENTS_3D_XZ_BEFORE_Y, -0.3250575836718682, 0, 0.3250575836718682, 0.8880738339771154);
|
||||||
|
|
||||||
Grad3[] gradients;
|
Grad3[] gradients;
|
||||||
double qx, qy, qz, qw;
|
double qx, qy, qz, qw;
|
||||||
|
|
||||||
private LatticeOrientation3D(Grad3[] gradients, double qx, double qy, double qz, double qw) {
|
private LatticeOrientation3D(Grad3[] gradients, double qx, double qy, double qz, double qw) {
|
||||||
this.gradients = gradients;
|
this.gradients = gradients;
|
||||||
this.qx = qx; this.qy = qy; this.qz = qz; this.qw = qw;
|
this.qx = qx;
|
||||||
|
this.qy = qy;
|
||||||
|
this.qz = qz;
|
||||||
|
this.qw = qw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -841,15 +953,20 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
public static class Grad2 {
|
public static class Grad2 {
|
||||||
double dx, dy;
|
double dx, dy;
|
||||||
|
|
||||||
public Grad2(double dx, double dy) {
|
public Grad2(double dx, double dy) {
|
||||||
this.dx = dx; this.dy = dy;
|
this.dx = dx;
|
||||||
|
this.dy = dy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Grad3 {
|
public static class Grad3 {
|
||||||
double dx, dy, dz;
|
double dx, dy, dz;
|
||||||
|
|
||||||
public Grad3(double dx, double dy, double dz) {
|
public Grad3(double dx, double dy, double dz) {
|
||||||
this.dx = dx; this.dy = dy; this.dz = dz;
|
this.dx = dx;
|
||||||
|
this.dy = dy;
|
||||||
|
this.dz = dz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -861,35 +978,23 @@ public class OpenSimplex2S {
|
|||||||
|
|
||||||
GRADIENTS_2D = new Grad2[PSIZE];
|
GRADIENTS_2D = new Grad2[PSIZE];
|
||||||
GRADIENTS_2D_X_BEFORE_Y = new Grad2[PSIZE];
|
GRADIENTS_2D_X_BEFORE_Y = new Grad2[PSIZE];
|
||||||
Grad2[] grad2 = {
|
Grad2[] grad2 = { new Grad2(0.130526192220052, 0.99144486137381),
|
||||||
new Grad2( 0.130526192220052, 0.99144486137381),
|
new Grad2(0.38268343236509, 0.923879532511287), new Grad2(0.608761429008721, 0.793353340291235),
|
||||||
new Grad2( 0.38268343236509, 0.923879532511287),
|
new Grad2(0.793353340291235, 0.608761429008721), new Grad2(0.923879532511287, 0.38268343236509),
|
||||||
new Grad2( 0.608761429008721, 0.793353340291235),
|
new Grad2(0.99144486137381, 0.130526192220051), new Grad2(0.99144486137381, -0.130526192220051),
|
||||||
new Grad2( 0.793353340291235, 0.608761429008721),
|
new Grad2(0.923879532511287, -0.38268343236509), new Grad2(0.793353340291235, -0.60876142900872),
|
||||||
new Grad2( 0.923879532511287, 0.38268343236509),
|
new Grad2(0.608761429008721, -0.793353340291235), new Grad2(0.38268343236509, -0.923879532511287),
|
||||||
new Grad2( 0.99144486137381, 0.130526192220051),
|
new Grad2(0.130526192220052, -0.99144486137381), new Grad2(-0.130526192220052, -0.99144486137381),
|
||||||
new Grad2( 0.99144486137381, -0.130526192220051),
|
new Grad2(-0.38268343236509, -0.923879532511287), new Grad2(-0.608761429008721, -0.793353340291235),
|
||||||
new Grad2( 0.923879532511287, -0.38268343236509),
|
new Grad2(-0.793353340291235, -0.608761429008721), new Grad2(-0.923879532511287, -0.38268343236509),
|
||||||
new Grad2( 0.793353340291235, -0.60876142900872),
|
new Grad2(-0.99144486137381, -0.130526192220052), new Grad2(-0.99144486137381, 0.130526192220051),
|
||||||
new Grad2( 0.608761429008721, -0.793353340291235),
|
new Grad2(-0.923879532511287, 0.38268343236509), new Grad2(-0.793353340291235, 0.608761429008721),
|
||||||
new Grad2( 0.38268343236509, -0.923879532511287),
|
new Grad2(-0.608761429008721, 0.793353340291235), new Grad2(-0.38268343236509, 0.923879532511287),
|
||||||
new Grad2( 0.130526192220052, -0.99144486137381),
|
new Grad2(-0.130526192220052, 0.99144486137381) };
|
||||||
new Grad2(-0.130526192220052, -0.99144486137381),
|
|
||||||
new Grad2(-0.38268343236509, -0.923879532511287),
|
|
||||||
new Grad2(-0.608761429008721, -0.793353340291235),
|
|
||||||
new Grad2(-0.793353340291235, -0.608761429008721),
|
|
||||||
new Grad2(-0.923879532511287, -0.38268343236509),
|
|
||||||
new Grad2(-0.99144486137381, -0.130526192220052),
|
|
||||||
new Grad2(-0.99144486137381, 0.130526192220051),
|
|
||||||
new Grad2(-0.923879532511287, 0.38268343236509),
|
|
||||||
new Grad2(-0.793353340291235, 0.608761429008721),
|
|
||||||
new Grad2(-0.608761429008721, 0.793353340291235),
|
|
||||||
new Grad2(-0.38268343236509, 0.923879532511287),
|
|
||||||
new Grad2(-0.130526192220052, 0.99144486137381)
|
|
||||||
};
|
|
||||||
Grad2[] grad2XBeforeY = new Grad2[grad2.length];
|
Grad2[] grad2XBeforeY = new Grad2[grad2.length];
|
||||||
for (int i = 0; i < grad2.length; i++) {
|
for (int i = 0; i < grad2.length; i++) {
|
||||||
grad2[i].dx /= N2; grad2[i].dy /= N2;
|
grad2[i].dx /= N2;
|
||||||
|
grad2[i].dy /= N2;
|
||||||
|
|
||||||
// Unrotated gradients for XBeforeY 2D
|
// Unrotated gradients for XBeforeY 2D
|
||||||
double xx = grad2[i].dx * 0.7071067811865476;
|
double xx = grad2[i].dx * 0.7071067811865476;
|
||||||
@ -905,77 +1010,59 @@ public class OpenSimplex2S {
|
|||||||
GRADIENTS_3D_CLASSIC = new Grad3[PSIZE];
|
GRADIENTS_3D_CLASSIC = new Grad3[PSIZE];
|
||||||
GRADIENTS_3D_XY_BEFORE_Z = new Grad3[PSIZE];
|
GRADIENTS_3D_XY_BEFORE_Z = new Grad3[PSIZE];
|
||||||
GRADIENTS_3D_XZ_BEFORE_Y = new Grad3[PSIZE];
|
GRADIENTS_3D_XZ_BEFORE_Y = new Grad3[PSIZE];
|
||||||
Grad3[] grad3 = {
|
Grad3[] grad3 = { new Grad3(-2.22474487139, -2.22474487139, -1.0),
|
||||||
new Grad3(-2.22474487139, -2.22474487139, -1.0),
|
|
||||||
new Grad3(-2.22474487139, -2.22474487139, 1.0),
|
new Grad3(-2.22474487139, -2.22474487139, 1.0),
|
||||||
new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0),
|
new Grad3(-3.0862664687972017, -1.1721513422464978, 0.0),
|
||||||
new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0),
|
new Grad3(-1.1721513422464978, -3.0862664687972017, 0.0),
|
||||||
new Grad3(-2.22474487139, -1.0, -2.22474487139),
|
new Grad3(-2.22474487139, -1.0, -2.22474487139), new Grad3(-2.22474487139, 1.0, -2.22474487139),
|
||||||
new Grad3(-2.22474487139, 1.0, -2.22474487139),
|
|
||||||
new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017),
|
new Grad3(-1.1721513422464978, 0.0, -3.0862664687972017),
|
||||||
new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978),
|
new Grad3(-3.0862664687972017, 0.0, -1.1721513422464978),
|
||||||
new Grad3(-2.22474487139, -1.0, 2.22474487139),
|
new Grad3(-2.22474487139, -1.0, 2.22474487139), new Grad3(-2.22474487139, 1.0, 2.22474487139),
|
||||||
new Grad3(-2.22474487139, 1.0, 2.22474487139),
|
|
||||||
new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978),
|
new Grad3(-3.0862664687972017, 0.0, 1.1721513422464978),
|
||||||
new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017),
|
new Grad3(-1.1721513422464978, 0.0, 3.0862664687972017), new Grad3(-2.22474487139, 2.22474487139, -1.0),
|
||||||
new Grad3(-2.22474487139, 2.22474487139, -1.0),
|
new Grad3(-2.22474487139, 2.22474487139, 1.0), new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0),
|
||||||
new Grad3(-2.22474487139, 2.22474487139, 1.0),
|
|
||||||
new Grad3(-1.1721513422464978, 3.0862664687972017, 0.0),
|
|
||||||
new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0),
|
new Grad3(-3.0862664687972017, 1.1721513422464978, 0.0),
|
||||||
new Grad3(-1.0, -2.22474487139, -2.22474487139),
|
new Grad3(-1.0, -2.22474487139, -2.22474487139), new Grad3(1.0, -2.22474487139, -2.22474487139),
|
||||||
new Grad3( 1.0, -2.22474487139, -2.22474487139),
|
new Grad3(0.0, -3.0862664687972017, -1.1721513422464978),
|
||||||
new Grad3( 0.0, -3.0862664687972017, -1.1721513422464978),
|
new Grad3(0.0, -1.1721513422464978, -3.0862664687972017),
|
||||||
new Grad3( 0.0, -1.1721513422464978, -3.0862664687972017),
|
new Grad3(-1.0, -2.22474487139, 2.22474487139), new Grad3(1.0, -2.22474487139, 2.22474487139),
|
||||||
new Grad3(-1.0, -2.22474487139, 2.22474487139),
|
new Grad3(0.0, -1.1721513422464978, 3.0862664687972017),
|
||||||
new Grad3( 1.0, -2.22474487139, 2.22474487139),
|
new Grad3(0.0, -3.0862664687972017, 1.1721513422464978), new Grad3(-1.0, 2.22474487139, -2.22474487139),
|
||||||
new Grad3( 0.0, -1.1721513422464978, 3.0862664687972017),
|
new Grad3(1.0, 2.22474487139, -2.22474487139), new Grad3(0.0, 1.1721513422464978, -3.0862664687972017),
|
||||||
new Grad3( 0.0, -3.0862664687972017, 1.1721513422464978),
|
new Grad3(0.0, 3.0862664687972017, -1.1721513422464978), new Grad3(-1.0, 2.22474487139, 2.22474487139),
|
||||||
new Grad3(-1.0, 2.22474487139, -2.22474487139),
|
new Grad3(1.0, 2.22474487139, 2.22474487139), new Grad3(0.0, 3.0862664687972017, 1.1721513422464978),
|
||||||
new Grad3( 1.0, 2.22474487139, -2.22474487139),
|
new Grad3(0.0, 1.1721513422464978, 3.0862664687972017), new Grad3(2.22474487139, -2.22474487139, -1.0),
|
||||||
new Grad3( 0.0, 1.1721513422464978, -3.0862664687972017),
|
new Grad3(2.22474487139, -2.22474487139, 1.0), new Grad3(1.1721513422464978, -3.0862664687972017, 0.0),
|
||||||
new Grad3( 0.0, 3.0862664687972017, -1.1721513422464978),
|
new Grad3(3.0862664687972017, -1.1721513422464978, 0.0), new Grad3(2.22474487139, -1.0, -2.22474487139),
|
||||||
new Grad3(-1.0, 2.22474487139, 2.22474487139),
|
new Grad3(2.22474487139, 1.0, -2.22474487139), new Grad3(3.0862664687972017, 0.0, -1.1721513422464978),
|
||||||
new Grad3( 1.0, 2.22474487139, 2.22474487139),
|
new Grad3(1.1721513422464978, 0.0, -3.0862664687972017), new Grad3(2.22474487139, -1.0, 2.22474487139),
|
||||||
new Grad3( 0.0, 3.0862664687972017, 1.1721513422464978),
|
new Grad3(2.22474487139, 1.0, 2.22474487139), new Grad3(1.1721513422464978, 0.0, 3.0862664687972017),
|
||||||
new Grad3( 0.0, 1.1721513422464978, 3.0862664687972017),
|
new Grad3(3.0862664687972017, 0.0, 1.1721513422464978), new Grad3(2.22474487139, 2.22474487139, -1.0),
|
||||||
new Grad3( 2.22474487139, -2.22474487139, -1.0),
|
new Grad3(2.22474487139, 2.22474487139, 1.0), new Grad3(3.0862664687972017, 1.1721513422464978, 0.0),
|
||||||
new Grad3( 2.22474487139, -2.22474487139, 1.0),
|
new Grad3(1.1721513422464978, 3.0862664687972017, 0.0) };
|
||||||
new Grad3( 1.1721513422464978, -3.0862664687972017, 0.0),
|
|
||||||
new Grad3( 3.0862664687972017, -1.1721513422464978, 0.0),
|
|
||||||
new Grad3( 2.22474487139, -1.0, -2.22474487139),
|
|
||||||
new Grad3( 2.22474487139, 1.0, -2.22474487139),
|
|
||||||
new Grad3( 3.0862664687972017, 0.0, -1.1721513422464978),
|
|
||||||
new Grad3( 1.1721513422464978, 0.0, -3.0862664687972017),
|
|
||||||
new Grad3( 2.22474487139, -1.0, 2.22474487139),
|
|
||||||
new Grad3( 2.22474487139, 1.0, 2.22474487139),
|
|
||||||
new Grad3( 1.1721513422464978, 0.0, 3.0862664687972017),
|
|
||||||
new Grad3( 3.0862664687972017, 0.0, 1.1721513422464978),
|
|
||||||
new Grad3( 2.22474487139, 2.22474487139, -1.0),
|
|
||||||
new Grad3( 2.22474487139, 2.22474487139, 1.0),
|
|
||||||
new Grad3( 3.0862664687972017, 1.1721513422464978, 0.0),
|
|
||||||
new Grad3( 1.1721513422464978, 3.0862664687972017, 0.0)
|
|
||||||
};
|
|
||||||
Grad3[] grad3Classic = new Grad3[grad3.length];
|
Grad3[] grad3Classic = new Grad3[grad3.length];
|
||||||
Grad3[] grad3XYBeforeZ = new Grad3[grad3.length];
|
Grad3[] grad3XYBeforeZ = new Grad3[grad3.length];
|
||||||
Grad3[] grad3XZBeforeY = new Grad3[grad3.length];
|
Grad3[] grad3XZBeforeY = new Grad3[grad3.length];
|
||||||
for (int i = 0; i < grad3.length; i++) {
|
for (int i = 0; i < grad3.length; i++) {
|
||||||
grad3[i].dx /= N3; grad3[i].dy /= N3; grad3[i].dz /= N3;
|
grad3[i].dx /= N3;
|
||||||
|
grad3[i].dy /= N3;
|
||||||
|
grad3[i].dz /= N3;
|
||||||
double gxr = grad3[i].dx, gyr = grad3[i].dy, gzr = grad3[i].dz;
|
double gxr = grad3[i].dx, gyr = grad3[i].dy, gzr = grad3[i].dz;
|
||||||
|
|
||||||
// Unrotated gradients for classic 3D
|
// Unrotated gradients for classic 3D
|
||||||
double grr = (2.0 / 3.0) * (gxr + gyr + gzr);
|
double grr = (2.0 / 3.0) * (gxr + gyr + gzr);
|
||||||
// double dx = grr - gxr, dy = grr - gyr, dz = grr - gzr;
|
// double dx = grr - gxr, dy = grr - gyr, dz = grr - gzr;
|
||||||
grad3Classic[i] = new Grad3( grr - gxr, grr - gyr, grr - gzr );
|
grad3Classic[i] = new Grad3(grr - gxr, grr - gyr, grr - gzr);
|
||||||
|
|
||||||
// Unrotated gradients for XYBeforeZ 3D
|
// Unrotated gradients for XYBeforeZ 3D
|
||||||
double s2 = (gxr + gyr) * -0.211324865405187;
|
double s2 = (gxr + gyr) * -0.211324865405187;
|
||||||
double zz = gzr * 0.577350269189626;
|
double zz = gzr * 0.577350269189626;
|
||||||
grad3XYBeforeZ[i] = new Grad3( gxr + s2 + zz, gyr + s2 + zz, (gzr - gxr - gyr) * 0.577350269189626 );
|
grad3XYBeforeZ[i] = new Grad3(gxr + s2 + zz, gyr + s2 + zz, (gzr - gxr - gyr) * 0.577350269189626);
|
||||||
|
|
||||||
// Unrotated gradients for plane-first 3D
|
// Unrotated gradients for plane-first 3D
|
||||||
s2 = (gxr + gzr) * -0.211324865405187;
|
s2 = (gxr + gzr) * -0.211324865405187;
|
||||||
double yy = gyr * 0.577350269189626;
|
double yy = gyr * 0.577350269189626;
|
||||||
grad3XZBeforeY[i] = new Grad3( gxr + s2 + yy, (gyr - gxr - gzr) * 0.577350269189626, gzr + s2 + yy );
|
grad3XZBeforeY[i] = new Grad3(gxr + s2 + yy, (gyr - gxr - gzr) * 0.577350269189626, gzr + s2 + yy);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < PSIZE; i++) {
|
for (int i = 0; i < PSIZE; i++) {
|
||||||
GRADIENTS_3D[i] = grad3[i % grad3.length];
|
GRADIENTS_3D[i] = grad3[i % grad3.length];
|
||||||
|
@ -611,8 +611,7 @@ public class ArrayUtil {
|
|||||||
int end = offset + length;
|
int end = offset + length;
|
||||||
if (end > arrayLength || offset < 0)
|
if (end > arrayLength || offset < 0)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Array contains [0; " + arrayLength + "), requested [" + offset + "; " + end + ")"
|
"Array contains [0; " + arrayLength + "), requested [" + offset + "; " + end + ")");
|
||||||
);
|
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
@ -628,8 +627,7 @@ public class ArrayUtil {
|
|||||||
|
|
||||||
if (end > arrayLength || start < 0)
|
if (end > arrayLength || start < 0)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Array contains [0; " + arrayLength + "), requested [" + start + "; " + end + ")"
|
"Array contains [0; " + arrayLength + "), requested [" + start + "; " + end + ")");
|
||||||
);
|
|
||||||
|
|
||||||
return end;
|
return end;
|
||||||
}
|
}
|
||||||
|
@ -30,18 +30,8 @@ public class PrimitiveUtil {
|
|||||||
private static final Map<Class<?>, Object> PRIMITIVE_TO_NULL = new HashMap<>();
|
private static final Map<Class<?>, Object> PRIMITIVE_TO_NULL = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (
|
for (Class<?> boxed : new Class<?>[] { Boolean.class, Byte.class, Short.class, Character.class, Integer.class,
|
||||||
Class<?> boxed : new Class<?>[] {
|
Long.class, Float.class, Double.class }) {
|
||||||
Boolean.class,
|
|
||||||
Byte.class,
|
|
||||||
Short.class,
|
|
||||||
Character.class,
|
|
||||||
Integer.class,
|
|
||||||
Long.class,
|
|
||||||
Float.class,
|
|
||||||
Double.class
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
try {
|
try {
|
||||||
PRIMITIVE_TO_BOXED.put((Class<?>) boxed.getField("TYPE").get(null), boxed);
|
PRIMITIVE_TO_BOXED.put((Class<?>) boxed.getField("TYPE").get(null), boxed);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -40,8 +40,7 @@ import java.util.stream.Stream;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains static methods to create {@link Stream Streams} that synchronize
|
* Contains static methods to create {@link Stream Streams} that synchronize
|
||||||
* their
|
* their <a href=
|
||||||
* <a href=
|
|
||||||
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
||||||
* terminal operations</a> on a given monitor.
|
* terminal operations</a> on a given monitor.
|
||||||
*
|
*
|
||||||
@ -1070,21 +1069,18 @@ public class SyncStreams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given {@link Stream} to make all
|
* Wraps the given {@link Stream} to make all <a href=
|
||||||
* <a href=
|
|
||||||
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
||||||
* terminal operations</a> acquire the provided monitor's lock before
|
* terminal operations</a> acquire the provided monitor's lock before
|
||||||
* execution. Intermediate operations
|
* execution. Intermediate operations return streams that are also
|
||||||
* return streams that are also synchronized on the same object. The created
|
* synchronized on the same object. The created stream will behave
|
||||||
* stream will behave identically
|
* identically to the provided stream in all other aspects. Use this to
|
||||||
* to the provided stream in all other aspects. Use this to synchronize
|
* synchronize access to stream's source.
|
||||||
* access to stream's source.
|
|
||||||
* <p>
|
* <p>
|
||||||
* <i>The returned {@code Stream}'s {@link Stream#iterator() iterator()} and
|
* <i>The returned {@code Stream}'s {@link Stream#iterator() iterator()} and
|
||||||
* {@link Stream#spliterator()
|
* {@link Stream#spliterator() spliterator()} methods return regular
|
||||||
* spliterator()} methods return regular non-synchronized iterators and
|
* non-synchronized iterators and spliterators respectively</i>. It is the
|
||||||
* spliterators respectively</i>. It
|
* user's responsibility to avoid concurrency issues:
|
||||||
* is the user's responsibility to avoid concurrency issues:
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* synchronized (stream.getMonitor()) {
|
* synchronized (stream.getMonitor()) {
|
||||||
@ -1103,14 +1099,17 @@ public class SyncStreams {
|
|||||||
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param <T> the class of objects in the Stream
|
* @param <T>
|
||||||
* @param stream the stream to wrap.
|
* the class of objects in the Stream
|
||||||
* @param monitor the object that the stream will use for synchronization.
|
* @param stream
|
||||||
* When {@code null}, the stream
|
* the stream to wrap.
|
||||||
* will synchronize on itself.
|
* @param monitor
|
||||||
|
* the object that the stream will use for synchronization. When
|
||||||
|
* {@code null}, the stream will synchronize on itself.
|
||||||
* @return a {@link SyncStream SyncStream<T>} synchronized on
|
* @return a {@link SyncStream SyncStream<T>} synchronized on
|
||||||
* {@code monitor} and backed by {@code stream}.
|
* {@code monitor} and backed by {@code stream}.
|
||||||
* @throws NullPointerException if {@code stream == null}.
|
* @throws NullPointerException
|
||||||
|
* if {@code stream == null}.
|
||||||
*/
|
*/
|
||||||
public static <T> SyncStream<T> synchronizedStream(Stream<T> stream, Object monitor) {
|
public static <T> SyncStream<T> synchronizedStream(Stream<T> stream, Object monitor) {
|
||||||
Objects.requireNonNull(stream, "stream cannot be null");
|
Objects.requireNonNull(stream, "stream cannot be null");
|
||||||
@ -1118,22 +1117,19 @@ public class SyncStreams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given {@link IntStream} to make all
|
* Wraps the given {@link IntStream} to make all <a href=
|
||||||
* <a href=
|
|
||||||
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
||||||
* terminal operations</a> acquire the provided monitor's lock before
|
* terminal operations</a> acquire the provided monitor's lock before
|
||||||
* execution. Intermediate operations
|
* execution. Intermediate operations return streams that are also
|
||||||
* return streams that are also synchronized on the same object. The created
|
* synchronized on the same object. The created stream will behave
|
||||||
* stream will behave identically
|
* identically to the provided stream in all other aspects. Use this to
|
||||||
* to the provided stream in all other aspects. Use this to synchronize
|
* synchronize access to stream's source.
|
||||||
* access to stream's source.
|
|
||||||
* <p>
|
* <p>
|
||||||
* <i>The returned {@code IntStream}'s {@link IntStream#iterator()
|
* <i>The returned {@code IntStream}'s {@link IntStream#iterator()
|
||||||
* iterator()} and
|
* iterator()} and {@link IntStream#spliterator() spliterator()} methods
|
||||||
* {@link IntStream#spliterator() spliterator()} methods return regular
|
* return regular non-synchronized iterators and spliterators
|
||||||
* non-synchronized iterators and
|
* respectively</i>. It is the user's responsibility to avoid concurrency
|
||||||
* spliterators respectively</i>. It is the user's responsibility to avoid
|
* issues:
|
||||||
* concurrency issues:
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* synchronized (stream.getMonitor()) {
|
* synchronized (stream.getMonitor()) {
|
||||||
@ -1152,13 +1148,15 @@ public class SyncStreams {
|
|||||||
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param stream the stream to wrap.
|
* @param stream
|
||||||
* @param monitor the object that the stream will use for synchronization.
|
* the stream to wrap.
|
||||||
* When {@code null}, the stream
|
* @param monitor
|
||||||
* will synchronize on itself.
|
* the object that the stream will use for synchronization. When
|
||||||
|
* {@code null}, the stream will synchronize on itself.
|
||||||
* @return a {@link SyncIntStream} synchronized on {@code monitor} and
|
* @return a {@link SyncIntStream} synchronized on {@code monitor} and
|
||||||
* backed by {@code stream}.
|
* backed by {@code stream}.
|
||||||
* @throws NullPointerException if {@code stream == null}.
|
* @throws NullPointerException
|
||||||
|
* if {@code stream == null}.
|
||||||
*/
|
*/
|
||||||
public static SyncIntStream synchronizedStream(IntStream stream, Object monitor) {
|
public static SyncIntStream synchronizedStream(IntStream stream, Object monitor) {
|
||||||
Objects.requireNonNull(stream, "stream cannot be null");
|
Objects.requireNonNull(stream, "stream cannot be null");
|
||||||
@ -1166,22 +1164,19 @@ public class SyncStreams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given {@link LongStream} to make all
|
* Wraps the given {@link LongStream} to make all <a href=
|
||||||
* <a href=
|
|
||||||
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
||||||
* terminal operations</a> acquire the provided monitor's lock before
|
* terminal operations</a> acquire the provided monitor's lock before
|
||||||
* execution. Intermediate operations
|
* execution. Intermediate operations return streams that are also
|
||||||
* return streams that are also synchronized on the same object. The created
|
* synchronized on the same object. The created stream will behave
|
||||||
* stream will behave identically
|
* identically to the provided stream in all other aspects. Use this to
|
||||||
* to the provided stream in all other aspects. Use this to synchronize
|
* synchronize access to stream's source.
|
||||||
* access to stream's source.
|
|
||||||
* <p>
|
* <p>
|
||||||
* <i>The returned {@code LongStream}'s {@link LongStream#iterator()
|
* <i>The returned {@code LongStream}'s {@link LongStream#iterator()
|
||||||
* iterator()} and
|
* iterator()} and {@link LongStream#spliterator() spliterator()} methods
|
||||||
* {@link LongStream#spliterator() spliterator()} methods return regular
|
* return regular non-synchronized iterators and spliterators
|
||||||
* non-synchronized iterators and
|
* respectively</i>. It is the user's responsibility to avoid concurrency
|
||||||
* spliterators respectively</i>. It is the user's responsibility to avoid
|
* issues:
|
||||||
* concurrency issues:
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* synchronized (stream.getMonitor()) {
|
* synchronized (stream.getMonitor()) {
|
||||||
@ -1200,13 +1195,15 @@ public class SyncStreams {
|
|||||||
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param stream the stream to wrap.
|
* @param stream
|
||||||
* @param monitor the object that the stream will use for synchronization.
|
* the stream to wrap.
|
||||||
* When {@code null}, the stream
|
* @param monitor
|
||||||
* will synchronize on itself.
|
* the object that the stream will use for synchronization. When
|
||||||
|
* {@code null}, the stream will synchronize on itself.
|
||||||
* @return a {@link SyncLongStream} synchronized on {@code monitor} and
|
* @return a {@link SyncLongStream} synchronized on {@code monitor} and
|
||||||
* backed by {@code stream}.
|
* backed by {@code stream}.
|
||||||
* @throws NullPointerException if {@code stream == null}.
|
* @throws NullPointerException
|
||||||
|
* if {@code stream == null}.
|
||||||
*/
|
*/
|
||||||
public static SyncLongStream synchronizedStream(LongStream stream, Object monitor) {
|
public static SyncLongStream synchronizedStream(LongStream stream, Object monitor) {
|
||||||
Objects.requireNonNull(stream, "stream cannot be null");
|
Objects.requireNonNull(stream, "stream cannot be null");
|
||||||
@ -1214,22 +1211,19 @@ public class SyncStreams {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wraps the given {@link DoubleStream} to make all
|
* Wraps the given {@link DoubleStream} to make all <a href=
|
||||||
* <a href=
|
|
||||||
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
* "https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#StreamOps">
|
||||||
* terminal operations</a> acquire the provided monitor's lock before
|
* terminal operations</a> acquire the provided monitor's lock before
|
||||||
* execution. Intermediate operations
|
* execution. Intermediate operations return streams that are also
|
||||||
* return streams that are also synchronized on the same object. The created
|
* synchronized on the same object. The created stream will behave
|
||||||
* stream will behave identically
|
* identically to the provided stream in all other aspects. Use this to
|
||||||
* to the provided stream in all other aspects. Use this to synchronize
|
* synchronize access to stream's source.
|
||||||
* access to stream's source.
|
|
||||||
* <p>
|
* <p>
|
||||||
* <i>The returned {@code DoubleStream}'s {@link DoubleStream#iterator()
|
* <i>The returned {@code DoubleStream}'s {@link DoubleStream#iterator()
|
||||||
* iterator()} and
|
* iterator()} and {@link DoubleStream#spliterator() spliterator()} methods
|
||||||
* {@link DoubleStream#spliterator() spliterator()} methods return regular
|
* return regular non-synchronized iterators and spliterators
|
||||||
* non-synchronized iterators and
|
* respectively</i>. It is the user's responsibility to avoid concurrency
|
||||||
* spliterators respectively</i>. It is the user's responsibility to avoid
|
* issues:
|
||||||
* concurrency issues:
|
|
||||||
*
|
*
|
||||||
* <pre>
|
* <pre>
|
||||||
* synchronized (stream.getMonitor()) {
|
* synchronized (stream.getMonitor()) {
|
||||||
@ -1248,13 +1242,15 @@ public class SyncStreams {
|
|||||||
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
* stream.forEach(System.out::println); // Should never throw a ConcurrentModificationException
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param stream the stream to wrap.
|
* @param stream
|
||||||
* @param monitor the object that the stream will use for synchronization.
|
* the stream to wrap.
|
||||||
* When {@code null}, the stream
|
* @param monitor
|
||||||
* will synchronize on itself.
|
* the object that the stream will use for synchronization. When
|
||||||
|
* {@code null}, the stream will synchronize on itself.
|
||||||
* @return a {@link SyncDoubleStream} synchronized on {@code monitor} and
|
* @return a {@link SyncDoubleStream} synchronized on {@code monitor} and
|
||||||
* backed by {@code stream}.
|
* backed by {@code stream}.
|
||||||
* @throws NullPointerException if {@code stream == null}.
|
* @throws NullPointerException
|
||||||
|
* if {@code stream == null}.
|
||||||
*/
|
*/
|
||||||
public static SyncDoubleStream synchronizedStream(DoubleStream stream, Object monitor) {
|
public static SyncDoubleStream synchronizedStream(DoubleStream stream, Object monitor) {
|
||||||
Objects.requireNonNull(stream, "stream cannot be null");
|
Objects.requireNonNull(stream, "stream cannot be null");
|
||||||
|
@ -108,7 +108,7 @@ public class CharArrayIterator implements CharacterIterator {
|
|||||||
return pos;
|
return pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @SuppressWarnings("all") Just STFU, this _is_ terrific
|
// @SuppressWarnings("all") Just STFU, this _is_ terrific
|
||||||
|
|
||||||
// SonarLint: "clone" should not be overridden (java:S2975)
|
// SonarLint: "clone" should not be overridden (java:S2975)
|
||||||
// And I wouldn't have done that if only CharacterIterator had not required
|
// And I wouldn't have done that if only CharacterIterator had not required
|
||||||
|
@ -103,14 +103,8 @@ public class Escaper {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final Escaper JAVA = new Escaper(
|
public static final Escaper JAVA = new Escaper('\\', 'u', "tbnrf'\"".toCharArray(), "\t\b\n\r\f\'\"".toCharArray(),
|
||||||
'\\',
|
true, true);
|
||||||
'u',
|
|
||||||
"tbnrf'\"".toCharArray(),
|
|
||||||
"\t\b\n\r\f\'\"".toCharArray(),
|
|
||||||
true,
|
|
||||||
true
|
|
||||||
);
|
|
||||||
|
|
||||||
private final char escapeChar;
|
private final char escapeChar;
|
||||||
private final char unicodeEscapeChar;
|
private final char unicodeEscapeChar;
|
||||||
@ -120,14 +114,8 @@ public class Escaper {
|
|||||||
private final boolean preferUnicode;
|
private final boolean preferUnicode;
|
||||||
private final boolean strict;
|
private final boolean strict;
|
||||||
|
|
||||||
protected Escaper(
|
protected Escaper(char escapeChar, char unicodeEscapeChar, char[] safes, char[] unsafes, boolean preferUnicode,
|
||||||
char escapeChar,
|
boolean strict) {
|
||||||
char unicodeEscapeChar,
|
|
||||||
char[] safes,
|
|
||||||
char[] unsafes,
|
|
||||||
boolean preferUnicode,
|
|
||||||
boolean strict
|
|
||||||
) {
|
|
||||||
this.escapeChar = escapeChar;
|
this.escapeChar = escapeChar;
|
||||||
this.unicodeEscapeChar = unicodeEscapeChar;
|
this.unicodeEscapeChar = unicodeEscapeChar;
|
||||||
this.safes = safes;
|
this.safes = safes;
|
||||||
@ -152,8 +140,7 @@ public class Escaper {
|
|||||||
for (char c : unsafes) {
|
for (char c : unsafes) {
|
||||||
if (c == escapeChar)
|
if (c == escapeChar)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Unsafe characters contain escape chatacter (escape character is escaped automatically)"
|
"Unsafe characters contain escape chatacter (escape character is escaped automatically)");
|
||||||
);
|
|
||||||
if (c == unicodeEscapeChar)
|
if (c == unicodeEscapeChar)
|
||||||
throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter");
|
throw new IllegalArgumentException("Unsafe characters contain Unicode escape chatacter");
|
||||||
}
|
}
|
||||||
@ -173,11 +160,7 @@ public class Escaper {
|
|||||||
end = Integer.MAX_VALUE;
|
end = Integer.MAX_VALUE;
|
||||||
else
|
else
|
||||||
end = src.getPosition() + length;
|
end = src.getPosition() + length;
|
||||||
while (
|
while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current())))
|
||||||
src.has() &&
|
|
||||||
src.getPosition() < end &&
|
|
||||||
(until == null || !until.test(src.current()))
|
|
||||||
)
|
|
||||||
escape(src.consume(), output);
|
escape(src.consume(), output);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,11 +208,7 @@ public class Escaper {
|
|||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
while (
|
while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) {
|
||||||
src.has() &&
|
|
||||||
src.getPosition() < end &&
|
|
||||||
(until == null || !until.test(src.current()))
|
|
||||||
) {
|
|
||||||
result += getEscapedLength(src.consume());
|
result += getEscapedLength(src.consume());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,11 +236,7 @@ public class Escaper {
|
|||||||
end = Integer.MAX_VALUE;
|
end = Integer.MAX_VALUE;
|
||||||
else
|
else
|
||||||
end = src.getPosition() + length;
|
end = src.getPosition() + length;
|
||||||
while (
|
while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) {
|
||||||
src.has() &&
|
|
||||||
src.getPosition() < end &&
|
|
||||||
(until == null || !until.test(src.current()))
|
|
||||||
) {
|
|
||||||
output.accept(unescapeOneSequence(src));
|
output.accept(unescapeOneSequence(src));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,10 +257,8 @@ public class Escaper {
|
|||||||
|
|
||||||
if (src.current() == unicodeEscapeChar) {
|
if (src.current() == unicodeEscapeChar) {
|
||||||
src.next();
|
src.next();
|
||||||
return (char) (hexValue(src.consume()) << (4 * 3) |
|
return (char) (hexValue(src.consume()) << (4 * 3) | hexValue(src.consume()) << (4 * 2)
|
||||||
hexValue(src.consume()) << (4 * 2) |
|
| hexValue(src.consume()) << (4 * 1) | hexValue(src.consume()) << (4 * 0));
|
||||||
hexValue(src.consume()) << (4 * 1) |
|
|
||||||
hexValue(src.consume()) << (4 * 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = ArrayUtil.firstIndexOf(safes, src.current());
|
int index = ArrayUtil.firstIndexOf(safes, src.current());
|
||||||
@ -315,11 +288,7 @@ public class Escaper {
|
|||||||
|
|
||||||
int result = 0;
|
int result = 0;
|
||||||
|
|
||||||
while (
|
while (src.has() && src.getPosition() < end && (until == null || !until.test(src.current()))) {
|
||||||
src.has() &&
|
|
||||||
src.getPosition() < end &&
|
|
||||||
(until == null || !until.test(src.current()))
|
|
||||||
) {
|
|
||||||
skipOneSequence(src);
|
skipOneSequence(src);
|
||||||
result++;
|
result++;
|
||||||
}
|
}
|
||||||
@ -328,11 +297,7 @@ public class Escaper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void skipOneSequence(CharReader src) {
|
public void skipOneSequence(CharReader src) {
|
||||||
if (
|
if (src.current() == escapeChar && src.next() == unicodeEscapeChar) {
|
||||||
src.current() == escapeChar
|
|
||||||
&&
|
|
||||||
src.next() == unicodeEscapeChar
|
|
||||||
) {
|
|
||||||
src.advance(4);
|
src.advance(4);
|
||||||
}
|
}
|
||||||
src.next();
|
src.next();
|
||||||
|
@ -86,7 +86,7 @@ public class FancyCharacterIterator implements CharacterIterator {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @SuppressWarnings("all") Just STFU, this _is_ terrific
|
// @SuppressWarnings("all") Just STFU, this _is_ terrific
|
||||||
|
|
||||||
// SonarLint: "clone" should not be overridden (java:S2975)
|
// SonarLint: "clone" should not be overridden (java:S2975)
|
||||||
// And I wouldn't have done that if only CharacterIterator had not required
|
// And I wouldn't have done that if only CharacterIterator had not required
|
||||||
|
@ -41,13 +41,8 @@ public class StringUtil {
|
|||||||
private static final String EMPTY_PLACEHOLDER = "[empty]";
|
private static final String EMPTY_PLACEHOLDER = "[empty]";
|
||||||
private static final String DEFAULT_SEPARATOR = "; ";
|
private static final String DEFAULT_SEPARATOR = "; ";
|
||||||
|
|
||||||
public static <T> String arrayToString(
|
public static <T> String arrayToString(T[] array, String separator, String empty, String nullPlaceholder,
|
||||||
T[] array,
|
String nullArray) {
|
||||||
String separator,
|
|
||||||
String empty,
|
|
||||||
String nullPlaceholder,
|
|
||||||
String nullArray
|
|
||||||
) {
|
|
||||||
|
|
||||||
if (separator == null) {
|
if (separator == null) {
|
||||||
throw new IllegalArgumentException(new NullPointerException());
|
throw new IllegalArgumentException(new NullPointerException());
|
||||||
@ -79,13 +74,8 @@ public class StringUtil {
|
|||||||
return arrayToString(array, DEFAULT_SEPARATOR);
|
return arrayToString(array, DEFAULT_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String iteratorToString(
|
public static String iteratorToString(Iterator<?> iterator, String separator, String empty, String nullPlaceholder,
|
||||||
Iterator<?> iterator,
|
String nullIterator) {
|
||||||
String separator,
|
|
||||||
String empty,
|
|
||||||
String nullPlaceholder,
|
|
||||||
String nullIterator
|
|
||||||
) {
|
|
||||||
|
|
||||||
if (separator == null) {
|
if (separator == null) {
|
||||||
throw new IllegalArgumentException(new NullPointerException());
|
throw new IllegalArgumentException(new NullPointerException());
|
||||||
@ -119,13 +109,8 @@ public class StringUtil {
|
|||||||
return iteratorToString(iterator, DEFAULT_SEPARATOR);
|
return iteratorToString(iterator, DEFAULT_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String iterableToString(
|
public static String iterableToString(Iterable<?> iterable, String separator, String empty, String nullPlaceholder,
|
||||||
Iterable<?> iterable,
|
String nullIterable) {
|
||||||
String separator,
|
|
||||||
String empty,
|
|
||||||
String nullPlaceholder,
|
|
||||||
String nullIterable
|
|
||||||
) {
|
|
||||||
|
|
||||||
if (separator == null) {
|
if (separator == null) {
|
||||||
throw new IllegalArgumentException(new NullPointerException());
|
throw new IllegalArgumentException(new NullPointerException());
|
||||||
@ -146,14 +131,8 @@ public class StringUtil {
|
|||||||
return iterableToString(iterable, DEFAULT_SEPARATOR);
|
return iterableToString(iterable, DEFAULT_SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T> String supplierToString(
|
public static <T> String supplierToString(IntFunction<T> supplier, int length, String separator, String empty,
|
||||||
IntFunction<T> supplier,
|
String nullPlaceholder, String nullSupplier) {
|
||||||
int length,
|
|
||||||
String separator,
|
|
||||||
String empty,
|
|
||||||
String nullPlaceholder,
|
|
||||||
String nullSupplier
|
|
||||||
) {
|
|
||||||
|
|
||||||
if (separator == null)
|
if (separator == null)
|
||||||
throw new IllegalArgumentException(new NullPointerException());
|
throw new IllegalArgumentException(new NullPointerException());
|
||||||
@ -163,28 +142,15 @@ public class StringUtil {
|
|||||||
return empty;
|
return empty;
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
return supplierToStringExactly(
|
return supplierToStringExactly(supplier, length, separator, nullPlaceholder);
|
||||||
supplier,
|
|
||||||
length,
|
|
||||||
separator,
|
|
||||||
nullPlaceholder
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return supplierToStringUntilNull(
|
return supplierToStringUntilNull(supplier, separator, empty);
|
||||||
supplier,
|
|
||||||
separator,
|
|
||||||
empty
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> String supplierToStringExactly(
|
private static <T> String supplierToStringExactly(IntFunction<T> supplier, int length, String separator,
|
||||||
IntFunction<T> supplier,
|
String nullPlaceholder) {
|
||||||
int length,
|
|
||||||
String separator,
|
|
||||||
String nullPlaceholder
|
|
||||||
) {
|
|
||||||
T element = supplier.apply(0);
|
T element = supplier.apply(0);
|
||||||
|
|
||||||
StringBuilder sb = new StringBuilder(element == null ? nullPlaceholder : element.toString());
|
StringBuilder sb = new StringBuilder(element == null ? nullPlaceholder : element.toString());
|
||||||
@ -198,11 +164,7 @@ public class StringUtil {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> String supplierToStringUntilNull(
|
private static <T> String supplierToStringUntilNull(IntFunction<T> supplier, String separator, String empty) {
|
||||||
IntFunction<T> supplier,
|
|
||||||
String separator,
|
|
||||||
String empty
|
|
||||||
) {
|
|
||||||
T element = supplier.apply(0);
|
T element = supplier.apply(0);
|
||||||
|
|
||||||
if (element == null) {
|
if (element == null) {
|
||||||
@ -366,11 +328,7 @@ public class StringUtil {
|
|||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
charLoop: for (char c : src.toCharArray()) {
|
charLoop: for (char c : src.toCharArray()) {
|
||||||
if (
|
if ((resultIndex + 1) < arrayLength && test.test(c)) {
|
||||||
(resultIndex + 1) < arrayLength
|
|
||||||
&&
|
|
||||||
test.test(c)
|
|
||||||
) {
|
|
||||||
result[resultIndex] = resetStringBuilder(sb);
|
result[resultIndex] = resetStringBuilder(sb);
|
||||||
++resultIndex;
|
++resultIndex;
|
||||||
continue charLoop;
|
continue charLoop;
|
||||||
@ -389,17 +347,17 @@ public class StringUtil {
|
|||||||
* index.
|
* index.
|
||||||
* <p>
|
* <p>
|
||||||
* Indices {@code 0} and {@code src.length() - 1} produce {@code str}
|
* Indices {@code 0} and {@code src.length() - 1} produce {@code str}
|
||||||
* excluding
|
* excluding the specified character and {@code ""}.
|
||||||
* the specified character and {@code ""}.
|
|
||||||
* <p>
|
* <p>
|
||||||
*
|
*
|
||||||
* @param src the String to split
|
* @param src
|
||||||
* @param at index to split at
|
* the String to split
|
||||||
* @throws IllegalArgumentException if the index is out of bounds for
|
* @param at
|
||||||
* {@code src}
|
* index to split at
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the index is out of bounds for {@code src}
|
||||||
* @return an array containing the substrings, in order of encounter in
|
* @return an array containing the substrings, in order of encounter in
|
||||||
* {@code src}.
|
* {@code src}. Its length is always 2.
|
||||||
* Its length is always 2.
|
|
||||||
*/
|
*/
|
||||||
public static String[] splitAt(String src, int at) {
|
public static String[] splitAt(String src, int at) {
|
||||||
Objects.requireNonNull(src, "src");
|
Objects.requireNonNull(src, "src");
|
||||||
@ -416,10 +374,7 @@ public class StringUtil {
|
|||||||
return new String[] { src.substring(0, src.length() - 1), "" };
|
return new String[] { src.substring(0, src.length() - 1), "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
return new String[] {
|
return new String[] { src.substring(0, at), src.substring(at + 1) };
|
||||||
src.substring(0, at),
|
|
||||||
src.substring(at + 1)
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -427,8 +382,7 @@ public class StringUtil {
|
|||||||
* indices.
|
* indices.
|
||||||
* <p>
|
* <p>
|
||||||
* Indices {@code 0} and {@code src.length() - 1} produce extra zero-length
|
* Indices {@code 0} and {@code src.length() - 1} produce extra zero-length
|
||||||
* outputs.
|
* outputs. Duplicate indices produce extra zero-length outputs.
|
||||||
* Duplicate indices produce extra zero-length outputs.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Examples:
|
* Examples:
|
||||||
*
|
*
|
||||||
@ -439,13 +393,14 @@ public class StringUtil {
|
|||||||
* splitAt("a.b", 1, 1, 1) -> {"a", "", "", "b"}
|
* splitAt("a.b", 1, 1, 1) -> {"a", "", "", "b"}
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @param src the String to split
|
* @param src
|
||||||
* @param at indices to split at, in any order
|
* the String to split
|
||||||
* @throws IllegalArgumentException if some index is out of bounds for
|
* @param at
|
||||||
* {@code src}
|
* indices to split at, in any order
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if some index is out of bounds for {@code src}
|
||||||
* @return an array containing the substrings, in order of encounter in
|
* @return an array containing the substrings, in order of encounter in
|
||||||
* {@code src}.
|
* {@code src}. Its length is always {@code at.length + 1}.
|
||||||
* Its length is always {@code at.length + 1}.
|
|
||||||
*/
|
*/
|
||||||
public static String[] splitAt(String src, int... at) {
|
public static String[] splitAt(String src, int... at) {
|
||||||
Objects.requireNonNull(src, "src");
|
Objects.requireNonNull(src, "src");
|
||||||
@ -553,10 +508,8 @@ public class StringUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (endPos < beginPos) {
|
if (endPos < beginPos) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("endPos must be greater than or equal to beginPos (endPos=" + endPos
|
||||||
"endPos must be greater than or equal to beginPos (endPos="
|
+ ", beginPos=" + beginPos + ")");
|
||||||
+ endPos + ", beginPos=" + beginPos + ")"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endPos >= Math.min(a.length, b.length)) {
|
if (endPos >= Math.min(a.length, b.length)) {
|
||||||
@ -592,8 +545,7 @@ public class StringUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds and returns the index of the specified appearance of the specified
|
* Finds and returns the index of the specified appearance of the specified
|
||||||
* character
|
* character in the given array. The search starts at index 0.
|
||||||
* in the given array. The search starts at index 0.
|
|
||||||
* <p>
|
* <p>
|
||||||
* Examples:
|
* Examples:
|
||||||
* <p>
|
* <p>
|
||||||
@ -630,10 +582,12 @@ public class StringUtil {
|
|||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* @param src - the array to search in.
|
* @param src
|
||||||
* @param target - the character to search for.
|
* - the array to search in.
|
||||||
* @param skip - the amount of <code>target</code> characters to be
|
* @param target
|
||||||
* skipped.
|
* - the character to search for.
|
||||||
|
* @param skip
|
||||||
|
* - the amount of <code>target</code> characters to be skipped.
|
||||||
* @return The index of the <code>skip+1</code>th <code>target</code>
|
* @return The index of the <code>skip+1</code>th <code>target</code>
|
||||||
* character or -1, if none found.
|
* character or -1, if none found.
|
||||||
* @see StringUtil#indexFromEnd(char[], char, int)
|
* @see StringUtil#indexFromEnd(char[], char, int)
|
||||||
@ -653,8 +607,7 @@ public class StringUtil {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Finds and returns the index of the specified appearance of the specified
|
* Finds and returns the index of the specified appearance of the specified
|
||||||
* character
|
* character in the given array. The search starts at index
|
||||||
* in the given array. The search starts at index
|
|
||||||
* <code>src.length - 1</code>.
|
* <code>src.length - 1</code>.
|
||||||
* <p>
|
* <p>
|
||||||
* Examples:
|
* Examples:
|
||||||
@ -692,13 +645,15 @@ public class StringUtil {
|
|||||||
* </tr>
|
* </tr>
|
||||||
* </table>
|
* </table>
|
||||||
*
|
*
|
||||||
* @param src - the array to search in.
|
* @param src
|
||||||
* @param target - the character to search for.
|
* - the array to search in.
|
||||||
* @param skip - the amount of <code>target</code> characters to be
|
* @param target
|
||||||
* skipped.
|
* - the character to search for.
|
||||||
|
* @param skip
|
||||||
|
* - the amount of <code>target</code> characters to be skipped.
|
||||||
* @return The index of the <code>skip+1</code>th
|
* @return The index of the <code>skip+1</code>th
|
||||||
* <code>target</code>character
|
* <code>target</code>character from the end of the array or -1, if
|
||||||
* from the end of the array or -1, if none found.
|
* none found.
|
||||||
* @see StringUtil#indexFromBeginning(char[], char, int)
|
* @see StringUtil#indexFromBeginning(char[], char, int)
|
||||||
*/
|
*/
|
||||||
public static int indexFromEnd(char[] src, char target, int skip) {
|
public static int indexFromEnd(char[] src, char target, int skip) {
|
||||||
@ -873,12 +828,8 @@ public class StringUtil {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildCombinations(
|
private static void buildCombinations(StringBuilder sb, Collection<String> result, Iterable<String>[] parts,
|
||||||
StringBuilder sb,
|
int index) {
|
||||||
Collection<String> result,
|
|
||||||
Iterable<String>[] parts,
|
|
||||||
int index
|
|
||||||
) {
|
|
||||||
if (index >= parts.length) {
|
if (index >= parts.length) {
|
||||||
result.add(sb.toString());
|
result.add(sb.toString());
|
||||||
} else {
|
} else {
|
||||||
@ -904,13 +855,8 @@ public class StringUtil {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void buildCombinations(
|
private static void buildCombinations(StringBuilder sb, String[] result, int[] resultIndex, String[][] parts,
|
||||||
StringBuilder sb,
|
int index) {
|
||||||
String[] result,
|
|
||||||
int[] resultIndex,
|
|
||||||
String[][] parts,
|
|
||||||
int index
|
|
||||||
) {
|
|
||||||
if (index >= parts.length) {
|
if (index >= parts.length) {
|
||||||
result[resultIndex[0]++] = sb.toString();
|
result[resultIndex[0]++] = sb.toString();
|
||||||
} else {
|
} else {
|
||||||
@ -985,10 +931,7 @@ public class StringUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static char hexDigit(long value, int digit) {
|
private static char hexDigit(long value, int digit) {
|
||||||
return hexDigit(
|
return hexDigit((int) (value >>> (4 * digit)) & 0xF);
|
||||||
(int) (value >>> (4 * digit))
|
|
||||||
& 0xF
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static char hexDigit(int value) {
|
public static char hexDigit(int value) {
|
||||||
|
@ -27,10 +27,9 @@ public abstract class AbstractCharReader implements CharReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Current position of this CharReader. The reader maps its input to
|
* Current position of this CharReader. The reader maps its input to
|
||||||
* positions starting from 0.
|
* positions starting from 0. Positions that are negative or lower than 0
|
||||||
* Positions that are negative or lower than 0 are invalid.
|
* are invalid. {@link #current()} will throw an exception if position is
|
||||||
* {@link #current()}
|
* invalid.
|
||||||
* will throw an exception if position is invalid.
|
|
||||||
*/
|
*/
|
||||||
protected int position = 0;
|
protected int position = 0;
|
||||||
|
|
||||||
|
@ -51,9 +51,12 @@ public abstract class BufferedCharReader extends AbstractCharReader {
|
|||||||
/**
|
/**
|
||||||
* Acquires next characters and stores them in the array.
|
* Acquires next characters and stores them in the array.
|
||||||
*
|
*
|
||||||
* @param buffer the output array
|
* @param buffer
|
||||||
* @param offset index of the first character
|
* the output array
|
||||||
* @param length maximum amount of characters to be pulled
|
* @param offset
|
||||||
|
* index of the first character
|
||||||
|
* @param length
|
||||||
|
* maximum amount of characters to be pulled
|
||||||
* @return the amount of characters actually pulled
|
* @return the amount of characters actually pulled
|
||||||
*/
|
*/
|
||||||
protected int pullChars(char[] buffer, int offset, int length) {
|
protected int pullChars(char[] buffer, int offset, int length) {
|
||||||
|
@ -179,8 +179,7 @@ public interface CharReader {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Skips to the end of the current line. Both <code>"\n"</code>,
|
* Skips to the end of the current line. Both <code>"\n"</code>,
|
||||||
* <code>"\r"</code>
|
* <code>"\r"</code> and <code>"\r\n"</code> are considered line separators.
|
||||||
* and <code>"\r\n"</code> are considered line separators.
|
|
||||||
*
|
*
|
||||||
* @return the amount of characters in the skipped line
|
* @return the amount of characters in the skipped line
|
||||||
*/
|
*/
|
||||||
|
@ -38,8 +38,7 @@ public class StringCharReader extends AbstractCharReader {
|
|||||||
int end = offset + length;
|
int end = offset + length;
|
||||||
if (end > str.length() || offset < 0)
|
if (end > str.length() || offset < 0)
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")"
|
"String contains [0; " + str.length() + "), requested [" + offset + "; " + end + ")");
|
||||||
);
|
|
||||||
|
|
||||||
this.offset = offset;
|
this.offset = offset;
|
||||||
this.length = length;
|
this.length = length;
|
||||||
|
@ -45,8 +45,15 @@ public interface ThrowingBiConsumer<T, U, E extends Exception> {
|
|||||||
|
|
||||||
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
|
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
|
||||||
ThrowingBiConsumer<? super T, ? super U, ? extends E> first,
|
ThrowingBiConsumer<? super T, ? super U, ? extends E> first,
|
||||||
ThrowingBiConsumer<? super T, ? super U, ? extends E> second
|
ThrowingBiConsumer<? super T, ? super U, ? extends E> second) {
|
||||||
) {
|
return (t, u) -> {
|
||||||
|
first.accept(t, u);
|
||||||
|
second.accept(t, u);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(BiConsumer<? super T, ? super U> first,
|
||||||
|
ThrowingBiConsumer<? super T, ? super U, E> second) {
|
||||||
return (t, u) -> {
|
return (t, u) -> {
|
||||||
first.accept(t, u);
|
first.accept(t, u);
|
||||||
second.accept(t, u);
|
second.accept(t, u);
|
||||||
@ -54,19 +61,7 @@ public interface ThrowingBiConsumer<T, U, E extends Exception> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
|
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
|
||||||
BiConsumer<? super T, ? super U> first,
|
ThrowingBiConsumer<? super T, ? super U, E> first, BiConsumer<? super T, ? super U> second) {
|
||||||
ThrowingBiConsumer<? super T, ? super U, E> second
|
|
||||||
) {
|
|
||||||
return (t, u) -> {
|
|
||||||
first.accept(t, u);
|
|
||||||
second.accept(t, u);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, U, E extends Exception> ThrowingBiConsumer<T, U, E> concat(
|
|
||||||
ThrowingBiConsumer<? super T, ? super U, E> first,
|
|
||||||
BiConsumer<? super T, ? super U> second
|
|
||||||
) {
|
|
||||||
return (t, u) -> {
|
return (t, u) -> {
|
||||||
first.accept(t, u);
|
first.accept(t, u);
|
||||||
second.accept(t, u);
|
second.accept(t, u);
|
||||||
|
@ -39,30 +39,24 @@ public interface ThrowingConsumer<T, E extends Exception> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(
|
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(ThrowingConsumer<? super T, ? extends E> first,
|
||||||
ThrowingConsumer<? super T, ? extends E> first,
|
ThrowingConsumer<? super T, ? extends E> second) {
|
||||||
ThrowingConsumer<? super T, ? extends E> second
|
|
||||||
) {
|
|
||||||
return t -> {
|
return t -> {
|
||||||
first.accept(t);
|
first.accept(t);
|
||||||
second.accept(t);
|
second.accept(t);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(
|
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(Consumer<? super T> first,
|
||||||
Consumer<? super T> first,
|
ThrowingConsumer<? super T, ? extends E> second) {
|
||||||
ThrowingConsumer<? super T, ? extends E> second
|
|
||||||
) {
|
|
||||||
return t -> {
|
return t -> {
|
||||||
first.accept(t);
|
first.accept(t);
|
||||||
second.accept(t);
|
second.accept(t);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(
|
public static <T, E extends Exception> ThrowingConsumer<T, E> concat(ThrowingConsumer<? super T, ? extends E> first,
|
||||||
ThrowingConsumer<? super T, ? extends E> first,
|
Consumer<? super T> second) {
|
||||||
Consumer<? super T> second
|
|
||||||
) {
|
|
||||||
return t -> {
|
return t -> {
|
||||||
first.accept(t);
|
first.accept(t);
|
||||||
second.accept(t);
|
second.accept(t);
|
||||||
|
@ -28,10 +28,8 @@ public interface ThrowingFunction<T, R, E extends Exception> {
|
|||||||
R apply(T t) throws E;
|
R apply(T t) throws E;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
default Function<T, R> withHandler(
|
default Function<T, R> withHandler(BiConsumer<? super T, ? super E> handler,
|
||||||
BiConsumer<? super T, ? super E> handler,
|
Function<? super T, ? extends R> value) {
|
||||||
Function<? super T, ? extends R> value
|
|
||||||
) {
|
|
||||||
return t -> {
|
return t -> {
|
||||||
try {
|
try {
|
||||||
return apply(t);
|
return apply(t);
|
||||||
@ -59,22 +57,17 @@ public interface ThrowingFunction<T, R, E extends Exception> {
|
|||||||
|
|
||||||
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
|
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
|
||||||
ThrowingFunction<? super T, I, ? extends E> first,
|
ThrowingFunction<? super T, I, ? extends E> first,
|
||||||
ThrowingFunction<? super I, ? extends R, ? extends E> second
|
ThrowingFunction<? super I, ? extends R, ? extends E> second) {
|
||||||
) {
|
return t -> second.apply(first.apply(t));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(Function<? super T, I> first,
|
||||||
|
ThrowingFunction<? super I, ? extends R, E> second) {
|
||||||
return t -> second.apply(first.apply(t));
|
return t -> second.apply(first.apply(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
|
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
|
||||||
Function<? super T, I> first,
|
ThrowingFunction<? super T, I, E> first, Function<? super I, ? extends R> second) {
|
||||||
ThrowingFunction<? super I, ? extends R, E> second
|
|
||||||
) {
|
|
||||||
return t -> second.apply(first.apply(t));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T, R, I, E extends Exception> ThrowingFunction<T, R, E> compose(
|
|
||||||
ThrowingFunction<? super T, I, E> first,
|
|
||||||
Function<? super I, ? extends R> second
|
|
||||||
) {
|
|
||||||
return t -> second.apply(first.apply(t));
|
return t -> second.apply(first.apply(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +38,8 @@ public interface ThrowingRunnable<E extends Exception> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends Exception> ThrowingRunnable<E> concat(
|
public static <E extends Exception> ThrowingRunnable<E> concat(ThrowingRunnable<? extends E> first,
|
||||||
ThrowingRunnable<? extends E> first,
|
ThrowingRunnable<? extends E> second) {
|
||||||
ThrowingRunnable<? extends E> second
|
|
||||||
) {
|
|
||||||
return () -> {
|
return () -> {
|
||||||
first.run();
|
first.run();
|
||||||
second.run();
|
second.run();
|
||||||
|
@ -49,10 +49,8 @@ public class RangeIterator<E> implements Iterator<E> {
|
|||||||
public E next() {
|
public E next() {
|
||||||
update();
|
update();
|
||||||
if (nextIndex >= from + amount) {
|
if (nextIndex >= from + amount) {
|
||||||
throw new NoSuchElementException(
|
throw new NoSuchElementException("RangeIterator about to retrieve element " + nextIndex
|
||||||
"RangeIterator about to retrieve element " + nextIndex
|
+ " which exceeds upper boundary " + (from + amount));
|
||||||
+ " which exceeds upper boundary " + (from + amount)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
E result = parent.next();
|
E result = parent.next();
|
||||||
|
@ -69,11 +69,7 @@ public class Client {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
getCamera().setAnchor(
|
getCamera().setAnchor(new EntityAnchor(getWorld().getEntityRenderable(entity)));
|
||||||
new EntityAnchor(
|
|
||||||
getWorld().getEntityRenderable(entity)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -42,10 +42,8 @@ public class ClientProxy implements Proxy {
|
|||||||
try {
|
try {
|
||||||
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
|
RenderTaskQueue.waitAndInvoke(FlatRenderProgram::init);
|
||||||
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
|
RenderTaskQueue.waitAndInvoke(WorldRenderProgram::init);
|
||||||
RenderTaskQueue.waitAndInvoke(
|
RenderTaskQueue.waitAndInvoke(() -> Typefaces
|
||||||
() -> Typefaces
|
.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz"))));
|
||||||
.setDefault(GNUUnifontLoader.load(ResourceManager.getResource("assets/unifont-13.0.03.hex.gz")))
|
|
||||||
);
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw CrashReports.report(e, "ClientProxy failed");
|
throw CrashReports.report(e, "ClientProxy failed");
|
||||||
}
|
}
|
||||||
|
@ -43,9 +43,7 @@ public class ClientState {
|
|||||||
|
|
||||||
DefaultWorldData world = new DefaultWorldData();
|
DefaultWorldData world = new DefaultWorldData();
|
||||||
|
|
||||||
LocalServerCommsChannel channel = new LocalServerCommsChannel(
|
LocalServerCommsChannel channel = new LocalServerCommsChannel(ServerState.getInstance());
|
||||||
ServerState.getInstance()
|
|
||||||
);
|
|
||||||
|
|
||||||
Client client = new Client(world, channel);
|
Client client = new Client(world, channel);
|
||||||
|
|
||||||
|
@ -43,10 +43,7 @@ public class AudioManager {
|
|||||||
private static Speaker musicSpeaker;
|
private static Speaker musicSpeaker;
|
||||||
|
|
||||||
public static void initAL() {
|
public static void initAL() {
|
||||||
String defaultDeviceName = alcGetString(
|
String defaultDeviceName = alcGetString(0, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||||
0,
|
|
||||||
ALC_DEFAULT_DEVICE_SPECIFIER
|
|
||||||
);
|
|
||||||
|
|
||||||
device = alcOpenDevice(defaultDeviceName);
|
device = alcOpenDevice(defaultDeviceName);
|
||||||
|
|
||||||
@ -75,10 +72,7 @@ public class AudioManager {
|
|||||||
lastSoundIndex = 0;
|
lastSoundIndex = 0;
|
||||||
}
|
}
|
||||||
speaker = soundSpeakers.get(lastSoundIndex);
|
speaker = soundSpeakers.get(lastSoundIndex);
|
||||||
} while (
|
} while (speaker.getState().equals(Speaker.State.PLAYING_LOOP));
|
||||||
speaker.getState()
|
|
||||||
.equals(Speaker.State.PLAYING_LOOP)
|
|
||||||
);
|
|
||||||
return speaker;
|
return speaker;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,10 +29,7 @@ public class AudioSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void loadAudioData() {
|
static void loadAudioData() {
|
||||||
AudioManager.loadSound(
|
AudioManager.loadSound(ResourceManager.getResource("assets/sounds/block_destroy_clap.ogg"),
|
||||||
ResourceManager.getResource("assets/sounds/block_destroy_clap.ogg"),
|
"Progressia:BlockDestroy", AudioFormat.MONO);
|
||||||
"Progressia:BlockDestroy",
|
|
||||||
AudioFormat.MONO
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,10 +22,7 @@ import glm.vec._3.Vec3;
|
|||||||
import ru.windcorp.progressia.client.audio.backend.SoundType;
|
import ru.windcorp.progressia.client.audio.backend.SoundType;
|
||||||
import ru.windcorp.progressia.client.audio.backend.Speaker;
|
import ru.windcorp.progressia.client.audio.backend.Speaker;
|
||||||
|
|
||||||
public class Music
|
public class Music extends Sound {
|
||||||
extends Sound {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public Music(SoundType soundType, int timeLength, float pitch, float gain) {
|
public Music(SoundType soundType, int timeLength, float pitch, float gain) {
|
||||||
super(soundType, timeLength, new Vec3(), new Vec3(), pitch, gain);
|
super(soundType, timeLength, new Vec3(), new Vec3(), pitch, gain);
|
||||||
|
@ -40,14 +40,7 @@ public class Sound {
|
|||||||
this(AudioRegistry.getInstance().get(id));
|
this(AudioRegistry.getInstance().get(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sound(
|
public Sound(String id, int timeLength, Vec3 position, Vec3 velocity, float pitch, float gain) {
|
||||||
String id,
|
|
||||||
int timeLength,
|
|
||||||
Vec3 position,
|
|
||||||
Vec3 velocity,
|
|
||||||
float pitch,
|
|
||||||
float gain
|
|
||||||
) {
|
|
||||||
this(id);
|
this(id);
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.velocity = velocity;
|
this.velocity = velocity;
|
||||||
@ -55,14 +48,7 @@ public class Sound {
|
|||||||
this.gain = gain;
|
this.gain = gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Sound(
|
public Sound(SoundType soundType, int timeLength, Vec3 position, Vec3 velocity, float pitch, float gain) {
|
||||||
SoundType soundType,
|
|
||||||
int timeLength,
|
|
||||||
Vec3 position,
|
|
||||||
Vec3 velocity,
|
|
||||||
float pitch,
|
|
||||||
float gain
|
|
||||||
) {
|
|
||||||
this(soundType);
|
this(soundType);
|
||||||
this.position = position;
|
this.position = position;
|
||||||
this.velocity = velocity;
|
this.velocity = velocity;
|
||||||
|
@ -39,12 +39,7 @@ public class AudioReader {
|
|||||||
|
|
||||||
ShortBuffer rawAudio = decodeVorbis(resource, channelBuffer, rateBuffer);
|
ShortBuffer rawAudio = decodeVorbis(resource, channelBuffer, rateBuffer);
|
||||||
|
|
||||||
return new SoundType(
|
return new SoundType(id, rawAudio, format, rateBuffer.get(0));
|
||||||
id,
|
|
||||||
rawAudio,
|
|
||||||
format,
|
|
||||||
rateBuffer.get(0)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SoundType readAsMono(Resource resource, String id) {
|
public static SoundType readAsMono(Resource resource, String id) {
|
||||||
@ -55,15 +50,7 @@ public class AudioReader {
|
|||||||
return readAsSpecified(resource, id, AL_FORMAT_STEREO16);
|
return readAsSpecified(resource, id, AL_FORMAT_STEREO16);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ShortBuffer decodeVorbis(
|
private static ShortBuffer decodeVorbis(Resource dataToDecode, IntBuffer channelsBuffer, IntBuffer rateBuffer) {
|
||||||
Resource dataToDecode,
|
return stb_vorbis_decode_memory(dataToDecode.readAsBytes(), channelsBuffer, rateBuffer);
|
||||||
IntBuffer channelsBuffer,
|
|
||||||
IntBuffer rateBuffer
|
|
||||||
) {
|
|
||||||
return stb_vorbis_decode_memory(
|
|
||||||
dataToDecode.readAsBytes(),
|
|
||||||
channelsBuffer,
|
|
||||||
rateBuffer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,9 +55,8 @@ public class Listener {
|
|||||||
if (isInWorld) {
|
if (isInWorld) {
|
||||||
|
|
||||||
if (wasInWorld) {
|
if (wasInWorld) {
|
||||||
velocity.set(camera.getLastAnchorPosition()).sub(position).div(
|
velocity.set(camera.getLastAnchorPosition()).sub(position)
|
||||||
(float) GraphicsInterface.getFrameLength()
|
.div((float) GraphicsInterface.getFrameLength());
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
// If !wasInWorld, previous position is nonsence. Assume 0.
|
// If !wasInWorld, previous position is nonsence. Assume 0.
|
||||||
velocity.set(0);
|
velocity.set(0);
|
||||||
@ -72,9 +71,9 @@ public class Listener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Only apply if there is a chance that params changed.
|
* Only apply if there is a chance that params changed. This can only
|
||||||
* This can only happen if we are in world now (isInWorld) or we just
|
* happen if we are in world now (isInWorld) or we just left world
|
||||||
* left world (wasInWorld, then we need to reset).
|
* (wasInWorld, then we need to reset).
|
||||||
*/
|
*/
|
||||||
if (isInWorld || wasInWorld) {
|
if (isInWorld || wasInWorld) {
|
||||||
applyParams();
|
applyParams();
|
||||||
@ -91,17 +90,7 @@ public class Listener {
|
|||||||
private void applyParams() {
|
private void applyParams() {
|
||||||
alListener3f(AL_POSITION, position.x, position.y, position.z);
|
alListener3f(AL_POSITION, position.x, position.y, position.z);
|
||||||
alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
|
alListener3f(AL_VELOCITY, velocity.x, velocity.y, velocity.z);
|
||||||
alListenerfv(
|
alListenerfv(AL_ORIENTATION, new float[] { oriAt.x, oriAt.y, oriAt.z, oriUp.x, oriUp.y, oriUp.z });
|
||||||
AL_ORIENTATION,
|
|
||||||
new float[] {
|
|
||||||
oriAt.x,
|
|
||||||
oriAt.y,
|
|
||||||
oriAt.z,
|
|
||||||
oriUp.x,
|
|
||||||
oriUp.y,
|
|
||||||
oriUp.z
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,7 @@ public class SoundType extends Namespaced {
|
|||||||
private int audioBuffer;
|
private int audioBuffer;
|
||||||
private double duration;
|
private double duration;
|
||||||
|
|
||||||
public SoundType(
|
public SoundType(String id, ShortBuffer rawAudio, int format, int sampleRate) {
|
||||||
String id,
|
|
||||||
ShortBuffer rawAudio,
|
|
||||||
int format,
|
|
||||||
int sampleRate
|
|
||||||
) {
|
|
||||||
super(id);
|
super(id);
|
||||||
this.rawAudio = rawAudio;
|
this.rawAudio = rawAudio;
|
||||||
this.sampleRate = sampleRate;
|
this.sampleRate = sampleRate;
|
||||||
|
@ -24,9 +24,7 @@ import static org.lwjgl.openal.AL11.*;
|
|||||||
public class Speaker {
|
public class Speaker {
|
||||||
|
|
||||||
public enum State {
|
public enum State {
|
||||||
NOT_PLAYING,
|
NOT_PLAYING, PLAYING, PLAYING_LOOP
|
||||||
PLAYING,
|
|
||||||
PLAYING_LOOP
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Buffers
|
// Buffers
|
||||||
@ -49,13 +47,7 @@ public class Speaker {
|
|||||||
setAudioData(audioData);
|
setAudioData(audioData);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Speaker(
|
public Speaker(int audioData, Vec3 position, Vec3 velocity, float pitch, float gain) {
|
||||||
int audioData,
|
|
||||||
Vec3 position,
|
|
||||||
Vec3 velocity,
|
|
||||||
float pitch,
|
|
||||||
float gain
|
|
||||||
) {
|
|
||||||
setAudioData(audioData);
|
setAudioData(audioData);
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
setVelocity(velocity);
|
setVelocity(velocity);
|
||||||
@ -63,12 +55,7 @@ public class Speaker {
|
|||||||
setGain(gain);
|
setGain(gain);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Speaker(
|
public Speaker(Vec3 position, Vec3 velocity, float pitch, float gain) {
|
||||||
Vec3 position,
|
|
||||||
Vec3 velocity,
|
|
||||||
float pitch,
|
|
||||||
float gain
|
|
||||||
) {
|
|
||||||
setPosition(position);
|
setPosition(position);
|
||||||
setVelocity(velocity);
|
setVelocity(velocity);
|
||||||
setPitch(pitch);
|
setPitch(pitch);
|
||||||
|
@ -39,9 +39,7 @@ public class DefaultClientCommsListener implements CommsListener {
|
|||||||
@Override
|
@Override
|
||||||
public void onPacketReceived(Packet packet) {
|
public void onPacketReceived(Packet packet) {
|
||||||
if (packet instanceof PacketAffectWorld) {
|
if (packet instanceof PacketAffectWorld) {
|
||||||
((PacketAffectWorld) packet).apply(
|
((PacketAffectWorld) packet).apply(getClient().getWorld().getData());
|
||||||
getClient().getWorld().getData()
|
|
||||||
);
|
|
||||||
} else if (packet instanceof PacketSetLocalPlayer) {
|
} else if (packet instanceof PacketSetLocalPlayer) {
|
||||||
setLocalPlayer((PacketSetLocalPlayer) packet);
|
setLocalPlayer((PacketSetLocalPlayer) packet);
|
||||||
}
|
}
|
||||||
|
@ -33,17 +33,12 @@ public class ControlTriggerLambda extends ControlTriggerInputBased {
|
|||||||
private final Predicate<InputEvent> predicate;
|
private final Predicate<InputEvent> predicate;
|
||||||
private final BiConsumer<InputEvent, ControlData> dataWriter;
|
private final BiConsumer<InputEvent, ControlData> dataWriter;
|
||||||
|
|
||||||
public ControlTriggerLambda(
|
public ControlTriggerLambda(String id, Predicate<InputEvent> predicate,
|
||||||
String id,
|
BiConsumer<InputEvent, ControlData> dataWriter) {
|
||||||
Predicate<InputEvent> predicate,
|
|
||||||
BiConsumer<InputEvent, ControlData> dataWriter
|
|
||||||
) {
|
|
||||||
super(id);
|
super(id);
|
||||||
|
|
||||||
this.packetId = NamespacedUtil.getId(
|
this.packetId = NamespacedUtil.getId(NamespacedUtil.getNamespace(id),
|
||||||
NamespacedUtil.getNamespace(id),
|
"ControlKeyPress" + NamespacedUtil.getName(id));
|
||||||
"ControlKeyPress" + NamespacedUtil.getName(id)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
this.dataWriter = dataWriter;
|
this.dataWriter = dataWriter;
|
||||||
@ -54,10 +49,7 @@ public class ControlTriggerLambda extends ControlTriggerInputBased {
|
|||||||
if (!predicate.test(event))
|
if (!predicate.test(event))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
PacketControl packet = new PacketControl(
|
PacketControl packet = new PacketControl(packetId, ControlDataRegistry.getInstance().create(getId()));
|
||||||
packetId,
|
|
||||||
ControlDataRegistry.getInstance().create(getId())
|
|
||||||
);
|
|
||||||
|
|
||||||
dataWriter.accept(event, packet.getControl());
|
dataWriter.accept(event, packet.getControl());
|
||||||
|
|
||||||
|
@ -29,11 +29,7 @@ public class ControlTriggerLocalLambda extends ControlTriggerInputBased {
|
|||||||
private final Predicate<InputEvent> predicate;
|
private final Predicate<InputEvent> predicate;
|
||||||
private final Consumer<InputEvent> action;
|
private final Consumer<InputEvent> action;
|
||||||
|
|
||||||
public ControlTriggerLocalLambda(
|
public ControlTriggerLocalLambda(String id, Predicate<InputEvent> predicate, Consumer<InputEvent> action) {
|
||||||
String id,
|
|
||||||
Predicate<InputEvent> predicate,
|
|
||||||
Consumer<InputEvent> action
|
|
||||||
) {
|
|
||||||
super(id);
|
super(id);
|
||||||
|
|
||||||
this.predicate = predicate;
|
this.predicate = predicate;
|
||||||
|
@ -27,120 +27,57 @@ import ru.windcorp.progressia.common.comms.controls.ControlData;
|
|||||||
|
|
||||||
public class ControlTriggers {
|
public class ControlTriggers {
|
||||||
|
|
||||||
public static ControlTriggerInputBased of(
|
public static ControlTriggerInputBased of(String id, BiConsumer<InputEvent, ControlData> dataWriter,
|
||||||
String id,
|
Predicate<InputEvent> predicate) {
|
||||||
BiConsumer<InputEvent, ControlData> dataWriter,
|
|
||||||
Predicate<InputEvent> predicate
|
|
||||||
) {
|
|
||||||
return new ControlTriggerLambda(id, predicate, dataWriter);
|
return new ControlTriggerLambda(id, predicate, dataWriter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ControlTriggerInputBased of(
|
public static ControlTriggerInputBased of(String id, Consumer<ControlData> dataWriter,
|
||||||
String id,
|
Predicate<InputEvent> predicate) {
|
||||||
Consumer<ControlData> dataWriter,
|
return of(id, (input, control) -> dataWriter.accept(control), predicate);
|
||||||
Predicate<InputEvent> predicate
|
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
(input, control) -> dataWriter.accept(control),
|
|
||||||
predicate
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ControlTriggerInputBased of(
|
public static ControlTriggerInputBased of(String id, Predicate<InputEvent> predicate) {
|
||||||
String id,
|
return of(id, (input, control) -> {
|
||||||
Predicate<InputEvent> predicate
|
}, predicate);
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
(input, control) -> {
|
|
||||||
},
|
|
||||||
predicate
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased of(
|
public static <I extends InputEvent> ControlTriggerInputBased of(String id, Class<I> inputType,
|
||||||
String id,
|
BiConsumer<I, ControlData> dataWriter, Predicate<I>... predicates) {
|
||||||
Class<I> inputType,
|
return of(id, createCheckedDataWriter(inputType, dataWriter),
|
||||||
BiConsumer<I, ControlData> dataWriter,
|
createCheckedCompoundPredicate(inputType, predicates));
|
||||||
Predicate<I>... predicates
|
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
createCheckedDataWriter(inputType, dataWriter),
|
|
||||||
createCheckedCompoundPredicate(inputType, predicates)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased of(
|
public static <I extends InputEvent> ControlTriggerInputBased of(String id, Class<I> inputType,
|
||||||
String id,
|
Consumer<ControlData> dataWriter, Predicate<I>... predicates) {
|
||||||
Class<I> inputType,
|
return of(id, inputType, (input, control) -> dataWriter.accept(control), predicates);
|
||||||
Consumer<ControlData> dataWriter,
|
|
||||||
Predicate<I>... predicates
|
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
inputType,
|
|
||||||
(input, control) -> dataWriter.accept(control),
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased of(
|
public static <I extends InputEvent> ControlTriggerInputBased of(String id, Class<I> inputType,
|
||||||
String id,
|
Predicate<I>... predicates) {
|
||||||
Class<I> inputType,
|
return of(id, (input, control) -> {
|
||||||
Predicate<I>... predicates
|
}, createCheckedCompoundPredicate(inputType, predicates));
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
(input, control) -> {
|
|
||||||
},
|
|
||||||
createCheckedCompoundPredicate(inputType, predicates)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static ControlTriggerInputBased of(
|
public static ControlTriggerInputBased of(String id, BiConsumer<InputEvent, ControlData> dataWriter,
|
||||||
String id,
|
Predicate<InputEvent>... predicates) {
|
||||||
BiConsumer<InputEvent, ControlData> dataWriter,
|
return of(id, InputEvent.class, dataWriter, predicates);
|
||||||
Predicate<InputEvent>... predicates
|
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
InputEvent.class,
|
|
||||||
dataWriter,
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased of(
|
public static <I extends InputEvent> ControlTriggerInputBased of(String id, Consumer<ControlData> dataWriter,
|
||||||
String id,
|
Predicate<InputEvent>... predicates) {
|
||||||
Consumer<ControlData> dataWriter,
|
return of(id, (input, control) -> dataWriter.accept(control), predicates);
|
||||||
Predicate<InputEvent>... predicates
|
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
(input, control) -> dataWriter.accept(control),
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static ControlTriggerInputBased of(
|
public static ControlTriggerInputBased of(String id, Predicate<InputEvent>... predicates) {
|
||||||
String id,
|
return of(id, InputEvent.class, (input, control) -> {
|
||||||
Predicate<InputEvent>... predicates
|
}, predicates);
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
InputEvent.class,
|
|
||||||
(input, control) -> {
|
|
||||||
},
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -157,100 +94,52 @@ public class ControlTriggers {
|
|||||||
//
|
//
|
||||||
//
|
//
|
||||||
|
|
||||||
public static ControlTriggerInputBased localOf(
|
public static ControlTriggerInputBased localOf(String id, Consumer<InputEvent> action,
|
||||||
String id,
|
Predicate<InputEvent> predicate) {
|
||||||
Consumer<InputEvent> action,
|
|
||||||
Predicate<InputEvent> predicate
|
|
||||||
) {
|
|
||||||
return new ControlTriggerLocalLambda(id, predicate, action);
|
return new ControlTriggerLocalLambda(id, predicate, action);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ControlTriggerInputBased localOf(
|
public static ControlTriggerInputBased localOf(String id, Runnable action, Predicate<InputEvent> predicate) {
|
||||||
String id,
|
return localOf(id, input -> action.run(), predicate);
|
||||||
Runnable action,
|
|
||||||
Predicate<InputEvent> predicate
|
|
||||||
) {
|
|
||||||
return localOf(
|
|
||||||
id,
|
|
||||||
input -> action.run(),
|
|
||||||
predicate
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased localOf(
|
public static <I extends InputEvent> ControlTriggerInputBased localOf(String id, Class<I> inputType,
|
||||||
String id,
|
Consumer<I> action, Predicate<I>... predicates) {
|
||||||
Class<I> inputType,
|
return localOf(id, createCheckedAction(inputType, action),
|
||||||
Consumer<I> action,
|
createCheckedCompoundPredicate(inputType, predicates));
|
||||||
Predicate<I>... predicates
|
|
||||||
) {
|
|
||||||
return localOf(
|
|
||||||
id,
|
|
||||||
createCheckedAction(inputType, action),
|
|
||||||
createCheckedCompoundPredicate(inputType, predicates)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased localOf(
|
public static <I extends InputEvent> ControlTriggerInputBased localOf(String id, Class<I> inputType,
|
||||||
String id,
|
Runnable action, Predicate<I>... predicates) {
|
||||||
Class<I> inputType,
|
return localOf(id, inputType, input -> action.run(), predicates);
|
||||||
Runnable action,
|
|
||||||
Predicate<I>... predicates
|
|
||||||
) {
|
|
||||||
return localOf(
|
|
||||||
id,
|
|
||||||
inputType,
|
|
||||||
input -> action.run(),
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static ControlTriggerInputBased localOf(
|
public static ControlTriggerInputBased localOf(String id, Consumer<InputEvent> action,
|
||||||
String id,
|
Predicate<InputEvent>... predicates) {
|
||||||
Consumer<InputEvent> action,
|
return localOf(id, InputEvent.class, action, predicates);
|
||||||
Predicate<InputEvent>... predicates
|
|
||||||
) {
|
|
||||||
return localOf(
|
|
||||||
id,
|
|
||||||
InputEvent.class,
|
|
||||||
action,
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SafeVarargs
|
@SafeVarargs
|
||||||
public static <I extends InputEvent> ControlTriggerInputBased localOf(
|
public static <I extends InputEvent> ControlTriggerInputBased localOf(String id, Runnable action,
|
||||||
String id,
|
Predicate<InputEvent>... predicates) {
|
||||||
Runnable action,
|
return of(id, input -> action.run(), predicates);
|
||||||
Predicate<InputEvent>... predicates
|
|
||||||
) {
|
|
||||||
return of(
|
|
||||||
id,
|
|
||||||
input -> action.run(),
|
|
||||||
predicates
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <I extends InputEvent> BiConsumer<InputEvent, ControlData> createCheckedDataWriter(
|
private static <I extends InputEvent> BiConsumer<InputEvent, ControlData> createCheckedDataWriter(
|
||||||
Class<I> inputType,
|
Class<I> inputType, BiConsumer<I, ControlData> dataWriter) {
|
||||||
BiConsumer<I, ControlData> dataWriter
|
|
||||||
) {
|
|
||||||
return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control);
|
return (inputEvent, control) -> dataWriter.accept(inputType.cast(inputEvent), control);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <I extends InputEvent> Consumer<InputEvent> createCheckedAction(
|
private static <I extends InputEvent> Consumer<InputEvent> createCheckedAction(Class<I> inputType,
|
||||||
Class<I> inputType,
|
Consumer<I> action) {
|
||||||
Consumer<I> action
|
|
||||||
) {
|
|
||||||
return inputEvent -> action.accept(inputType.cast(inputEvent));
|
return inputEvent -> action.accept(inputType.cast(inputEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <I extends InputEvent> Predicate<InputEvent> createCheckedCompoundPredicate(
|
private static <I extends InputEvent> Predicate<InputEvent> createCheckedCompoundPredicate(Class<I> inputType,
|
||||||
Class<I> inputType,
|
Predicate<I>[] predicates) {
|
||||||
Predicate<I>[] predicates
|
|
||||||
) {
|
|
||||||
return new CompoundCastPredicate<>(inputType, predicates);
|
return new CompoundCastPredicate<>(inputType, predicates);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +32,7 @@ public class InputBasedControls {
|
|||||||
this.client = client;
|
this.client = client;
|
||||||
|
|
||||||
this.controls = ControlTriggerRegistry.getInstance().values().stream()
|
this.controls = ControlTriggerRegistry.getInstance().values().stream()
|
||||||
.filter(ControlTriggerInputBased.class::isInstance)
|
.filter(ControlTriggerInputBased.class::isInstance).toArray(ControlTriggerInputBased[]::new);
|
||||||
.toArray(ControlTriggerInputBased[]::new);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleInput(Input input) {
|
public void handleInput(Input input) {
|
||||||
|
@ -34,11 +34,7 @@ public class LocalServerCommsChannel extends ServerCommsChannel {
|
|||||||
public void connect(String login) {
|
public void connect(String login) {
|
||||||
setState(State.CONNECTED);
|
setState(State.CONNECTED);
|
||||||
|
|
||||||
this.localClient = new LocalClient(
|
this.localClient = new LocalClient(server.getClientManager().grabClientId(), login, this);
|
||||||
server.getClientManager().grabClientId(),
|
|
||||||
login,
|
|
||||||
this
|
|
||||||
);
|
|
||||||
|
|
||||||
server.getClientManager().addClient(localClient);
|
server.getClientManager().addClient(localClient);
|
||||||
}
|
}
|
||||||
|
@ -159,27 +159,14 @@ public class GraphicsBackend {
|
|||||||
|
|
||||||
public static void setFullscreen() {
|
public static void setFullscreen() {
|
||||||
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||||
glfwSetWindowMonitor(
|
glfwSetWindowMonitor(getWindowHandle(), glfwGetPrimaryMonitor(), 0, 0, vidmode.width(), vidmode.height(), 0);
|
||||||
getWindowHandle(),
|
|
||||||
glfwGetPrimaryMonitor(),
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
vidmode.width(),
|
|
||||||
vidmode.height(),
|
|
||||||
0);
|
|
||||||
isFullscreen = true;
|
isFullscreen = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setWindowed() {
|
public static void setWindowed() {
|
||||||
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
GLFWVidMode vidmode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||||
glfwSetWindowMonitor(
|
glfwSetWindowMonitor(getWindowHandle(), 0, (vidmode.width() - getFrameWidth()) / 2,
|
||||||
getWindowHandle(),
|
(vidmode.height() - getFrameHeight()) / 2, getFrameWidth(), getFrameHeight(), 0);
|
||||||
0,
|
|
||||||
(vidmode.width() - getFrameWidth()) / 2,
|
|
||||||
(vidmode.height() - getFrameHeight()) / 2,
|
|
||||||
getFrameWidth(),
|
|
||||||
getFrameHeight(),
|
|
||||||
0);
|
|
||||||
isFullscreen = false;
|
isFullscreen = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,13 +49,7 @@ public class InputHandler {
|
|||||||
|
|
||||||
private static final ModifiableKeyEvent THE_KEY_EVENT = new ModifiableKeyEvent();
|
private static final ModifiableKeyEvent THE_KEY_EVENT = new ModifiableKeyEvent();
|
||||||
|
|
||||||
static void handleKeyInput(
|
static void handleKeyInput(long window, int key, int scancode, int action, int mods) {
|
||||||
long window,
|
|
||||||
int key,
|
|
||||||
int scancode,
|
|
||||||
int action,
|
|
||||||
int mods
|
|
||||||
) {
|
|
||||||
if (GraphicsBackend.getWindowHandle() != window)
|
if (GraphicsBackend.getWindowHandle() != window)
|
||||||
return;
|
return;
|
||||||
THE_KEY_EVENT.initialize(key, scancode, action, mods);
|
THE_KEY_EVENT.initialize(key, scancode, action, mods);
|
||||||
@ -71,12 +65,7 @@ public class InputHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void handleMouseButtonInput(
|
static void handleMouseButtonInput(long window, int key, int action, int mods) {
|
||||||
long window,
|
|
||||||
int key,
|
|
||||||
int action,
|
|
||||||
int mods
|
|
||||||
) {
|
|
||||||
handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods);
|
handleKeyInput(window, key, Integer.MAX_VALUE - key, action, mods);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,11 +86,7 @@ public class InputHandler {
|
|||||||
|
|
||||||
private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT = new ModifiableCursorMoveEvent();
|
private static final ModifiableCursorMoveEvent THE_CURSOR_MOVE_EVENT = new ModifiableCursorMoveEvent();
|
||||||
|
|
||||||
static void handleMouseMoveInput(
|
static void handleMouseMoveInput(long window, double x, double y) {
|
||||||
long window,
|
|
||||||
double x,
|
|
||||||
double y
|
|
||||||
) {
|
|
||||||
if (GraphicsBackend.getWindowHandle() != window)
|
if (GraphicsBackend.getWindowHandle() != window)
|
||||||
return;
|
return;
|
||||||
y = GraphicsInterface.getFrameHeight() - y; // Flip y axis
|
y = GraphicsInterface.getFrameHeight() - y; // Flip y axis
|
||||||
@ -131,11 +116,7 @@ public class InputHandler {
|
|||||||
|
|
||||||
private static final ModifiableWheelScrollEvent THE_WHEEL_SCROLL_EVENT = new ModifiableWheelScrollEvent();
|
private static final ModifiableWheelScrollEvent THE_WHEEL_SCROLL_EVENT = new ModifiableWheelScrollEvent();
|
||||||
|
|
||||||
static void handleWheelScroll(
|
static void handleWheelScroll(long window, double xoffset, double yoffset) {
|
||||||
long window,
|
|
||||||
double xoffset,
|
|
||||||
double yoffset
|
|
||||||
) {
|
|
||||||
if (GraphicsBackend.getWindowHandle() != window)
|
if (GraphicsBackend.getWindowHandle() != window)
|
||||||
return;
|
return;
|
||||||
THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset);
|
THE_WHEEL_SCROLL_EVENT.initialize(xoffset, yoffset);
|
||||||
@ -162,10 +143,7 @@ public class InputHandler {
|
|||||||
/*
|
/*
|
||||||
* NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend
|
* NB: this is NOT a GLFW callback, the raw callback is in GraphicsBackend
|
||||||
*/
|
*/
|
||||||
static void handleFrameResize(
|
static void handleFrameResize(int width, int height) {
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
) {
|
|
||||||
THE_FRAME_RESIZE_EVENT.initialize(width, height);
|
THE_FRAME_RESIZE_EVENT.initialize(width, height);
|
||||||
dispatch(THE_FRAME_RESIZE_EVENT);
|
dispatch(THE_FRAME_RESIZE_EVENT);
|
||||||
}
|
}
|
||||||
|
@ -24,10 +24,7 @@ import gnu.trove.set.hash.TIntHashSet;
|
|||||||
|
|
||||||
public class InputTracker {
|
public class InputTracker {
|
||||||
|
|
||||||
private static final Vec2d CURSOR_POSITION = new Vec2d(
|
private static final Vec2d CURSOR_POSITION = new Vec2d(Double.NaN, Double.NaN);
|
||||||
Double.NaN,
|
|
||||||
Double.NaN
|
|
||||||
);
|
|
||||||
|
|
||||||
private static final TIntSet PRESSED_KEYS = new TIntHashSet(256);
|
private static final TIntSet PRESSED_KEYS = new TIntHashSet(256);
|
||||||
|
|
||||||
|
@ -92,16 +92,10 @@ class LWJGLInitializer {
|
|||||||
private static void setupWindowCallbacks() {
|
private static void setupWindowCallbacks() {
|
||||||
long handle = GraphicsBackend.getWindowHandle();
|
long handle = GraphicsBackend.getWindowHandle();
|
||||||
|
|
||||||
glfwSetFramebufferSizeCallback(
|
glfwSetFramebufferSizeCallback(handle, GraphicsBackend::onFrameResized);
|
||||||
handle,
|
|
||||||
GraphicsBackend::onFrameResized
|
|
||||||
);
|
|
||||||
|
|
||||||
glfwSetKeyCallback(handle, InputHandler::handleKeyInput);
|
glfwSetKeyCallback(handle, InputHandler::handleKeyInput);
|
||||||
glfwSetMouseButtonCallback(
|
glfwSetMouseButtonCallback(handle, InputHandler::handleMouseButtonInput);
|
||||||
handle,
|
|
||||||
InputHandler::handleMouseButtonInput
|
|
||||||
);
|
|
||||||
|
|
||||||
glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput);
|
glfwSetCursorPosCallback(handle, InputHandler::handleMouseMoveInput);
|
||||||
|
|
||||||
|
@ -34,19 +34,13 @@ public class OpenGLObjectTracker {
|
|||||||
private static final ReferenceQueue<OpenGLDeletable> DELETE_QUEUE = new ReferenceQueue<>();
|
private static final ReferenceQueue<OpenGLDeletable> DELETE_QUEUE = new ReferenceQueue<>();
|
||||||
|
|
||||||
public synchronized static void register(OpenGLDeletable object, IntConsumer glDeleter) {
|
public synchronized static void register(OpenGLDeletable object, IntConsumer glDeleter) {
|
||||||
GLPhantomReference<OpenGLDeletable> glRef = new GLPhantomReference<>(
|
GLPhantomReference<OpenGLDeletable> glRef = new GLPhantomReference<>(object, DELETE_QUEUE, object.getHandle(),
|
||||||
object,
|
glDeleter);
|
||||||
DELETE_QUEUE,
|
|
||||||
object.getHandle(),
|
|
||||||
glDeleter
|
|
||||||
);
|
|
||||||
TO_DELETE.add(glRef);
|
TO_DELETE.add(glRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void deleteAllObjects() {
|
public static void deleteAllObjects() {
|
||||||
for (
|
for (GLPhantomReference<OpenGLDeletable> glRef : TO_DELETE) {
|
||||||
GLPhantomReference<OpenGLDeletable> glRef : TO_DELETE
|
|
||||||
) {
|
|
||||||
glRef.clear();
|
glRef.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -75,20 +69,16 @@ public class OpenGLObjectTracker {
|
|||||||
* It is possible to create a phantom reference with a {@code null}
|
* It is possible to create a phantom reference with a {@code null}
|
||||||
* queue, but such a reference is completely useless: Its {@code get}
|
* queue, but such a reference is completely useless: Its {@code get}
|
||||||
* method will always return {@code null} and, since it does not have a
|
* method will always return {@code null} and, since it does not have a
|
||||||
* queue,
|
* queue, it will never be enqueued.
|
||||||
* it will never be enqueued.
|
|
||||||
*
|
*
|
||||||
* @param referent the object the new phantom reference will refer to
|
* @param referent
|
||||||
* @param q the queue with which the reference is to be
|
* the object the new phantom reference will refer to
|
||||||
* registered,
|
* @param q
|
||||||
* or {@code null} if registration is not required
|
* the queue with which the reference is to be registered, or
|
||||||
|
* {@code null} if registration is not required
|
||||||
*/
|
*/
|
||||||
public GLPhantomReference(
|
public GLPhantomReference(T referent, ReferenceQueue<? super T> q, int referentGLhandle,
|
||||||
T referent,
|
IntConsumer GLDeleter) {
|
||||||
ReferenceQueue<? super T> q,
|
|
||||||
int referentGLhandle,
|
|
||||||
IntConsumer GLDeleter
|
|
||||||
) {
|
|
||||||
super(referent, q);
|
super(referent, q);
|
||||||
this.referentGLhandle = referentGLhandle;
|
this.referentGLhandle = referentGLhandle;
|
||||||
this.GLDeleter = GLDeleter;
|
this.GLDeleter = GLDeleter;
|
||||||
|
@ -41,11 +41,7 @@ public class RenderTaskQueue {
|
|||||||
HANDLER.invokeNow(task);
|
HANDLER.invokeNow(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <E extends Exception> void waitAndInvoke(
|
public static <E extends Exception> void waitAndInvoke(ThrowingRunnable<E> task) throws InterruptedException, E {
|
||||||
ThrowingRunnable<E> task
|
|
||||||
)
|
|
||||||
throws InterruptedException,
|
|
||||||
E {
|
|
||||||
HANDLER.waitAndInvoke(task);
|
HANDLER.waitAndInvoke(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,9 +23,7 @@ import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW;
|
|||||||
import static org.lwjgl.opengl.GL15.GL_STREAM_DRAW;
|
import static org.lwjgl.opengl.GL15.GL_STREAM_DRAW;
|
||||||
|
|
||||||
public enum Usage { // TODO add _COPY and _READ, pref. as another enum
|
public enum Usage { // TODO add _COPY and _READ, pref. as another enum
|
||||||
STATIC(GL_STATIC_DRAW),
|
STATIC(GL_STATIC_DRAW), DYNAMIC(GL_DYNAMIC_DRAW), STREAM(GL_STREAM_DRAW);
|
||||||
DYNAMIC(GL_DYNAMIC_DRAW),
|
|
||||||
STREAM(GL_STREAM_DRAW);
|
|
||||||
|
|
||||||
private final int glCode;
|
private final int glCode;
|
||||||
|
|
||||||
|
@ -28,8 +28,7 @@ import ru.windcorp.progressia.client.graphics.backend.OpenGLObjectTracker.OpenGL
|
|||||||
public class VertexBufferObject implements OpenGLDeletable {
|
public class VertexBufferObject implements OpenGLDeletable {
|
||||||
|
|
||||||
public static enum BindTarget {
|
public static enum BindTarget {
|
||||||
ARRAY(GL_ARRAY_BUFFER),
|
ARRAY(GL_ARRAY_BUFFER), ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER);
|
||||||
ELEMENT_ARRAY(GL_ELEMENT_ARRAY_BUFFER);
|
|
||||||
|
|
||||||
private final int glCode;
|
private final int glCode;
|
||||||
|
|
||||||
|
@ -32,12 +32,7 @@ public class CombinedShader extends Shader {
|
|||||||
for (int i = 1; i < resources.length; ++i) {
|
for (int i = 1; i < resources.length; ++i) {
|
||||||
if (ShaderType.guessByResourceName(resources[i]) != first) {
|
if (ShaderType.guessByResourceName(resources[i]) != first) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Deduced shader types of "
|
"Deduced shader types of " + resources[0] + " and " + resources[i] + " differ");
|
||||||
+ resources[0]
|
|
||||||
+ " and "
|
|
||||||
+ resources[i]
|
|
||||||
+ " differ"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,19 +66,8 @@ public class CombinedShader extends Shader {
|
|||||||
if (contents.codePointAt(versionIndex) == '#') {
|
if (contents.codePointAt(versionIndex) == '#') {
|
||||||
final String versionAnnotation = "#version ";
|
final String versionAnnotation = "#version ";
|
||||||
|
|
||||||
if (
|
if (contents.regionMatches(versionIndex, versionAnnotation, 0, versionAnnotation.length())) {
|
||||||
contents.regionMatches(
|
contents = contents.substring(versionIndex + versionAnnotation.length() + "120".length());
|
||||||
versionIndex,
|
|
||||||
versionAnnotation,
|
|
||||||
0,
|
|
||||||
versionAnnotation.length()
|
|
||||||
)
|
|
||||||
) {
|
|
||||||
contents = contents.substring(
|
|
||||||
versionIndex
|
|
||||||
+ versionAnnotation.length()
|
|
||||||
+ "120".length()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -57,10 +57,7 @@ public class Shader implements OpenGLDeletable {
|
|||||||
if (resource.contains("fsh"))
|
if (resource.contains("fsh"))
|
||||||
return FRAGMENT;
|
return FRAGMENT;
|
||||||
|
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException("Cannot deduce shader type from resource name \"" + resource + "\"");
|
||||||
"Cannot deduce shader type from resource name \"" +
|
|
||||||
resource + "\""
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,10 +87,7 @@ public class Shader implements OpenGLDeletable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Shader(String resource) {
|
public Shader(String resource) {
|
||||||
this(
|
this(ShaderType.guessByResourceName(resource), getShaderResource(resource).readAsString());
|
||||||
ShaderType.guessByResourceName(resource),
|
|
||||||
getShaderResource(resource).readAsString()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -51,104 +51,29 @@ public class AttributeVertexArray extends Attribute {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(
|
public void set(int size, boolean normalized, int stride, ByteBuffer pointer) {
|
||||||
int size,
|
glVertexAttribPointer(handle, size, GL_BYTE, normalized, stride, pointer);
|
||||||
boolean normalized,
|
|
||||||
int stride,
|
|
||||||
ByteBuffer pointer
|
|
||||||
) {
|
|
||||||
glVertexAttribPointer(
|
|
||||||
handle,
|
|
||||||
size,
|
|
||||||
GL_BYTE,
|
|
||||||
normalized,
|
|
||||||
stride,
|
|
||||||
pointer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(
|
public void set(int size, boolean normalized, int stride, FloatBuffer pointer) {
|
||||||
int size,
|
glVertexAttribPointer(handle, size, GL_FLOAT, normalized, stride, pointer);
|
||||||
boolean normalized,
|
|
||||||
int stride,
|
|
||||||
FloatBuffer pointer
|
|
||||||
) {
|
|
||||||
glVertexAttribPointer(
|
|
||||||
handle,
|
|
||||||
size,
|
|
||||||
GL_FLOAT,
|
|
||||||
normalized,
|
|
||||||
stride,
|
|
||||||
pointer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(
|
public void set(int size, boolean normalized, int stride, IntBuffer pointer) {
|
||||||
int size,
|
glVertexAttribPointer(handle, size, GL_INT, normalized, stride, pointer);
|
||||||
boolean normalized,
|
|
||||||
int stride,
|
|
||||||
IntBuffer pointer
|
|
||||||
) {
|
|
||||||
glVertexAttribPointer(
|
|
||||||
handle,
|
|
||||||
size,
|
|
||||||
GL_INT,
|
|
||||||
normalized,
|
|
||||||
stride,
|
|
||||||
pointer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(
|
public void set(int size, boolean normalized, int stride, ShortBuffer pointer) {
|
||||||
int size,
|
glVertexAttribPointer(handle, size, GL_SHORT, normalized, stride, pointer);
|
||||||
boolean normalized,
|
|
||||||
int stride,
|
|
||||||
ShortBuffer pointer
|
|
||||||
) {
|
|
||||||
glVertexAttribPointer(
|
|
||||||
handle,
|
|
||||||
size,
|
|
||||||
GL_SHORT,
|
|
||||||
normalized,
|
|
||||||
stride,
|
|
||||||
pointer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(
|
public void set(int size, int type, boolean normalized, int stride, long pointer) {
|
||||||
int size,
|
glVertexAttribPointer(handle, size, type, normalized, stride, pointer);
|
||||||
int type,
|
|
||||||
boolean normalized,
|
|
||||||
int stride,
|
|
||||||
long pointer
|
|
||||||
) {
|
|
||||||
glVertexAttribPointer(
|
|
||||||
handle,
|
|
||||||
size,
|
|
||||||
type,
|
|
||||||
normalized,
|
|
||||||
stride,
|
|
||||||
pointer
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(
|
public void set(int size, int type, boolean normalized, int stride, VertexBufferObject vbo, long offset) {
|
||||||
int size,
|
|
||||||
int type,
|
|
||||||
boolean normalized,
|
|
||||||
int stride,
|
|
||||||
VertexBufferObject vbo,
|
|
||||||
long offset
|
|
||||||
) {
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, vbo.getHandle());
|
glBindBuffer(GL_ARRAY_BUFFER, vbo.getHandle());
|
||||||
glVertexAttribPointer(
|
glVertexAttribPointer(handle, size, type, normalized, stride, offset);
|
||||||
handle,
|
|
||||||
size,
|
|
||||||
type,
|
|
||||||
normalized,
|
|
||||||
stride,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,8 +37,7 @@ public abstract class FlatRenderHelper extends ShapeRenderHelper {
|
|||||||
float width = GraphicsInterface.getFrameWidth();
|
float width = GraphicsInterface.getFrameWidth();
|
||||||
float height = GraphicsInterface.getFrameHeight();
|
float height = GraphicsInterface.getFrameHeight();
|
||||||
|
|
||||||
return finalTransform.identity().translate(-1, -1, 0)
|
return finalTransform.identity().translate(-1, -1, 0).scale(2 / width, 2 / height, 1 / MAX_DEPTH)
|
||||||
.scale(2 / width, 2 / height, 1 / MAX_DEPTH)
|
|
||||||
.mul(getTransform());
|
.mul(getTransform());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,10 +33,8 @@ public class FlatRenderProgram extends ShapeRenderProgram {
|
|||||||
private static FlatRenderProgram def = null;
|
private static FlatRenderProgram def = null;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
def = new FlatRenderProgram(
|
def = new FlatRenderProgram(new String[] { "FlatDefault.vertex.glsl" },
|
||||||
new String[] { "FlatDefault.vertex.glsl" },
|
new String[] { "FlatDefault.fragment.glsl" });
|
||||||
new String[] { "FlatDefault.fragment.glsl" }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FlatRenderProgram getDefault() {
|
public static FlatRenderProgram getDefault() {
|
||||||
@ -48,20 +46,13 @@ public class FlatRenderProgram extends ShapeRenderProgram {
|
|||||||
private static final String FLAT_VERTEX_SHADER_RESOURCE = "Flat.vertex.glsl";
|
private static final String FLAT_VERTEX_SHADER_RESOURCE = "Flat.vertex.glsl";
|
||||||
private static final String FLAT_FRAGMENT_SHADER_RESOURCE = "Flat.fragment.glsl";
|
private static final String FLAT_FRAGMENT_SHADER_RESOURCE = "Flat.fragment.glsl";
|
||||||
|
|
||||||
private static final String MASK_COUNT_UNIFORM_NAME = "maskCount",
|
private static final String MASK_COUNT_UNIFORM_NAME = "maskCount", MASKS_UNIFORM_NAME = "masks";
|
||||||
MASKS_UNIFORM_NAME = "masks";
|
|
||||||
|
|
||||||
private final Uniform1Int maskCountUniform;
|
private final Uniform1Int maskCountUniform;
|
||||||
private final Uniform2Float masksUniform;
|
private final Uniform2Float masksUniform;
|
||||||
|
|
||||||
public FlatRenderProgram(
|
public FlatRenderProgram(String[] vertexShaderResources, String[] fragmentShaderResources) {
|
||||||
String[] vertexShaderResources,
|
super(attachVertexShader(vertexShaderResources), attachFragmentShader(fragmentShaderResources));
|
||||||
String[] fragmentShaderResources
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
attachVertexShader(vertexShaderResources),
|
|
||||||
attachFragmentShader(fragmentShaderResources)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.maskCountUniform = getUniform(MASK_COUNT_UNIFORM_NAME).as1Int();
|
this.maskCountUniform = getUniform(MASK_COUNT_UNIFORM_NAME).as1Int();
|
||||||
this.masksUniform = getUniform(MASKS_UNIFORM_NAME).as2Float();
|
this.masksUniform = getUniform(MASKS_UNIFORM_NAME).as2Float();
|
||||||
|
@ -88,8 +88,7 @@ public class Mask {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "(" + getStartX() + "; " + getStartY() +
|
return "(" + getStartX() + "; " + getStartY() + ") -> (" + getEndX() + "; " + getEndY() + ")";
|
||||||
") -> (" + getEndX() + "; " + getEndY() + ")";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -24,9 +24,8 @@ import org.lwjgl.BufferUtils;
|
|||||||
|
|
||||||
public class MaskStack {
|
public class MaskStack {
|
||||||
|
|
||||||
private final FloatBuffer buffer = BufferUtils.createFloatBuffer(
|
private final FloatBuffer buffer = BufferUtils
|
||||||
FlatRenderProgram.MASK_STACK_SIZE * TransformedMask.SIZE_IN_FLOATS
|
.createFloatBuffer(FlatRenderProgram.MASK_STACK_SIZE * TransformedMask.SIZE_IN_FLOATS);
|
||||||
);
|
|
||||||
|
|
||||||
public void pushMask(TransformedMask mask) {
|
public void pushMask(TransformedMask mask) {
|
||||||
mask.writeToBuffer(buffer);
|
mask.writeToBuffer(buffer);
|
||||||
|
@ -42,14 +42,8 @@ public class TransformedMask {
|
|||||||
private Vec4 endXstartY = null;
|
private Vec4 endXstartY = null;
|
||||||
private Vec4 endXendY = null;
|
private Vec4 endXendY = null;
|
||||||
|
|
||||||
public TransformedMask(
|
public TransformedMask(Vec2 origin, Vec2 width, Vec2 height, Vec2 counterOrigin, Vec2 counterWidth,
|
||||||
Vec2 origin,
|
Vec2 counterHeight) {
|
||||||
Vec2 width,
|
|
||||||
Vec2 height,
|
|
||||||
Vec2 counterOrigin,
|
|
||||||
Vec2 counterWidth,
|
|
||||||
Vec2 counterHeight
|
|
||||||
) {
|
|
||||||
set(origin, width, height, counterOrigin, counterWidth, counterHeight);
|
set(origin, width, height, counterOrigin, counterWidth, counterHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,14 +55,8 @@ public class TransformedMask {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransformedMask set(
|
public TransformedMask set(Vec2 origin, Vec2 width, Vec2 height, Vec2 counterOrigin, Vec2 counterWidth,
|
||||||
Vec2 origin,
|
Vec2 counterHeight) {
|
||||||
Vec2 width,
|
|
||||||
Vec2 height,
|
|
||||||
Vec2 counterOrigin,
|
|
||||||
Vec2 counterWidth,
|
|
||||||
Vec2 counterHeight
|
|
||||||
) {
|
|
||||||
this.origin.set(origin.x, origin.y);
|
this.origin.set(origin.x, origin.y);
|
||||||
this.width.set(width.x, width.y);
|
this.width.set(width.x, width.y);
|
||||||
this.height.set(height.x, height.y);
|
this.height.set(height.x, height.y);
|
||||||
@ -112,35 +100,17 @@ public class TransformedMask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void setFields() {
|
private void setFields() {
|
||||||
origin.set(
|
origin.set(startXstartY.x, startXstartY.y);
|
||||||
startXstartY.x,
|
|
||||||
startXstartY.y
|
|
||||||
);
|
|
||||||
|
|
||||||
width.set(
|
width.set(endXstartY.x - startXstartY.x, endXstartY.y - startXstartY.y);
|
||||||
endXstartY.x - startXstartY.x,
|
|
||||||
endXstartY.y - startXstartY.y
|
|
||||||
);
|
|
||||||
|
|
||||||
height.set(
|
height.set(startXendY.x - startXstartY.x, startXendY.y - startXstartY.y);
|
||||||
startXendY.x - startXstartY.x,
|
|
||||||
startXendY.y - startXstartY.y
|
|
||||||
);
|
|
||||||
|
|
||||||
counterOrigin.set(
|
counterOrigin.set(endXendY.x, endXendY.y);
|
||||||
endXendY.x,
|
|
||||||
endXendY.y
|
|
||||||
);
|
|
||||||
|
|
||||||
counterWidth.set(
|
counterWidth.set(startXendY.x - endXendY.x, startXendY.y - endXendY.y);
|
||||||
startXendY.x - endXendY.x,
|
|
||||||
startXendY.y - endXendY.y
|
|
||||||
);
|
|
||||||
|
|
||||||
counterHeight.set(
|
counterHeight.set(endXstartY.x - endXendY.x, endXstartY.y - endXendY.y);
|
||||||
endXstartY.x - endXendY.x,
|
|
||||||
endXstartY.y - endXendY.y
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void writeToBuffer(FloatBuffer output) {
|
public void writeToBuffer(FloatBuffer output) {
|
||||||
|
@ -68,17 +68,11 @@ public class Font {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Renderable assemble(
|
public Renderable assemble(CharSequence chars, float maxWidth) {
|
||||||
CharSequence chars,
|
|
||||||
float maxWidth
|
|
||||||
) {
|
|
||||||
return typeface.assembleStatic(chars, style, align, maxWidth, color);
|
return typeface.assembleStatic(chars, style, align, maxWidth, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Renderable assembleDynamic(
|
public Renderable assembleDynamic(Supplier<CharSequence> supplier, float maxWidth) {
|
||||||
Supplier<CharSequence> supplier,
|
|
||||||
float maxWidth
|
|
||||||
) {
|
|
||||||
return typeface.assembleDynamic(supplier, style, align, maxWidth, color);
|
return typeface.assembleDynamic(supplier, style, align, maxWidth, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,7 +96,8 @@ public class Font {
|
|||||||
* Creates a new {@link Font} with the specified {@code style} exactly. This
|
* Creates a new {@link Font} with the specified {@code style} exactly. This
|
||||||
* object's style is ignored.
|
* object's style is ignored.
|
||||||
*
|
*
|
||||||
* @param style the new style
|
* @param style
|
||||||
|
* the new style
|
||||||
* @return the new font
|
* @return the new font
|
||||||
*/
|
*/
|
||||||
public Font withStyle(int style) {
|
public Font withStyle(int style) {
|
||||||
|
@ -81,8 +81,7 @@ public class GNUUnifontLoader {
|
|||||||
|
|
||||||
private static BufferedReader createReader(Resource resource) throws IOException {
|
private static BufferedReader createReader(Resource resource) throws IOException {
|
||||||
return new BufferedReader(
|
return new BufferedReader(
|
||||||
new InputStreamReader(new GZIPInputStream(resource.getInputStream()), StandardCharsets.UTF_8)
|
new InputStreamReader(new GZIPInputStream(resource.getInputStream()), StandardCharsets.UTF_8));
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Stream<String> createStream(BufferedReader reader) {
|
private static Stream<String> createStream(BufferedReader reader) {
|
||||||
@ -97,13 +96,8 @@ public class GNUUnifontLoader {
|
|||||||
|
|
||||||
char c = getChar(declar);
|
char c = getChar(declar);
|
||||||
|
|
||||||
TextureDataEditor editor = new TextureDataEditor(
|
TextureDataEditor editor = new TextureDataEditor(width, GNUUnifont.HEIGHT, width, GNUUnifont.HEIGHT,
|
||||||
width,
|
TEXTURE_SETTINGS);
|
||||||
GNUUnifont.HEIGHT,
|
|
||||||
width,
|
|
||||||
GNUUnifont.HEIGHT,
|
|
||||||
TEXTURE_SETTINGS
|
|
||||||
);
|
|
||||||
|
|
||||||
for (int y = 0; y < GNUUnifont.HEIGHT; ++y) {
|
for (int y = 0; y < GNUUnifont.HEIGHT; ++y) {
|
||||||
for (int x = 0; x < width; ++x) {
|
for (int x = 0; x < width; ++x) {
|
||||||
@ -165,8 +159,7 @@ public class GNUUnifontLoader {
|
|||||||
|
|
||||||
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) {
|
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) {
|
||||||
throw new IOException(
|
throw new IOException(
|
||||||
"Illegal char in declar \"" + declar + "\" at index " + i + "; expected 0-9A-F"
|
"Illegal char in declar \"" + declar + "\" at index " + i + "; expected 0-9A-F");
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -190,8 +183,7 @@ public class GNUUnifontLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Collector<AtlasGlyph, ?, TCharObjectMap<Texture>> createMapper() {
|
private static Collector<AtlasGlyph, ?, TCharObjectMap<Texture>> createMapper() {
|
||||||
return Collector.of(
|
return Collector.of(TCharObjectHashMap<Texture>::new,
|
||||||
TCharObjectHashMap<Texture>::new,
|
|
||||||
|
|
||||||
(map, glyph) -> map.put(glyph.c, glyph.texture),
|
(map, glyph) -> map.put(glyph.c, glyph.texture),
|
||||||
|
|
||||||
@ -200,8 +192,7 @@ public class GNUUnifontLoader {
|
|||||||
return a;
|
return a;
|
||||||
},
|
},
|
||||||
|
|
||||||
Characteristics.UNORDERED
|
Characteristics.UNORDERED);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private GNUUnifontLoader() {
|
private GNUUnifontLoader() {
|
||||||
|
@ -29,12 +29,8 @@ import ru.windcorp.progressia.common.util.Vectors;
|
|||||||
public abstract class Typeface extends Named {
|
public abstract class Typeface extends Named {
|
||||||
|
|
||||||
public static class Style {
|
public static class Style {
|
||||||
public static final int BOLD = 1 << 0,
|
public static final int BOLD = 1 << 0, ITALIC = 1 << 1, UNDERLINED = 1 << 2, STRIKETHRU = 1 << 3,
|
||||||
ITALIC = 1 << 1,
|
SHADOW = 1 << 4, OUTLINED = 1 << 5;
|
||||||
UNDERLINED = 1 << 2,
|
|
||||||
STRIKETHRU = 1 << 3,
|
|
||||||
SHADOW = 1 << 4,
|
|
||||||
OUTLINED = 1 << 5;
|
|
||||||
|
|
||||||
public static final int PLAIN = 0;
|
public static final int PLAIN = 0;
|
||||||
|
|
||||||
@ -71,40 +67,19 @@ public abstract class Typeface extends Named {
|
|||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Renderable assembleStatic(
|
public abstract Renderable assembleStatic(CharSequence chars, int style, float align, float maxWidth, Vec4 color);
|
||||||
CharSequence chars,
|
|
||||||
int style,
|
|
||||||
float align,
|
|
||||||
float maxWidth,
|
|
||||||
Vec4 color
|
|
||||||
);
|
|
||||||
|
|
||||||
public abstract Renderable assembleDynamic(
|
public abstract Renderable assembleDynamic(Supplier<CharSequence> supplier, int style, float align, float maxWidth,
|
||||||
Supplier<CharSequence> supplier,
|
Vec4 color);
|
||||||
int style,
|
|
||||||
float align,
|
|
||||||
float maxWidth,
|
|
||||||
Vec4 color
|
|
||||||
);
|
|
||||||
|
|
||||||
public int getWidth(
|
public int getWidth(CharSequence chars, int style, float align, float maxWidth) {
|
||||||
CharSequence chars,
|
|
||||||
int style,
|
|
||||||
float align,
|
|
||||||
float maxWidth
|
|
||||||
) {
|
|
||||||
Vec2i v = Vectors.grab2i();
|
Vec2i v = Vectors.grab2i();
|
||||||
v = getSize(chars, style, align, maxWidth, v);
|
v = getSize(chars, style, align, maxWidth, v);
|
||||||
Vectors.release(v);
|
Vectors.release(v);
|
||||||
return v.x;
|
return v.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight(
|
public int getHeight(CharSequence chars, int style, float align, float maxWidth) {
|
||||||
CharSequence chars,
|
|
||||||
int style,
|
|
||||||
float align,
|
|
||||||
float maxWidth
|
|
||||||
) {
|
|
||||||
Vec2i v = Vectors.grab2i();
|
Vec2i v = Vectors.grab2i();
|
||||||
v = getSize(chars, style, align, maxWidth, v);
|
v = getSize(chars, style, align, maxWidth, v);
|
||||||
Vectors.release(v);
|
Vectors.release(v);
|
||||||
@ -113,13 +88,7 @@ public abstract class Typeface extends Named {
|
|||||||
|
|
||||||
public abstract int getLineHeight();
|
public abstract int getLineHeight();
|
||||||
|
|
||||||
public abstract Vec2i getSize(
|
public abstract Vec2i getSize(CharSequence chars, int style, float align, float maxWidth, Vec2i result);
|
||||||
CharSequence chars,
|
|
||||||
int style,
|
|
||||||
float align,
|
|
||||||
float maxWidth,
|
|
||||||
Vec2i result
|
|
||||||
);
|
|
||||||
|
|
||||||
public abstract boolean supports(char c);
|
public abstract boolean supports(char c);
|
||||||
|
|
||||||
|
@ -542,11 +542,8 @@ public class Component extends Named {
|
|||||||
eventBus.post(event);
|
eventBus.post(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends InputEvent> void addListener(
|
public <T extends InputEvent> void addListener(Class<? extends T> type, boolean handlesConsumed,
|
||||||
Class<? extends T> type,
|
InputListener<T> listener) {
|
||||||
boolean handlesConsumed,
|
|
||||||
InputListener<T> listener
|
|
||||||
) {
|
|
||||||
if (inputBus == null) {
|
if (inputBus == null) {
|
||||||
inputBus = new InputBus();
|
inputBus = new InputBus();
|
||||||
}
|
}
|
||||||
|
0
src/main/java/ru/windcorp/progressia/client/graphics/gui/Group.java
Executable file → Normal file
0
src/main/java/ru/windcorp/progressia/client/graphics/gui/Group.java
Executable file → Normal file
0
src/main/java/ru/windcorp/progressia/client/graphics/gui/Panel.java
Normal file → Executable file
0
src/main/java/ru/windcorp/progressia/client/graphics/gui/Panel.java
Normal file → Executable file
@ -56,13 +56,8 @@ public class LayoutAlign implements Layout {
|
|||||||
size.x = min(size.x, cWidth);
|
size.x = min(size.x, cWidth);
|
||||||
size.y = min(size.y, cHeight);
|
size.y = min(size.y, cHeight);
|
||||||
|
|
||||||
child.setBounds(
|
child.setBounds(c.getX() + (int) ((cWidth - size.x) * alignX) + margin,
|
||||||
c.getX() +
|
c.getY() + (int) ((cHeight - size.y) * alignY) + margin, size);
|
||||||
(int) ((cWidth - size.x) * alignX) + margin,
|
|
||||||
c.getY() +
|
|
||||||
(int) ((cHeight - size.y) * alignY) + margin,
|
|
||||||
size
|
|
||||||
);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -71,9 +66,7 @@ public class LayoutAlign implements Layout {
|
|||||||
public Vec2i calculatePreferredSize(Component c) {
|
public Vec2i calculatePreferredSize(Component c) {
|
||||||
Vec2i result = new Vec2i(0, 0);
|
Vec2i result = new Vec2i(0, 0);
|
||||||
|
|
||||||
c.getChildren().stream()
|
c.getChildren().stream().map(child -> child.getPreferredSize()).forEach(size -> {
|
||||||
.map(child -> child.getPreferredSize())
|
|
||||||
.forEach(size -> {
|
|
||||||
result.x = max(size.x, result.x);
|
result.x = max(size.x, result.x);
|
||||||
result.y = max(size.y, result.y);
|
result.y = max(size.y, result.y);
|
||||||
});
|
});
|
||||||
|
@ -26,9 +26,7 @@ import ru.windcorp.progressia.client.graphics.gui.Layout;
|
|||||||
|
|
||||||
public class LayoutBorderHorizontal implements Layout {
|
public class LayoutBorderHorizontal implements Layout {
|
||||||
|
|
||||||
public static final String CENTER = "Center",
|
public static final String CENTER = "Center", LEFT = "Left", RIGHT = "Right";
|
||||||
LEFT = "Left",
|
|
||||||
RIGHT = "Right";
|
|
||||||
|
|
||||||
private final int margin;
|
private final int margin;
|
||||||
|
|
||||||
@ -51,32 +49,17 @@ public class LayoutBorderHorizontal implements Layout {
|
|||||||
if (child.getLayoutHint() == LEFT) {
|
if (child.getLayoutHint() == LEFT) {
|
||||||
childSize = child.getPreferredSize();
|
childSize = child.getPreferredSize();
|
||||||
left = childSize.x + margin;
|
left = childSize.x + margin;
|
||||||
child.setBounds(
|
child.setBounds(c.getX(), c.getY(), childSize.x, c.getHeight());
|
||||||
c.getX(),
|
|
||||||
c.getY(),
|
|
||||||
childSize.x,
|
|
||||||
c.getHeight()
|
|
||||||
);
|
|
||||||
} else if (child.getLayoutHint() == RIGHT) {
|
} else if (child.getLayoutHint() == RIGHT) {
|
||||||
childSize = child.getPreferredSize();
|
childSize = child.getPreferredSize();
|
||||||
right = childSize.x + margin;
|
right = childSize.x + margin;
|
||||||
child.setBounds(
|
child.setBounds(c.getX() + c.getWidth() - childSize.x, c.getY(), childSize.x, c.getHeight());
|
||||||
c.getX() + c.getWidth() - childSize.x,
|
|
||||||
c.getY(),
|
|
||||||
childSize.x,
|
|
||||||
c.getHeight()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Component child : c.getChildren()) {
|
for (Component child : c.getChildren()) {
|
||||||
if (child.getLayoutHint() == CENTER) {
|
if (child.getLayoutHint() == CENTER) {
|
||||||
child.setBounds(
|
child.setBounds(c.getX() + left, c.getY(), c.getWidth() - left - right, c.getHeight());
|
||||||
c.getX() + left,
|
|
||||||
c.getY(),
|
|
||||||
c.getWidth() - left - right,
|
|
||||||
c.getHeight()
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,7 @@ import ru.windcorp.progressia.client.graphics.gui.Layout;
|
|||||||
|
|
||||||
public class LayoutBorderVertical implements Layout {
|
public class LayoutBorderVertical implements Layout {
|
||||||
|
|
||||||
public static final String CENTER = "Center",
|
public static final String CENTER = "Center", UP = "Up", DOWN = "Down";
|
||||||
UP = "Up",
|
|
||||||
DOWN = "Down";
|
|
||||||
|
|
||||||
private final int margin;
|
private final int margin;
|
||||||
|
|
||||||
@ -51,32 +49,17 @@ public class LayoutBorderVertical implements Layout {
|
|||||||
if (child.getLayoutHint() == UP) {
|
if (child.getLayoutHint() == UP) {
|
||||||
childSize = child.getPreferredSize();
|
childSize = child.getPreferredSize();
|
||||||
top = childSize.y + margin;
|
top = childSize.y + margin;
|
||||||
child.setBounds(
|
child.setBounds(c.getX(), c.getY(), c.getWidth(), childSize.y);
|
||||||
c.getX(),
|
|
||||||
c.getY(),
|
|
||||||
c.getWidth(),
|
|
||||||
childSize.y
|
|
||||||
);
|
|
||||||
} else if (child.getLayoutHint() == DOWN) {
|
} else if (child.getLayoutHint() == DOWN) {
|
||||||
childSize = child.getPreferredSize();
|
childSize = child.getPreferredSize();
|
||||||
bottom = childSize.y + margin;
|
bottom = childSize.y + margin;
|
||||||
child.setBounds(
|
child.setBounds(c.getX(), c.getY() + c.getHeight() - childSize.y, c.getWidth(), childSize.y);
|
||||||
c.getX(),
|
|
||||||
c.getY() + c.getHeight() - childSize.y,
|
|
||||||
c.getWidth(),
|
|
||||||
childSize.y
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Component child : c.getChildren()) {
|
for (Component child : c.getChildren()) {
|
||||||
if (child.getLayoutHint() == CENTER) {
|
if (child.getLayoutHint() == CENTER) {
|
||||||
child.setBounds(
|
child.setBounds(c.getX(), c.getY() + top, c.getWidth(), c.getHeight() - top - bottom);
|
||||||
c.getX(),
|
|
||||||
c.getY() + top,
|
|
||||||
c.getWidth(),
|
|
||||||
c.getHeight() - top - bottom
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,7 @@ public class LayoutHorizontal implements Layout {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void layout(Component c) {
|
public void layout(Component c) {
|
||||||
int x = c.getX() + margin,
|
int x = c.getX() + margin, y = c.getY() + margin;
|
||||||
y = c.getY() + margin;
|
|
||||||
|
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
|
@ -43,8 +43,7 @@ public class LayoutVertical implements Layout {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void layout(Component c) {
|
public void layout(Component c) {
|
||||||
int x = c.getX() + margin,
|
int x = c.getX() + margin, y = c.getY() + c.getHeight();
|
||||||
y = c.getY() + c.getHeight();
|
|
||||||
|
|
||||||
synchronized (c.getChildren()) {
|
synchronized (c.getChildren()) {
|
||||||
for (Component child : c.getChildren()) {
|
for (Component child : c.getChildren()) {
|
||||||
|
@ -87,22 +87,14 @@ public class CursorMoveEvent extends CursorEvent {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CursorMoveEvent snapshot() {
|
public CursorMoveEvent snapshot() {
|
||||||
return new StaticMouseMoveEvent(
|
return new StaticMouseMoveEvent(getPreviousPosition(), getNewPosition(), getTime());
|
||||||
getPreviousPosition(),
|
|
||||||
getNewPosition(),
|
|
||||||
getTime()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class StaticMouseMoveEvent extends CursorMoveEvent {
|
private class StaticMouseMoveEvent extends CursorMoveEvent {
|
||||||
|
|
||||||
private final Vec2d previousPosition = new Vec2d();
|
private final Vec2d previousPosition = new Vec2d();
|
||||||
|
|
||||||
public StaticMouseMoveEvent(
|
public StaticMouseMoveEvent(Vec2d previousPosition, Vec2d newPosition, double time) {
|
||||||
Vec2d previousPosition,
|
|
||||||
Vec2d newPosition,
|
|
||||||
double time
|
|
||||||
) {
|
|
||||||
super(newPosition, time);
|
super(newPosition, time);
|
||||||
this.previousPosition.set(previousPosition.x, previousPosition.y);
|
this.previousPosition.set(previousPosition.x, previousPosition.y);
|
||||||
}
|
}
|
||||||
|
@ -67,11 +67,7 @@ public class FrameResizeEvent extends InputEvent {
|
|||||||
|
|
||||||
private final Vec2i previousSize;
|
private final Vec2i previousSize;
|
||||||
|
|
||||||
public StaticFrameResizeEvent(
|
public StaticFrameResizeEvent(Vec2i newSize, Vec2i previousSize, double time) {
|
||||||
Vec2i newSize,
|
|
||||||
Vec2i previousSize,
|
|
||||||
double time
|
|
||||||
) {
|
|
||||||
super(newSize, time);
|
super(newSize, time);
|
||||||
this.previousSize = previousSize;
|
this.previousSize = previousSize;
|
||||||
}
|
}
|
||||||
|
@ -27,13 +27,7 @@ public class KeyEvent extends InputEvent {
|
|||||||
protected int action;
|
protected int action;
|
||||||
protected int mods;
|
protected int mods;
|
||||||
|
|
||||||
protected KeyEvent(
|
protected KeyEvent(int key, int scancode, int action, int mods, double time) {
|
||||||
int key,
|
|
||||||
int scancode,
|
|
||||||
int action,
|
|
||||||
int mods,
|
|
||||||
double time
|
|
||||||
) {
|
|
||||||
super(time);
|
super(time);
|
||||||
this.key = key;
|
this.key = key;
|
||||||
this.scancode = scancode;
|
this.scancode = scancode;
|
||||||
|
@ -46,17 +46,12 @@ public class Keys {
|
|||||||
private static final String MOUSE_BUTTON_PREFIX = "GLFW_MOUSE_BUTTON_";
|
private static final String MOUSE_BUTTON_PREFIX = "GLFW_MOUSE_BUTTON_";
|
||||||
|
|
||||||
private static final Set<String> IGNORE_FIELDS = new HashSet<>(
|
private static final Set<String> IGNORE_FIELDS = new HashSet<>(
|
||||||
Arrays.asList(
|
Arrays.asList("GLFW_KEY_UNKNOWN", "GLFW_KEY_LAST", "GLFW_MOUSE_BUTTON_LAST", "GLFW_MOUSE_BUTTON_1", // Alias
|
||||||
"GLFW_KEY_UNKNOWN",
|
|
||||||
"GLFW_KEY_LAST",
|
|
||||||
"GLFW_MOUSE_BUTTON_LAST",
|
|
||||||
"GLFW_MOUSE_BUTTON_1", // Alias
|
|
||||||
// for
|
// for
|
||||||
// LEFT
|
// LEFT
|
||||||
"GLFW_MOUSE_BUTTON_2", // Alias for RIGHT
|
"GLFW_MOUSE_BUTTON_2", // Alias for RIGHT
|
||||||
"GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE
|
"GLFW_MOUSE_BUTTON_3" // Alias for MIDDLE
|
||||||
)
|
));
|
||||||
);
|
|
||||||
|
|
||||||
static {
|
static {
|
||||||
initializeDictionary();
|
initializeDictionary();
|
||||||
@ -100,14 +95,8 @@ public class Keys {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (CODES_TO_NAMES.containsKey(value)) {
|
if (CODES_TO_NAMES.containsKey(value)) {
|
||||||
throw CrashReports.report(
|
throw CrashReports.report(null, "Duplicate keys: %s and %s both map to %d(0x%s)", CODES_TO_NAMES.get(value),
|
||||||
null,
|
name, value, Integer.toHexString(value));
|
||||||
"Duplicate keys: %s and %s both map to %d(0x%s)",
|
|
||||||
CODES_TO_NAMES.get(value),
|
|
||||||
name,
|
|
||||||
value,
|
|
||||||
Integer.toHexString(value)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CODES_TO_NAMES.put(value, name);
|
CODES_TO_NAMES.put(value, name);
|
||||||
|
@ -31,28 +31,21 @@ public class InputBus {
|
|||||||
private final boolean handleConsumed;
|
private final boolean handleConsumed;
|
||||||
private final InputListener<?> listener;
|
private final InputListener<?> listener;
|
||||||
|
|
||||||
public WrappedListener(
|
public WrappedListener(Class<?> type, boolean handleConsumed, InputListener<?> listener) {
|
||||||
Class<?> type,
|
|
||||||
boolean handleConsumed,
|
|
||||||
InputListener<?> listener
|
|
||||||
) {
|
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.handleConsumed = handleConsumed;
|
this.handleConsumed = handleConsumed;
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handles(Input input) {
|
private boolean handles(Input input) {
|
||||||
return (!input.isConsumed() || handleConsumed) &&
|
return (!input.isConsumed() || handleConsumed) && type.isInstance(input.getEvent());
|
||||||
type.isInstance(input.getEvent());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void handle(Input input) {
|
public void handle(Input input) {
|
||||||
if (handles(input)) {
|
if (handles(input)) {
|
||||||
boolean consumed = ((InputListener<InputEvent>) listener)
|
boolean consumed = ((InputListener<InputEvent>) listener)
|
||||||
.handle(
|
.handle((InputEvent) type.cast(input.getEvent()));
|
||||||
(InputEvent) type.cast(input.getEvent())
|
|
||||||
);
|
|
||||||
|
|
||||||
input.setConsumed(consumed);
|
input.setConsumed(consumed);
|
||||||
}
|
}
|
||||||
@ -66,18 +59,12 @@ public class InputBus {
|
|||||||
listeners.forEach(l -> l.handle(input));
|
listeners.forEach(l -> l.handle(input));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends InputEvent> void register(
|
public <T extends InputEvent> void register(Class<? extends T> type, boolean handlesConsumed,
|
||||||
Class<? extends T> type,
|
InputListener<T> listener) {
|
||||||
boolean handlesConsumed,
|
|
||||||
InputListener<T> listener
|
|
||||||
) {
|
|
||||||
listeners.add(new WrappedListener(type, handlesConsumed, listener));
|
listeners.add(new WrappedListener(type, handlesConsumed, listener));
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends InputEvent> void register(
|
public <T extends InputEvent> void register(Class<? extends T> type, InputListener<T> listener) {
|
||||||
Class<? extends T> type,
|
|
||||||
InputListener<T> listener
|
|
||||||
) {
|
|
||||||
register(type, false, listener);
|
register(type, false, listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,22 +33,14 @@ public abstract class DynamicModel extends Model {
|
|||||||
private final Mat4[] transforms;
|
private final Mat4[] transforms;
|
||||||
private final boolean[] dynamics;
|
private final boolean[] dynamics;
|
||||||
|
|
||||||
public DynamicModel(
|
public DynamicModel(Renderable[] parts, Mat4[] transforms, boolean[] dynamic) {
|
||||||
Renderable[] parts,
|
|
||||||
Mat4[] transforms,
|
|
||||||
boolean[] dynamic
|
|
||||||
) {
|
|
||||||
super(parts);
|
super(parts);
|
||||||
this.transforms = transforms;
|
this.transforms = transforms;
|
||||||
this.dynamics = dynamic;
|
this.dynamics = dynamic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public DynamicModel(Builder builder) {
|
public DynamicModel(Builder builder) {
|
||||||
this(
|
this(builder.getParts(), builder.getTransforms(), builder.getDynamics());
|
||||||
builder.getParts(),
|
|
||||||
builder.getTransforms(),
|
|
||||||
builder.getDynamics()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -78,11 +70,7 @@ public abstract class DynamicModel extends Model {
|
|||||||
protected Builder() {
|
protected Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Builder addPart(
|
private Builder addPart(Renderable part, Mat4 transform, boolean isDynamic) {
|
||||||
Renderable part,
|
|
||||||
Mat4 transform,
|
|
||||||
boolean isDynamic
|
|
||||||
) {
|
|
||||||
parts.add(Objects.requireNonNull(part, "part"));
|
parts.add(Objects.requireNonNull(part, "part"));
|
||||||
transforms.add(Objects.requireNonNull(transform, "transform"));
|
transforms.add(Objects.requireNonNull(transform, "transform"));
|
||||||
dynamics.add(isDynamic);
|
dynamics.add(isDynamic);
|
||||||
@ -90,22 +78,15 @@ public abstract class DynamicModel extends Model {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addStaticPart(
|
public Builder addStaticPart(Renderable part, Mat4 transform) {
|
||||||
Renderable part,
|
|
||||||
Mat4 transform
|
|
||||||
) {
|
|
||||||
return addPart(part, new Mat4(transform), false);
|
return addPart(part, new Mat4(transform), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addDynamicPart(
|
public Builder addDynamicPart(Renderable part) {
|
||||||
Renderable part
|
|
||||||
) {
|
|
||||||
return addPart(part, new Mat4(), true);
|
return addPart(part, new Mat4(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addStaticPart(
|
public Builder addStaticPart(Renderable part) {
|
||||||
Renderable part
|
|
||||||
) {
|
|
||||||
return addStaticPart(part, IDENTITY);
|
return addStaticPart(part, IDENTITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,23 +37,13 @@ public class LambdaModel extends DynamicModel {
|
|||||||
|
|
||||||
private final TransformGetter[] getters;
|
private final TransformGetter[] getters;
|
||||||
|
|
||||||
public LambdaModel(
|
public LambdaModel(Renderable[] parts, Mat4[] transforms, boolean[] dynamic, TransformGetter[] getters) {
|
||||||
Renderable[] parts,
|
|
||||||
Mat4[] transforms,
|
|
||||||
boolean[] dynamic,
|
|
||||||
TransformGetter[] getters
|
|
||||||
) {
|
|
||||||
super(parts, transforms, dynamic);
|
super(parts, transforms, dynamic);
|
||||||
this.getters = getters;
|
this.getters = getters;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LambdaModel(Builder builder) {
|
public LambdaModel(Builder builder) {
|
||||||
this(
|
this(builder.getParts(), builder.getTransforms(), builder.getDynamics(), builder.getGetters());
|
||||||
builder.getParts(),
|
|
||||||
builder.getTransforms(),
|
|
||||||
builder.getDynamics(),
|
|
||||||
builder.getGetters()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -75,11 +65,7 @@ public class LambdaModel extends DynamicModel {
|
|||||||
protected Builder() {
|
protected Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Builder addPart(
|
private Builder addPart(Renderable part, Mat4 transform, TransformGetter getter) {
|
||||||
Renderable part,
|
|
||||||
Mat4 transform,
|
|
||||||
TransformGetter getter
|
|
||||||
) {
|
|
||||||
parts.add(Objects.requireNonNull(part, "part"));
|
parts.add(Objects.requireNonNull(part, "part"));
|
||||||
transforms.add(Objects.requireNonNull(transform, "transform"));
|
transforms.add(Objects.requireNonNull(transform, "transform"));
|
||||||
dynamics.add(getter != null);
|
dynamics.add(getter != null);
|
||||||
@ -88,23 +74,15 @@ public class LambdaModel extends DynamicModel {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addStaticPart(
|
public Builder addStaticPart(Renderable part, Mat4 transform) {
|
||||||
Renderable part,
|
|
||||||
Mat4 transform
|
|
||||||
) {
|
|
||||||
return addPart(part, new Mat4(transform), null);
|
return addPart(part, new Mat4(transform), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addDynamicPart(
|
public Builder addDynamicPart(Renderable part, TransformGetter getter) {
|
||||||
Renderable part,
|
|
||||||
TransformGetter getter
|
|
||||||
) {
|
|
||||||
return addPart(part, new Mat4(), getter);
|
return addPart(part, new Mat4(), getter);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addStaticPart(
|
public Builder addStaticPart(Renderable part) {
|
||||||
Renderable part
|
|
||||||
) {
|
|
||||||
return addStaticPart(part, IDENTITY);
|
return addStaticPart(part, IDENTITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -127,12 +105,8 @@ public class LambdaModel extends DynamicModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static LambdaModel animate(Renderable model, TransformGetter transform) {
|
public static LambdaModel animate(Renderable model, TransformGetter transform) {
|
||||||
return new LambdaModel(
|
return new LambdaModel(new Renderable[] { model }, new Mat4[] { new Mat4() }, new boolean[] { true },
|
||||||
new Renderable[] { model },
|
new TransformGetter[] { transform });
|
||||||
new Mat4[] { new Mat4() },
|
|
||||||
new boolean[] { true },
|
|
||||||
new TransformGetter[] { transform }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,7 @@ public class ShapePartGroup {
|
|||||||
for (int i = start; i < end; ++i) {
|
for (int i = start; i < end; ++i) {
|
||||||
ShapePart face = faces[i];
|
ShapePart face = faces[i];
|
||||||
|
|
||||||
assert this.texture == null
|
assert this.texture == null ? (face.getTexture() == null)
|
||||||
? (face.getTexture() == null)
|
|
||||||
: (face.getTexture().getSprite().getPrimitive() == this.texture);
|
: (face.getTexture().getSprite().getPrimitive() == this.texture);
|
||||||
|
|
||||||
indexCount += face.getIndexCount();
|
indexCount += face.getIndexCount();
|
||||||
|
@ -28,15 +28,10 @@ public class ShapeRenderHelper {
|
|||||||
protected static final int TRANSFORM_STACK_SIZE = 64;
|
protected static final int TRANSFORM_STACK_SIZE = 64;
|
||||||
protected static final int COLOR_MULTIPLIER_STACK_SIZE = TRANSFORM_STACK_SIZE;
|
protected static final int COLOR_MULTIPLIER_STACK_SIZE = TRANSFORM_STACK_SIZE;
|
||||||
|
|
||||||
protected final StashingStack<Mat4> transformStack = new StashingStack<>(
|
protected final StashingStack<Mat4> transformStack = new StashingStack<>(TRANSFORM_STACK_SIZE, Mat4::new);
|
||||||
TRANSFORM_STACK_SIZE,
|
|
||||||
Mat4::new
|
|
||||||
);
|
|
||||||
|
|
||||||
protected final StashingStack<Vec4> colorMultiplierStack = new StashingStack<>(
|
protected final StashingStack<Vec4> colorMultiplierStack = new StashingStack<>(COLOR_MULTIPLIER_STACK_SIZE,
|
||||||
COLOR_MULTIPLIER_STACK_SIZE,
|
Vec4::new);
|
||||||
Vec4::new
|
|
||||||
);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
transformStack.push().identity();
|
transformStack.push().identity();
|
||||||
|
@ -53,8 +53,7 @@ public class ShapeRenderProgram extends Program {
|
|||||||
POSITIONS_ATTRIBUTE_NAME = "inputPositions",
|
POSITIONS_ATTRIBUTE_NAME = "inputPositions",
|
||||||
UNIFORM_COLOR_MULTIPLER_ATTRIBUTE_NAME = "uniformColorMultiplier",
|
UNIFORM_COLOR_MULTIPLER_ATTRIBUTE_NAME = "uniformColorMultiplier",
|
||||||
ATTRIBUTE_COLOR_MULTIPLER_ATTRIBUTE_NAME = "inputColorMultiplier",
|
ATTRIBUTE_COLOR_MULTIPLER_ATTRIBUTE_NAME = "inputColorMultiplier",
|
||||||
TEXTURE_COORDS_ATTRIBUTE_NAME = "inputTextureCoords",
|
TEXTURE_COORDS_ATTRIBUTE_NAME = "inputTextureCoords", USE_TEXTURE_UNIFORM_NAME = "useTexture",
|
||||||
USE_TEXTURE_UNIFORM_NAME = "useTexture",
|
|
||||||
TEXTURE_SLOT_UNIFORM_NAME = "textureSlot";
|
TEXTURE_SLOT_UNIFORM_NAME = "textureSlot";
|
||||||
|
|
||||||
private final Uniform4Matrix finalTransformUniform;
|
private final Uniform4Matrix finalTransformUniform;
|
||||||
@ -65,21 +64,11 @@ public class ShapeRenderProgram extends Program {
|
|||||||
private final Uniform1Int useTextureUniform;
|
private final Uniform1Int useTextureUniform;
|
||||||
private final Uniform1Int textureSlotUniform;
|
private final Uniform1Int textureSlotUniform;
|
||||||
|
|
||||||
public ShapeRenderProgram(
|
public ShapeRenderProgram(String[] vertexShaderResources, String[] fragmentShaderResources) {
|
||||||
String[] vertexShaderResources,
|
super(new CombinedShader(attachVertexShader(vertexShaderResources)),
|
||||||
String[] fragmentShaderResources
|
new CombinedShader(attachFragmentShader(fragmentShaderResources)));
|
||||||
) {
|
|
||||||
super(
|
|
||||||
new CombinedShader(
|
|
||||||
attachVertexShader(vertexShaderResources)
|
|
||||||
),
|
|
||||||
new CombinedShader(
|
|
||||||
attachFragmentShader(fragmentShaderResources)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.finalTransformUniform = getUniform(FINAL_TRANSFORM_UNIFORM_NAME)
|
this.finalTransformUniform = getUniform(FINAL_TRANSFORM_UNIFORM_NAME).as4Matrix();
|
||||||
.as4Matrix();
|
|
||||||
|
|
||||||
this.positionsAttribute = getAttribute(POSITIONS_ATTRIBUTE_NAME).asVertexArray();
|
this.positionsAttribute = getAttribute(POSITIONS_ATTRIBUTE_NAME).asVertexArray();
|
||||||
|
|
||||||
@ -89,11 +78,9 @@ public class ShapeRenderProgram extends Program {
|
|||||||
|
|
||||||
this.textureCoordsAttribute = getAttribute(TEXTURE_COORDS_ATTRIBUTE_NAME).asVertexArray();
|
this.textureCoordsAttribute = getAttribute(TEXTURE_COORDS_ATTRIBUTE_NAME).asVertexArray();
|
||||||
|
|
||||||
this.useTextureUniform = getUniform(USE_TEXTURE_UNIFORM_NAME)
|
this.useTextureUniform = getUniform(USE_TEXTURE_UNIFORM_NAME).as1Int();
|
||||||
.as1Int();
|
|
||||||
|
|
||||||
this.textureSlotUniform = getUniform(TEXTURE_SLOT_UNIFORM_NAME)
|
this.textureSlotUniform = getUniform(TEXTURE_SLOT_UNIFORM_NAME).as1Int();
|
||||||
.as1Int();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] attachVertexShader(String[] others) {
|
private static String[] attachVertexShader(String[] others) {
|
||||||
@ -104,10 +91,7 @@ public class ShapeRenderProgram extends Program {
|
|||||||
return ObjectArrays.concat(SHAPE_FRAGMENT_SHADER_RESOURCE, others);
|
return ObjectArrays.concat(SHAPE_FRAGMENT_SHADER_RESOURCE, others);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(
|
public void render(ShapeRenderHelper helper, Shape shape) {
|
||||||
ShapeRenderHelper helper,
|
|
||||||
Shape shape
|
|
||||||
) {
|
|
||||||
use();
|
use();
|
||||||
configure(helper);
|
configure(helper);
|
||||||
|
|
||||||
@ -145,34 +129,13 @@ public class ShapeRenderProgram extends Program {
|
|||||||
int vertexStride = getBytesPerVertex();
|
int vertexStride = getBytesPerVertex();
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
positionsAttribute.set(
|
positionsAttribute.set(3, GL11.GL_FLOAT, false, vertexStride, vertices, offset);
|
||||||
3,
|
|
||||||
GL11.GL_FLOAT,
|
|
||||||
false,
|
|
||||||
vertexStride,
|
|
||||||
vertices,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
offset += 3 * Float.BYTES;
|
offset += 3 * Float.BYTES;
|
||||||
|
|
||||||
colorsAttribute.set(
|
colorsAttribute.set(4, GL11.GL_FLOAT, false, vertexStride, vertices, offset);
|
||||||
4,
|
|
||||||
GL11.GL_FLOAT,
|
|
||||||
false,
|
|
||||||
vertexStride,
|
|
||||||
vertices,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
offset += 4 * Float.BYTES;
|
offset += 4 * Float.BYTES;
|
||||||
|
|
||||||
textureCoordsAttribute.set(
|
textureCoordsAttribute.set(2, GL11.GL_FLOAT, false, vertexStride, vertices, offset);
|
||||||
2,
|
|
||||||
GL11.GL_FLOAT,
|
|
||||||
false,
|
|
||||||
vertexStride,
|
|
||||||
vertices,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
offset += 2 * Float.BYTES;
|
offset += 2 * Float.BYTES;
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
@ -193,12 +156,8 @@ public class ShapeRenderProgram extends Program {
|
|||||||
useTextureUniform.set(0);
|
useTextureUniform.set(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
GL11.glDrawElements(
|
GL11.glDrawElements(GL11.GL_TRIANGLES, group.getIndexCount(), GL11.GL_UNSIGNED_SHORT,
|
||||||
GL11.GL_TRIANGLES,
|
group.getByteOffsetOfIndices());
|
||||||
group.getIndexCount(),
|
|
||||||
GL11.GL_UNSIGNED_SHORT,
|
|
||||||
group.getByteOffsetOfIndices()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getBytesPerVertex() {
|
public int getBytesPerVertex() {
|
||||||
@ -220,13 +179,9 @@ public class ShapeRenderProgram extends Program {
|
|||||||
Sprite sprite = face.getTexture().getSprite();
|
Sprite sprite = face.getTexture().getSprite();
|
||||||
|
|
||||||
for (int i = 0; i < face.getVertexCount(); i++) {
|
for (int i = 0; i < face.getVertexCount(); i++) {
|
||||||
int offset = vertices.position() + i * getBytesPerVertex() + (3 * Float.BYTES +
|
int offset = vertices.position() + i * getBytesPerVertex() + (3 * Float.BYTES + 4 * Float.BYTES);
|
||||||
4 * Float.BYTES);
|
|
||||||
|
|
||||||
v.set(
|
v.set(vertices.getFloat(offset + 0 * Float.BYTES), vertices.getFloat(offset + 1 * Float.BYTES));
|
||||||
vertices.getFloat(offset + 0 * Float.BYTES),
|
|
||||||
vertices.getFloat(offset + 1 * Float.BYTES)
|
|
||||||
);
|
|
||||||
|
|
||||||
v.mul(sprite.getSize()).add(sprite.getStart());
|
v.mul(sprite.getSize()).add(sprite.getStart());
|
||||||
|
|
||||||
@ -244,34 +199,11 @@ public class ShapeRenderProgram extends Program {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static interface VertexBuilder {
|
public static interface VertexBuilder {
|
||||||
VertexBuilder addVertex(
|
VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float tx, float ty);
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
float z,
|
|
||||||
float r,
|
|
||||||
float g,
|
|
||||||
float b,
|
|
||||||
float tx,
|
|
||||||
float ty
|
|
||||||
);
|
|
||||||
|
|
||||||
VertexBuilder addVertex(
|
VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float a, float tx, float ty);
|
||||||
float x,
|
|
||||||
float y,
|
|
||||||
float z,
|
|
||||||
float r,
|
|
||||||
float g,
|
|
||||||
float b,
|
|
||||||
float a,
|
|
||||||
float tx,
|
|
||||||
float ty
|
|
||||||
);
|
|
||||||
|
|
||||||
VertexBuilder addVertex(
|
VertexBuilder addVertex(Vec3 position, Vec4 colorMultiplier, Vec2 textureCoords);
|
||||||
Vec3 position,
|
|
||||||
Vec4 colorMultiplier,
|
|
||||||
Vec2 textureCoords
|
|
||||||
);
|
|
||||||
|
|
||||||
ByteBuffer assemble();
|
ByteBuffer assemble();
|
||||||
}
|
}
|
||||||
@ -293,84 +225,35 @@ public class ShapeRenderProgram extends Program {
|
|||||||
private final List<Vertex> vertices = new ArrayList<>();
|
private final List<Vertex> vertices = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexBuilder addVertex(
|
public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float a, float tx,
|
||||||
float x,
|
float ty) {
|
||||||
float y,
|
vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, a), new Vec2(tx, ty)));
|
||||||
float z,
|
|
||||||
float r,
|
|
||||||
float g,
|
|
||||||
float b,
|
|
||||||
float a,
|
|
||||||
float tx,
|
|
||||||
float ty
|
|
||||||
) {
|
|
||||||
vertices.add(
|
|
||||||
new Vertex(
|
|
||||||
new Vec3(x, y, z),
|
|
||||||
new Vec4(r, g, b, a),
|
|
||||||
new Vec2(tx, ty)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexBuilder addVertex(
|
public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float tx, float ty) {
|
||||||
float x,
|
vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, 1f), new Vec2(tx, ty)));
|
||||||
float y,
|
|
||||||
float z,
|
|
||||||
float r,
|
|
||||||
float g,
|
|
||||||
float b,
|
|
||||||
float tx,
|
|
||||||
float ty
|
|
||||||
) {
|
|
||||||
vertices.add(
|
|
||||||
new Vertex(
|
|
||||||
new Vec3(x, y, z),
|
|
||||||
new Vec4(r, g, b, 1f),
|
|
||||||
new Vec2(tx, ty)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexBuilder addVertex(
|
public VertexBuilder addVertex(Vec3 position, Vec4 colorMultiplier, Vec2 textureCoords) {
|
||||||
Vec3 position,
|
vertices.add(new Vertex(new Vec3(position), new Vec4(colorMultiplier), new Vec2(textureCoords)));
|
||||||
Vec4 colorMultiplier,
|
|
||||||
Vec2 textureCoords
|
|
||||||
) {
|
|
||||||
vertices.add(
|
|
||||||
new Vertex(
|
|
||||||
new Vec3(position),
|
|
||||||
new Vec4(colorMultiplier),
|
|
||||||
new Vec2(textureCoords)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer assemble() {
|
public ByteBuffer assemble() {
|
||||||
ByteBuffer result = BufferUtils.createByteBuffer(
|
ByteBuffer result = BufferUtils.createByteBuffer(DEFAULT_BYTES_PER_VERTEX * vertices.size());
|
||||||
DEFAULT_BYTES_PER_VERTEX * vertices.size()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (Vertex v : vertices) {
|
for (Vertex v : vertices) {
|
||||||
result
|
result.putFloat(v.position.x).putFloat(v.position.y).putFloat(v.position.z)
|
||||||
.putFloat(v.position.x)
|
.putFloat(v.colorMultiplier.x).putFloat(v.colorMultiplier.y).putFloat(v.colorMultiplier.z)
|
||||||
.putFloat(v.position.y)
|
.putFloat(v.colorMultiplier.w).putFloat(v.textureCoords.x).putFloat(v.textureCoords.y);
|
||||||
.putFloat(v.position.z)
|
|
||||||
.putFloat(v.colorMultiplier.x)
|
|
||||||
.putFloat(v.colorMultiplier.y)
|
|
||||||
.putFloat(v.colorMultiplier.z)
|
|
||||||
.putFloat(v.colorMultiplier.w)
|
|
||||||
.putFloat(v.textureCoords.x)
|
|
||||||
.putFloat(v.textureCoords.y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.flip();
|
result.flip();
|
||||||
|
@ -30,10 +30,7 @@ public class StaticModel extends Model {
|
|||||||
|
|
||||||
private final Mat4[] transforms;
|
private final Mat4[] transforms;
|
||||||
|
|
||||||
public StaticModel(
|
public StaticModel(Renderable[] parts, Mat4[] transforms) {
|
||||||
Renderable[] parts,
|
|
||||||
Mat4[] transforms
|
|
||||||
) {
|
|
||||||
super(parts);
|
super(parts);
|
||||||
this.transforms = transforms;
|
this.transforms = transforms;
|
||||||
}
|
}
|
||||||
@ -55,19 +52,14 @@ public class StaticModel extends Model {
|
|||||||
protected Builder() {
|
protected Builder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addPart(
|
public Builder addPart(Renderable part, Mat4 transform) {
|
||||||
Renderable part,
|
|
||||||
Mat4 transform
|
|
||||||
) {
|
|
||||||
parts.add(Objects.requireNonNull(part, "part"));
|
parts.add(Objects.requireNonNull(part, "part"));
|
||||||
transforms.add(Objects.requireNonNull(transform, "transform"));
|
transforms.add(Objects.requireNonNull(transform, "transform"));
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Builder addPart(
|
public Builder addPart(Renderable part) {
|
||||||
Renderable part
|
|
||||||
) {
|
|
||||||
return addPart(part, IDENTITY);
|
return addPart(part, IDENTITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,11 +87,8 @@ public class Atlases {
|
|||||||
|
|
||||||
editor.draw(data, nextX, nextY);
|
editor.draw(data, nextX, nextY);
|
||||||
|
|
||||||
Sprite result = new Sprite(
|
Sprite result = new Sprite(getPrimitive(), toPrimitiveCoords(nextX, nextY),
|
||||||
getPrimitive(),
|
toPrimitiveCoords(width, height));
|
||||||
toPrimitiveCoords(nextX, nextY),
|
|
||||||
toPrimitiveCoords(width, height)
|
|
||||||
);
|
|
||||||
|
|
||||||
nextX += width;
|
nextX += width;
|
||||||
|
|
||||||
|
@ -44,9 +44,7 @@ public class SimpleTextures {
|
|||||||
try {
|
try {
|
||||||
TextureDataEditor data = TextureLoader.loadPixels(resource, SETTINGS);
|
TextureDataEditor data = TextureLoader.loadPixels(resource, SETTINGS);
|
||||||
|
|
||||||
return new SimpleTexture(
|
return new SimpleTexture(new Sprite(new TexturePrimitive(data.getData())));
|
||||||
new Sprite(new TexturePrimitive(data.getData()))
|
|
||||||
);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw CrashReports.report(e, "Could not load texture %s", resource);
|
throw CrashReports.report(e, "Could not load texture %s", resource);
|
||||||
}
|
}
|
||||||
|
@ -38,14 +38,8 @@ public class Sprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Sprite(TexturePrimitive primitive) {
|
public Sprite(TexturePrimitive primitive) {
|
||||||
this(
|
this(primitive, ORIGIN, new Vec2(primitive.getWidth() / (float) primitive.getBufferWidth(),
|
||||||
primitive,
|
primitive.getHeight() / (float) primitive.getBufferHeight()));
|
||||||
ORIGIN,
|
|
||||||
new Vec2(
|
|
||||||
primitive.getWidth() / (float) primitive.getBufferWidth(),
|
|
||||||
primitive.getHeight() / (float) primitive.getBufferHeight()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TexturePrimitive getPrimitive() {
|
public TexturePrimitive getPrimitive() {
|
||||||
|
@ -35,14 +35,8 @@ class TextureData {
|
|||||||
private final int width;
|
private final int width;
|
||||||
private final int height;
|
private final int height;
|
||||||
|
|
||||||
public TextureData(
|
public TextureData(ByteBuffer data, int bufferWidth, int bufferHeight, int width, int height,
|
||||||
ByteBuffer data,
|
TextureSettings settings) {
|
||||||
int bufferWidth,
|
|
||||||
int bufferHeight,
|
|
||||||
int width,
|
|
||||||
int height,
|
|
||||||
TextureSettings settings
|
|
||||||
) {
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
@ -66,8 +60,7 @@ class TextureData {
|
|||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||||
|
|
||||||
glTexImage2D(
|
glTexImage2D(GL_TEXTURE_2D, // Load 2D image
|
||||||
GL_TEXTURE_2D, // Load 2D image
|
|
||||||
0, // Not mipmapped
|
0, // Not mipmapped
|
||||||
GL_RGBA, // Use RGBA
|
GL_RGBA, // Use RGBA
|
||||||
bufferWidth, // Width
|
bufferWidth, // Width
|
||||||
|
@ -28,21 +28,10 @@ public class TextureDataEditor {
|
|||||||
|
|
||||||
protected final TextureData data;
|
protected final TextureData data;
|
||||||
|
|
||||||
public TextureDataEditor(
|
public TextureDataEditor(int bufferWidth, int bufferHeight, int contentWidth, int contentHeight,
|
||||||
int bufferWidth,
|
TextureSettings settings) {
|
||||||
int bufferHeight,
|
this.data = new TextureData(BufferUtils.createByteBuffer(bufferWidth * bufferHeight * 4), bufferWidth,
|
||||||
int contentWidth,
|
bufferHeight, contentWidth, contentHeight, settings);
|
||||||
int contentHeight,
|
|
||||||
TextureSettings settings
|
|
||||||
) {
|
|
||||||
this.data = new TextureData(
|
|
||||||
BufferUtils.createByteBuffer(bufferWidth * bufferHeight * 4),
|
|
||||||
bufferWidth,
|
|
||||||
bufferHeight,
|
|
||||||
contentWidth,
|
|
||||||
contentHeight,
|
|
||||||
settings
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureDataEditor(TextureData data) {
|
public TextureDataEditor(TextureData data) {
|
||||||
@ -61,21 +50,13 @@ public class TextureDataEditor {
|
|||||||
TextureData t = getData();
|
TextureData t = getData();
|
||||||
|
|
||||||
ByteBuffer fromBuffer = getBuffer();
|
ByteBuffer fromBuffer = getBuffer();
|
||||||
ByteBuffer toBuffer = BufferUtils.createByteBuffer(
|
ByteBuffer toBuffer = BufferUtils.createByteBuffer(fromBuffer.capacity());
|
||||||
fromBuffer.capacity()
|
|
||||||
);
|
|
||||||
|
|
||||||
copy(fromBuffer, 0, fromBuffer.capacity(), toBuffer);
|
copy(fromBuffer, 0, fromBuffer.capacity(), toBuffer);
|
||||||
toBuffer.clear();
|
toBuffer.clear();
|
||||||
|
|
||||||
return new TextureData(
|
return new TextureData(toBuffer, t.getBufferWidth(), t.getBufferHeight(), t.getContentWidth(),
|
||||||
toBuffer,
|
t.getContentHeight(), t.getSettings());
|
||||||
t.getBufferWidth(),
|
|
||||||
t.getBufferHeight(),
|
|
||||||
t.getContentWidth(),
|
|
||||||
t.getContentHeight(),
|
|
||||||
t.getSettings()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureData createSnapshot(TextureData output) {
|
public TextureData createSnapshot(TextureData output) {
|
||||||
@ -114,16 +95,7 @@ public class TextureDataEditor {
|
|||||||
return getData().getSettings();
|
return getData().getSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(
|
public void draw(ByteBuffer src, int srcWidth, int srcX, int srcY, int dstX, int dstY, int width, int height) {
|
||||||
ByteBuffer src,
|
|
||||||
int srcWidth,
|
|
||||||
int srcX,
|
|
||||||
int srcY,
|
|
||||||
int dstX,
|
|
||||||
int dstY,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
) {
|
|
||||||
ByteBuffer dst = getBuffer();
|
ByteBuffer dst = getBuffer();
|
||||||
|
|
||||||
int position = src.position();
|
int position = src.position();
|
||||||
@ -148,77 +120,20 @@ public class TextureDataEditor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(
|
public void draw(TextureData source, int srcX, int srcY, int dstX, int dstY, int width, int height) {
|
||||||
TextureData source,
|
draw(source.getData(), source.getBufferWidth(), srcX, srcY, dstX, dstY, width, height);
|
||||||
int srcX,
|
|
||||||
int srcY,
|
|
||||||
int dstX,
|
|
||||||
int dstY,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
) {
|
|
||||||
draw(
|
|
||||||
source.getData(),
|
|
||||||
source.getBufferWidth(),
|
|
||||||
srcX,
|
|
||||||
srcY,
|
|
||||||
dstX,
|
|
||||||
dstY,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(
|
public void draw(TextureData source, int dstX, int dstY) {
|
||||||
TextureData source,
|
draw(source, 0, 0, dstX, dstY, source.getContentWidth(), source.getContentHeight());
|
||||||
int dstX,
|
|
||||||
int dstY
|
|
||||||
) {
|
|
||||||
draw(
|
|
||||||
source,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
dstX,
|
|
||||||
dstY,
|
|
||||||
source.getContentWidth(),
|
|
||||||
source.getContentHeight()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(
|
public void draw(TextureDataEditor source, int srcX, int srcY, int dstX, int dstY, int width, int height) {
|
||||||
TextureDataEditor source,
|
draw(source.getData(), srcX, srcY, dstX, dstY, width, height);
|
||||||
int srcX,
|
|
||||||
int srcY,
|
|
||||||
int dstX,
|
|
||||||
int dstY,
|
|
||||||
int width,
|
|
||||||
int height
|
|
||||||
) {
|
|
||||||
draw(
|
|
||||||
source.getData(),
|
|
||||||
srcX,
|
|
||||||
srcY,
|
|
||||||
dstX,
|
|
||||||
dstY,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void draw(
|
public void draw(TextureDataEditor source, int dstX, int dstY) {
|
||||||
TextureDataEditor source,
|
draw(source, 0, 0, dstX, dstY, source.getContentWidth(), source.getContentHeight());
|
||||||
int dstX,
|
|
||||||
int dstY
|
|
||||||
) {
|
|
||||||
draw(
|
|
||||||
source,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
dstX,
|
|
||||||
dstY,
|
|
||||||
source.getContentWidth(),
|
|
||||||
source.getContentHeight()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPixel(int x, int y, int color) {
|
public void setPixel(int x, int y, int color) {
|
||||||
@ -237,12 +152,7 @@ public class TextureDataEditor {
|
|||||||
buffer.limit(buffer.position() + length * BYTES_PER_PIXEL);
|
buffer.limit(buffer.position() + length * BYTES_PER_PIXEL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void copy(
|
private static void copy(ByteBuffer src, int srcStart, int srcEnd, ByteBuffer dst) {
|
||||||
ByteBuffer src,
|
|
||||||
int srcStart,
|
|
||||||
int srcEnd,
|
|
||||||
ByteBuffer dst
|
|
||||||
) {
|
|
||||||
int position = src.position();
|
int position = src.position();
|
||||||
int limit = src.limit();
|
int limit = src.limit();
|
||||||
|
|
||||||
|
@ -31,11 +31,7 @@ import ru.windcorp.progressia.common.util.BinUtil;
|
|||||||
|
|
||||||
public class TextureLoader {
|
public class TextureLoader {
|
||||||
|
|
||||||
public static TextureDataEditor loadPixels(
|
public static TextureDataEditor loadPixels(InputStream compressed, TextureSettings settings) throws IOException {
|
||||||
InputStream compressed,
|
|
||||||
TextureSettings settings
|
|
||||||
)
|
|
||||||
throws IOException {
|
|
||||||
BufferedImage readResult = ImageIO.read(compressed);
|
BufferedImage readResult = ImageIO.read(compressed);
|
||||||
|
|
||||||
int width = readResult.getWidth();
|
int width = readResult.getWidth();
|
||||||
@ -44,10 +40,7 @@ public class TextureLoader {
|
|||||||
int bufferWidth = BinUtil.roundToGreaterPowerOf2(width);
|
int bufferWidth = BinUtil.roundToGreaterPowerOf2(width);
|
||||||
int bufferHeight = BinUtil.roundToGreaterPowerOf2(height);
|
int bufferHeight = BinUtil.roundToGreaterPowerOf2(height);
|
||||||
|
|
||||||
WritableRaster raster = TextureUtil.createRaster(
|
WritableRaster raster = TextureUtil.createRaster(bufferWidth, bufferHeight);
|
||||||
bufferWidth,
|
|
||||||
bufferHeight
|
|
||||||
);
|
|
||||||
|
|
||||||
BufferedImage canvas = TextureUtil.createCanvas(raster);
|
BufferedImage canvas = TextureUtil.createCanvas(raster);
|
||||||
|
|
||||||
@ -56,49 +49,22 @@ public class TextureLoader {
|
|||||||
try {
|
try {
|
||||||
g.setColor(TextureUtil.CANVAS_BACKGROUND);
|
g.setColor(TextureUtil.CANVAS_BACKGROUND);
|
||||||
g.fillRect(0, 0, bufferWidth, bufferHeight);
|
g.fillRect(0, 0, bufferWidth, bufferHeight);
|
||||||
g.drawImage(
|
g.drawImage(readResult, 0, 0, width, height, 0, height, width, 0, // Flip
|
||||||
readResult,
|
// the
|
||||||
0,
|
// image
|
||||||
0,
|
null);
|
||||||
width,
|
|
||||||
height,
|
|
||||||
0,
|
|
||||||
height,
|
|
||||||
width,
|
|
||||||
0, // Flip the image
|
|
||||||
null
|
|
||||||
);
|
|
||||||
} finally {
|
} finally {
|
||||||
g.dispose();
|
g.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureDataEditor result = new TextureDataEditor(
|
TextureDataEditor result = new TextureDataEditor(bufferWidth, bufferHeight, width, height, settings);
|
||||||
bufferWidth,
|
|
||||||
bufferHeight,
|
|
||||||
width,
|
|
||||||
height,
|
|
||||||
settings
|
|
||||||
);
|
|
||||||
|
|
||||||
result.draw(
|
result.draw(TextureUtil.extractBytes(raster), bufferWidth, 0, 0, 0, 0, width, height);
|
||||||
TextureUtil.extractBytes(raster),
|
|
||||||
bufferWidth,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
width,
|
|
||||||
height
|
|
||||||
);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TextureDataEditor loadPixels(
|
public static TextureDataEditor loadPixels(Resource resource, TextureSettings settings) throws IOException {
|
||||||
Resource resource,
|
|
||||||
TextureSettings settings
|
|
||||||
)
|
|
||||||
throws IOException {
|
|
||||||
return loadPixels(resource.getInputStream(), settings);
|
return loadPixels(resource.getInputStream(), settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,8 +39,8 @@ public class TextureUtil {
|
|||||||
|
|
||||||
public static final Color CANVAS_BACKGROUND = new Color(0, true);
|
public static final Color CANVAS_BACKGROUND = new Color(0, true);
|
||||||
|
|
||||||
public static final ColorModel COLOR_MODEL = new ComponentColorModel(
|
public static final ColorModel COLOR_MODEL = new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB), // Use
|
||||||
ColorSpace.getInstance(ColorSpace.CS_sRGB), // Use RGB
|
// RGB
|
||||||
null, // Use every bit
|
null, // Use every bit
|
||||||
true, // Has alpha
|
true, // Has alpha
|
||||||
false, // Not premultiplied
|
false, // Not premultiplied
|
||||||
@ -50,12 +50,9 @@ public class TextureUtil {
|
|||||||
|
|
||||||
private static final Hashtable<?, ?> BUFFERED_IMAGE_PROPERTIES = new Hashtable<>();
|
private static final Hashtable<?, ?> BUFFERED_IMAGE_PROPERTIES = new Hashtable<>();
|
||||||
|
|
||||||
public static WritableRaster createRaster(
|
public static WritableRaster createRaster(int bufferWidth, int bufferHeight) {
|
||||||
int bufferWidth,
|
return Raster.createInterleavedRaster(DataBuffer.TYPE_BYTE, // Storage
|
||||||
int bufferHeight
|
// model
|
||||||
) {
|
|
||||||
return Raster.createInterleavedRaster(
|
|
||||||
DataBuffer.TYPE_BYTE, // Storage model
|
|
||||||
bufferWidth, // Buffer width
|
bufferWidth, // Buffer width
|
||||||
bufferHeight, // Buffer height
|
bufferHeight, // Buffer height
|
||||||
BYTES_PER_PIXEL, // ARGB
|
BYTES_PER_PIXEL, // ARGB
|
||||||
@ -63,11 +60,7 @@ public class TextureUtil {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WritableRaster createRaster(
|
public static WritableRaster createRaster(ByteBuffer buffer, int bufferWidth, int bufferHeight) {
|
||||||
ByteBuffer buffer,
|
|
||||||
int bufferWidth,
|
|
||||||
int bufferHeight
|
|
||||||
) {
|
|
||||||
final int bands = BYTES_PER_PIXEL;
|
final int bands = BYTES_PER_PIXEL;
|
||||||
|
|
||||||
byte[] bytes = new byte[bufferWidth * bufferHeight * bands];
|
byte[] bytes = new byte[bufferWidth * bufferHeight * bands];
|
||||||
@ -77,8 +70,7 @@ public class TextureUtil {
|
|||||||
|
|
||||||
DataBufferByte dataBuffer = new DataBufferByte(bytes, bytes.length);
|
DataBufferByte dataBuffer = new DataBufferByte(bytes, bytes.length);
|
||||||
|
|
||||||
return Raster.createInterleavedRaster(
|
return Raster.createInterleavedRaster(dataBuffer, // The buffer
|
||||||
dataBuffer, // The buffer
|
|
||||||
bufferWidth, // Buffer width
|
bufferWidth, // Buffer width
|
||||||
bufferHeight, // Buffer height
|
bufferHeight, // Buffer height
|
||||||
bands * bufferWidth, // Scanline stride
|
bands * bufferWidth, // Scanline stride
|
||||||
@ -89,8 +81,7 @@ public class TextureUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static BufferedImage createCanvas(WritableRaster raster) {
|
public static BufferedImage createCanvas(WritableRaster raster) {
|
||||||
return new BufferedImage(
|
return new BufferedImage(COLOR_MODEL, // Color model
|
||||||
COLOR_MODEL, // Color model
|
|
||||||
raster, // Backing raster
|
raster, // Backing raster
|
||||||
false, // Raster is not premultipied
|
false, // Raster is not premultipied
|
||||||
BUFFERED_IMAGE_PROPERTIES // Properties
|
BUFFERED_IMAGE_PROPERTIES // Properties
|
||||||
@ -107,10 +98,7 @@ public class TextureUtil {
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ByteBuffer extractBytes(
|
public static ByteBuffer extractBytes(WritableRaster raster, ByteBuffer output) {
|
||||||
WritableRaster raster,
|
|
||||||
ByteBuffer output
|
|
||||||
) {
|
|
||||||
byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData();
|
byte[] data = ((DataBufferByte) raster.getDataBuffer()).getData();
|
||||||
|
|
||||||
output.put(data);
|
output.put(data);
|
||||||
|
@ -44,18 +44,11 @@ public class EntityAnchor implements Anchor {
|
|||||||
}),
|
}),
|
||||||
|
|
||||||
// Third person, looking forward
|
// Third person, looking forward
|
||||||
Mode.of(
|
Mode.of(v -> v.set(-3.5f, +0.5f, 0), m -> {
|
||||||
v -> v.set(-3.5f, +0.5f, 0),
|
}),
|
||||||
m -> {
|
|
||||||
}
|
|
||||||
),
|
|
||||||
|
|
||||||
// Third person, looking back
|
// Third person, looking back
|
||||||
Mode.of(
|
Mode.of(v -> v.set(-3.5f, 0, 0), m -> m.rotateZ((float) Math.PI)));
|
||||||
v -> v.set(-3.5f, 0, 0),
|
|
||||||
m -> m.rotateZ((float) Math.PI)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -114,11 +114,11 @@ public class LayerWorld extends Layer {
|
|||||||
|
|
||||||
tmp_testControls.applyPlayerControls();
|
tmp_testControls.applyPlayerControls();
|
||||||
|
|
||||||
for (EntityData data : this.client.getWorld().getData().getEntities()) {
|
this.client.getWorld().getData().getEntities().forEach(data -> {
|
||||||
tmp_applyFriction(data, tickLength);
|
tmp_applyFriction(data, tickLength);
|
||||||
tmp_applyGravity(data, tickLength);
|
tmp_applyGravity(data, tickLength);
|
||||||
tmp_renderCollisionModel(data);
|
tmp_renderCollisionModel(data);
|
||||||
}
|
});
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
System.err.println("OLEGSHA is to blame. Tell him he vry stupiDD!!");
|
System.err.println("OLEGSHA is to blame. Tell him he vry stupiDD!!");
|
||||||
@ -136,12 +136,8 @@ public class LayerWorld extends Layer {
|
|||||||
tmp_collideableList.clear();
|
tmp_collideableList.clear();
|
||||||
tmp_collideableList.addAll(this.client.getWorld().getData().getEntities());
|
tmp_collideableList.addAll(this.client.getWorld().getData().getEntities());
|
||||||
|
|
||||||
Collider.performCollisions(
|
Collider.performCollisions(tmp_collideableList, this.client.getWorld().getData(), tickLength,
|
||||||
tmp_collideableList,
|
tmp_colliderWorkspace);
|
||||||
this.client.getWorld().getData(),
|
|
||||||
tickLength,
|
|
||||||
tmp_colliderWorkspace
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final Renderable SELECTION_BOX = tmp_createSelectionBox();
|
private static final Renderable SELECTION_BOX = tmp_createSelectionBox();
|
||||||
@ -170,26 +166,14 @@ public class LayerWorld extends Layer {
|
|||||||
for (float phi = 0; phi < 2 * FloatMathUtil.PI_F; phi += FloatMathUtil.PI_F / 2) {
|
for (float phi = 0; phi < 2 * FloatMathUtil.PI_F; phi += FloatMathUtil.PI_F / 2) {
|
||||||
Mat4 rot = new Mat4().identity().rotateZ(phi).scale(scale);
|
Mat4 rot = new Mat4().identity().rotateZ(phi).scale(scale);
|
||||||
|
|
||||||
b.addPart(
|
b.addPart(new PppBuilder(p, (Texture) null).setOrigin(new Vec3(-f - 0.5f, -f - 0.5f, -f - 0.5f))
|
||||||
new PppBuilder(p, (Texture) null).setOrigin(
|
.setSize(f, f, 2 * f + 1).setColorMultiplier(color).create(), rot);
|
||||||
new Vec3(-f - 0.5f, -f - 0.5f, -f - 0.5f)
|
|
||||||
).setSize(f, f, 2 * f + 1).setColorMultiplier(color).create(),
|
|
||||||
rot
|
|
||||||
);
|
|
||||||
|
|
||||||
b.addPart(
|
b.addPart(new PppBuilder(p, (Texture) null).setOrigin(new Vec3(-f - 0.5f, -0.5f, -f - 0.5f))
|
||||||
new PppBuilder(p, (Texture) null).setOrigin(
|
.setSize(f, 1, f).setColorMultiplier(color).create(), rot);
|
||||||
new Vec3(-f - 0.5f, -0.5f, -f - 0.5f)
|
|
||||||
).setSize(f, 1, f).setColorMultiplier(color).create(),
|
|
||||||
rot
|
|
||||||
);
|
|
||||||
|
|
||||||
b.addPart(
|
b.addPart(new PppBuilder(p, (Texture) null).setOrigin(new Vec3(-f - 0.5f, -0.5f, +0.5f)).setSize(f, 1, f)
|
||||||
new PppBuilder(p, (Texture) null).setOrigin(
|
.setColorMultiplier(color).create(), rot);
|
||||||
new Vec3(-f - 0.5f, -0.5f, +0.5f)
|
|
||||||
).setSize(f, 1, f).setColorMultiplier(color).create(),
|
|
||||||
rot
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return b.build();
|
return b.build();
|
||||||
|
@ -24,10 +24,7 @@ import ru.windcorp.progressia.common.util.StashingStack;
|
|||||||
|
|
||||||
public class WorldRenderHelper extends ShapeRenderHelper {
|
public class WorldRenderHelper extends ShapeRenderHelper {
|
||||||
|
|
||||||
private final StashingStack<Mat4> viewTransformStack = new StashingStack<>(
|
private final StashingStack<Mat4> viewTransformStack = new StashingStack<>(TRANSFORM_STACK_SIZE, Mat4::new);
|
||||||
TRANSFORM_STACK_SIZE,
|
|
||||||
Mat4::new
|
|
||||||
);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
viewTransformStack.push().identity();
|
viewTransformStack.push().identity();
|
||||||
|
@ -44,10 +44,8 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
private static WorldRenderProgram def = null;
|
private static WorldRenderProgram def = null;
|
||||||
|
|
||||||
public static void init() {
|
public static void init() {
|
||||||
def = new WorldRenderProgram(
|
def = new WorldRenderProgram(new String[] { "WorldDefault.vertex.glsl" },
|
||||||
new String[] { "WorldDefault.vertex.glsl" },
|
new String[] { "WorldDefault.fragment.glsl" });
|
||||||
new String[] { "WorldDefault.fragment.glsl" }
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static WorldRenderProgram getDefault() {
|
public static WorldRenderProgram getDefault() {
|
||||||
@ -68,20 +66,12 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
private final Uniform4Matrix worldTransformUniform;
|
private final Uniform4Matrix worldTransformUniform;
|
||||||
private final AttributeVertexArray normalsAttribute;
|
private final AttributeVertexArray normalsAttribute;
|
||||||
|
|
||||||
public WorldRenderProgram(
|
public WorldRenderProgram(String[] vertexShaderResources, String[] fragmentShaderResources) {
|
||||||
String[] vertexShaderResources,
|
super(attachVertexShader(vertexShaderResources), attachFragmentShader(fragmentShaderResources));
|
||||||
String[] fragmentShaderResources
|
|
||||||
) {
|
|
||||||
super(
|
|
||||||
attachVertexShader(vertexShaderResources),
|
|
||||||
attachFragmentShader(fragmentShaderResources)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.worldTransformUniform = getUniform(WORLD_TRANSFORM_UNIFORM_NAME)
|
this.worldTransformUniform = getUniform(WORLD_TRANSFORM_UNIFORM_NAME).as4Matrix();
|
||||||
.as4Matrix();
|
|
||||||
|
|
||||||
this.normalsAttribute = getAttribute(NORMALS_ATTRIBUTE_NAME)
|
this.normalsAttribute = getAttribute(NORMALS_ATTRIBUTE_NAME).asVertexArray();
|
||||||
.asVertexArray();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String[] attachVertexShader(String[] others) {
|
private static String[] attachVertexShader(String[] others) {
|
||||||
@ -103,14 +93,7 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
int vertexStride = getBytesPerVertex();
|
int vertexStride = getBytesPerVertex();
|
||||||
int offset = super.bindVertices(vertices);
|
int offset = super.bindVertices(vertices);
|
||||||
|
|
||||||
normalsAttribute.set(
|
normalsAttribute.set(3, GL11.GL_FLOAT, false, vertexStride, vertices, offset);
|
||||||
3,
|
|
||||||
GL11.GL_FLOAT,
|
|
||||||
false,
|
|
||||||
vertexStride,
|
|
||||||
vertices,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
offset += 3 * Float.BYTES;
|
offset += 3 * Float.BYTES;
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
@ -130,8 +113,7 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytesPerVertex() {
|
public int getBytesPerVertex() {
|
||||||
return super.getBytesPerVertex() +
|
return super.getBytesPerVertex() + 3 * Float.BYTES; // Normals
|
||||||
3 * Float.BYTES; // Normals
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -171,12 +153,7 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
Vectors.release(normal);
|
Vectors.release(normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeOneNormal(
|
private void computeOneNormal(Vec3 a, Vec3 b, Vec3 c, Vec3 normal) {
|
||||||
Vec3 a,
|
|
||||||
Vec3 b,
|
|
||||||
Vec3 c,
|
|
||||||
Vec3 normal
|
|
||||||
) {
|
|
||||||
b.sub(a);
|
b.sub(a);
|
||||||
c.sub(a);
|
c.sub(a);
|
||||||
b.cross(c, normal);
|
b.cross(c, normal);
|
||||||
@ -187,18 +164,14 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
ByteBuffer vertices = face.getVertices();
|
ByteBuffer vertices = face.getVertices();
|
||||||
int offset = vertices.position() + index * getBytesPerVertex();
|
int offset = vertices.position() + index * getBytesPerVertex();
|
||||||
|
|
||||||
result.set(
|
result.set(vertices.getFloat(offset + 0 * Float.BYTES), vertices.getFloat(offset + 1 * Float.BYTES),
|
||||||
vertices.getFloat(offset + 0 * Float.BYTES),
|
vertices.getFloat(offset + 2 * Float.BYTES));
|
||||||
vertices.getFloat(offset + 1 * Float.BYTES),
|
|
||||||
vertices.getFloat(offset + 2 * Float.BYTES)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveVertexNormal(ShapePart face, int index, Vec3 normal) {
|
private void saveVertexNormal(ShapePart face, int index, Vec3 normal) {
|
||||||
ByteBuffer vertices = face.getVertices();
|
ByteBuffer vertices = face.getVertices();
|
||||||
int offset = vertices.position() + index * getBytesPerVertex() + (3 * Float.BYTES +
|
int offset = vertices.position() + index * getBytesPerVertex()
|
||||||
4 * Float.BYTES +
|
+ (3 * Float.BYTES + 4 * Float.BYTES + 2 * Float.BYTES);
|
||||||
2 * Float.BYTES);
|
|
||||||
|
|
||||||
vertices.putFloat(offset + 0 * Float.BYTES, normal.x);
|
vertices.putFloat(offset + 0 * Float.BYTES, normal.x);
|
||||||
vertices.putFloat(offset + 1 * Float.BYTES, normal.y);
|
vertices.putFloat(offset + 1 * Float.BYTES, normal.y);
|
||||||
@ -231,87 +204,36 @@ public class WorldRenderProgram extends ShapeRenderProgram {
|
|||||||
private final List<Vertex> vertices = new ArrayList<>();
|
private final List<Vertex> vertices = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexBuilder addVertex(
|
public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float tx, float ty) {
|
||||||
float x,
|
vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, 1), new Vec2(tx, ty)));
|
||||||
float y,
|
|
||||||
float z,
|
|
||||||
float r,
|
|
||||||
float g,
|
|
||||||
float b,
|
|
||||||
float tx,
|
|
||||||
float ty
|
|
||||||
) {
|
|
||||||
vertices.add(
|
|
||||||
new Vertex(
|
|
||||||
new Vec3(x, y, z),
|
|
||||||
new Vec4(r, g, b, 1),
|
|
||||||
new Vec2(tx, ty)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexBuilder addVertex(
|
public VertexBuilder addVertex(float x, float y, float z, float r, float g, float b, float a, float tx,
|
||||||
float x,
|
float ty) {
|
||||||
float y,
|
vertices.add(new Vertex(new Vec3(x, y, z), new Vec4(r, g, b, a), new Vec2(tx, ty)));
|
||||||
float z,
|
|
||||||
float r,
|
|
||||||
float g,
|
|
||||||
float b,
|
|
||||||
float a,
|
|
||||||
float tx,
|
|
||||||
float ty
|
|
||||||
) {
|
|
||||||
vertices.add(
|
|
||||||
new Vertex(
|
|
||||||
new Vec3(x, y, z),
|
|
||||||
new Vec4(r, g, b, a),
|
|
||||||
new Vec2(tx, ty)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexBuilder addVertex(
|
public VertexBuilder addVertex(Vec3 position, Vec4 colorMultiplier, Vec2 textureCoords) {
|
||||||
Vec3 position,
|
vertices.add(new Vertex(new Vec3(position), new Vec4(colorMultiplier), new Vec2(textureCoords)));
|
||||||
Vec4 colorMultiplier,
|
|
||||||
Vec2 textureCoords
|
|
||||||
) {
|
|
||||||
vertices.add(
|
|
||||||
new Vertex(
|
|
||||||
new Vec3(position),
|
|
||||||
new Vec4(colorMultiplier),
|
|
||||||
new Vec2(textureCoords)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ByteBuffer assemble() {
|
public ByteBuffer assemble() {
|
||||||
ByteBuffer result = BufferUtils.createByteBuffer(
|
ByteBuffer result = BufferUtils.createByteBuffer(DEFAULT_BYTES_PER_VERTEX * vertices.size());
|
||||||
DEFAULT_BYTES_PER_VERTEX * vertices.size()
|
|
||||||
);
|
|
||||||
|
|
||||||
for (Vertex v : vertices) {
|
for (Vertex v : vertices) {
|
||||||
result
|
result.putFloat(v.position.x).putFloat(v.position.y).putFloat(v.position.z)
|
||||||
.putFloat(v.position.x)
|
.putFloat(v.colorMultiplier.x).putFloat(v.colorMultiplier.y).putFloat(v.colorMultiplier.z)
|
||||||
.putFloat(v.position.y)
|
.putFloat(v.colorMultiplier.w).putFloat(v.textureCoords.x).putFloat(v.textureCoords.y)
|
||||||
.putFloat(v.position.z)
|
.putFloat(Float.NaN).putFloat(Float.NaN).putFloat(Float.NaN);
|
||||||
.putFloat(v.colorMultiplier.x)
|
|
||||||
.putFloat(v.colorMultiplier.y)
|
|
||||||
.putFloat(v.colorMultiplier.z)
|
|
||||||
.putFloat(v.colorMultiplier.w)
|
|
||||||
.putFloat(v.textureCoords.x)
|
|
||||||
.putFloat(v.textureCoords.y)
|
|
||||||
.putFloat(Float.NaN)
|
|
||||||
.putFloat(Float.NaN)
|
|
||||||
.putFloat(Float.NaN);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.flip();
|
result.flip();
|
||||||
|
@ -30,8 +30,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class Parser {
|
public class Parser {
|
||||||
private String filePath;
|
private String filePath;
|
||||||
static private final Escaper ESCAPER = new Escaper.EscaperBuilder()
|
static private final Escaper ESCAPER = new Escaper.EscaperBuilder().withChars("n", "\n").build();
|
||||||
.withChars("n", "\n").build();
|
|
||||||
|
|
||||||
public Parser(String filePath) {
|
public Parser(String filePath) {
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
@ -43,11 +42,7 @@ public class Parser {
|
|||||||
|
|
||||||
public Map<String, String> parse() {
|
public Map<String, String> parse() {
|
||||||
Map<String, String> parsedData = new HashMap<>();
|
Map<String, String> parsedData = new HashMap<>();
|
||||||
try (
|
try (Reader rawData = ResourceManager.getResource(filePath).getReader()) {
|
||||||
Reader rawData = ResourceManager
|
|
||||||
.getResource(filePath)
|
|
||||||
.getReader()
|
|
||||||
) {
|
|
||||||
int code;
|
int code;
|
||||||
char c;
|
char c;
|
||||||
StringBuilder stringBuilder = new StringBuilder();
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
@ -88,10 +83,7 @@ public class Parser {
|
|||||||
stringBuilder.append(c);
|
stringBuilder.append(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
parsedData.put(
|
parsedData.put(ESCAPER.unescape(key), ESCAPER.unescape(stringBuilder.toString()));
|
||||||
ESCAPER.unescape(key),
|
|
||||||
ESCAPER.unescape(stringBuilder.toString())
|
|
||||||
);
|
|
||||||
stringBuilder.setLength(0);
|
stringBuilder.setLength(0);
|
||||||
}
|
}
|
||||||
} else if (c == '\n') {
|
} else if (c == '\n') {
|
||||||
|
@ -37,11 +37,7 @@ public class BlockRenderRegistry extends NamespacedInstanceRegistry<BlockRender>
|
|||||||
|
|
||||||
public static Texture getBlockTexture(String name) {
|
public static Texture getBlockTexture(String name) {
|
||||||
return new SimpleTexture(
|
return new SimpleTexture(
|
||||||
Atlases.getSprite(
|
Atlases.getSprite(ResourceManager.getTextureResource("blocks/" + name), BLOCKS_ATLAS_GROUP));
|
||||||
ResourceManager.getTextureResource("blocks/" + name),
|
|
||||||
BLOCKS_ATLAS_GROUP
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static AtlasGroup getBlocksAtlasGroup() {
|
public static AtlasGroup getBlocksAtlasGroup() {
|
||||||
|
@ -37,14 +37,9 @@ public class EntityRenderRegistry extends NamespacedInstanceRegistry<EntityRende
|
|||||||
|
|
||||||
public static TexturePrimitive getEntityTexture(String name) {
|
public static TexturePrimitive getEntityTexture(String name) {
|
||||||
try {
|
try {
|
||||||
return new TexturePrimitive(
|
return new TexturePrimitive(TextureLoader
|
||||||
TextureLoader.loadPixels(
|
.loadPixels(ResourceManager.getTextureResource("entities/" + name), new TextureSettings(false))
|
||||||
ResourceManager.getTextureResource(
|
.getData());
|
||||||
"entities/" + name
|
|
||||||
),
|
|
||||||
new TextureSettings(false)
|
|
||||||
).getData()
|
|
||||||
);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw CrashReports.report(e, "Could not load entity texture %s", name);
|
throw CrashReports.report(e, "Could not load entity texture %s", name);
|
||||||
}
|
}
|
||||||
|
@ -32,11 +32,7 @@ public class HumanoidModel extends NPedModel {
|
|||||||
protected static abstract class Limb extends BodyPart {
|
protected static abstract class Limb extends BodyPart {
|
||||||
private final float animationOffset;
|
private final float animationOffset;
|
||||||
|
|
||||||
public Limb(
|
public Limb(Renderable renderable, Vec3 joint, float animationOffset) {
|
||||||
Renderable renderable,
|
|
||||||
Vec3 joint,
|
|
||||||
float animationOffset
|
|
||||||
) {
|
|
||||||
super(renderable, joint);
|
super(renderable, joint);
|
||||||
this.animationOffset = animationOffset;
|
this.animationOffset = animationOffset;
|
||||||
}
|
}
|
||||||
@ -55,11 +51,7 @@ public class HumanoidModel extends NPedModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Leg extends Limb {
|
public static class Leg extends Limb {
|
||||||
public Leg(
|
public Leg(Renderable renderable, Vec3 joint, float animationOffset) {
|
||||||
Renderable renderable,
|
|
||||||
Vec3 joint,
|
|
||||||
float animationOffset
|
|
||||||
) {
|
|
||||||
super(renderable, joint, animationOffset);
|
super(renderable, joint, animationOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,11 +62,7 @@ public class HumanoidModel extends NPedModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static class Arm extends Limb {
|
public static class Arm extends Limb {
|
||||||
public Arm(
|
public Arm(Renderable renderable, Vec3 joint, float animationOffset) {
|
||||||
Renderable renderable,
|
|
||||||
Vec3 joint,
|
|
||||||
float animationOffset
|
|
||||||
) {
|
|
||||||
super(renderable, joint, animationOffset);
|
super(renderable, joint, animationOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,18 +80,11 @@ public class HumanoidModel extends NPedModel {
|
|||||||
private float walkingLegSwing;
|
private float walkingLegSwing;
|
||||||
private float walkingArmSwing;
|
private float walkingArmSwing;
|
||||||
|
|
||||||
public HumanoidModel(
|
public HumanoidModel(EntityData entity,
|
||||||
EntityData entity,
|
|
||||||
|
|
||||||
Body body,
|
Body body, Head head, Arm leftArm, Arm rightArm, Leg leftLeg, Leg rightLeg,
|
||||||
Head head,
|
|
||||||
Arm leftArm,
|
|
||||||
Arm rightArm,
|
|
||||||
Leg leftLeg,
|
|
||||||
Leg rightLeg,
|
|
||||||
|
|
||||||
float scale
|
float scale) {
|
||||||
) {
|
|
||||||
super(entity, body, head, scale);
|
super(entity, body, head, scale);
|
||||||
this.leftArm = leftArm;
|
this.leftArm = leftArm;
|
||||||
this.rightArm = rightArm;
|
this.rightArm = rightArm;
|
||||||
|
@ -33,11 +33,7 @@ public class QuadripedModel extends NPedModel {
|
|||||||
public static class Leg extends BodyPart {
|
public static class Leg extends BodyPart {
|
||||||
private final float animationOffset;
|
private final float animationOffset;
|
||||||
|
|
||||||
public Leg(
|
public Leg(Renderable renderable, Vec3 joint, float animationOffset) {
|
||||||
Renderable renderable,
|
|
||||||
Vec3 joint,
|
|
||||||
float animationOffset
|
|
||||||
) {
|
|
||||||
super(renderable, joint);
|
super(renderable, joint);
|
||||||
this.animationOffset = animationOffset;
|
this.animationOffset = animationOffset;
|
||||||
}
|
}
|
||||||
@ -58,18 +54,11 @@ public class QuadripedModel extends NPedModel {
|
|||||||
|
|
||||||
private float walkingSwing = (float) toRadians(30);
|
private float walkingSwing = (float) toRadians(30);
|
||||||
|
|
||||||
public QuadripedModel(
|
public QuadripedModel(EntityData entity,
|
||||||
EntityData entity,
|
|
||||||
|
|
||||||
Body body,
|
Body body, Head head, Leg leftForeLeg, Leg rightForeLeg, Leg leftHindLeg, Leg rightHindLeg,
|
||||||
Head head,
|
|
||||||
Leg leftForeLeg,
|
|
||||||
Leg rightForeLeg,
|
|
||||||
Leg leftHindLeg,
|
|
||||||
Leg rightHindLeg,
|
|
||||||
|
|
||||||
float scale
|
float scale) {
|
||||||
) {
|
|
||||||
super(entity, body, head, scale);
|
super(entity, body, head, scale);
|
||||||
|
|
||||||
this.leftForeLeg = leftForeLeg;
|
this.leftForeLeg = leftForeLeg;
|
||||||
|
@ -41,11 +41,7 @@ public class TileRenderRegistry extends NamespacedInstanceRegistry<TileRender> {
|
|||||||
|
|
||||||
public static Texture getTileTexture(String name) {
|
public static Texture getTileTexture(String name) {
|
||||||
return new SimpleTexture(
|
return new SimpleTexture(
|
||||||
Atlases.getSprite(
|
Atlases.getSprite(ResourceManager.getTextureResource("tiles/" + name), TILES_ATLAS_GROUP));
|
||||||
ResourceManager.getTextureResource("tiles/" + name),
|
|
||||||
TILES_ATLAS_GROUP
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -112,12 +112,9 @@ public class Units {
|
|||||||
|
|
||||||
private static final TCharFloatMap PREFIXES_BY_CHAR;
|
private static final TCharFloatMap PREFIXES_BY_CHAR;
|
||||||
static {
|
static {
|
||||||
TCharFloatMap prefixes = new TCharFloatHashMap(
|
TCharFloatMap prefixes = new TCharFloatHashMap(gnu.trove.impl.Constants.DEFAULT_CAPACITY,
|
||||||
gnu.trove.impl.Constants.DEFAULT_CAPACITY,
|
gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR, gnu.trove.impl.Constants.DEFAULT_CHAR_NO_ENTRY_VALUE,
|
||||||
gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR,
|
Float.NaN);
|
||||||
gnu.trove.impl.Constants.DEFAULT_CHAR_NO_ENTRY_VALUE,
|
|
||||||
Float.NaN
|
|
||||||
);
|
|
||||||
|
|
||||||
prefixes.put('G', 1e+9f);
|
prefixes.put('G', 1e+9f);
|
||||||
prefixes.put('M', 1e+6f);
|
prefixes.put('M', 1e+6f);
|
||||||
@ -133,13 +130,8 @@ public class Units {
|
|||||||
private static final TObjectFloatMap<String> KNOWN_UNITS = createMap();
|
private static final TObjectFloatMap<String> KNOWN_UNITS = createMap();
|
||||||
|
|
||||||
private static TObjectFloatMap<String> createMap() {
|
private static TObjectFloatMap<String> createMap() {
|
||||||
return TCollections.synchronizedMap(
|
return TCollections.synchronizedMap(new TObjectFloatHashMap<>(gnu.trove.impl.Constants.DEFAULT_CAPACITY,
|
||||||
new TObjectFloatHashMap<>(
|
gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR, Float.NaN));
|
||||||
gnu.trove.impl.Constants.DEFAULT_CAPACITY,
|
|
||||||
gnu.trove.impl.Constants.DEFAULT_LOAD_FACTOR,
|
|
||||||
Float.NaN
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void registerUnits(Class<?> source) throws IllegalAccessException {
|
public static void registerUnits(Class<?> source) throws IllegalAccessException {
|
||||||
@ -210,9 +202,9 @@ public class Units {
|
|||||||
* parenthesis are allowed at all. As such,
|
* parenthesis are allowed at all. As such,
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>Multiple units under the division bar should be located after the
|
* <li>Multiple units under the division bar should be located after the
|
||||||
* single {@code '/'} and separated by {@code '*'}:
|
* single {@code '/'} and separated by {@code '*'}: <a
|
||||||
* <a href=https://en.wikipedia.org/wiki/Gas_constant>gas constant</a> ought
|
* href=https://en.wikipedia.org/wiki/Gas_constant>gas constant</a> ought to
|
||||||
* to have {@code "J/K*mol"} units.</li>
|
* have {@code "J/K*mol"} units.</li>
|
||||||
* <li>Exponentiation of parenthesis should be expanded: (m/s)² =
|
* <li>Exponentiation of parenthesis should be expanded: (m/s)² =
|
||||||
* {@code "m^2/s^2"}.</li>
|
* {@code "m^2/s^2"}.</li>
|
||||||
* <li>Exponents should also be used for expressing roots: √s =
|
* <li>Exponents should also be used for expressing roots: √s =
|
||||||
@ -221,8 +213,10 @@ public class Units {
|
|||||||
* discouraged.</li>
|
* discouraged.</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @param unit unit declaration
|
* @param unit
|
||||||
* @throws IllegalArgumentException if the declaration is invalid
|
* unit declaration
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* if the declaration is invalid
|
||||||
* @return the value of the unit
|
* @return the value of the unit
|
||||||
* @see #get(String) get(String)
|
* @see #get(String) get(String)
|
||||||
* @see #registerUnit(float, String...)
|
* @see #registerUnit(float, String...)
|
||||||
|
@ -21,8 +21,7 @@ package ru.windcorp.progressia.common.collision;
|
|||||||
import glm.vec._3.Vec3;
|
import glm.vec._3.Vec3;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An implementation of an
|
* An implementation of an <a href=
|
||||||
* <a href=
|
|
||||||
* "https://en.wikipedia.org/wiki/Minimum_bounding_box#Axis-aligned_minimum_bounding_box">Axis-Aligned
|
* "https://en.wikipedia.org/wiki/Minimum_bounding_box#Axis-aligned_minimum_bounding_box">Axis-Aligned
|
||||||
* Bounding Box</a>.
|
* Bounding Box</a>.
|
||||||
*
|
*
|
||||||
@ -36,17 +35,7 @@ public class AABB implements AABBoid {
|
|||||||
private final Vec3 widthSelector = new Vec3();
|
private final Vec3 widthSelector = new Vec3();
|
||||||
private final Vec3 heightSelector = new Vec3();
|
private final Vec3 heightSelector = new Vec3();
|
||||||
|
|
||||||
public AABBWallImpl(
|
public AABBWallImpl(float ox, float oy, float oz, float wx, float wy, float wz, float hx, float hy, float hz) {
|
||||||
float ox,
|
|
||||||
float oy,
|
|
||||||
float oz,
|
|
||||||
float wx,
|
|
||||||
float wy,
|
|
||||||
float wz,
|
|
||||||
float hx,
|
|
||||||
float hy,
|
|
||||||
float hz
|
|
||||||
) {
|
|
||||||
this.originOffset.set(ox, oy, oz);
|
this.originOffset.set(ox, oy, oz);
|
||||||
this.widthSelector.set(wx, wy, wz);
|
this.widthSelector.set(wx, wy, wz);
|
||||||
this.heightSelector.set(hx, hy, hz);
|
this.heightSelector.set(hx, hy, hz);
|
||||||
@ -71,8 +60,7 @@ public class AABB implements AABBoid {
|
|||||||
|
|
||||||
public static final AABB UNIT_CUBE = new AABB(0, 0, 0, 1, 1, 1);
|
public static final AABB UNIT_CUBE = new AABB(0, 0, 0, 1, 1, 1);
|
||||||
|
|
||||||
private final Wall[] walls = new Wall[] {
|
private final Wall[] walls = new Wall[] { new AABBWallImpl(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0), // Top
|
||||||
new AABBWallImpl(-0.5f, -0.5f, +0.5f, +1, 0, 0, 0, +1, 0), // Top
|
|
||||||
new AABBWallImpl(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0), // Bottom
|
new AABBWallImpl(-0.5f, -0.5f, -0.5f, 0, +1, 0, +1, 0, 0), // Bottom
|
||||||
new AABBWallImpl(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1), // North
|
new AABBWallImpl(+0.5f, -0.5f, -0.5f, 0, +1, 0, 0, 0, +1), // North
|
||||||
new AABBWallImpl(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1), // South
|
new AABBWallImpl(-0.5f, +0.5f, -0.5f, 0, -1, 0, 0, 0, +1), // South
|
||||||
@ -87,14 +75,7 @@ public class AABB implements AABBoid {
|
|||||||
this(origin.x, origin.y, origin.z, size.x, size.y, size.z);
|
this(origin.x, origin.y, origin.z, size.x, size.y, size.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
public AABB(
|
public AABB(float ox, float oy, float oz, float xSize, float ySize, float zSize) {
|
||||||
float ox,
|
|
||||||
float oy,
|
|
||||||
float oz,
|
|
||||||
float xSize,
|
|
||||||
float ySize,
|
|
||||||
float zSize
|
|
||||||
) {
|
|
||||||
this.origin.set(ox, oy, oz);
|
this.origin.set(ox, oy, oz);
|
||||||
this.size.set(xSize, ySize, zSize);
|
this.size.set(xSize, ySize, zSize);
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,11 @@ public interface Collideable {
|
|||||||
CollisionModel getCollisionModel();
|
CollisionModel getCollisionModel();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked by {@link Collider} when two entities are about to collide.
|
* Invoked by {@link Collider} when two entities are about to collide. The
|
||||||
* The world is at the moment of collision.
|
* world is at the moment of collision.
|
||||||
*
|
*
|
||||||
* @param other the colliding object
|
* @param other
|
||||||
|
* the colliding object
|
||||||
* @return {@code true} iff the collision should not be handled normally
|
* @return {@code true} iff the collision should not be handled normally
|
||||||
* (e.g. this object has disappeared)
|
* (e.g. this object has disappeared)
|
||||||
*/
|
*/
|
||||||
@ -37,8 +38,8 @@ public interface Collideable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the mass of this {@link Collideable} that should be used to
|
* Returns the mass of this {@link Collideable} that should be used to
|
||||||
* calculate collisions.
|
* calculate collisions. Collision mass must be a positive number. Positive
|
||||||
* Collision mass must be a positive number. Positive infinity is allowed.
|
* infinity is allowed.
|
||||||
*
|
*
|
||||||
* @return this object's collision mass
|
* @return this object's collision mass
|
||||||
*/
|
*/
|
||||||
|
@ -30,11 +30,7 @@ public class CollisionPathComputer {
|
|||||||
|
|
||||||
private static final float PADDING = 0.5f;
|
private static final float PADDING = 0.5f;
|
||||||
|
|
||||||
public static void forEveryBlockInCollisionPath(
|
public static void forEveryBlockInCollisionPath(Collideable coll, float maxTime, Consumer<Vec3i> action) {
|
||||||
Collideable coll,
|
|
||||||
float maxTime,
|
|
||||||
Consumer<Vec3i> action
|
|
||||||
) {
|
|
||||||
Vec3 displacement = Vectors.grab3();
|
Vec3 displacement = Vectors.grab3();
|
||||||
coll.getCollideableVelocity(displacement);
|
coll.getCollideableVelocity(displacement);
|
||||||
displacement.mul(maxTime);
|
displacement.mul(maxTime);
|
||||||
@ -44,11 +40,7 @@ public class CollisionPathComputer {
|
|||||||
Vectors.release(displacement);
|
Vectors.release(displacement);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void handleModel(
|
private static void handleModel(CollisionModel model, Vec3 displacement, Consumer<Vec3i> action) {
|
||||||
CollisionModel model,
|
|
||||||
Vec3 displacement,
|
|
||||||
Consumer<Vec3i> action
|
|
||||||
) {
|
|
||||||
if (model instanceof CompoundCollisionModel) {
|
if (model instanceof CompoundCollisionModel) {
|
||||||
for (CollisionModel subModel : ((CompoundCollisionModel) model).getModels()) {
|
for (CollisionModel subModel : ((CompoundCollisionModel) model).getModels()) {
|
||||||
handleModel(subModel, displacement, action);
|
handleModel(subModel, displacement, action);
|
||||||
@ -71,21 +63,13 @@ public class CollisionPathComputer {
|
|||||||
|
|
||||||
Vec3i pos = Vectors.grab3i();
|
Vec3i pos = Vectors.grab3i();
|
||||||
|
|
||||||
for (
|
for (pos.x = (int) floor(origin.x + min(0, size.x) + min(0, displacement.x) - PADDING); pos.x <= (int) ceil(
|
||||||
pos.x = (int) floor(origin.x + min(0, size.x) + min(0, displacement.x) - PADDING);
|
origin.x + max(0, size.x) + max(0, displacement.x) + PADDING); pos.x += 1) {
|
||||||
pos.x <= (int) ceil(origin.x + max(0, size.x) + max(0, displacement.x) + PADDING);
|
for (pos.y = (int) floor(origin.y + min(0, size.y) + min(0, displacement.y) - PADDING); pos.y <= (int) ceil(
|
||||||
pos.x += 1
|
origin.y + max(0, size.y) + max(0, displacement.y) + PADDING); pos.y += 1) {
|
||||||
) {
|
for (pos.z = (int) floor(
|
||||||
for (
|
origin.z + min(0, size.z) + min(0, displacement.z) - PADDING); pos.z <= (int) ceil(
|
||||||
pos.y = (int) floor(origin.y + min(0, size.y) + min(0, displacement.y) - PADDING);
|
origin.z + max(0, size.z) + max(0, displacement.z) + PADDING); pos.z += 1) {
|
||||||
pos.y <= (int) ceil(origin.y + max(0, size.y) + max(0, displacement.y) + PADDING);
|
|
||||||
pos.y += 1
|
|
||||||
) {
|
|
||||||
for (
|
|
||||||
pos.z = (int) floor(origin.z + min(0, size.z) + min(0, displacement.z) - PADDING);
|
|
||||||
pos.z <= (int) ceil(origin.z + max(0, size.z) + max(0, displacement.z) + PADDING);
|
|
||||||
pos.z += 1
|
|
||||||
) {
|
|
||||||
action.accept(pos);
|
action.accept(pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,25 +68,22 @@ public class WorldCollisionHelper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the state of this helper's {@link #getCollideable()} so it is
|
* Changes the state of this helper's {@link #getCollideable()} so it is
|
||||||
* ready to adequately handle
|
* ready to adequately handle collisions with the {@code collideable} that
|
||||||
* collisions with the {@code collideable} that might happen in the next
|
* might happen in the next {@code maxTime} seconds. This helper is only
|
||||||
* {@code maxTime} seconds.
|
* valid for checking collisions with the given Collideable and only within
|
||||||
* This helper is only valid for checking collisions with the given
|
|
||||||
* Collideable and only within
|
|
||||||
* the given time limit.
|
* the given time limit.
|
||||||
*
|
*
|
||||||
* @param collideable the {@link Collideable} that collisions will be
|
* @param collideable
|
||||||
* checked against
|
* the {@link Collideable} that collisions will be checked
|
||||||
* @param maxTime maximum collision time
|
* against
|
||||||
|
* @param maxTime
|
||||||
|
* maximum collision time
|
||||||
*/
|
*/
|
||||||
public void tuneToCollideable(DefaultWorldData world, Collideable collideable, float maxTime) {
|
public void tuneToCollideable(DefaultWorldData world, Collideable collideable, float maxTime) {
|
||||||
activeBlockModels.forEach(blockModelCache::release);
|
activeBlockModels.forEach(blockModelCache::release);
|
||||||
activeBlockModels.clear();
|
activeBlockModels.clear();
|
||||||
CollisionPathComputer.forEveryBlockInCollisionPath(
|
CollisionPathComputer.forEveryBlockInCollisionPath(collideable, maxTime,
|
||||||
collideable,
|
v -> addModel(world.getCollisionModelOfBlock(v), v));
|
||||||
maxTime,
|
|
||||||
v -> addModel(world.getCollisionModelOfBlock(v), v)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addModel(CollisionModel model, Vec3i pos) {
|
private void addModel(CollisionModel model, Vec3i pos) {
|
||||||
|
@ -26,26 +26,13 @@ import ru.windcorp.progressia.common.collision.colliders.Collider.Collision;
|
|||||||
|
|
||||||
class AnythingWithCompoundCollider {
|
class AnythingWithCompoundCollider {
|
||||||
|
|
||||||
static Collider.Collision computeModelCollision(
|
static Collider.Collision computeModelCollision(Collideable aBody, Collideable bBody, CompoundCollisionModel aModel,
|
||||||
Collideable aBody,
|
CollisionModel bModel, float tickLength, ColliderWorkspace workspace) {
|
||||||
Collideable bBody,
|
|
||||||
CompoundCollisionModel aModel,
|
|
||||||
CollisionModel bModel,
|
|
||||||
float tickLength,
|
|
||||||
ColliderWorkspace workspace
|
|
||||||
) {
|
|
||||||
Collision result = null;
|
Collision result = null;
|
||||||
|
|
||||||
for (CollisionModel aModelPart : aModel.getModels()) {
|
for (CollisionModel aModelPart : aModel.getModels()) {
|
||||||
|
|
||||||
Collision collision = Collider.getCollision(
|
Collision collision = Collider.getCollision(aBody, bBody, aModelPart, bModel, tickLength, workspace);
|
||||||
aBody,
|
|
||||||
bBody,
|
|
||||||
aModelPart,
|
|
||||||
bModel,
|
|
||||||
tickLength,
|
|
||||||
workspace
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update result
|
// Update result
|
||||||
if (collision != null) {
|
if (collision != null) {
|
||||||
|
@ -56,15 +56,9 @@ public abstract class CommsChannel {
|
|||||||
|
|
||||||
protected abstract void doSendPacket(Packet packet) throws IOException;
|
protected abstract void doSendPacket(Packet packet) throws IOException;
|
||||||
|
|
||||||
private synchronized void sendPacket(
|
private synchronized void sendPacket(Packet packet, State expectedState, String errorMessage) {
|
||||||
Packet packet,
|
|
||||||
State expectedState,
|
|
||||||
String errorMessage
|
|
||||||
) {
|
|
||||||
if (getState() != expectedState) {
|
if (getState() != expectedState) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(String.format(errorMessage, this, getState()));
|
||||||
String.format(errorMessage, this, getState())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -75,27 +69,15 @@ public abstract class CommsChannel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendPacket(Packet packet) {
|
public synchronized void sendPacket(Packet packet) {
|
||||||
sendPacket(
|
sendPacket(packet, State.CONNECTED, "Client %s is in state %s and cannot receive packets normally");
|
||||||
packet,
|
|
||||||
State.CONNECTED,
|
|
||||||
"Client %s is in state %s and cannot receive packets normally"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendConnectingPacket(Packet packet) {
|
public synchronized void sendConnectingPacket(Packet packet) {
|
||||||
sendPacket(
|
sendPacket(packet, State.CONNECTING, "Client %s is in state %s and is no longer connecting");
|
||||||
packet,
|
|
||||||
State.CONNECTING,
|
|
||||||
"Client %s is in state %s and is no longer connecting"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void sendDisconnectingPacket(Packet packet) {
|
public synchronized void sendDisconnectingPacket(Packet packet) {
|
||||||
sendPacket(
|
sendPacket(packet, State.CONNECTING, "Client %s is in state %s and is no longer disconnecting");
|
||||||
packet,
|
|
||||||
State.CONNECTING,
|
|
||||||
"Client %s is in state %s and is no longer disconnecting"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void disconnect();
|
public abstract void disconnect();
|
||||||
|
@ -22,8 +22,7 @@ import java.io.DataInput;
|
|||||||
import java.io.DataOutput;
|
import java.io.DataOutput;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public abstract class AbstractStatefulObjectLayout
|
public abstract class AbstractStatefulObjectLayout extends StatefulObjectLayout {
|
||||||
extends StatefulObjectLayout {
|
|
||||||
|
|
||||||
public AbstractStatefulObjectLayout(String objectId) {
|
public AbstractStatefulObjectLayout(String objectId) {
|
||||||
super(objectId);
|
super(objectId);
|
||||||
@ -34,12 +33,7 @@ public abstract class AbstractStatefulObjectLayout
|
|||||||
protected abstract StateField getField(int fieldIndex);
|
protected abstract StateField getField(int fieldIndex);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(
|
public void read(StatefulObject object, DataInput input, IOContext context) throws IOException {
|
||||||
StatefulObject object,
|
|
||||||
DataInput input,
|
|
||||||
IOContext context
|
|
||||||
)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
int fieldCount = getFieldCount();
|
int fieldCount = getFieldCount();
|
||||||
for (int i = 0; i < fieldCount; ++i) {
|
for (int i = 0; i < fieldCount; ++i) {
|
||||||
@ -53,12 +47,7 @@ public abstract class AbstractStatefulObjectLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(
|
public void write(StatefulObject object, DataOutput output, IOContext context) throws IOException {
|
||||||
StatefulObject object,
|
|
||||||
DataOutput output,
|
|
||||||
IOContext context
|
|
||||||
)
|
|
||||||
throws IOException {
|
|
||||||
|
|
||||||
int fieldCount = getFieldCount();
|
int fieldCount = getFieldCount();
|
||||||
for (int i = 0; i < fieldCount; ++i) {
|
for (int i = 0; i < fieldCount; ++i) {
|
||||||
|
@ -20,8 +20,6 @@ package ru.windcorp.progressia.common.state;
|
|||||||
|
|
||||||
public enum IOContext {
|
public enum IOContext {
|
||||||
|
|
||||||
COMMS,
|
COMMS, SAVE, INTERNAL;
|
||||||
SAVE,
|
|
||||||
INTERNAL;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,7 @@ package ru.windcorp.progressia.common.state;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class InspectingStatefulObjectLayout
|
public class InspectingStatefulObjectLayout extends AbstractStatefulObjectLayout {
|
||||||
extends AbstractStatefulObjectLayout {
|
|
||||||
|
|
||||||
private final List<StateField> fields = new ArrayList<>();
|
private final List<StateField> fields = new ArrayList<>();
|
||||||
|
|
||||||
@ -48,11 +47,7 @@ public class InspectingStatefulObjectLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
public StatefulObjectLayout compile() {
|
public StatefulObjectLayout compile() {
|
||||||
return new OptimizedStatefulObjectLayout(
|
return new OptimizedStatefulObjectLayout(getObjectId(), fields, fieldIndexCounters);
|
||||||
getObjectId(),
|
|
||||||
fields,
|
|
||||||
fieldIndexCounters
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T extends StateField> T registerField(T field) {
|
private <T extends StateField> T registerField(T field) {
|
||||||
@ -71,13 +66,7 @@ public class InspectingStatefulObjectLayout
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IntStateField build() {
|
public IntStateField build() {
|
||||||
return registerField(
|
return registerField(new IntStateField(id, isLocal, fieldIndexCounters.getIntsThenIncrement()));
|
||||||
new IntStateField(
|
|
||||||
id,
|
|
||||||
isLocal,
|
|
||||||
fieldIndexCounters.getIntsThenIncrement()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -105,10 +94,7 @@ public class InspectingStatefulObjectLayout
|
|||||||
public void setOrdinal(int ordinal) {
|
public void setOrdinal(int ordinal) {
|
||||||
if (ordinal != fields.size()) {
|
if (ordinal != fields.size()) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
"This field is going to receive ordinal "
|
"This field is going to receive ordinal " + fields.size() + ", requested ordinal " + ordinal);
|
||||||
+ fields.size() + ", requested ordinal "
|
|
||||||
+ ordinal
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,11 +24,7 @@ import java.io.IOException;
|
|||||||
|
|
||||||
public class IntStateField extends StateField {
|
public class IntStateField extends StateField {
|
||||||
|
|
||||||
public IntStateField(
|
public IntStateField(String id, boolean isLocal, int index) {
|
||||||
String id,
|
|
||||||
boolean isLocal,
|
|
||||||
int index
|
|
||||||
) {
|
|
||||||
super(id, isLocal, index);
|
super(id, isLocal, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,22 +41,12 @@ public class IntStateField extends StateField {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void read(
|
public void read(StatefulObject object, DataInput input, IOContext context) throws IOException {
|
||||||
StatefulObject object,
|
|
||||||
DataInput input,
|
|
||||||
IOContext context
|
|
||||||
)
|
|
||||||
throws IOException {
|
|
||||||
object.getStorage().setInt(getIndex(), input.readInt());
|
object.getStorage().setInt(getIndex(), input.readInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(
|
public void write(StatefulObject object, DataOutput output, IOContext context) throws IOException {
|
||||||
StatefulObject object,
|
|
||||||
DataOutput output,
|
|
||||||
IOContext context
|
|
||||||
)
|
|
||||||
throws IOException {
|
|
||||||
output.writeInt(object.getStorage().getInt(getIndex()));
|
output.writeInt(object.getStorage().getInt(getIndex()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user