parent
7eb390d915
commit
4721351ed9
@ -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.HashMap; |
||||||
import java.util.Map; |
import java.util.Map; |
||||||
|
|
||||||
|
|
||||||
public class Items { |
public final class Items { |
||||||
|
|
||||||
private static final Map<Integer, ItemModel> registered = new HashMap<>(); |
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<>(); |
||||||
|
|
||||||
|
} |
@ -1,9 +1,9 @@ |
|||||||
package mightypork.rogue.world; |
package mightypork.rogue.world.tile; |
||||||
|
|
||||||
|
|
||||||
public interface TileHolder { |
public interface TileHolder { |
||||||
|
|
||||||
TileData getTile(int x, int y); |
Tile getTile(int x, int y); |
||||||
|
|
||||||
|
|
||||||
int getWidth(); |
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); |
||||||
|
|
||||||
|
} |
@ -1,11 +1,11 @@ |
|||||||
package mightypork.rogue.world; |
package mightypork.rogue.world.tile; |
||||||
|
|
||||||
|
|
||||||
import java.util.HashMap; |
import java.util.HashMap; |
||||||
import java.util.Map; |
import java.util.Map; |
||||||
|
|
||||||
|
|
||||||
public class Tiles { |
public final class Tiles { |
||||||
|
|
||||||
private static final Map<Integer, TileModel> registered = new HashMap<>(); |
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); |
|
||||||
|
|
||||||
} |
|
||||||
} |
|
@ -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]; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue