Some work on terrain rendering

This commit is contained in:
Adam
2016-12-26 19:29:34 -05:00
parent d5af1c6fdf
commit c23da5d33a
8 changed files with 388 additions and 160 deletions

View File

@@ -55,8 +55,8 @@ public class HeightMapDumper
public void load() throws IOException
{
regionLoader = new RegionLoader();
regionLoader.loadRegions(store);
regionLoader = new RegionLoader(store);
regionLoader.loadRegions();
regionLoader.calculateBounds();
}

View File

@@ -163,7 +163,8 @@ public class MapImageDumper
if (labelRegions)
{
graphics.setColor(Color.WHITE);
graphics.drawString(baseX + "," + baseY, drawBaseX * MAP_SCALE, drawBaseY * MAP_SCALE + graphics.getFontMetrics().getHeight());
String str = baseX + "," + baseY + " (" + region.getRegionX() + "," + region.getRegionY() + ")";
graphics.drawString(str, drawBaseX * MAP_SCALE, drawBaseY * MAP_SCALE + graphics.getFontMetrics().getHeight());
}
if (outlineRegions)
@@ -351,8 +352,8 @@ public class MapImageDumper
private void loadRegions(Store store) throws IOException
{
regionLoader = new RegionLoader();
regionLoader.loadRegions(store);
regionLoader = new RegionLoader(store);
regionLoader.loadRegions();
regionLoader.calculateBounds();
logger.info("North most region: {}", regionLoader.getLowestY().getBaseY());

View File

@@ -5,4 +5,99 @@ public class Vector3f
public float x;
public float y;
public float z;
public Vector3f()
{
}
public Vector3f(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public Vector3f(Vector3f other)
{
this.x = other.x;
this.y = other.y;
this.z = other.z;
}
@Override
public String toString()
{
return "Vector3f{" + "x=" + x + ", y=" + y + ", z=" + z + '}';
}
@Override
public int hashCode()
{
int hash = 7;
hash = 23 * hash + Float.floatToIntBits(this.x);
hash = 23 * hash + Float.floatToIntBits(this.y);
hash = 23 * hash + Float.floatToIntBits(this.z);
return hash;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
{
return true;
}
if (obj == null)
{
return false;
}
if (getClass() != obj.getClass())
{
return false;
}
final Vector3f other = (Vector3f) obj;
if (Float.floatToIntBits(this.x) != Float.floatToIntBits(other.x))
{
return false;
}
if (Float.floatToIntBits(this.y) != Float.floatToIntBits(other.y))
{
return false;
}
if (Float.floatToIntBits(this.z) != Float.floatToIntBits(other.z))
{
return false;
}
return true;
}
public float getX()
{
return x;
}
public void setX(float x)
{
this.x = x;
}
public float getY()
{
return y;
}
public void setY(float y)
{
this.y = y;
}
public float getZ()
{
return z;
}
public void setZ(float z)
{
this.z = z;
}
}

View File

@@ -57,6 +57,13 @@ public class Region
this.baseY = (id & 0xFF) << 6;
}
public Region(int x, int y)
{
this.regionID = x << 8 | y;
this.baseX = x << 6;
this.baseY = y << 6;
}
public void loadTerrain(byte[] buf)
{
InputStream in = new InputStream(buf);
@@ -202,4 +209,14 @@ public class Region
{
return locations;
}
public int getRegionX()
{
return baseX >> 6;
}
public int getRegionY()
{
return baseY >> 6;
}
}

View File

@@ -46,60 +46,75 @@ public class RegionLoader
private static final int MAX_REGION = 32768;
private final Store store;
private final Index index;
private final XteaKeyManager keyManager;
private final List<Region> regions = new ArrayList<>();
private Region lowestX = null, lowestY = null;
private Region highestX = null, highestY = null;
public void loadRegions(Store store) throws IOException
public RegionLoader(Store store)
{
Index index = store.getIndex(IndexType.MAPS);
XteaKeyManager keyManager = index.getXteaManager();
this.store = store;
index = store.getIndex(IndexType.MAPS);
keyManager = index.getXteaManager();
}
public void loadRegions() throws IOException
{
for (int i = 0; i < MAX_REGION; ++i)
{
int x = i >> 8;
int y = i & 0xFF;
Archive map = index.findArchiveByName("m" + x + "_" + y);
Archive land = index.findArchiveByName("l" + x + "_" + y);
assert (map == null) == (land == null);
if (map == null || land == null)
{
continue;
}
assert map.getFiles().size() == 1;
assert land.getFiles().size() == 1;
map.decompressAndLoad(null);
byte[] data = map.getFiles().get(0).getContents();
Region region = new Region(i);
region.loadTerrain(data);
int[] keys = keyManager.getKeys(i);
if (keys != null)
{
try
{
land.decompressAndLoad(keys);
data = land.getFiles().get(0).getContents();
region.loadLocations(data);
}
catch (IOException ex)
{
logger.debug("Can't decrypt region " + i, ex);
}
}
regions.add(region);
Region region = this.loadRegionFromArchive(i);
if (region != null)
regions.add(region);
}
}
public Region loadRegionFromArchive(int i) throws IOException
{
int x = i >> 8;
int y = i & 0xFF;
Archive map = index.findArchiveByName("m" + x + "_" + y);
Archive land = index.findArchiveByName("l" + x + "_" + y);
assert (map == null) == (land == null);
if (map == null || land == null)
{
return null;
}
assert map.getFiles().size() == 1;
assert land.getFiles().size() == 1;
map.decompressAndLoad(null);
byte[] data = map.getFiles().get(0).getContents();
Region region = new Region(i);
region.loadTerrain(data);
int[] keys = keyManager.getKeys(i);
if (keys != null)
{
try
{
land.decompressAndLoad(keys);
data = land.getFiles().get(0).getContents();
region.loadLocations(data);
}
catch (IOException ex)
{
logger.debug("Can't decrypt region " + i, ex);
}
}
return region;
}
public void calculateBounds()
{
for (Region region : regions)

View File

@@ -0,0 +1,85 @@
/*
* Copyright (c) 2016, Adam <Adam@sigterm.info>
* 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Adam <Adam@sigterm.info>
* 4. Neither the name of the Adam <Adam@sigterm.info> nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Adam <Adam@sigterm.info> ''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 Adam <Adam@sigterm.info> 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.cache;
import com.google.common.io.Files;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.io.IOException;
import java.nio.charset.Charset;
import net.runelite.cache.definitions.OverlayDefinition;
import net.runelite.cache.definitions.loaders.OverlayLoader;
import net.runelite.cache.fs.Archive;
import net.runelite.cache.fs.File;
import net.runelite.cache.fs.Index;
import net.runelite.cache.fs.Store;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class OverlayDumper
{
private static final Logger logger = LoggerFactory.getLogger(OverlayDumper.class);
@Rule
public TemporaryFolder folder = StoreLocation.getTemporaryFolder();
private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
@Test
public void extract() throws IOException
{
java.io.File base = StoreLocation.LOCATION,
outDir = folder.newFile();
int count = 0;
try (Store store = new Store(base))
{
store.load();
Index index = store.getIndex(IndexType.CONFIGS);
Archive archive = index.getArchive(ConfigType.OVERLAY.getId());
for (File file : archive.getFiles())
{
OverlayLoader loader = new OverlayLoader();
OverlayDefinition overlay = loader.load(file.getFileId(), file.getContents());
Files.write(gson.toJson(overlay), new java.io.File(outDir, file.getFileId() + ".json"), Charset.defaultCharset());
++count;
}
}
logger.info("Dumped {} overlays to {}", count, outDir);
}
}