@@ -1513,6 +1513,16 @@ public interface Client extends GameEngine
|
||||
*/
|
||||
void setOculusOrbNormalSpeed(int speed);
|
||||
|
||||
/**
|
||||
* Gets local X coord where the camera is pointing when the Oculus orb is active
|
||||
*/
|
||||
int getOculusOrbFocalPointX();
|
||||
|
||||
/**
|
||||
* Gets local Y coord where the camera is pointing when the Oculus orb is active
|
||||
*/
|
||||
int getOculusOrbFocalPointY();
|
||||
|
||||
/**
|
||||
* Opens in-game world hopper interface
|
||||
*/
|
||||
@@ -1524,6 +1534,16 @@ public interface Client extends GameEngine
|
||||
*/
|
||||
void hopToWorld(World world);
|
||||
|
||||
/**
|
||||
* Sets the RGB color of the skybox
|
||||
*/
|
||||
void setSkyboxColor(int skyboxColor);
|
||||
|
||||
/**
|
||||
* Gets the RGB color of the skybox
|
||||
*/
|
||||
int getSkyboxColor();
|
||||
|
||||
boolean isGpu();
|
||||
|
||||
void setGpu(boolean gpu);
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.api.events;
|
||||
|
||||
/**
|
||||
* Posted at the start of every frame
|
||||
*/
|
||||
public class BeforeRender
|
||||
{
|
||||
}
|
||||
@@ -46,6 +46,7 @@ import net.runelite.api.MainBufferProvider;
|
||||
import net.runelite.api.RenderOverview;
|
||||
import net.runelite.api.Renderable;
|
||||
import net.runelite.api.WorldMapManager;
|
||||
import net.runelite.api.events.BeforeRender;
|
||||
import net.runelite.api.events.GameTick;
|
||||
import net.runelite.api.hooks.Callbacks;
|
||||
import net.runelite.api.hooks.DrawCallbacks;
|
||||
@@ -81,6 +82,7 @@ public class Hooks implements Callbacks
|
||||
private static final OverlayRenderer renderer = injector.getInstance(OverlayRenderer.class);
|
||||
|
||||
private static final GameTick GAME_TICK = new GameTick();
|
||||
private static final BeforeRender BEFORE_RENDER = new BeforeRender();
|
||||
|
||||
@Inject
|
||||
private EventBus eventBus;
|
||||
@@ -149,6 +151,8 @@ public class Hooks implements Callbacks
|
||||
client.setTickCount(tick + 1);
|
||||
}
|
||||
|
||||
eventBus.post(BEFORE_RENDER);
|
||||
|
||||
clientThread.invoke();
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
@@ -849,6 +849,8 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
lastAntiAliasingMode = antiAliasingMode;
|
||||
|
||||
// Clear scene
|
||||
int sky = client.getSkyboxColor();
|
||||
gl.glClearColor((sky >> 16 & 0xFF) / 255f, (sky >> 8 & 0xFF) / 255f, (sky & 0xFF) / 255f, 1f);
|
||||
gl.glClear(gl.GL_COLOR_BUFFER_BIT);
|
||||
|
||||
// Upload buffers
|
||||
|
||||
@@ -0,0 +1,510 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.skybox;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.Reader;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import net.runelite.api.Client;
|
||||
|
||||
class Skybox
|
||||
{
|
||||
@FunctionalInterface
|
||||
public interface ChunkMapper
|
||||
{
|
||||
/**
|
||||
* Gets the instance template chunk data for the specified point
|
||||
*
|
||||
* @see Client#getInstanceTemplateChunks
|
||||
*/
|
||||
int getTemplateChunk(int cx, int cy, int plane);
|
||||
}
|
||||
|
||||
private static final double SQRT2 = Math.sqrt(2);
|
||||
|
||||
// How many stddev per direction we need to stay visibly continuous
|
||||
// 511/512 accuracy
|
||||
private static final double BLEND_DISTRIBUTION = 3.075;
|
||||
|
||||
// This has a worst case complexity of O((BLEND_RADUS*2)^2)
|
||||
// BLEND_RADIUS is in chunks (8 tiles)
|
||||
private static final int BLEND_RADIUS = 5;
|
||||
|
||||
// The maximum number of tiles that can be blended before becoming visibly discontinuous
|
||||
private static final int MAX_BLEND = (int) ((BLEND_RADIUS * 8) / BLEND_DISTRIBUTION);
|
||||
|
||||
private static final int PLANE_ALL = 0b1111;
|
||||
|
||||
private static final Pattern PATTERN = Pattern.compile("^[ \\t]*(?<expr>" +
|
||||
"//.*$|" + // //comment
|
||||
"m[ \\t]*(?<mrx>[0-9]+)[ \\t]+(?<mry>[0-9]+)|" + // m <rx> <ry>
|
||||
"r[ \\t]*(?<rx>[0-9]+)[ \\t]+(?<ry>[0-9]+)|" + // r <rx> <ry>
|
||||
"R[ \\t]*(?<rx1>[0-9]+)[ \\t]+(?<ry1>[0-9]+)[ \\t]+(?<rx2>[0-9]+)[ \\t]+(?<ry2>[0-9]+)|" + // R <rx1> <ry1> <rx2> <ry2>
|
||||
"c[ \\t]*(?<cx>[0-9-]+)[ \\t]+(?<cy>[0-9-]+)|" + // c <cx> <cy>
|
||||
"C[ \\t]*(?<cx1>[0-9-]+)[ \\t]+(?<cy1>[0-9-]+)[ \\t]+(?<cx2>[0-9-]+)[ \\t]+(?<cy2>[0-9-]+)|" + // C <cx1> <cy1> <cx2> <cy2>
|
||||
"#[ \\t]*(?<color>[0-9a-fA-F]{6}|[0-9a-fA-F]{3})|" + // #<RRGGBB> or #<RGB>
|
||||
"p[ \\t]*(?<plane>all|0?[ \\t]*1?[ \\t]*2?[ \\t]*3?)|" + // p all or p<1><2><3><4>
|
||||
"b[ \\t]*(?<blend>[0-9]+)|" + // b <blend>
|
||||
"bounds[ \\t]+(?<bx1>[0-9]+)[ \\t]+(?<by1>[0-9]+)[ \\t]+(?<bx2>[0-9]+)[ \\t]+(?<by2>[0-9]+)" + // bounds <x0> <y0> <x1> <y1>
|
||||
")[ \\t]*");
|
||||
|
||||
private final int[] chunks;
|
||||
private final int[] planeOverrides;
|
||||
|
||||
private final int x1;
|
||||
private final int y1;
|
||||
private final int x2;
|
||||
private final int y2;
|
||||
private final int stride;
|
||||
|
||||
public Skybox(InputStream is, String filename) throws IOException
|
||||
{
|
||||
this(new InputStreamReader(is), filename);
|
||||
}
|
||||
|
||||
public Skybox(Reader reader, String filename) throws IOException
|
||||
{
|
||||
int[] chunks = null;
|
||||
int[] planeOverrides = new int[64];
|
||||
int planeOverrideEnd = 0;
|
||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, stride = 0;
|
||||
BufferedReader br = new BufferedReader(reader);
|
||||
int lineNo = 1;
|
||||
int color = 0;
|
||||
int plane = PLANE_ALL;
|
||||
int rx1 = 0, ry1 = 0, rx2 = 0, ry2 = 0;
|
||||
try
|
||||
{
|
||||
Matcher m = PATTERN.matcher("");
|
||||
for (String line; (line = br.readLine()) != null; lineNo++)
|
||||
{
|
||||
m.reset(line);
|
||||
int end = 0;
|
||||
for (; end < line.length(); )
|
||||
{
|
||||
m.region(end, line.length());
|
||||
if (!m.find())
|
||||
{
|
||||
throw new IllegalArgumentException("Unexpected: \"" + line.substring(end) + "\" (" + filename + ":" + lineNo + ")");
|
||||
}
|
||||
end = m.end();
|
||||
|
||||
String expr = m.group("expr");
|
||||
if (expr == null || expr.length() <= 0 || expr.startsWith("//"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (chunks == null)
|
||||
{
|
||||
if (!expr.startsWith("bounds"))
|
||||
{
|
||||
throw new IllegalArgumentException("Expceted bounds (" + filename + ":" + lineNo + ")");
|
||||
}
|
||||
x1 = Integer.parseInt(m.group("bx1")) * 8;
|
||||
y1 = Integer.parseInt(m.group("by1")) * 8;
|
||||
x2 = (Integer.parseInt(m.group("bx2")) + 1) * 8;
|
||||
y2 = (Integer.parseInt(m.group("by2")) + 1) * 8;
|
||||
stride = (x2 - x1);
|
||||
chunks = new int[stride * (y2 - y1)];
|
||||
Arrays.fill(chunks, -1);
|
||||
continue;
|
||||
}
|
||||
|
||||
char cha = expr.charAt(0);
|
||||
switch (cha)
|
||||
{
|
||||
case '#':
|
||||
String sColor = m.group("color");
|
||||
int scolor = Integer.parseInt(sColor, 16);
|
||||
int cr, cg, cb;
|
||||
if (sColor.length() == 3)
|
||||
{
|
||||
// Expand #RGB to #RRGGBB
|
||||
cr = scolor >> 8 & 0xF;
|
||||
cr |= cr << 4;
|
||||
cg = scolor >> 4 & 0xF;
|
||||
cg |= cg << 4;
|
||||
cb = scolor & 0xF;
|
||||
cb |= cb << 4;
|
||||
}
|
||||
else
|
||||
{
|
||||
cr = scolor >> 16 & 0xFF;
|
||||
cg = scolor >> 8 & 0xFF;
|
||||
cb = scolor & 0xFF;
|
||||
}
|
||||
|
||||
// Convert to YCoCg24 because it produces less blending artifacts due
|
||||
// to mismatched skew rates
|
||||
// See: https://stackoverflow.com/questions/10566668/lossless-rgb-to-ycbcr-transformation
|
||||
byte cco = (byte) (cb - cr);
|
||||
byte tmp = (byte) (cr + (cco >> 1));
|
||||
byte ccg = (byte) (tmp - cg);
|
||||
byte cy = (byte) (cg + (ccg >> 1));
|
||||
|
||||
color = color & 0xFF000000 | (cy & 0xFF) << 16 | (cco & 0xFF) << 8 | (ccg & 0xFF);
|
||||
break;
|
||||
case 'b':
|
||||
int iblend = Integer.parseInt(m.group("blend"));
|
||||
if (iblend < 0)
|
||||
{
|
||||
throw new IllegalArgumentException("Blend must be >=0 (" + filename + ":" + lineNo + ")");
|
||||
}
|
||||
if (iblend > MAX_BLEND)
|
||||
{
|
||||
throw new IllegalArgumentException("Blend must be <= " + MAX_BLEND + " (" + filename + ":" + lineNo + ")");
|
||||
}
|
||||
color = color & 0x00FFFFFF | iblend << 24;
|
||||
break;
|
||||
case 'm':
|
||||
rx2 = rx1 = Integer.parseInt(m.group("mrx"));
|
||||
ry2 = ry1 = Integer.parseInt(m.group("mry"));
|
||||
break;
|
||||
case 'p':
|
||||
String planes = m.group("plane");
|
||||
if ("all".equals(planes))
|
||||
{
|
||||
plane = PLANE_ALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
plane = 0;
|
||||
for (int i = 0; i < planes.length(); i++)
|
||||
{
|
||||
plane |= 1 << (planes.charAt(i) - '0');
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
case 'R':
|
||||
if (cha == 'r')
|
||||
{
|
||||
rx2 = rx1 = Integer.parseInt(m.group("rx"));
|
||||
ry2 = ry1 = Integer.parseInt(m.group("ry"));
|
||||
}
|
||||
else
|
||||
{
|
||||
rx1 = Integer.parseInt(m.group("rx1"));
|
||||
ry1 = Integer.parseInt(m.group("ry1"));
|
||||
rx2 = Integer.parseInt(m.group("rx2"));
|
||||
ry2 = Integer.parseInt(m.group("ry2"));
|
||||
}
|
||||
// fallthrough
|
||||
case 'c':
|
||||
case 'C':
|
||||
int cx1 = rx1 * 8;
|
||||
int cy1 = ry1 * 8;
|
||||
int cx2 = rx2 * 8 + 7;
|
||||
int cy2 = ry2 * 8 + 7;
|
||||
if (cha == 'c')
|
||||
{
|
||||
cx2 = cx1 = cx1 + Integer.parseInt(m.group("cx"));
|
||||
cy2 = cy1 = cy1 + Integer.parseInt(m.group("cy"));
|
||||
}
|
||||
else if (cha == 'C')
|
||||
{
|
||||
cx2 = cx1 + Integer.parseInt(m.group("cx2"));
|
||||
cy2 = cy1 + Integer.parseInt(m.group("cy2"));
|
||||
cx1 = cx1 + Integer.parseInt(m.group("cx1"));
|
||||
cy1 = cy1 + Integer.parseInt(m.group("cy1"));
|
||||
}
|
||||
|
||||
if (cx1 < x1 || cy1 < y1 || cx2 >= x2 || cy2 >= y2)
|
||||
{
|
||||
throw new IllegalArgumentException("Coordinate out of bounds (" + filename + ":" + lineNo + ")");
|
||||
}
|
||||
if (cx1 > cx2 || cy1 > cy2)
|
||||
{
|
||||
throw new IllegalArgumentException("First coord must be before second (" + filename + ":" + lineNo + ")");
|
||||
}
|
||||
|
||||
for (int y = cy1; y <= cy2; y++)
|
||||
{
|
||||
int yoffset = stride * (y - y1);
|
||||
for (int x = cx1; x <= cx2; x++)
|
||||
{
|
||||
int offset = (x - x1) + yoffset;
|
||||
|
||||
if (plane == PLANE_ALL)
|
||||
{
|
||||
chunks[offset] = color;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We are not setting all planes in this chunk, so allocate a plane override section
|
||||
// and add a pointer to it in the normal chunk's space. We do this because most chunks
|
||||
// do not have plane-specific data
|
||||
int ocv = chunks[offset];
|
||||
int poptr;
|
||||
if ((ocv & 0x8000_0000) != 0 && ocv != -1)
|
||||
{
|
||||
// Existing plane override
|
||||
poptr = ocv & 0x7FFF_FFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
poptr = planeOverrideEnd;
|
||||
planeOverrideEnd += 4;
|
||||
if (planeOverrideEnd > planeOverrides.length)
|
||||
{
|
||||
planeOverrides = Arrays.copyOf(planeOverrides, planeOverrideEnd + 64);
|
||||
}
|
||||
chunks[offset] = poptr | 0x8000_0000;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
planeOverrides[poptr + i] = ocv;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if ((plane & (1 << i)) != 0)
|
||||
{
|
||||
planeOverrides[poptr + i] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (NumberFormatException ex)
|
||||
{
|
||||
throw new IllegalArgumentException("Expected number (" + filename + ":" + lineNo + ")", ex);
|
||||
}
|
||||
if (chunks == null)
|
||||
{
|
||||
throw new IllegalArgumentException(filename + ": no data");
|
||||
}
|
||||
|
||||
this.chunks = chunks;
|
||||
this.planeOverrides = planeOverrides;
|
||||
this.stride = stride;
|
||||
this.x1 = x1;
|
||||
this.y1 = y1;
|
||||
this.x2 = x2;
|
||||
this.y2 = y2;
|
||||
}
|
||||
|
||||
private int chunkData(int cx, int cy, int plane, ChunkMapper chunkMapper)
|
||||
{
|
||||
if (chunkMapper != null)
|
||||
{
|
||||
int itp = chunkMapper.getTemplateChunk(cx, cy, plane);
|
||||
if (itp == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
cy = itp >> 3 & 0x7FF;
|
||||
cx = itp >> 14 & 0x3FF;
|
||||
plane = itp >> 24 & 0x3;
|
||||
}
|
||||
|
||||
if (cx < x1)
|
||||
{
|
||||
cx = x1;
|
||||
}
|
||||
if (cx >= x2)
|
||||
{
|
||||
cx = x2 - 1;
|
||||
}
|
||||
if (cy < y1)
|
||||
{
|
||||
cy = y1;
|
||||
}
|
||||
if (cy >= y2)
|
||||
{
|
||||
cy = y2 - 1;
|
||||
}
|
||||
|
||||
int cv = chunks[(stride * (cy - y1)) + (cx - x1)];
|
||||
if (cv == -1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if ((cv & 0x8000_0000) != 0)
|
||||
{
|
||||
cv = planeOverrides[(cv & 0x7FFF_FFFF) | plane];
|
||||
}
|
||||
return cv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the RGB color for a specific world coordinate. Arguments are floats for sub-tile accuracy.
|
||||
*
|
||||
* @param x X coordinate in tiles
|
||||
* @param y Y coordinate in tiles
|
||||
* @param chunkMapper maps chunks to their instance templates, or null if not in an instance
|
||||
*/
|
||||
public int getColorForPoint(double x, double y, int plane, double brightness, ChunkMapper chunkMapper)
|
||||
{
|
||||
x /= 8.d;
|
||||
y /= 8.d;
|
||||
|
||||
int cx = (int) x;
|
||||
int cy = (int) y;
|
||||
|
||||
int centerChunkData = chunkData(cx, cy, plane, chunkMapper);
|
||||
if (centerChunkData == -1)
|
||||
{
|
||||
// No data in the center chunk?
|
||||
return 0;
|
||||
}
|
||||
|
||||
double t = 0;
|
||||
double ty = 0;
|
||||
double tco = 0;
|
||||
double tcg = 0;
|
||||
|
||||
int xmin = (int) (x - BLEND_RADIUS);
|
||||
int xmax = (int) Math.ceil(x + BLEND_RADIUS);
|
||||
int ymin = (int) (y - BLEND_RADIUS);
|
||||
int ymax = (int) Math.ceil(y + BLEND_RADIUS);
|
||||
|
||||
for (int ucx = xmin; ucx < xmax; ucx++)
|
||||
{
|
||||
for (int ucy = ymin; ucy <= ymax; ucy++)
|
||||
{
|
||||
int val = chunkData(ucx, ucy, plane, chunkMapper);
|
||||
if (val == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get the blend value, add 1/8 tile to make sure we don't div/0, convert to chunks
|
||||
double sigma = ((val >>> 24) + .125) / 8.d;
|
||||
|
||||
// Calculate how far we have to be away before we can discard this value without
|
||||
// becoming visibly discontinuous
|
||||
double minDist = 1 + (sigma * BLEND_DISTRIBUTION);
|
||||
|
||||
// Try to fast-fail
|
||||
double dxl = ucx - x;
|
||||
double dxh = dxl + 1.d;
|
||||
if (dxl < -minDist || dxl > minDist)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
double dyl = ucy - y;
|
||||
double dyh = dyl + 1.d;
|
||||
if (dyl < -minDist || dyh > minDist)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Calculate integrate a gaussian distribution in each dimension for
|
||||
// this chunk relative to the requested point
|
||||
double erfdivc = sigma * SQRT2;
|
||||
double m = (erf(dxl / erfdivc) - erf(dxh / erfdivc)) * (erf(dyl / erfdivc) - erf(dyh / erfdivc));
|
||||
|
||||
// Load our YCoCg24 values into floats
|
||||
double vy = (val >>> 16 & 0xFF) / 255.d;
|
||||
double vco = (byte) (val >>> 8) / 128.d;
|
||||
double vcg = (byte) val / 128.d;
|
||||
|
||||
// And multiply by the weight
|
||||
ty += vy * m;
|
||||
tco += vco * m;
|
||||
tcg += vcg * m;
|
||||
t += m;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert back to int range values, and bounds check while we are at it
|
||||
byte ay = (byte) Math.min(Math.max(Math.round(Math.pow(ty / t, brightness) * 255.d), 0), 255);
|
||||
byte aco = (byte) Math.min(Math.max(Math.round(tco * 128.d / t), -128), 127);
|
||||
byte acg = (byte) Math.min(Math.max(Math.round(tcg * 128.d / t), -128), 127);
|
||||
|
||||
// convert back to rgb from YCoCg24
|
||||
int g = (ay - (acg >> 1)) & 0xFF;
|
||||
int tmp = (g + acg) & 0xFF;
|
||||
int r = (tmp - (aco >> 1)) & 0xFF;
|
||||
int b = (r + aco) & 0xFF;
|
||||
|
||||
return r << 16 | g << 8 | b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Approximation of erf 'Gauss error function' which is used to calculate
|
||||
* the cumulative distribution of a gaussian distribution.
|
||||
* This is used to simulate a large kernel gaussian blur without having
|
||||
* to sample the same chunk multiple times.
|
||||
*/
|
||||
private double erf(double x)
|
||||
{
|
||||
double ax = Math.abs(x);
|
||||
double t = 1.d / (1.d + (ax * .3275911d));
|
||||
double y = 1.d - ((((((1.061405429d * t) - 1.453152027d) * t) + 1.421413741d) * t - 0.284496736d) * t + 0.254829592d) * t * Math.exp(-ax * ax);
|
||||
return Math.copySign(y, x);
|
||||
}
|
||||
|
||||
/**
|
||||
* Draws the skybox map to an image
|
||||
*
|
||||
* @param resolution The number of pixels per tile
|
||||
* @param line How many tiles to put a line
|
||||
* @param plane the plane (0-4) to render
|
||||
*/
|
||||
BufferedImage render(double resolution, int line, int plane, ChunkMapper chunkMapper)
|
||||
{
|
||||
int w = (int) (((x2 - x1) * 8) * resolution);
|
||||
int h = (int) (((y2 - y1) * 8) * resolution);
|
||||
BufferedImage img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
|
||||
int lineEvery = line <= 0 ? Integer.MAX_VALUE : (int) (line * resolution);
|
||||
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
int color;
|
||||
if (x % lineEvery == 0 || y % lineEvery == 0)
|
||||
{
|
||||
color = 0x00FFFFFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
double fx = (x1 * 8) + (x / resolution);
|
||||
double fy = (y1 * 8) + (y / resolution);
|
||||
color = getColorForPoint(fx, fy, plane, .8, chunkMapper);
|
||||
}
|
||||
img.setRGB(x, h - 1 - y, color | 0xFF000000);
|
||||
}
|
||||
}
|
||||
|
||||
return img;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.skybox;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.io.IOException;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.api.Player;
|
||||
import net.runelite.api.coords.LocalPoint;
|
||||
import net.runelite.api.events.BeforeRender;
|
||||
import net.runelite.api.events.GameStateChanged;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Skybox",
|
||||
description = "Draws a oldschool styled skybox",
|
||||
enabledByDefault = false,
|
||||
tags = {"sky"}
|
||||
)
|
||||
public class SkyboxPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
private Skybox skybox;
|
||||
|
||||
@Override
|
||||
public void startUp() throws IOException
|
||||
{
|
||||
skybox = new Skybox(SkyboxPlugin.class.getResourceAsStream("skybox.txt"), "skybox.txt");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
client.setSkyboxColor(0);
|
||||
skybox = null;
|
||||
}
|
||||
|
||||
private int mapChunk(int cx, int cy, int plane)
|
||||
{
|
||||
cx -= client.getBaseX() / 8;
|
||||
cy -= client.getBaseY() / 8;
|
||||
|
||||
int[][] instanceTemplateChunks = client.getInstanceTemplateChunks()[plane];
|
||||
// Blending can access this out of bounds, so do a range check
|
||||
if (cx < 0 || cx >= instanceTemplateChunks.length || cy < 0 || cy >= instanceTemplateChunks[cx].length)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return instanceTemplateChunks[cx][cy];
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onBeforeRender(BeforeRender r)
|
||||
{
|
||||
if (skybox == null || client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Player player = client.getLocalPlayer();
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int px, py;
|
||||
if (client.getOculusOrbState() == 1)
|
||||
{
|
||||
px = client.getOculusOrbFocalPointX();
|
||||
py = client.getOculusOrbFocalPointY();
|
||||
}
|
||||
else
|
||||
{
|
||||
LocalPoint p = client.getLocalPlayer().getLocalLocation();
|
||||
px = p.getX();
|
||||
py = p.getY();
|
||||
}
|
||||
|
||||
// Inverse of camera location / 2
|
||||
int spx = px - ((client.getCameraX() - px) >> 1);
|
||||
int spy = py - ((client.getCameraY() - py) >> 1);
|
||||
|
||||
client.setSkyboxColor(skybox.getColorForPoint(
|
||||
client.getBaseX() + (spx / 128.f),
|
||||
client.getBaseY() + (spy / 128.f),
|
||||
client.getPlane(),
|
||||
client.getTextureProvider().getBrightness(),
|
||||
client.isInInstancedRegion() ? this::mapChunk : null
|
||||
));
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged gameStateChanged)
|
||||
{
|
||||
if (gameStateChanged.getGameState() == GameState.LOGIN_SCREEN)
|
||||
{
|
||||
client.setSkyboxColor(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,925 @@
|
||||
// Copyright (c) 2019, Abex
|
||||
// Copyright (c) 2019, Psikoi <https://github.com/psikoi>
|
||||
// Copyright (c) 2019, Ron Young <https://github.com/raiyni>
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this
|
||||
// list of conditions and the following disclaimer.
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
// Skybox format
|
||||
//
|
||||
// Comments are c-style; Starts with // and ends with the next newline
|
||||
//
|
||||
// The first expression must be
|
||||
// bounds rx1 ry1 rx2 ry2
|
||||
// which sets the bounds of the image
|
||||
//
|
||||
// Color is set with #RRGGBB or #RGB and persists until set again
|
||||
// Blending is set with b<blend radius>. It persists until set again. The number is in tiles, up to 13
|
||||
//
|
||||
// p <0> <1> <2> <3>
|
||||
// p all
|
||||
// Sets a mask for the planes to be altered by the next operation
|
||||
//
|
||||
// m <region X> <region Y>
|
||||
// Moves the cursor to the specified region. This does not change any chunks
|
||||
//
|
||||
// The following operations commit chunks to the map:
|
||||
//
|
||||
// r <region X> <region Y>
|
||||
// Sets all of the chunks in a region to the current color and blending
|
||||
//
|
||||
// R <region X 1> <region Y 1> <region X 2> <region Y 2>
|
||||
// Sets all of the chunks in [x1,x2] [y1,y2] are set to the current color and blending
|
||||
//
|
||||
// c <chunk X> <chunk Y>
|
||||
// Sets the chunk relative to the last region/region1 to the current color and blending
|
||||
//
|
||||
// C <chunk X 1> <chunk Y 1> <chunk X 2> <chunk Y 2>
|
||||
// Sets the chunks relative to the last region/region1 to the current color and blending
|
||||
|
||||
bounds 18 39 60 162
|
||||
|
||||
b 8
|
||||
|
||||
#8AD2DF
|
||||
R 18 39 60 64
|
||||
|
||||
#0f0f0f
|
||||
r 34 75
|
||||
|
||||
#161616
|
||||
R 47 61 53 62
|
||||
|
||||
#181818
|
||||
R 37 79 39 80
|
||||
|
||||
#1a1a1a
|
||||
R 47 60 53 60
|
||||
|
||||
#202020
|
||||
R 46 59 53 59
|
||||
|
||||
#242424
|
||||
r 29 81
|
||||
|
||||
#242e2c
|
||||
r 56 160
|
||||
|
||||
#262626
|
||||
R 46 58 53 58
|
||||
r 24 79
|
||||
|
||||
#271010
|
||||
R 46 74 48 75
|
||||
r 47 76
|
||||
|
||||
#2a2f42
|
||||
r 38 75
|
||||
|
||||
#2b2b2b
|
||||
R 46 57 53 57
|
||||
R 55 62 56 62
|
||||
r 45 151
|
||||
|
||||
#2e2e2e
|
||||
R 36 147 37 147
|
||||
|
||||
#323232
|
||||
R 46 56 52 56
|
||||
R 51 74 52 75
|
||||
R 54 75 55 76
|
||||
R 58 58 59 58
|
||||
r 59 59
|
||||
|
||||
#332a15
|
||||
R 26 73 27 73
|
||||
R 27 80 27 81
|
||||
R 27 158 28 158
|
||||
R 29 84 29 85
|
||||
R 30 72 31 72
|
||||
R 36 153 36 154
|
||||
R 37 150 41 154
|
||||
R 39 147 42 149
|
||||
R 40 69 40 70
|
||||
R 40 81 40 82
|
||||
R 41 70 41 71
|
||||
R 41 79 42 79
|
||||
R 42 142 43 142
|
||||
R 42 150 42 152
|
||||
R 44 148 44 150
|
||||
R 44 152 49 153
|
||||
R 45 150 46 150
|
||||
R 46 161 47 161
|
||||
R 47 151 48 151
|
||||
R 48 150 49 150
|
||||
R 48 154 50 155
|
||||
R 49 77 49 79
|
||||
R 52 152 52 153
|
||||
r 20 155
|
||||
r 22 157
|
||||
r 24 154
|
||||
r 28 66
|
||||
r 30 80
|
||||
r 31 81
|
||||
r 34 77
|
||||
r 34 85
|
||||
r 35 73
|
||||
r 35 75
|
||||
r 35 156
|
||||
r 36 79
|
||||
r 36 146
|
||||
r 36 150
|
||||
r 37 73
|
||||
r 37 148
|
||||
r 38 147
|
||||
r 39 145
|
||||
r 41 75
|
||||
r 41 146
|
||||
r 42 154
|
||||
r 43 146
|
||||
r 43 149
|
||||
r 45 79
|
||||
r 45 148
|
||||
r 45 154
|
||||
r 46 149
|
||||
r 47 85
|
||||
r 47 87
|
||||
r 47 160
|
||||
r 48 148
|
||||
r 50 151
|
||||
r 51 147
|
||||
r 54 151
|
||||
r 54 153
|
||||
r 58 88
|
||||
|
||||
#342b29
|
||||
R 50 144 51 144
|
||||
|
||||
#353535
|
||||
R 42 81 42 83
|
||||
|
||||
#383838
|
||||
R 46 55 52 55
|
||||
|
||||
#393326
|
||||
R 51 77 51 79
|
||||
|
||||
#3c3c3c
|
||||
r 30 73
|
||||
r 39 73
|
||||
r 49 81
|
||||
|
||||
#3e3e3e
|
||||
r 48 52
|
||||
|
||||
#3f384a
|
||||
R 25 156 26 157
|
||||
|
||||
#40645d
|
||||
r 49 49
|
||||
|
||||
#406e8c
|
||||
R 37 68 38 69
|
||||
r 26 154
|
||||
r 36 69
|
||||
|
||||
#413d2d
|
||||
r 50 145
|
||||
|
||||
#424242
|
||||
r 50 150
|
||||
|
||||
#424940
|
||||
R 29 68 30 68
|
||||
R 38 158 39 158
|
||||
R 42 69 43 71
|
||||
R 45 68 45 69
|
||||
R 49 149 50 149
|
||||
R 55 151 56 151
|
||||
R 58 151 58 152
|
||||
r 39 72
|
||||
r 39 156
|
||||
r 51 150
|
||||
r 53 150
|
||||
r 53 154
|
||||
r 55 154
|
||||
r 56 150
|
||||
|
||||
#474747
|
||||
R 50 146 51 146
|
||||
r 25 83
|
||||
r 27 83
|
||||
|
||||
#49432a
|
||||
R 25 152 26 153
|
||||
R 51 148 52 149
|
||||
r 42 76
|
||||
r 46 148
|
||||
r 53 149
|
||||
r 54 148
|
||||
|
||||
#496e53
|
||||
r 33 82
|
||||
|
||||
#4a706a
|
||||
R 18 54 19 54
|
||||
R 20 54 21 56
|
||||
R 31 78 38 78
|
||||
R 34 47 34 48
|
||||
R 42 73 43 74
|
||||
R 54 50 56 50
|
||||
R 54 51 57 55
|
||||
R 56 58 56 59
|
||||
R 56 141 57 142
|
||||
R 57 57 57 58
|
||||
R 58 51 58 53
|
||||
r 43 72
|
||||
r 44 71
|
||||
r 53 55
|
||||
r 53 77
|
||||
|
||||
#4a718f
|
||||
R 25 58 25 59
|
||||
r 26 58
|
||||
|
||||
#4c463a
|
||||
R 58 146 58 147
|
||||
r 59 147
|
||||
|
||||
#4f4f4f
|
||||
r 48 81
|
||||
|
||||
#51649c
|
||||
r 37 59
|
||||
r 39 58
|
||||
|
||||
#543232
|
||||
r 32 76
|
||||
r 36 75
|
||||
r 36 81
|
||||
r 46 81
|
||||
r 47 83
|
||||
|
||||
#553d75
|
||||
R 26 60 28 60
|
||||
|
||||
#57493e
|
||||
r 35 83
|
||||
|
||||
#575757
|
||||
R 49 157 50 159
|
||||
R 52 150 52 151
|
||||
|
||||
#576f6f
|
||||
r 56 159
|
||||
|
||||
#606060
|
||||
r 43 75
|
||||
|
||||
#64554b
|
||||
R 22 59 22 60
|
||||
R 23 58 23 59
|
||||
r 24 58
|
||||
|
||||
#665742
|
||||
r 40 75
|
||||
|
||||
#697387
|
||||
R 40 57 41 57
|
||||
r 36 57
|
||||
r 41 58
|
||||
|
||||
#6a5151
|
||||
r 39 75
|
||||
|
||||
#6d758e
|
||||
R 44 55 45 57
|
||||
r 43 56
|
||||
|
||||
#707b98
|
||||
R 32 60 32 61
|
||||
r 33 61
|
||||
r 34 59
|
||||
|
||||
#7fc7d9
|
||||
R 27 53 28 53
|
||||
R 27 58 28 58
|
||||
R 29 54 29 55
|
||||
R 38 44 40 44
|
||||
R 42 42 43 43
|
||||
R 42 49 43 50
|
||||
R 43 45 46 48
|
||||
R 44 49 45 49
|
||||
R 49 45 49 47
|
||||
R 50 43 51 44
|
||||
R 50 45 53 48
|
||||
R 51 49 52 51
|
||||
R 57 46 59 47
|
||||
r 28 57
|
||||
r 45 42
|
||||
r 52 44
|
||||
r 53 49
|
||||
r 54 48
|
||||
r 57 60
|
||||
|
||||
#817843
|
||||
R 58 160 59 160
|
||||
|
||||
#85857a
|
||||
R 45 70 46 71
|
||||
r 25 77
|
||||
r 27 77
|
||||
r 47 68
|
||||
|
||||
#89a4ab
|
||||
r 44 51
|
||||
r 59 44
|
||||
|
||||
#a4d3df
|
||||
R 25 75 26 75
|
||||
R 28 75 31 75
|
||||
r 28 74
|
||||
r 37 75
|
||||
r 38 71
|
||||
r 42 75
|
||||
r 47 73
|
||||
r 49 75
|
||||
|
||||
#a5996a
|
||||
r 29 72
|
||||
|
||||
#a5d5e1
|
||||
R 25 86 26 89
|
||||
R 28 76 31 76
|
||||
R 30 86 31 87
|
||||
R 32 86 33 86
|
||||
R 33 76 33 77
|
||||
R 40 73 41 74
|
||||
R 53 90 54 92
|
||||
R 54 74 55 74
|
||||
R 54 89 55 89
|
||||
r 26 66
|
||||
r 28 70
|
||||
r 30 83
|
||||
r 32 84
|
||||
r 36 71
|
||||
r 38 84
|
||||
r 40 71
|
||||
r 44 75
|
||||
r 44 79
|
||||
r 45 73
|
||||
r 45 85
|
||||
r 47 70
|
||||
r 53 78
|
||||
r 55 90
|
||||
r 57 154
|
||||
|
||||
#b2b595
|
||||
r 40 67
|
||||
|
||||
#b6cbd8
|
||||
R 22 61 28 62
|
||||
R 36 60 37 60
|
||||
R 42 59 42 61
|
||||
R 42 159 43 159
|
||||
R 43 58 45 61
|
||||
r 24 60
|
||||
r 29 60
|
||||
r 32 75
|
||||
r 44 155
|
||||
r 47 158
|
||||
r 53 76
|
||||
|
||||
#dbd9db
|
||||
r 45 75
|
||||
|
||||
// RegionID 4663
|
||||
m 18 55
|
||||
#4a706a
|
||||
C 0 0 5 7
|
||||
#527874
|
||||
C 6 0 7 1
|
||||
#668d8d
|
||||
C 6 2 7 7
|
||||
|
||||
// RegionID 4664
|
||||
m 18 56
|
||||
#4a706a
|
||||
C 0 0 5 7
|
||||
C 6 2 7 7
|
||||
#608786
|
||||
C 6 0 7 1
|
||||
|
||||
// RegionID 4919
|
||||
m 19 55
|
||||
C 6 0 7 1
|
||||
#668d8d
|
||||
C 0 0 5 1
|
||||
#8dbac1
|
||||
C 6 2 7 7
|
||||
#9dccd6
|
||||
C 0 2 5 7
|
||||
|
||||
// RegionID 4920
|
||||
m 19 56
|
||||
#4a706a
|
||||
C 0 2 7 7
|
||||
#80aab0
|
||||
C 6 0 7 1
|
||||
#8dbac1
|
||||
C 0 0 5 1
|
||||
|
||||
// RegionID 5689
|
||||
m 22 57
|
||||
#4a706a
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 5690
|
||||
m 22 58
|
||||
C 0 0 7 1
|
||||
#64554b
|
||||
C 0 2 7 7
|
||||
|
||||
// RegionID 5945
|
||||
m 23 57
|
||||
#4a706a
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 5948
|
||||
m 23 60
|
||||
#64554b
|
||||
C 0 0 5 5
|
||||
C 0 6 3 7
|
||||
C 6 0 7 3
|
||||
#b6cbd8
|
||||
C 4 6 7 7
|
||||
C 6 4 7 5
|
||||
|
||||
// RegionID 6201
|
||||
m 24 57
|
||||
#4a706a
|
||||
C 0 4 3 7
|
||||
|
||||
// RegionID 6203
|
||||
m 24 59
|
||||
#4a718f
|
||||
C 4 2 7 7
|
||||
C 6 0 7 1
|
||||
#64554b
|
||||
C 0 0 3 7
|
||||
C 4 0 5 1
|
||||
|
||||
// RegionID 6460
|
||||
m 25 60
|
||||
#4a718f
|
||||
C 0 0 5 1
|
||||
#553d75
|
||||
C 0 2 7 5
|
||||
C 4 6 7 7
|
||||
C 6 0 7 1
|
||||
#adc0cf
|
||||
C 2 6 3 7
|
||||
#b6cbd8
|
||||
C 0 6 1 7
|
||||
|
||||
// RegionID 6710
|
||||
m 26 54
|
||||
#7fc7d9
|
||||
C 0 0 7 3
|
||||
|
||||
// RegionID 6715
|
||||
m 26 59
|
||||
#4a718f
|
||||
C 0 0 5 7
|
||||
C 6 0 7 5
|
||||
b 5
|
||||
#4d020a
|
||||
C 5 5 8 8
|
||||
b 8
|
||||
|
||||
// RegionID 6966
|
||||
m 27 54
|
||||
#7fc7d9
|
||||
C 0 0 7 3
|
||||
|
||||
// RegionID 6971
|
||||
m 27 59
|
||||
#553d75
|
||||
C 2 6 7 7
|
||||
#5e2423
|
||||
C 0 6 1 7
|
||||
#7fc7d9
|
||||
C 0 0 7 3
|
||||
|
||||
// RegionID 7222
|
||||
m 28 54
|
||||
C 0 0 7 3
|
||||
C 6 4 7 7
|
||||
|
||||
// RegionID 7223
|
||||
m 28 55
|
||||
C 6 0 7 7
|
||||
|
||||
// RegionID 7224
|
||||
m 28 56
|
||||
C 4 0 7 7
|
||||
|
||||
// RegionID 7227
|
||||
m 28 59
|
||||
#553d75
|
||||
C 0 6 7 7
|
||||
#7fc7d9
|
||||
C 0 0 7 3
|
||||
C 4 4 7 5
|
||||
|
||||
// RegionID 8508
|
||||
m 33 60
|
||||
#707b98
|
||||
C 0 0 1 3
|
||||
C 0 4 7 7
|
||||
#838aa1
|
||||
C 2 0 7 3
|
||||
|
||||
// RegionID 9007
|
||||
m 35 47
|
||||
#3b4f4d
|
||||
C 2 6 5 7
|
||||
#4a706a
|
||||
C 0 0 7 5
|
||||
C 0 6 1 7
|
||||
C 6 6 7 7
|
||||
|
||||
// RegionID 9008
|
||||
m 35 48
|
||||
#384947
|
||||
C 2 0 5 1
|
||||
#4a706a
|
||||
C 0 2 7 7
|
||||
C 0 0 1 1
|
||||
C 6 0 7 1
|
||||
|
||||
// RegionID 10029
|
||||
m 39 45
|
||||
#7fc7d9
|
||||
C 0 0 7 1
|
||||
|
||||
// RegionID 10040
|
||||
m 39 56
|
||||
#6d758e
|
||||
C 0 4 3 7
|
||||
|
||||
// RegionID 10044
|
||||
m 39 60
|
||||
#b6cbd8
|
||||
C 0 6 7 7
|
||||
|
||||
// RegionID 10055
|
||||
m 39 71
|
||||
#a4d3df
|
||||
C 0 0 1 7
|
||||
#a5d5e1
|
||||
C 2 0 7 7
|
||||
|
||||
// RegionID 10285
|
||||
m 40 45
|
||||
#7fc7d9
|
||||
C 2 0 7 3
|
||||
C 4 4 7 5
|
||||
C 0 0 1 1
|
||||
C 6 6 7 7
|
||||
|
||||
// RegionID 10555
|
||||
m 41 59
|
||||
#b6cbd8
|
||||
C 6 0 7 7
|
||||
|
||||
// RegionID 10556
|
||||
m 41 60
|
||||
C 6 0 7 7
|
||||
|
||||
// RegionID 10810
|
||||
m 42 58
|
||||
#869dcc
|
||||
C 0 0 3 3
|
||||
#b6cbd8
|
||||
C 0 4 7 7
|
||||
C 4 0 7 3
|
||||
|
||||
// RegionID 10905
|
||||
m 42 153
|
||||
#332a15
|
||||
C 2 0 5 5
|
||||
C 6 0 7 1
|
||||
#a9bbc6
|
||||
C 6 2 7 3
|
||||
#b3c7d3
|
||||
C 0 2 1 5
|
||||
C 2 6 5 7
|
||||
C 6 4 7 5
|
||||
#b6cbd8
|
||||
C 0 0 1 1
|
||||
C 0 6 1 7
|
||||
C 6 6 7 7
|
||||
|
||||
// RegionID 11062
|
||||
m 43 54
|
||||
C 6 6 7 7
|
||||
|
||||
// RegionID 11065
|
||||
m 43 57
|
||||
#6d758e
|
||||
C 0 0 7 3
|
||||
#b6cbd8
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 11314
|
||||
m 44 50
|
||||
#89a4ab
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 11317
|
||||
m 44 53
|
||||
#b6cbd8
|
||||
C 4 6 7 7
|
||||
|
||||
// RegionID 11318
|
||||
m 44 54
|
||||
C 0 4 1 7
|
||||
C 2 2 7 7
|
||||
C 4 0 7 1
|
||||
|
||||
// RegionID 11418
|
||||
m 44 154
|
||||
#332a15
|
||||
C 0 0 7 3
|
||||
#acbfcb
|
||||
C 0 4 7 5
|
||||
#b6cbd8
|
||||
C 0 6 7 7
|
||||
|
||||
// RegionID 11675
|
||||
m 45 155
|
||||
C 0 0 1 7
|
||||
|
||||
// RegionID 11825
|
||||
m 46 49
|
||||
#7fc7d9
|
||||
C 0 0 7 3
|
||||
C 6 4 7 5
|
||||
|
||||
// RegionID 11830
|
||||
m 46 54
|
||||
#b6cbd8
|
||||
C 6 0 7 5
|
||||
|
||||
// RegionID 11836
|
||||
m 46 60
|
||||
#1a1a1a
|
||||
C 2 0 3 3
|
||||
C 4 0 7 7
|
||||
#b4c9d6
|
||||
C 2 4 3 5
|
||||
#b6cbd8
|
||||
C 0 0 1 7
|
||||
C 2 6 3 7
|
||||
|
||||
// RegionID 11837
|
||||
m 46 61
|
||||
#161616
|
||||
C 6 0 7 9
|
||||
#b6cbd8
|
||||
C 0 0 5 9
|
||||
|
||||
// RegionID 12081
|
||||
m 47 49
|
||||
#7fc7d9
|
||||
C 0 0 3 5
|
||||
|
||||
// RegionID 12086
|
||||
m 47 54
|
||||
#b6cbd8
|
||||
C 0 0 1 5
|
||||
|
||||
// RegionID 12113
|
||||
m 47 81
|
||||
#4f4f4f
|
||||
C 0 0 3 3
|
||||
C 4 4 7 7
|
||||
#543232
|
||||
C 0 4 3 7
|
||||
C 4 0 7 3
|
||||
|
||||
// RegionID 12181
|
||||
m 47 149
|
||||
#332a15
|
||||
C 0 0 1 7
|
||||
#b6cbd8
|
||||
C 2 0 7 7
|
||||
|
||||
// RegionID 12339
|
||||
m 48 51
|
||||
#3e3e3e
|
||||
C 0 6 7 7
|
||||
|
||||
// RegionID 12437
|
||||
m 48 149
|
||||
#332a15
|
||||
C 2 0 7 7
|
||||
#b6cbd8
|
||||
C 0 0 1 7
|
||||
|
||||
// RegionID 12444
|
||||
m 48 156
|
||||
#332a15
|
||||
C 0 0 7 3
|
||||
|
||||
// RegionID 12595
|
||||
m 49 51
|
||||
#3e3e3e
|
||||
C 0 6 1 7
|
||||
|
||||
// RegionID 12596
|
||||
m 49 52
|
||||
C 0 0 1 5
|
||||
|
||||
// RegionID 12849
|
||||
m 50 49
|
||||
#40645d
|
||||
C 0 0 5 7
|
||||
#426660
|
||||
C 6 0 7 7
|
||||
|
||||
// RegionID 13209
|
||||
m 51 153
|
||||
#3b3535
|
||||
C 0 0 3 3
|
||||
C 4 4 7 7
|
||||
#543232
|
||||
C 0 4 3 7
|
||||
C 4 0 7 3
|
||||
|
||||
// RegionID 13210
|
||||
m 51 154
|
||||
#332a15
|
||||
C 0 0 3 7
|
||||
|
||||
// RegionID 13618
|
||||
m 53 50
|
||||
#4a706a
|
||||
C 4 0 7 7
|
||||
#7fc7d9
|
||||
C 0 0 3 7
|
||||
|
||||
// RegionID 13619
|
||||
m 53 51
|
||||
#4a706a
|
||||
C 4 0 7 7
|
||||
#7fc7d9
|
||||
C 0 0 3 7
|
||||
|
||||
// RegionID 13620
|
||||
m 53 52
|
||||
#4a706a
|
||||
C 2 0 7 7
|
||||
|
||||
// RegionID 13621
|
||||
m 53 53
|
||||
C 2 0 7 7
|
||||
|
||||
// RegionID 13622
|
||||
m 53 54
|
||||
C 4 0 7 7
|
||||
|
||||
// RegionID 13873
|
||||
m 54 49
|
||||
C 0 4 7 7
|
||||
#7fc7d9
|
||||
C 0 0 7 3
|
||||
|
||||
// RegionID 14129
|
||||
m 55 49
|
||||
#4a706a
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 14385
|
||||
m 56 49
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 14641
|
||||
m 57 49
|
||||
#543232
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 14642
|
||||
m 57 50
|
||||
#4a706a
|
||||
C 0 6 7 7
|
||||
#543232
|
||||
C 0 0 7 5
|
||||
|
||||
// RegionID 14651
|
||||
m 57 59
|
||||
#4a706a
|
||||
C 0 0 7 3
|
||||
#7fc7d9
|
||||
C 0 4 7 7
|
||||
|
||||
// RegionID 14907
|
||||
m 58 59
|
||||
#323232
|
||||
C 0 0 7 3
|
||||
|
||||
// RegionID 14908
|
||||
m 58 60
|
||||
#7fc7d9
|
||||
C 0 0 3 7
|
||||
|
||||
|
||||
// Demonic Gorillas
|
||||
#1A2B2B
|
||||
R 32 88 33 88
|
||||
|
||||
// POH
|
||||
b 12
|
||||
m29 89
|
||||
|
||||
// 29 89 p0 Basic wood
|
||||
// 29 89 p1 Basic stone
|
||||
// 29 89 p3 Fremennik-style wood
|
||||
p 0 1 3
|
||||
#8AD2DF
|
||||
C 0 0 7 15
|
||||
p 0
|
||||
#251B09
|
||||
c 3 0
|
||||
c 0 3
|
||||
c 2 3
|
||||
c 4 3
|
||||
c 6 3
|
||||
c 7 4
|
||||
p 1
|
||||
#484840
|
||||
c 3 0
|
||||
c 0 3
|
||||
c 2 3
|
||||
c 4 3
|
||||
c 6 3
|
||||
c 7 4
|
||||
|
||||
// 29 89 p2 Whitewashed stone
|
||||
p 2
|
||||
#7fc7d9
|
||||
C 0 0 7 15
|
||||
p 2 3
|
||||
#2C2C29
|
||||
c 3 0
|
||||
c 0 3
|
||||
c 2 3
|
||||
c 4 3
|
||||
c 6 3
|
||||
c 7 4
|
||||
|
||||
m30 89
|
||||
|
||||
// 30 89 p0 Tropical wood
|
||||
p 0
|
||||
#7fc7d9
|
||||
C 0 0 7 15
|
||||
|
||||
// 30 89 p1 Fancy stone
|
||||
// 30 89 p2 Deathly mansion
|
||||
p 1 2
|
||||
#8AD2DF
|
||||
C 0 0 7 15
|
||||
|
||||
p 2
|
||||
#8AD2DF
|
||||
C 0 0 7 15
|
||||
|
||||
p all
|
||||
#2C2C29
|
||||
c 3 0
|
||||
c 0 3
|
||||
c 2 3
|
||||
c 4 3
|
||||
c 6 3
|
||||
c 7 4
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.skybox;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.io.CharSource;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import javax.imageio.ImageIO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
@Slf4j
|
||||
public class SkyboxTest
|
||||
{
|
||||
@Test
|
||||
public void testLoadSimple() throws IOException
|
||||
{
|
||||
Skybox skybox = new Skybox(CharSource.wrap("bounds 0 0 100 100 #00F // R 0 0 100 100\r\nr 99 99").openStream(), "simple");
|
||||
Assert.assertEquals(0, skybox.getColorForPoint(0, 0, 0, 1, null));
|
||||
Assert.assertEquals(0x0000FF, skybox.getColorForPoint((99 * 64) + 32, (99 * 64) + 32, 0, 1, null));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testLoadActual() throws IOException
|
||||
{
|
||||
long start = System.nanoTime();
|
||||
Skybox skybox = new Skybox(SkyboxPlugin.class.getResourceAsStream("skybox.txt"), "skybox.txt");
|
||||
log.info("Parse took {}ms", (System.nanoTime() - start) / 1_000_000);
|
||||
|
||||
String skyboxFile = System.getProperty("skyboxExport");
|
||||
if (!Strings.isNullOrEmpty(skyboxFile))
|
||||
{
|
||||
start = System.nanoTime();
|
||||
BufferedImage img = skybox.render(1f, 0, 0, null);
|
||||
long time = System.nanoTime() - start;
|
||||
log.info("Map render took {}ms", time / 1_000_000);
|
||||
log.info("Single render takes ~{}ns/frame", time / (img.getWidth() * img.getHeight()));
|
||||
ImageIO.write(img, "png", new File(skyboxFile));
|
||||
}
|
||||
|
||||
Assert.assertNotEquals(skybox.getColorForPoint(3232, 3232, 0, .9, null), 0); // Lumbridge will never be black
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,9 @@ public abstract class RSClientMixin implements RSClient
|
||||
@Inject
|
||||
private static boolean oldIsResized;
|
||||
|
||||
@Inject
|
||||
static int skyboxColor;
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public Callbacks getCallbacks()
|
||||
@@ -1381,4 +1384,18 @@ public abstract class RSClientMixin implements RSClient
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public void setSkyboxColor(int newSkyboxColor)
|
||||
{
|
||||
skyboxColor = newSkyboxColor;
|
||||
}
|
||||
|
||||
@Inject
|
||||
@Override
|
||||
public int getSkyboxColor()
|
||||
{
|
||||
return skyboxColor;
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,9 @@ public abstract class RSSceneMixin implements RSScene
|
||||
@Inject
|
||||
private static int[] tmpX = new int[6];
|
||||
|
||||
@Shadow("skyboxColor")
|
||||
static int skyboxColor;
|
||||
|
||||
@Inject
|
||||
private static int[] tmpY = new int[6];
|
||||
|
||||
@@ -80,6 +83,22 @@ public abstract class RSSceneMixin implements RSScene
|
||||
drawCallbacks.drawScene(cameraX, cameraY, cameraZ, cameraPitch, cameraYaw, plane);
|
||||
}
|
||||
|
||||
final boolean isGpu = client.isGpu();
|
||||
|
||||
if (!isGpu)
|
||||
{
|
||||
if (skyboxColor != 0)
|
||||
{
|
||||
client.RasterizerFillRectangle(
|
||||
client.getViewportXOffset(),
|
||||
client.getViewportYOffset(),
|
||||
client.getViewportWidth(),
|
||||
client.getViewportHeight(),
|
||||
skyboxColor
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
final int maxX = getMaxX();
|
||||
final int maxY = getMaxY();
|
||||
final int maxZ = getMaxZ();
|
||||
@@ -87,7 +106,6 @@ public abstract class RSSceneMixin implements RSScene
|
||||
final int minLevel = getMinLevel();
|
||||
|
||||
final RSTile[][][] tiles = getTiles();
|
||||
final boolean isGpu = client.isGpu();
|
||||
final int distance = isGpu ? rl$drawDistance : DEFAULT_DISTANCE;
|
||||
|
||||
if (cameraX < 0)
|
||||
|
||||
@@ -794,6 +794,14 @@ public interface RSClient extends RSGameEngine, Client
|
||||
@Override
|
||||
void setOculusOrbNormalSpeed(int state);
|
||||
|
||||
@Import("lookingAtX")
|
||||
@Override
|
||||
int getOculusOrbFocalPointX();
|
||||
|
||||
@Import("lookingAtY")
|
||||
@Override
|
||||
int getOculusOrbFocalPointY();
|
||||
|
||||
RSItem getLastItemDespawn();
|
||||
|
||||
void setLastItemDespawn(RSItem lastItemDespawn);
|
||||
@@ -896,6 +904,9 @@ public interface RSClient extends RSGameEngine, Client
|
||||
@Import("graphicsPixelsHeight")
|
||||
int getGraphicsPixelsHeight();
|
||||
|
||||
@Import("fillRectangle")
|
||||
void RasterizerFillRectangle(int x, int y, int w, int h, int rgb);
|
||||
|
||||
@Import("startX")
|
||||
int getStartX();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user