Removed test classes, improved ION error handling & performance.
This commit is contained in:
@@ -295,6 +295,7 @@ public class Render {
|
||||
* Load texture
|
||||
*
|
||||
* @param resourcePath
|
||||
* @param filtering filtering mode to use while loading.
|
||||
* @return the loaded texture
|
||||
*/
|
||||
public synchronized static Texture loadTexture(String resourcePath, FilterMode filtering)
|
||||
|
||||
@@ -6,7 +6,6 @@ import java.util.Locale;
|
||||
|
||||
import mightypork.gamecore.control.BaseApp;
|
||||
import mightypork.gamecore.control.GameLoop;
|
||||
import mightypork.gamecore.control.events.ScreenRequestEvent;
|
||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||
import mightypork.gamecore.input.InputSystem;
|
||||
import mightypork.gamecore.input.KeyStroke;
|
||||
@@ -23,8 +22,11 @@ import mightypork.rogue.screens.main_menu.ScreenMainMenu;
|
||||
import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
|
||||
import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;
|
||||
import mightypork.rogue.screens.test_render.ScreenTestRender;
|
||||
import mightypork.rogue.world.item.Item;
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
import mightypork.util.control.eventbus.EventBus;
|
||||
import mightypork.util.control.eventbus.events.Event;
|
||||
import mightypork.util.files.ion.Ion;
|
||||
import mightypork.util.logging.Log;
|
||||
import mightypork.util.logging.writers.LogWriter;
|
||||
|
||||
@@ -34,7 +36,7 @@ import mightypork.util.logging.writers.LogWriter;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class App extends BaseApp {
|
||||
public final class App extends BaseApp {
|
||||
|
||||
/**
|
||||
* Launcher
|
||||
@@ -100,6 +102,13 @@ public class App extends BaseApp {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void preInit()
|
||||
{
|
||||
Ion.registerIonizable(Tile.ION_MARK, Tile.class);
|
||||
Ion.registerIonizable(Item.ION_MARK, Item.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected File getLockFile()
|
||||
{
|
||||
|
||||
@@ -10,7 +10,7 @@ import mightypork.util.logging.Log;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Config {
|
||||
public final class Config {
|
||||
|
||||
private static PropertyManager mgr;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ package mightypork.rogue;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Const {
|
||||
public final class Const {
|
||||
|
||||
// STRINGS
|
||||
public static final int VERSION = 1;
|
||||
|
||||
@@ -17,7 +17,7 @@ import mightypork.util.control.Action;
|
||||
import mightypork.util.logging.Log;
|
||||
|
||||
|
||||
public class MainLoop extends GameLoop implements ActionRequest.Listener {
|
||||
public final class MainLoop extends GameLoop implements ActionRequest.Listener {
|
||||
|
||||
public MainLoop(BaseApp app) {
|
||||
super(app);
|
||||
|
||||
@@ -6,7 +6,7 @@ import java.io.File;
|
||||
import mightypork.util.files.OsUtils;
|
||||
|
||||
|
||||
public class Paths {
|
||||
public final class Paths {
|
||||
|
||||
private static final String APPDIR_NAME = "rogue";
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.newdawn.slick.opengl.Texture;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Res {
|
||||
public final class Res {
|
||||
|
||||
private static TextureBank textures;
|
||||
private static SoundBank sounds;
|
||||
|
||||
@@ -6,7 +6,7 @@ package mightypork.rogue.util;
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class Utils {
|
||||
public final class Utils {
|
||||
|
||||
public static Thread runAsThread(Runnable r)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
import mightypork.util.control.timing.Updateable;
|
||||
import mightypork.util.files.ion.Ion;
|
||||
import mightypork.util.files.ion.Ionizable;
|
||||
|
||||
|
||||
/**
|
||||
* Abstract entity
|
||||
*
|
||||
* @author MightyPork
|
||||
* @param <D> Data object class
|
||||
* @param <M> Model class
|
||||
* @param <R> Render context class
|
||||
*/
|
||||
public abstract class Entity<D, M extends EntityModel<D, R>, R extends RectBound> implements Ionizable, Updateable {
|
||||
|
||||
protected M model;
|
||||
protected D data;
|
||||
|
||||
|
||||
/**
|
||||
* Used by Ion for loading.
|
||||
*/
|
||||
public Entity() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create from model
|
||||
*
|
||||
* @param model model
|
||||
*/
|
||||
public Entity(M model) {
|
||||
setModel(model);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void loadFrom(InputStream in) throws IOException
|
||||
{
|
||||
final int id = Ion.readInt(in);
|
||||
setModel(id);
|
||||
model.load(data, in); // load saved data
|
||||
}
|
||||
|
||||
|
||||
private void initData()
|
||||
{
|
||||
data = model.createData();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return entity model
|
||||
*/
|
||||
public final M getModel()
|
||||
{
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assign a model.
|
||||
*
|
||||
* @param id model id
|
||||
*/
|
||||
public final void setModel(int id)
|
||||
{
|
||||
setModel(getModelForId(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Assign a model.
|
||||
*
|
||||
* @param model model
|
||||
*/
|
||||
public final void setModel(M model)
|
||||
{
|
||||
this.model = model;
|
||||
initData();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void saveTo(OutputStream out) throws IOException
|
||||
{
|
||||
Ion.writeInt(out, model.getId());
|
||||
model.save(data, out);
|
||||
}
|
||||
|
||||
|
||||
public void render(R context)
|
||||
{
|
||||
model.render(data, context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
model.update(data, delta);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get model for ID
|
||||
*
|
||||
* @param id id
|
||||
* @return model for the ID
|
||||
*/
|
||||
protected abstract M getModelForId(int id);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
|
||||
|
||||
/**
|
||||
* Entity model. Provides concrete implementation to an entity, working with
|
||||
* it's data object.
|
||||
*
|
||||
* @author MightyPork
|
||||
* @param <D> Data object class
|
||||
* @param <R> Render context class
|
||||
*/
|
||||
public abstract class EntityModel<D, R extends RectBound> {
|
||||
|
||||
/** Model id */
|
||||
private final int id;
|
||||
|
||||
|
||||
/**
|
||||
* Create a model. The caller must then register this instance in a Model
|
||||
* registry for the particular entity type.
|
||||
*
|
||||
* @param id model id
|
||||
*/
|
||||
public EntityModel(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the model id.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public final int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a data object and populate it with default values.
|
||||
*
|
||||
* @return data object
|
||||
*/
|
||||
public abstract D createData();
|
||||
|
||||
|
||||
/**
|
||||
* Load an entity from ION input stream.
|
||||
*
|
||||
* @param data data to load
|
||||
* @param in input stream
|
||||
*/
|
||||
public abstract void load(D data, InputStream in);
|
||||
|
||||
|
||||
/**
|
||||
* Save an entity to ION output stream.
|
||||
*
|
||||
* @param data data to save
|
||||
* @param out output stream
|
||||
*/
|
||||
@DefaultImpl
|
||||
public abstract void save(D data, OutputStream out);
|
||||
|
||||
|
||||
/**
|
||||
* Render the item according to given context.
|
||||
*
|
||||
* @param data rendered item
|
||||
* @param context rendering context
|
||||
*/
|
||||
public abstract void render(D data, R context);
|
||||
|
||||
|
||||
/**
|
||||
* Update the item (animation, decay etc)
|
||||
*
|
||||
* @param item item to update
|
||||
* @param delta delta time
|
||||
*/
|
||||
@DefaultImpl
|
||||
public abstract void update(D item, double delta);
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
import mightypork.util.control.timing.Updateable;
|
||||
import mightypork.util.files.ion.BinaryUtils;
|
||||
import mightypork.util.files.ion.Ionizable;
|
||||
|
||||
|
||||
public class ItemData implements Ionizable, Updateable {
|
||||
|
||||
public static final short ION_MARK = 701;
|
||||
|
||||
private Model<ItemData, RectBound> model;
|
||||
|
||||
// data fields for models to use
|
||||
public Object data;
|
||||
public boolean[] flags;
|
||||
public int[] ints;
|
||||
|
||||
|
||||
/**
|
||||
* Create from model id
|
||||
*
|
||||
* @param id model id
|
||||
*/
|
||||
public ItemData(int id) {
|
||||
this(Items.get(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create from model
|
||||
*
|
||||
* @param model model
|
||||
*/
|
||||
public ItemData(Model<ItemData, RectBound> model) {
|
||||
this.model = model;
|
||||
model.create(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create without model. Model will be read from ION input stream.
|
||||
*/
|
||||
public ItemData() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loadFrom(InputStream in) throws IOException
|
||||
{
|
||||
final int id = BinaryUtils.readInt(in);
|
||||
model = Items.get(id);
|
||||
model.load(this, in);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void saveTo(OutputStream out) throws IOException
|
||||
{
|
||||
BinaryUtils.writeInt(out, model.getId());
|
||||
model.save(this, out);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public short getIonMark()
|
||||
{
|
||||
return ION_MARK;
|
||||
}
|
||||
|
||||
|
||||
public void render(RectBound context)
|
||||
{
|
||||
model.render(this, context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
model.update(this, delta);
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
|
||||
|
||||
/**
|
||||
* An item model
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class ItemModel implements Model<ItemData, RectBound> {
|
||||
|
||||
public final int id;
|
||||
|
||||
|
||||
public ItemModel(int id) {
|
||||
this.id = id;
|
||||
Items.register(id, this);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void create(ItemData item)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* On search performed (reveal hidden door etc)
|
||||
*
|
||||
* @param item item in world
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void search(TileData item)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an entity can walk this item. If the item is not potentially
|
||||
* walkable, then this method must always return false.
|
||||
*
|
||||
* @param item item in world
|
||||
*/
|
||||
public abstract void isWalkable(TileData item);
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void load(ItemData item, InputStream in)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void save(ItemData item, OutputStream out)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public abstract void render(ItemData item, RectBound context);
|
||||
|
||||
|
||||
@Override
|
||||
@DefaultImpl
|
||||
public void update(ItemData item, double delta)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
|
||||
|
||||
public interface Model<DATA, RCTX> {
|
||||
|
||||
/**
|
||||
* Get the id.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
int getId();
|
||||
|
||||
|
||||
/**
|
||||
* Populate an entity with data for this model
|
||||
*
|
||||
* @param entity entity in world
|
||||
*/
|
||||
void create(DATA entity);
|
||||
|
||||
|
||||
/**
|
||||
* Load entity data from a binary stream.
|
||||
*
|
||||
* @param entity item to load
|
||||
* @param in input stream
|
||||
*/
|
||||
void load(DATA entity, InputStream in);
|
||||
|
||||
|
||||
/**
|
||||
* Save entity data to a binary stream.
|
||||
*
|
||||
* @param entity entity to save
|
||||
* @param out output stream
|
||||
*/
|
||||
void save(DATA entity, OutputStream out);
|
||||
|
||||
|
||||
/**
|
||||
* Render according to given context.
|
||||
*
|
||||
* @param entity data object
|
||||
* @param context rendering context
|
||||
*/
|
||||
void render(DATA entity, RCTX context);
|
||||
|
||||
|
||||
/**
|
||||
* Update the entity (animation, decay etc)
|
||||
*
|
||||
* @param entity data object
|
||||
* @param delta delta time
|
||||
*/
|
||||
void update(DATA entity, double delta);
|
||||
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Stack;
|
||||
|
||||
import mightypork.util.control.timing.Updateable;
|
||||
import mightypork.util.files.ion.BinaryUtils;
|
||||
import mightypork.util.files.ion.Ionizable;
|
||||
|
||||
|
||||
/**
|
||||
* Concrete tile in the world.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class TileData implements Ionizable, Updateable {
|
||||
|
||||
public static final short ION_MARK = 700;
|
||||
|
||||
/** Items dropped onto this tile */
|
||||
public final Stack<ItemData> items = new Stack<>();
|
||||
|
||||
/** Whether the tile is occupied by an entity */
|
||||
public boolean occupied;
|
||||
|
||||
private TileModel model;
|
||||
|
||||
// data fields for models to use
|
||||
public Object data;
|
||||
public boolean[] flags;
|
||||
public int[] ints;
|
||||
|
||||
|
||||
/**
|
||||
* Create from model id
|
||||
*
|
||||
* @param id model id
|
||||
*/
|
||||
public TileData(int id) {
|
||||
this(Tiles.get(id));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create from model
|
||||
*
|
||||
* @param model model
|
||||
*/
|
||||
public TileData(TileModel model) {
|
||||
this.model = model;
|
||||
model.create(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create without model. Model will be read from ION input stream.
|
||||
*/
|
||||
public TileData() {
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loadFrom(InputStream in) throws IOException
|
||||
{
|
||||
final int id = BinaryUtils.readInt(in);
|
||||
model = Tiles.get(id);
|
||||
model.load(this, in);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void saveTo(OutputStream out) throws IOException
|
||||
{
|
||||
BinaryUtils.writeInt(out, model.getId());
|
||||
model.save(this, out);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public short getIonMark()
|
||||
{
|
||||
return ION_MARK;
|
||||
}
|
||||
|
||||
|
||||
public void render(TileRenderContext context)
|
||||
{
|
||||
model.render(this, context);
|
||||
if (!items.isEmpty()) items.peek().render(context);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
model.update(this, delta);
|
||||
if (!items.isEmpty()) items.peek().update(delta);
|
||||
}
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
|
||||
|
||||
public abstract class TileModel {
|
||||
|
||||
public final int id;
|
||||
|
||||
|
||||
public TileModel(int id) {
|
||||
this.id = id;
|
||||
Tiles.register(id, this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the id.
|
||||
*
|
||||
* @return id
|
||||
*/
|
||||
public final int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return can be walked through (if discovered / open)
|
||||
*/
|
||||
public abstract boolean isPotentiallyWalkable();
|
||||
|
||||
|
||||
/**
|
||||
* Populate a tile holder with data for this tile model
|
||||
*
|
||||
* @param tile tile in world
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void create(TileData tile)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* On search performed (reveal hidden door etc)
|
||||
*
|
||||
* @param tile tile in world
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void search(TileData tile)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if an entity can walk this tile. If the tile is not potentially
|
||||
* walkable, then this method must always return false.
|
||||
*
|
||||
* @param tile tile in world
|
||||
*/
|
||||
public abstract void isWalkable(TileData tile);
|
||||
|
||||
|
||||
/**
|
||||
* Load a tile from binary stream.
|
||||
*
|
||||
* @param tile tile to load
|
||||
* @param in input stream
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void load(TileData tile, InputStream in)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Save a tile to binary stream.
|
||||
*
|
||||
* @param tile tile to save
|
||||
* @param out output stream
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void save(TileData tile, OutputStream out)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
public abstract void render(TileData tile, TileRenderContext context);
|
||||
|
||||
|
||||
/**
|
||||
* Update the tile (animation, item spawning etc)
|
||||
*
|
||||
* @param tile tile to update
|
||||
* @param delta delta time
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void update(TileData tile, double delta)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
package mightypork.rogue.world;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import mightypork.rogue.world.tile.Tile;
|
||||
import mightypork.rogue.world.tile.TileHolder;
|
||||
import mightypork.util.files.ion.Ion;
|
||||
import mightypork.util.files.ion.Ionizable;
|
||||
|
||||
|
||||
public class WorldMap implements TileHolder, Ionizable {
|
||||
|
||||
private int width, height;
|
||||
|
||||
/** Array of tiles [y][x] */
|
||||
private Tile[][] tiles;
|
||||
|
||||
|
||||
public WorldMap(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
buildArray();
|
||||
}
|
||||
|
||||
|
||||
private void buildArray()
|
||||
{
|
||||
this.tiles = new Tile[height][width];
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Tile getTile(int x, int y)
|
||||
{
|
||||
return tiles[y][x];
|
||||
}
|
||||
|
||||
|
||||
public void setTile(Tile tile, int x, int y)
|
||||
{
|
||||
tiles[y][x] = tile;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getWidth()
|
||||
{
|
||||
return width;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public int getHeight()
|
||||
{
|
||||
return height;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void loadFrom(InputStream in) throws IOException
|
||||
{
|
||||
width = Ion.readInt(in);
|
||||
height = Ion.readInt(in);
|
||||
|
||||
buildArray();
|
||||
|
||||
short mark;
|
||||
|
||||
mark = Ion.readMark(in);
|
||||
if(mark == Ion.START);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void saveTo(OutputStream out) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public short getIonMark()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package mightypork.rogue.world.item;
|
||||
|
||||
|
||||
import mightypork.rogue.world.Entity;
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
|
||||
|
||||
public final class Item extends Entity<ItemData, ItemModel, RectBound> {
|
||||
|
||||
public static final short ION_MARK = 701;
|
||||
|
||||
|
||||
public Item() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public Item(ItemModel model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
public Item(int id) {
|
||||
super(Items.get(id));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected ItemModel getModelForId(int id)
|
||||
{
|
||||
return Items.get(id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public short getIonMark()
|
||||
{
|
||||
return ION_MARK;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package mightypork.rogue.world.item;
|
||||
|
||||
|
||||
/**
|
||||
* Item data object. Can be extended for particular models' needs.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class ItemData {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package mightypork.rogue.world.item;
|
||||
|
||||
|
||||
import mightypork.rogue.world.EntityModel;
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
|
||||
|
||||
/**
|
||||
* An item model
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class ItemModel extends EntityModel<ItemData, RectBound> {
|
||||
|
||||
public ItemModel(int id) {
|
||||
super(id);
|
||||
Items.register(id, this);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package mightypork.rogue.world;
|
||||
package mightypork.rogue.world.item;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Items {
|
||||
public final class Items {
|
||||
|
||||
private static final Map<Integer, ItemModel> registered = new HashMap<>();
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
package mightypork.rogue.world.tile;
|
||||
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import mightypork.rogue.world.Entity;
|
||||
import mightypork.rogue.world.item.Item;
|
||||
|
||||
|
||||
/**
|
||||
* Concrete tile in the world.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public final class Tile extends Entity<TileData, TileModel, TileRenderContext> {
|
||||
|
||||
public static final short ION_MARK = 700;
|
||||
|
||||
/** Items dropped onto this tile */
|
||||
public final Stack<Item> items = new Stack<>();
|
||||
|
||||
/** Whether the tile is occupied by an entity */
|
||||
public boolean occupied;
|
||||
|
||||
|
||||
public Tile() {
|
||||
super();
|
||||
}
|
||||
|
||||
|
||||
public Tile(TileModel model) {
|
||||
super(model);
|
||||
}
|
||||
|
||||
|
||||
public Tile(int id) {
|
||||
super(Tiles.get(id));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected TileModel getModelForId(int id)
|
||||
{
|
||||
return Tiles.get(id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public short getIonMark()
|
||||
{
|
||||
return ION_MARK;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void render(TileRenderContext context)
|
||||
{
|
||||
super.render(context);
|
||||
|
||||
// render laying-on-top item
|
||||
if (!items.isEmpty()) {
|
||||
Item item = items.peek();
|
||||
|
||||
item.render(context.getRect());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(double delta)
|
||||
{
|
||||
super.update(delta);
|
||||
|
||||
// update laying-on-top item
|
||||
if (!items.isEmpty()) {
|
||||
Item item = items.peek();
|
||||
item.update(delta);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Try to reveal secrets of this tile
|
||||
*/
|
||||
public void search()
|
||||
{
|
||||
model.search(data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if a mob can walk through
|
||||
*/
|
||||
public boolean isWalkable()
|
||||
{
|
||||
return model.isWalkable(data);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package mightypork.rogue.world.tile;
|
||||
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
import mightypork.rogue.world.item.Item;
|
||||
|
||||
/**
|
||||
* Tile data object. Can be extended for particular models' needs.
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public abstract class TileData {
|
||||
|
||||
/** Items dropped onto this tile */
|
||||
public final Stack<Item> items = new Stack<>();
|
||||
|
||||
}
|
||||
+2
-2
@@ -1,9 +1,9 @@
|
||||
package mightypork.rogue.world;
|
||||
package mightypork.rogue.world.tile;
|
||||
|
||||
|
||||
public interface TileHolder {
|
||||
|
||||
TileData getTile(int x, int y);
|
||||
Tile getTile(int x, int y);
|
||||
|
||||
|
||||
int getWidth();
|
||||
@@ -0,0 +1,45 @@
|
||||
package mightypork.rogue.world.tile;
|
||||
|
||||
|
||||
import mightypork.rogue.world.EntityModel;
|
||||
import mightypork.util.annotations.DefaultImpl;
|
||||
|
||||
|
||||
public abstract class TileModel extends EntityModel<TileData, TileRenderContext> {
|
||||
|
||||
public TileModel(int id) {
|
||||
super(id);
|
||||
Tiles.register(id, this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test if this tile type is potentially walkable. Used during world
|
||||
* generation.
|
||||
*
|
||||
* @return can be walked through (if discovered / open)
|
||||
*/
|
||||
public abstract boolean isPotentiallyWalkable();
|
||||
|
||||
|
||||
/**
|
||||
* Try to reveal a secret.
|
||||
*
|
||||
* @param data tile data
|
||||
*/
|
||||
@DefaultImpl
|
||||
public void search(TileData data)
|
||||
{
|
||||
// do nothing.
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Check if a mob can walk through.
|
||||
*
|
||||
* @param data tile data
|
||||
* @return is walkable
|
||||
*/
|
||||
public abstract boolean isWalkable(TileData data);
|
||||
|
||||
}
|
||||
+4
-4
@@ -1,4 +1,4 @@
|
||||
package mightypork.rogue.world;
|
||||
package mightypork.rogue.world.tile;
|
||||
|
||||
|
||||
import mightypork.util.constraints.rect.Rect;
|
||||
@@ -6,7 +6,7 @@ import mightypork.util.constraints.rect.builders.TiledRect;
|
||||
import mightypork.util.constraints.rect.proxy.RectBound;
|
||||
|
||||
|
||||
public class TileRenderContext implements RectBound {
|
||||
public final class TileRenderContext implements RectBound {
|
||||
|
||||
private final TileHolder map;
|
||||
private final TiledRect tiler;
|
||||
@@ -19,13 +19,13 @@ public class TileRenderContext implements RectBound {
|
||||
}
|
||||
|
||||
|
||||
public TileData getTile()
|
||||
public Tile getTile()
|
||||
{
|
||||
return map.getTile(x, y);
|
||||
}
|
||||
|
||||
|
||||
public TileData getAdjacentTile(int offsetX, int offsetY)
|
||||
public Tile getAdjacentTile(int offsetX, int offsetY)
|
||||
{
|
||||
return map.getTile(x + offsetX, y + offsetY);
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
package mightypork.rogue.world;
|
||||
package mightypork.rogue.world.tile;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class Tiles {
|
||||
public final class Tiles {
|
||||
|
||||
private static final Map<Integer, TileModel> registered = new HashMap<>();
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import mightypork.util.constraints.vect.Vect;
|
||||
import mightypork.util.constraints.vect.caching.VectCache;
|
||||
import mightypork.util.constraints.vect.mutable.VectVar;
|
||||
|
||||
|
||||
public class TestConstCaching {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
final VectVar in = Vect.makeVar(0, 0);
|
||||
final VectCache cache = in.cached();
|
||||
cache.enableDigestCaching(true);
|
||||
|
||||
System.out.println("in = " + in);
|
||||
System.out.println("cache = " + cache);
|
||||
System.out.println("cache digest = " + cache.digest());
|
||||
System.out.println("\n-- in := 100, 50, 25 --\n");
|
||||
in.setTo(100, 50, 25);
|
||||
System.out.println("in = " + in);
|
||||
System.out.println("cache = " + cache);
|
||||
System.out.println("cache digest = " + cache.digest());
|
||||
System.out.println("\n-- cache.poll() --\n");
|
||||
cache.markDigestDirty();
|
||||
System.out.println("in = " + in);
|
||||
System.out.println("cache = " + cache);
|
||||
System.out.println("cache digest = " + cache.digest());
|
||||
System.out.println("\n-- in := 1, 2, 3 --\n");
|
||||
in.setTo(1, 2, 3);
|
||||
System.out.println("in = " + in);
|
||||
System.out.println("cache = " + cache);
|
||||
System.out.println("cache digest = " + cache.digest());
|
||||
System.out.println("\n-- cache.poll() --\n");
|
||||
cache.markDigestDirty();
|
||||
System.out.println("cache = " + cache);
|
||||
System.out.println("cache digest = " + cache.digest());
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import mightypork.util.constraints.num.Num;
|
||||
import mightypork.util.constraints.num.mutable.NumVar;
|
||||
import mightypork.util.constraints.rect.Rect;
|
||||
import mightypork.util.constraints.rect.RectConst;
|
||||
import mightypork.util.constraints.vect.Vect;
|
||||
import mightypork.util.constraints.vect.VectConst;
|
||||
import mightypork.util.constraints.vect.mutable.VectVar;
|
||||
|
||||
|
||||
public class TestConstr {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Locale.setDefault(Locale.ENGLISH);
|
||||
|
||||
int cnt = -1;
|
||||
|
||||
{
|
||||
final RectConst rect = Rect.make(0, 0, 10, 10);
|
||||
final VectConst point = Vect.make(50, 50);
|
||||
System.out.println("Test " + ++cnt + ": rect = " + rect);
|
||||
System.out.println("Test " + cnt + ": point = " + point);
|
||||
System.out.println("Test " + cnt + ": centered rect = " + rect.centerTo(point));
|
||||
}
|
||||
|
||||
{
|
||||
final RectConst rect = Rect.make(0, 0, 10, 10);
|
||||
final Rect v = rect;
|
||||
System.out.println("\nTest " + ++cnt + ": " + (v == rect));
|
||||
}
|
||||
|
||||
{
|
||||
final RectConst rect = Rect.make(0, 0, 10, 10);
|
||||
final Rect v = rect;
|
||||
System.out.println("\nTest " + ++cnt + ": " + (v == rect));
|
||||
}
|
||||
|
||||
{
|
||||
final Vect a = Vect.make(3, 3);
|
||||
@SuppressWarnings("deprecation")
|
||||
final VectConst v = a.freeze().freeze().freeze();
|
||||
System.out.println("\nTest " + ++cnt + ": " + (v == a.freeze()));
|
||||
}
|
||||
|
||||
{
|
||||
final Vect a = Vect.make(3, 3);
|
||||
@SuppressWarnings("deprecation")
|
||||
final VectConst v = a.freeze().freeze().freeze();
|
||||
System.out.println("\nTest " + ++cnt + ": " + (v == a.freeze()));
|
||||
}
|
||||
|
||||
{
|
||||
final VectVar a = Vect.makeVar(10, 10);
|
||||
final Vect view = a.mul(10).half().sub(1, 1);
|
||||
System.out.println("\nTest " + ++cnt + ": " + (view.equals(Vect.make(49, 49))));
|
||||
a.add(10, 0);
|
||||
System.out.println("Test " + cnt + ": " + (view.equals(Vect.make(99, 49))));
|
||||
a.setTo(900, 999);
|
||||
System.out.println(view);
|
||||
}
|
||||
|
||||
{
|
||||
final NumVar side = Num.makeVar(100);
|
||||
final VectVar center = Vect.makeVar(0, 0);
|
||||
|
||||
final Rect box = Rect.make(side, side).centerTo(center);
|
||||
|
||||
System.out.println(box);
|
||||
|
||||
side.setTo(10);
|
||||
|
||||
System.out.println(box);
|
||||
|
||||
center.setTo(900, -50);
|
||||
|
||||
System.out.println(box);
|
||||
|
||||
}
|
||||
|
||||
{
|
||||
final NumVar a = Num.makeVar(100);
|
||||
|
||||
a.setTo(a.mul(50).add(10).div(2));
|
||||
|
||||
System.out.println(a);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import mightypork.util.objects.Convert;
|
||||
|
||||
|
||||
public class TestConvert {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Locale.setDefault(Locale.ENGLISH);
|
||||
|
||||
System.out.println(Convert.toVect("(10:20:30)"));
|
||||
System.out.println(Convert.toVect("30.6 ; 80"));
|
||||
System.out.println(Convert.toVect("30.6"));
|
||||
|
||||
System.out.println(Convert.toRange("10"));
|
||||
System.out.println(Convert.toRange("10..60"));
|
||||
System.out.println(Convert.toRange("10-60"));
|
||||
System.out.println(Convert.toRange("10--60"));
|
||||
System.out.println(Convert.toRange("-10--60"));
|
||||
System.out.println(Convert.toRange("3.1;22"));
|
||||
System.out.println(Convert.toRange("3.1|22"));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import mightypork.util.constraints.num.Num;
|
||||
import mightypork.util.constraints.num.mutable.NumVar;
|
||||
import mightypork.util.constraints.vect.Vect;
|
||||
import mightypork.util.constraints.vect.mutable.VectVar;
|
||||
|
||||
|
||||
public class TestCoords {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
{
|
||||
final VectVar a = Vect.makeVar();
|
||||
final VectVar b = Vect.makeVar();
|
||||
|
||||
final Vect cross = a.cross(b);
|
||||
final Num dot = a.dot(b);
|
||||
final Vect sum = a.add(b);
|
||||
final Num dist = a.dist(b);
|
||||
|
||||
a.setTo(0, 10, 0);
|
||||
b.setTo(0, 6, 7);
|
||||
|
||||
System.out.println("a = " + a);
|
||||
System.out.println("b = " + b);
|
||||
System.out.println("axb = " + cross);
|
||||
System.out.println("a.b = " + dot);
|
||||
System.out.println("a+b = " + sum);
|
||||
System.out.println("dist(a,b) = " + dist);
|
||||
}
|
||||
|
||||
{
|
||||
final NumVar a = Num.makeVar();
|
||||
|
||||
Num end = a;
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
end = end.add(1);
|
||||
}
|
||||
|
||||
System.out.println(end);
|
||||
a.setTo(37);
|
||||
System.out.println(end);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import mightypork.util.math.noise.NoiseGen;
|
||||
|
||||
|
||||
public class TestPerlin {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Locale.setDefault(Locale.ENGLISH);
|
||||
|
||||
int w = 50, h = 50;
|
||||
|
||||
NoiseGen ng = new NoiseGen(0.12, 0, 2.5, 5, (long) (Math.random()*100));
|
||||
|
||||
double[][] map = ng.buildMap(w, h);
|
||||
|
||||
char[] colors = {' ', '░','▒','▓','█'};
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
for (int x = 0; x < w; x++) {
|
||||
// "pixels" two-thick
|
||||
System.out.print(colors[(int) Math.floor(map[y][x])]);
|
||||
System.out.print(colors[(int) Math.floor(map[y][x])]);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import mightypork.util.constraints.num.Num;
|
||||
import mightypork.util.constraints.num.mutable.NumVar;
|
||||
import mightypork.util.constraints.rect.Rect;
|
||||
|
||||
|
||||
public class TestTiled {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
// {
|
||||
// RectVar area = Rect.makeVar(0, 0, 100, 100);
|
||||
//
|
||||
// TiledRect tiled = area.tiles(5, 5).oneBased();
|
||||
//
|
||||
// System.out.println(tiled.span(1, 1, 1, 1));
|
||||
// System.out.println(tiled.span(1, 1, 3, 1));
|
||||
// }
|
||||
|
||||
// {
|
||||
// RectVar area = Rect.makeVar(0, 0, 100, 100);
|
||||
// TiledRect tiled = area.columns(4);
|
||||
//
|
||||
// System.out.println(tiled.column(2));
|
||||
//
|
||||
//
|
||||
//
|
||||
// }
|
||||
//
|
||||
{
|
||||
Rect abox;
|
||||
final Rect b = Rect.make(100, 100, 100, 10);
|
||||
final NumVar pos = Num.makeVar(1);
|
||||
|
||||
abox = b.leftEdge().growRight(b.height());
|
||||
abox = abox.move(b.width().sub(b.height()).mul(pos), Num.ZERO);
|
||||
//abox = abox.shrink(b.height().perc(10));
|
||||
|
||||
System.out.println(abox);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
package mightypork.test;
|
||||
|
||||
|
||||
import mightypork.util.constraints.vect.Vect;
|
||||
import mightypork.util.constraints.vect.VectConst;
|
||||
import mightypork.util.constraints.vect.mutable.VectVar;
|
||||
|
||||
|
||||
public class TestVec {
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
final VectVar a = Vect.makeVar(-100, 12, 6);
|
||||
|
||||
final VectConst b = a.freeze();
|
||||
|
||||
a.setTo(400, 400, 300);
|
||||
|
||||
System.out.println(a);
|
||||
System.out.println(b);
|
||||
|
||||
final Vect c = a.abs().neg();
|
||||
|
||||
System.out.println(c);
|
||||
|
||||
System.out.println("20,1");
|
||||
a.setTo(20, 1);
|
||||
|
||||
System.out.println(a);
|
||||
System.out.println(c);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -112,22 +112,28 @@ public class Ion {
|
||||
/**
|
||||
* Register new {@link Ionizable} for direct reconstructing.
|
||||
*
|
||||
* @param mark mark to be used. Numbers 0..99 are reserved.
|
||||
* @param mark mark to be used. Numbers 0..99 are reserved. Mark is of type
|
||||
* Short, using values out of the short range will raise an
|
||||
* exception.
|
||||
* @param objClass class of the registered Ionizable
|
||||
*/
|
||||
public static void registerIonizable(short mark, Class<?> objClass)
|
||||
public static void registerIonizable(int mark, Class<?> objClass)
|
||||
{
|
||||
// negative marks are allowed.
|
||||
if (mark > Short.MAX_VALUE) throw new IllegalArgumentException("Mark too high (max " + Short.MAX_VALUE + ").");
|
||||
if (mark < Short.MIN_VALUE) throw new IllegalArgumentException("Mark too low (min " + Short.MIN_VALUE + ").");
|
||||
|
||||
if (markRangeChecking && mark >= 0 && mark < 100) {
|
||||
throw new RuntimeException("Marks 0..99 are reserved.");
|
||||
short m = (short) mark;
|
||||
|
||||
if (markRangeChecking && m >= 0 && m < 100) {
|
||||
throw new IllegalArgumentException("Marks 0..99 are reserved.");
|
||||
}
|
||||
|
||||
if (customIonizables.containsKey(mark)) {
|
||||
throw new RuntimeException("Mark " + mark + " is already in use.");
|
||||
if (customIonizables.containsKey(m)) {
|
||||
throw new IllegalArgumentException("Mark " + m + " is already in use.");
|
||||
}
|
||||
|
||||
customIonizables.put(mark, objClass);
|
||||
customIonizables.put(m, objClass);
|
||||
}
|
||||
|
||||
|
||||
@@ -151,6 +157,27 @@ public class Ion {
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Store an object to file.
|
||||
*
|
||||
* @param path file path
|
||||
* @param obj object to store
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void toFile(File path, Object obj) throws IOException
|
||||
{
|
||||
try(OutputStream out = new FileOutputStream(path)) {
|
||||
|
||||
writeObject(out, obj);
|
||||
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (final Exception e) {
|
||||
throw new IOException("Error writing to ION file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load an object from stream.
|
||||
*
|
||||
@@ -177,27 +204,6 @@ public class Ion {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Store an object to file.
|
||||
*
|
||||
* @param path file path
|
||||
* @param obj object to store
|
||||
* @throws IOException
|
||||
*/
|
||||
public static void toFile(File path, Object obj) throws IOException
|
||||
{
|
||||
try(OutputStream out = new FileOutputStream(path)) {
|
||||
|
||||
writeObject(out, obj);
|
||||
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (final Exception e) {
|
||||
throw new IOException("Error writing to ION file.", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Read single object from input stream, preceded by a mark. If a mark is
|
||||
* not present, the behavior is undefined - in case the read bytes happen to
|
||||
|
||||
@@ -650,19 +650,6 @@ public class Calc {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get class simple name
|
||||
*
|
||||
* @param obj object
|
||||
* @return simple name
|
||||
*/
|
||||
public static String cname(Object obj)
|
||||
{
|
||||
if (obj == null) return "NULL";
|
||||
return obj.getClass().getSimpleName();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cube a double
|
||||
*
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package mightypork.util.math.noise;
|
||||
|
||||
|
||||
/**
|
||||
* 2D Perlin noise generator
|
||||
*
|
||||
* @author MightyPork
|
||||
*/
|
||||
public class NoiseGen {
|
||||
|
||||
private static final double lowBound = -0.7072;
|
||||
private static final double highBound = 0.7072;
|
||||
|
||||
private final PerlinNoiseGenerator noiser;
|
||||
|
||||
private final double lowMul;
|
||||
private final double highMul;
|
||||
private final double middle;
|
||||
private final double density;
|
||||
|
||||
|
||||
/**
|
||||
* make a new noise generator
|
||||
*
|
||||
* @param density noise density (0..1). Lower density means larger "spots".
|
||||
* @param low low bound ("valley")
|
||||
* @param middle middle bound ("surface")
|
||||
* @param high high bound ("hill")
|
||||
* @param seed random seed to use
|
||||
*/
|
||||
public NoiseGen(double density, double low, double middle, double high, long seed) {
|
||||
if (low > middle || middle > high) throw new IllegalArgumentException("Invalid value range.");
|
||||
|
||||
this.density = density;
|
||||
|
||||
// norm low and high to be around zero
|
||||
low -= middle;
|
||||
high -= middle;
|
||||
|
||||
// scale
|
||||
this.middle = middle;
|
||||
|
||||
lowMul = Math.abs(low / lowBound);
|
||||
highMul = Math.abs(high / highBound);
|
||||
|
||||
noiser = new PerlinNoiseGenerator(seed);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get value at coord
|
||||
*
|
||||
* @param x x coordinate
|
||||
* @param y y coordinate
|
||||
* @return value
|
||||
*/
|
||||
public double valueAt(double x, double y)
|
||||
{
|
||||
double raw = noiser.noise2(x * density, y * density);
|
||||
|
||||
if (raw < lowBound) {
|
||||
raw = lowBound;
|
||||
} else if (raw > highBound) {
|
||||
raw = highBound;
|
||||
}
|
||||
|
||||
if (raw < 0) {
|
||||
return middle + lowMul * raw;
|
||||
} else {
|
||||
return middle + highMul * raw;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build a map [height][width] of noise values
|
||||
*
|
||||
* @param width map width (number of columns)
|
||||
* @param height map height (number of rows )
|
||||
* @return the map
|
||||
*/
|
||||
public double[][] buildMap(int width, int height)
|
||||
{
|
||||
double[][] map = new double[height][width];
|
||||
|
||||
for (int y = 0; y < height; y++) {
|
||||
for (int x = 0; x < width; x++) {
|
||||
map[y][x] = valueAt(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,575 @@
|
||||
/*****************************************************************************
|
||||
* J3D.org Copyright (c) 2000
|
||||
* Java Source
|
||||
*
|
||||
* This source is licensed under the GNU LGPL v2.1
|
||||
* Please read http://www.gnu.org/copyleft/lgpl.html for more information
|
||||
*
|
||||
* This software comes with the standard NO WARRANTY disclaimer for any
|
||||
* purpose. Use it at your own risk. If there's a problem you get to fix it.
|
||||
*
|
||||
****************************************************************************/
|
||||
package mightypork.util.math.noise;
|
||||
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
|
||||
/**
|
||||
* Computes Perlin Noise for three dimensions.
|
||||
* <p>
|
||||
* The result is a continuous function that interpolates a smooth path along a
|
||||
* series random points. The function is consitent, so given the same
|
||||
* parameters, it will always return the same value. The smoothing function is
|
||||
* based on the Improving Noise paper presented at Siggraph 2002.
|
||||
* <p>
|
||||
* Computing noise for one and two dimensions can make use of the 3D problem
|
||||
* space by just setting the un-needed dimensions to a fixed value.
|
||||
*
|
||||
* @author Justin Couch
|
||||
* @edited by MightyPork
|
||||
* @version $Revision: 1.4 $
|
||||
* @source http://code.j3d.org/download.html
|
||||
*/
|
||||
public class PerlinNoiseGenerator {
|
||||
|
||||
// Constants for setting up the Perlin-1 noise functions
|
||||
private static final int B = 0x1000;
|
||||
private static final int BM = 0xff;
|
||||
|
||||
private static final int N = 0x1000;
|
||||
|
||||
/** Default seed to use for the random number generation */
|
||||
private static final int DEFAULT_SEED = 100;
|
||||
|
||||
/** Default sample size to work with */
|
||||
private static final int DEFAULT_SAMPLE_SIZE = 256;
|
||||
|
||||
private final Random rand = new Random(DEFAULT_SEED);
|
||||
|
||||
/** Permutation array for the improved noise function */
|
||||
private int[] p_imp;
|
||||
|
||||
/** P array for perline 1 noise */
|
||||
private int[] p;
|
||||
private double[][] g3;
|
||||
private double[][] g2;
|
||||
private double[] g1;
|
||||
|
||||
|
||||
/**
|
||||
* Create a new noise creator with the default seed value
|
||||
*/
|
||||
public PerlinNoiseGenerator() {
|
||||
this(DEFAULT_SEED);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new noise creator with the given seed value for the randomness
|
||||
*
|
||||
* @param seed The seed value to use
|
||||
*/
|
||||
public PerlinNoiseGenerator(long seed) {
|
||||
p_imp = new int[DEFAULT_SAMPLE_SIZE << 1];
|
||||
|
||||
int i, j, k;
|
||||
rand.setSeed(seed);
|
||||
|
||||
// Calculate the table of psuedo-random coefficients.
|
||||
for (i = 0; i < DEFAULT_SAMPLE_SIZE; i++)
|
||||
p_imp[i] = i;
|
||||
|
||||
// generate the psuedo-random permutation table.
|
||||
while (--i > 0) {
|
||||
k = p_imp[i];
|
||||
j = (int) (rand.nextLong() & DEFAULT_SAMPLE_SIZE);
|
||||
p_imp[i] = p_imp[j];
|
||||
p_imp[j] = k;
|
||||
}
|
||||
|
||||
initPerlin1();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Computes noise function for three dimensions at the point (x,y,z).
|
||||
*
|
||||
* @param x x dimension parameter
|
||||
* @param y y dimension parameter
|
||||
* @param z z dimension parameter
|
||||
* @return the noise value at the point (x, y, z)
|
||||
*/
|
||||
public double improvedNoise(double x, double y, double z)
|
||||
{
|
||||
// Constraint the point to a unit cube
|
||||
int uc_x = (int) Math.floor(x) & 255;
|
||||
int uc_y = (int) Math.floor(y) & 255;
|
||||
int uc_z = (int) Math.floor(z) & 255;
|
||||
|
||||
// Relative location of the point in the unit cube
|
||||
double xo = x - Math.floor(x);
|
||||
double yo = y - Math.floor(y);
|
||||
double zo = z - Math.floor(z);
|
||||
|
||||
// Fade curves for x, y and z
|
||||
double u = fade(xo);
|
||||
double v = fade(yo);
|
||||
double w = fade(zo);
|
||||
|
||||
// Generate a hash for each coordinate to find out where in the cube
|
||||
// it lies.
|
||||
int a = p_imp[uc_x] + uc_y;
|
||||
int aa = p_imp[a] + uc_z;
|
||||
int ab = p_imp[a + 1] + uc_z;
|
||||
|
||||
int b = p_imp[uc_x + 1] + uc_y;
|
||||
int ba = p_imp[b] + uc_z;
|
||||
int bb = p_imp[b + 1] + uc_z;
|
||||
|
||||
// blend results from the 8 corners based on the noise function
|
||||
double c1 = grad(p_imp[aa], xo, yo, zo);
|
||||
double c2 = grad(p_imp[ba], xo - 1, yo, zo);
|
||||
double c3 = grad(p_imp[ab], xo, yo - 1, zo);
|
||||
double c4 = grad(p_imp[bb], xo - 1, yo - 1, zo);
|
||||
double c5 = grad(p_imp[aa + 1], xo, yo, zo - 1);
|
||||
double c6 = grad(p_imp[ba + 1], xo - 1, yo, zo - 1);
|
||||
double c7 = grad(p_imp[ab + 1], xo, yo - 1, zo - 1);
|
||||
double c8 = grad(p_imp[bb + 1], xo - 1, yo - 1, zo - 1);
|
||||
|
||||
return lerp(w, lerp(v, lerp(u, c1, c2), lerp(u, c3, c4)), lerp(v, lerp(u, c5, c6), lerp(u, c7, c8)));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 1-D noise generation function using the original perlin algorithm.
|
||||
*
|
||||
* @param x Seed for the noise function
|
||||
* @return The noisy output
|
||||
*/
|
||||
public double noise1(double x)
|
||||
{
|
||||
double t = x + N;
|
||||
int bx0 = ((int) t) & BM;
|
||||
int bx1 = (bx0 + 1) & BM;
|
||||
double rx0 = t - (int) t;
|
||||
double rx1 = rx0 - 1;
|
||||
|
||||
double sx = sCurve(rx0);
|
||||
|
||||
double u = rx0 * g1[p[bx0]];
|
||||
double v = rx1 * g1[p[bx1]];
|
||||
|
||||
return lerp(sx, u, v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create noise in a 2D space using the orignal perlin noise algorithm.
|
||||
*
|
||||
* @param x The X coordinate of the location to sample
|
||||
* @param y The Y coordinate of the location to sample
|
||||
* @return A noisy value at the given position
|
||||
*/
|
||||
public double noise2(double x, double y)
|
||||
{
|
||||
double t = x + N;
|
||||
int bx0 = ((int) t) & BM;
|
||||
int bx1 = (bx0 + 1) & BM;
|
||||
double rx0 = t - (int) t;
|
||||
double rx1 = rx0 - 1;
|
||||
|
||||
t = y + N;
|
||||
int by0 = ((int) t) & BM;
|
||||
int by1 = (by0 + 1) & BM;
|
||||
double ry0 = t - (int) t;
|
||||
double ry1 = ry0 - 1;
|
||||
|
||||
int i = p[bx0];
|
||||
int j = p[bx1];
|
||||
|
||||
int b00 = p[i + by0];
|
||||
int b10 = p[j + by0];
|
||||
int b01 = p[i + by1];
|
||||
int b11 = p[j + by1];
|
||||
|
||||
double sx = sCurve(rx0);
|
||||
double sy = sCurve(ry0);
|
||||
|
||||
double[] q = g2[b00];
|
||||
double u = rx0 * q[0] + ry0 * q[1];
|
||||
q = g2[b10];
|
||||
double v = rx1 * q[0] + ry0 * q[1];
|
||||
double a = lerp(sx, u, v);
|
||||
|
||||
q = g2[b01];
|
||||
u = rx0 * q[0] + ry1 * q[1];
|
||||
q = g2[b11];
|
||||
v = rx1 * q[0] + ry1 * q[1];
|
||||
double b = lerp(sx, u, v);
|
||||
|
||||
return lerp(sy, a, b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create noise in a 3D space using the orignal perlin noise algorithm.
|
||||
*
|
||||
* @param x The X coordinate of the location to sample
|
||||
* @param y The Y coordinate of the location to sample
|
||||
* @param z The Z coordinate of the location to sample
|
||||
* @return A noisy value at the given position
|
||||
*/
|
||||
public double noise3(double x, double y, double z)
|
||||
{
|
||||
double t = x + N;
|
||||
int bx0 = ((int) t) & BM;
|
||||
int bx1 = (bx0 + 1) & BM;
|
||||
double rx0 = t - (int) t;
|
||||
double rx1 = rx0 - 1;
|
||||
|
||||
t = y + N;
|
||||
int by0 = ((int) t) & BM;
|
||||
int by1 = (by0 + 1) & BM;
|
||||
double ry0 = t - (int) t;
|
||||
double ry1 = ry0 - 1;
|
||||
|
||||
t = z + N;
|
||||
int bz0 = ((int) t) & BM;
|
||||
int bz1 = (bz0 + 1) & BM;
|
||||
double rz0 = t - (int) t;
|
||||
double rz1 = rz0 - 1;
|
||||
|
||||
int i = p[bx0];
|
||||
int j = p[bx1];
|
||||
|
||||
int b00 = p[i + by0];
|
||||
int b10 = p[j + by0];
|
||||
int b01 = p[i + by1];
|
||||
int b11 = p[j + by1];
|
||||
|
||||
t = sCurve(rx0);
|
||||
double sy = sCurve(ry0);
|
||||
double sz = sCurve(rz0);
|
||||
|
||||
double[] q = g3[b00 + bz0];
|
||||
double u = (rx0 * q[0] + ry0 * q[1] + rz0 * q[2]);
|
||||
q = g3[b10 + bz0];
|
||||
double v = (rx1 * q[0] + ry0 * q[1] + rz0 * q[2]);
|
||||
double a = lerp(t, u, v);
|
||||
|
||||
q = g3[b01 + bz0];
|
||||
u = (rx0 * q[0] + ry1 * q[1] + rz0 * q[2]);
|
||||
q = g3[b11 + bz0];
|
||||
v = (rx1 * q[0] + ry1 * q[1] + rz0 * q[2]);
|
||||
double b = lerp(t, u, v);
|
||||
|
||||
double c = lerp(sy, a, b);
|
||||
|
||||
q = g3[b00 + bz1];
|
||||
u = (rx0 * q[0] + ry0 * q[1] + rz1 * q[2]);
|
||||
q = g3[b10 + bz1];
|
||||
v = (rx1 * q[0] + ry0 * q[1] + rz1 * q[2]);
|
||||
a = lerp(t, u, v);
|
||||
|
||||
q = g3[b01 + bz1];
|
||||
u = (rx0 * q[0] + ry1 * q[1] + rz1 * q[2]);
|
||||
q = g3[b11 + bz1];
|
||||
v = (rx1 * q[0] + ry1 * q[1] + rz1 * q[2]);
|
||||
b = lerp(t, u, v);
|
||||
|
||||
double d = lerp(sy, a, b);
|
||||
|
||||
return lerp(sz, c, d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a turbulent noise output based on the core noise function. This
|
||||
* uses the noise as a base function and is suitable for creating clouds,
|
||||
* marble and explosion effects. For example, a typical marble effect would
|
||||
* set the colour to be:
|
||||
*
|
||||
* <pre>
|
||||
* sin(point + turbulence(point) * point.x);
|
||||
* </pre>
|
||||
*
|
||||
* @param x
|
||||
* @param y
|
||||
* @param z
|
||||
* @param loF
|
||||
* @param hiF
|
||||
* @return value
|
||||
*/
|
||||
public double imporvedTurbulence(double x, double y, double z, double loF, double hiF)
|
||||
{
|
||||
double p_x = x + 123.456f;
|
||||
double p_y = y;
|
||||
double p_z = z;
|
||||
double t = 0;
|
||||
double f;
|
||||
|
||||
for (f = loF; f < hiF; f *= 2) {
|
||||
t += Math.abs(improvedNoise(p_x, p_y, p_z)) / f;
|
||||
|
||||
p_x *= 2;
|
||||
p_y *= 2;
|
||||
p_z *= 2;
|
||||
}
|
||||
|
||||
return t - 0.3;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a turbulance function in 2D using the original perlin noise
|
||||
* function.
|
||||
*
|
||||
* @param x The X coordinate of the location to sample
|
||||
* @param y The Y coordinate of the location to sample
|
||||
* @param freq The frequency of the turbluance to create
|
||||
* @return The value at the given coordinates
|
||||
*/
|
||||
public double turbulence2(double x, double y, double freq)
|
||||
{
|
||||
double t = 0;
|
||||
|
||||
do {
|
||||
t += noise2(freq * x, freq * y) / freq;
|
||||
freq *= 0.5f;
|
||||
} while (freq >= 1);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a turbulance function in 3D using the original perlin noise
|
||||
* function.
|
||||
*
|
||||
* @param x The X coordinate of the location to sample
|
||||
* @param y The Y coordinate of the location to sample
|
||||
* @param z The Z coordinate of the location to sample
|
||||
* @param freq The frequency of the turbluance to create
|
||||
* @return The value at the given coordinates
|
||||
*/
|
||||
public double turbulence3(double x, double y, double z, double freq)
|
||||
{
|
||||
double t = 0;
|
||||
|
||||
do {
|
||||
t += noise3(freq * x, freq * y, freq * z) / freq;
|
||||
freq *= 0.5f;
|
||||
} while (freq >= 1);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a 1D tileable noise function for the given width.
|
||||
*
|
||||
* @param x The X coordinate to generate the noise for
|
||||
* @param w The width of the tiled block
|
||||
* @return The value of the noise at the given coordinate
|
||||
*/
|
||||
public double tileableNoise1(double x, double w)
|
||||
{
|
||||
return (noise1(x) * (w - x) + noise1(x - w) * x) / w;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a 2D tileable noise function for the given width and height.
|
||||
*
|
||||
* @param x The X coordinate to generate the noise for
|
||||
* @param y The Y coordinate to generate the noise for
|
||||
* @param w The width of the tiled block
|
||||
* @param h The height of the tiled block
|
||||
* @return The value of the noise at the given coordinate
|
||||
*/
|
||||
public double tileableNoise2(double x, double y, double w, double h)
|
||||
{
|
||||
return (noise2(x, y) * (w - x) * (h - y) + noise2(x - w, y) * x * (h - y) + noise2(x, y - h) * (w - x) * y + noise2(x - w, y - h) * x * y) / (w * h);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a 3D tileable noise function for the given width, height and
|
||||
* depth.
|
||||
*
|
||||
* @param x The X coordinate to generate the noise for
|
||||
* @param y The Y coordinate to generate the noise for
|
||||
* @param z The Z coordinate to generate the noise for
|
||||
* @param w The width of the tiled block
|
||||
* @param h The height of the tiled block
|
||||
* @param d The depth of the tiled block
|
||||
* @return The value of the noise at the given coordinate
|
||||
*/
|
||||
public double tileableNoise3(double x, double y, double z, double w, double h, double d)
|
||||
{
|
||||
return (noise3(x, y, z) * (w - x) * (h - y) * (d - z) + noise3(x - w, y, z) * x * (h - y) * (d - z) + noise3(x, y - h, z) * (w - x) * y * (d - z)
|
||||
+ noise3(x - w, y - h, z) * x * y * (d - z) + noise3(x, y, z - d) * (w - x) * (h - y) * z + noise3(x - w, y, z - d) * x * (h - y) * z
|
||||
+ noise3(x, y - h, z - d) * (w - x) * y * z + noise3(x - w, y - h, z - d) * x * y * z)
|
||||
/ (w * h * d);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a turbulance function that can be tiled across a surface in 2D.
|
||||
*
|
||||
* @param x The X coordinate of the location to sample
|
||||
* @param y The Y coordinate of the location to sample
|
||||
* @param w The width to tile over
|
||||
* @param h The height to tile over
|
||||
* @param freq The frequency of the turbluance to create
|
||||
* @return The value at the given coordinates
|
||||
*/
|
||||
public double tileableTurbulence2(double x, double y, double w, double h, double freq)
|
||||
{
|
||||
double t = 0;
|
||||
|
||||
do {
|
||||
t += tileableNoise2(freq * x, freq * y, w * freq, h * freq) / freq;
|
||||
freq *= 0.5f;
|
||||
} while (freq >= 1);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a turbulance function that can be tiled across a surface in 3D.
|
||||
*
|
||||
* @param x The X coordinate of the location to sample
|
||||
* @param y The Y coordinate of the location to sample
|
||||
* @param z The Z coordinate of the location to sample
|
||||
* @param w The width to tile over
|
||||
* @param h The height to tile over
|
||||
* @param d The depth to tile over
|
||||
* @param freq The frequency of the turbluance to create
|
||||
* @return The value at the given coordinates
|
||||
*/
|
||||
public double tileableTurbulence3(double x, double y, double z, double w, double h, double d, double freq)
|
||||
{
|
||||
double t = 0;
|
||||
|
||||
do {
|
||||
t += tileableNoise3(freq * x, freq * y, freq * z, w * freq, h * freq, d * freq) / freq;
|
||||
freq *= 0.5f;
|
||||
} while (freq >= 1);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Simple lerp function using doubles.
|
||||
*/
|
||||
private double lerp(double t, double a, double b)
|
||||
{
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fade curve calculation which is 6t^5 - 15t^4 + 10t^3. This is the new
|
||||
* algorithm, where the old one used to be 3t^2 - 2t^3.
|
||||
*
|
||||
* @param t The t parameter to calculate the fade for
|
||||
* @return the drop-off amount.
|
||||
*/
|
||||
private double fade(double t)
|
||||
{
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Calculate the gradient function based on the hash code.
|
||||
*/
|
||||
private double grad(int hash, double x, double y, double z)
|
||||
{
|
||||
// Convert low 4 bits of hash code into 12 gradient directions.
|
||||
int h = hash & 15;
|
||||
double u = (h < 8 || h == 12 || h == 13) ? x : y;
|
||||
double v = (h < 4 || h == 12 || h == 13) ? y : z;
|
||||
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* S-curve function for value distribution for Perlin-1 noise function.
|
||||
*/
|
||||
private double sCurve(double t)
|
||||
{
|
||||
return (t * t * (3 - 2 * t));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 2D-vector normalisation function.
|
||||
*/
|
||||
private void normalize2(double[] v)
|
||||
{
|
||||
double s = 1 / Math.sqrt(v[0] * v[0] + v[1] * v[1]);
|
||||
v[0] *= s;
|
||||
v[1] *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 3D-vector normalisation function.
|
||||
*/
|
||||
private void normalize3(double[] v)
|
||||
{
|
||||
double s = 1 / Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
v[0] *= s;
|
||||
v[1] *= s;
|
||||
v[2] *= s;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the lookup arrays used by Perlin 1 function.
|
||||
*/
|
||||
private void initPerlin1()
|
||||
{
|
||||
p = new int[B + B + 2];
|
||||
g3 = new double[B + B + 2][3];
|
||||
g2 = new double[B + B + 2][2];
|
||||
g1 = new double[B + B + 2];
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0; i < B; i++) {
|
||||
p[i] = i;
|
||||
|
||||
g1[i] = (((rand.nextDouble() * Integer.MAX_VALUE) % (B + B)) - B) / B;
|
||||
|
||||
for (j = 0; j < 2; j++)
|
||||
g2[i][j] = (((rand.nextDouble() * Integer.MAX_VALUE) % (B + B)) - B) / B;
|
||||
normalize2(g2[i]);
|
||||
|
||||
for (j = 0; j < 3; j++)
|
||||
g3[i][j] = (((rand.nextDouble() * Integer.MAX_VALUE) % (B + B)) - B) / B;
|
||||
normalize3(g3[i]);
|
||||
}
|
||||
|
||||
while (--i > 0) {
|
||||
k = p[i];
|
||||
j = (int) ((rand.nextDouble() * Integer.MAX_VALUE) % B);
|
||||
p[i] = p[j];
|
||||
p[j] = k;
|
||||
}
|
||||
|
||||
for (i = 0; i < B + 2; i++) {
|
||||
p[B + i] = p[i];
|
||||
g1[B + i] = g1[i];
|
||||
for (j = 0; j < 2; j++)
|
||||
g2[B + i][j] = g2[i][j];
|
||||
for (j = 0; j < 3; j++)
|
||||
g3[B + i][j] = g3[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user