Initial Commit

This commit is contained in:
josua 2019-08-21 14:04:31 +10:00
commit aa18145fca
36 changed files with 3228 additions and 0 deletions

9
.classpath Normal file
View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="lib" path="/home/josua/code/Java Libraries/binary-data-format-v1.3.jar"/>
<classpathentry kind="lib" path="/home/josua/code/Java Libraries/mainloop.jar"/>
<classpathentry kind="con" path="org.eclipse.jdt.USER_LIBRARY/LWJGL"/>
<classpathentry kind="output" path="bin"/>
</classpath>

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/bin/

17
.project Normal file
View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>ShooterGame</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,11 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.8

29
src/shootergame/Main.java Normal file
View File

@ -0,0 +1,29 @@
package shootergame;
import mainloop.manager.MainloopManager;
import shootergame.display.DisplayWindow;
import shootergame.init.Textures;
import shootergame.mainloop.MainloopEventHandler;
public class Main
{
public static MainloopManager mainloop;
public static DisplayWindow window;
public static void main(String[] args)
{
// Create the mainloop
mainloop = new MainloopManager(MainloopEventHandler.MAINLOOP_EVENT_HANDLER);
mainloop.register(MainloopEventHandler.MAINLOOP_EVENT_HANDLER);
// Create the display
window = new DisplayWindow("ShooterGame");
window.init();
// Initialize the textures
Textures.initTextures(window);
// Start the mainloop
mainloop.start();
}
}

View File

@ -0,0 +1,35 @@
package shootergame.display;
import static org.lwjgl.opengl.GL11.*;
import org.lwjgl.opengl.GL;
import shootergame.init.Textures;
import shootergame.init.Tiles;
import shootergame.util.gl.GlHelpers;
import shootergame.util.math.vec.Vec2i;
public class DisplayRender
{
public static void render(int w, int h)
{
// Setup GL and clear the colour
GL.createCapabilities();
glClear(GL_COLOR_BUFFER_BIT);
glViewport(0, 0, w, h);
// Enable some stuff
GlHelpers.enableTexture2d();
// Set the colour to white
GlHelpers.color4(1, 1, 1, 1);
// Bind the texmap
Textures.texmap.bindTexture();
Tiles.GRASS.render(new Vec2i(0, 0));
// Unbind the texmap
Textures.texmap.unbindTexture();
}
}

View File

@ -0,0 +1,129 @@
package shootergame.display;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL11;
import mainloop.task.IMainloopTask;
import shootergame.Main;
import shootergame.input.CursorEnterCallback;
import shootergame.input.CursorPosCallback;
import shootergame.input.KeyCallback;
import shootergame.input.KeyCharCallback;
import shootergame.input.MouseButtonCallback;
import shootergame.mainloop.MainloopEventHandler;
import shootergame.util.gl.GlHelpers;
public class DisplayWindow implements IMainloopTask
{
private String name;
private long window;
private int width;
private int height;
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public DisplayWindow(String name)
{
this.name = name;
}
public void init()
{
// Initialize GLFW
if(!GLFW.glfwInit())
throw new RuntimeException("Failed to initialize GLFW");
// Get the monitor size
IntBuffer w = BufferUtils.createIntBuffer(1);
IntBuffer h = BufferUtils.createIntBuffer(1);
long monitor = GLFW.glfwGetPrimaryMonitor();
GLFW.glfwGetMonitorPhysicalSize(monitor, w, h);
this.width = w.get()*4;
this.height = h.get()*4;
// Set the window hint
GLFW.glfwWindowHint(GLFW.GLFW_VISIBLE, GLFW.GLFW_FALSE);
// Create the window
this.window = GLFW.glfwCreateWindow(this.width, this.height, this.name, 0, 0);
// Has the window been created
if(this.window == 0) {
System.err.println("Failed to create the window");
}
// Set the key handlers
GLFW.glfwSetKeyCallback(this.window, new KeyCallback());
GLFW.glfwSetCursorPosCallback(this.window, new CursorPosCallback());
GLFW.glfwSetCharCallback(this.window, new KeyCharCallback());
GLFW.glfwSetCursorEnterCallback(this.window, new CursorEnterCallback());
GLFW.glfwSetMouseButtonCallback(this.window, new MouseButtonCallback());
// Show the window
GLFW.glfwShowWindow(this.window);
// Register the display event loop
Main.mainloop.register(this);
}
public void render()
{
// Make the context current
this.makeContextCurrent();
// Set the framebuffer size
int w[] = {0};
int h[] = {0};
GLFW.glfwGetFramebufferSize(this.window, w, h);
// Render everything
DisplayRender.render(w[0], h[0]);
// Check if the matrix count is ok
GlHelpers.checkMatrixCount();
// Swap the framebuffers and poll events
this.swapBuffers();
this.pollEvents();
}
public void swapBuffers() {
GLFW.glfwSwapBuffers(this.window);
}
public void pollEvents() {
GLFW.glfwPollEvents();
}
public void makeContextCurrent() {
GLFW.glfwMakeContextCurrent(this.window);
}
public boolean shouldClose() {
return GLFW.glfwWindowShouldClose(this.window);
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > MainloopEventHandler.MAINLOOP_EVENT_HANDLER.mspf;
}
@Override
public boolean MainLoopRepeat() {
return true;
}
@Override
public void MainLoopUpdate() {
this.render();
}
}

View File

@ -0,0 +1,29 @@
package shootergame.init;
import java.util.ArrayList;
import org.lwjgl.opengl.GL;
import shootergame.display.DisplayWindow;
import shootergame.util.gl.texture.TextureMap;
import shootergame.util.gl.texture.TextureReference;
import shootergame.util.gl.texture.TextureReferenceAnimation;
public class Textures
{
public static void initTextures(DisplayWindow window)
{
// Make the context current
window.makeContextCurrent();
GL.createCapabilities();
// Initiaize all the textures
texmap.init();
}
public static final ArrayList<TextureReferenceAnimation> animations = new ArrayList<TextureReferenceAnimation>();
public static final TextureMap texmap = new TextureMap("/home/josua/eclipse-workspace/ShooterGame/src/shootergame/resources/texmap.png");
public static final TextureReference TILE_GRASS = texmap.getTextureReference(0, 0, 16, 16);
}

View File

@ -0,0 +1,9 @@
package shootergame.init;
import shootergame.tiles.Tile;
import shootergame.tiles.TileGrass;
public class Tiles
{
public static final Tile GRASS = new TileGrass("grass");
}

View File

@ -0,0 +1,14 @@
package shootergame.input;
import org.lwjgl.glfw.GLFWCursorEnterCallbackI;
public class CursorEnterCallback implements GLFWCursorEnterCallbackI
{
@Override
public void invoke(long arg0, boolean arg1) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,14 @@
package shootergame.input;
import org.lwjgl.glfw.GLFWCursorPosCallbackI;
public class CursorPosCallback implements GLFWCursorPosCallbackI
{
@Override
public void invoke(long arg0, double arg1, double arg2) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,14 @@
package shootergame.input;
import org.lwjgl.glfw.GLFWKeyCallbackI;
public class KeyCallback implements GLFWKeyCallbackI
{
@Override
public void invoke(long arg0, int arg1, int arg2, int arg3, int arg4) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,14 @@
package shootergame.input;
import org.lwjgl.glfw.GLFWCharCallbackI;
public class KeyCharCallback implements GLFWCharCallbackI
{
@Override
public void invoke(long arg0, int arg1) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,14 @@
package shootergame.input;
import org.lwjgl.glfw.GLFWMouseButtonCallbackI;
public class MouseButtonCallback implements GLFWMouseButtonCallbackI
{
@Override
public void invoke(long arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
}

View File

@ -0,0 +1,51 @@
package shootergame.mainloop;
import mainloop.event.IMainloopEvent;
import mainloop.task.IMainloopTask;
import shootergame.Main;
public class MainloopEventHandler implements IMainloopEvent, IMainloopTask
{
public static final MainloopEventHandler MAINLOOP_EVENT_HANDLER = new MainloopEventHandler();
public long mspf = 1000/60;
@Override
public void onClose() {
System.out.println("Mainloop closed normally");
}
@Override
public void onEarly() {
mspf -= 1;
if(mspf < 1) mspf = 1;
}
@Override
public void onLate() {
mspf += 1;
}
@Override
public void onStart() {
System.out.println("Mainloop started");
}
@Override
public boolean MainLoopDelay(long millis) {
return millis > 1;
}
@Override
public boolean MainLoopRepeat() {
return true;
}
@Override
public void MainLoopUpdate()
{
// Stop the mainloop if the window should close
if(Main.window.shouldClose()) Main.mainloop.stop();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 672 B

View File

@ -0,0 +1,19 @@
package shootergame.tiles;
import shootergame.util.math.vec.Vec2i;
public class Tile
{
private String id;
public Tile(String id) {
this.id = id;
}
public String getID() {
return this.id;
}
public void render(Vec2i pos) {
}
}

View File

@ -0,0 +1,30 @@
package shootergame.tiles;
import shootergame.util.gl.GlHelpers;
import shootergame.util.gl.texture.TextureReference;
import shootergame.util.math.vec.Vec2i;
public class TileFlat extends Tile
{
private TextureReference tex;
public TileFlat(String id, TextureReference tex) {
super(id);
this.tex = tex;
}
@Override
public void render(Vec2i pos)
{
// Call super
super.render(pos);
// Render the tile
GlHelpers.begin();
tex.texCoord(0, 0); GlHelpers.vertex2(pos.x+0, pos.y+0);
tex.texCoord(1, 0); GlHelpers.vertex2(pos.x+1, pos.y+0);
tex.texCoord(1, 1); GlHelpers.vertex2(pos.x+1, pos.y+1);
tex.texCoord(0, 1); GlHelpers.vertex2(pos.x+0, pos.y+1);
GlHelpers.end();
}
}

View File

@ -0,0 +1,12 @@
package shootergame.tiles;
import shootergame.init.Textures;
public class TileGrass extends TileFlat
{
public TileGrass(String id) {
super(id, Textures.TILE_GRASS);
}
}

View File

@ -0,0 +1,108 @@
package shootergame.util.gl;
import static org.lwjgl.opengl.GL11.*;
import shootergame.Main;
import shootergame.display.DisplayRender;
public class GlHelpers
{
private static int MATRIX_COUNT = 0;
public static void checkMatrixCount() {
if(MATRIX_COUNT != 0) {
MATRIX_COUNT = 0;
System.err.println("Matrix count is unbalanced!");
}
}
public static void begin() {
glBegin(GL_QUADS);
}
public static void end() {
glEnd();
}
public static void vertex3(float x, float y, float z) {
glVertex3f(x, y, z);
}
public static void vertex2(float x, float y) {
glVertex2f(x/Main.window.getWidth()*100, y/Main.window.getHeight()*100);
}
public static void color3(float r, float g, float b) {
glColor3f(r, g, b);
}
public static void color4(float r, float g, float b, float a) {
glColor4f(r, g, b, a);
}
public static void rotate(float a, float x, float y, float z) {
glRotatef(a, x, y, z);
}
public static void translate(float x, float y, float z) {
glTranslatef(x, y, z);
}
public static void disableCullFace() {
glDisable(GL_CULL_FACE);
}
public static void enableCullFace() {
glEnable(GL_CULL_FACE);
}
public static void disableDepthTest() {
glDisable(GL_DEPTH_TEST);
}
public static void enableDepthTest() {
glEnable(GL_DEPTH_TEST);
}
public static void disableTexture2d() {
glDisable(GL_TEXTURE_2D);
}
public static void enableTexture2d() {
glEnable(GL_TEXTURE_2D);
}
public static void disableAlpha() {
glDisable(GL_ALPHA);
}
public static void enableAlpha() {
glEnable(GL_ALPHA);
}
public static void disableBlend() {
glDisable(GL_BLEND);
}
public static void enableBlend() {
glEnable(GL_BLEND);
}
public static void popMatrix() {
glPopMatrix();
MATRIX_COUNT += 1;
}
public static void pushMatrix() {
glPushMatrix();
MATRIX_COUNT -= 1;
}
public static void translate(double x, double y, double z) {
translate((float)x, (float)y, (float)z);
}
public static void rotate(double a, float x, float y, float z) {
rotate((float)a, x, y, z);
}
}

View File

@ -0,0 +1,49 @@
package shootergame.util.gl.texture;
import java.nio.ByteBuffer;
import org.lwjgl.stb.STBImage;
public class Texture
{
private ByteBuffer texture;
private int width;
private int height;
private int channels;
public Texture(String path)
{
// Get the width, height, and channels
int width[] = {0};
int height[] = {0};
int channels[] = {0};
// Load the specified texture
this.texture = STBImage.stbi_load(path, width, height, channels, STBImage.STBI_rgb_alpha);
this.width = width[0];
this.height = height[0];
this.channels = channels[0];
System.out.println("w:"+this.width+" h:"+this.height+" c:"+this.channels+"\npath: "+path);
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public int getChannels() {
return this.channels;
}
public ByteBuffer getByteBuffer() {
return this.texture;
}
public void free() {
//STBImage.stbi_image_free(this.texture);
}
}

View File

@ -0,0 +1,64 @@
package shootergame.util.gl.texture;
import static org.lwjgl.opengl.GL11.*;
public class TextureMap
{
private int texture_gl;
private String path;
private int max_x;
private int max_y;
public TextureMap(String path) {
this.path = path;
}
public void init()
{
// Generate and bind the texture map
this.texture_gl = glGenTextures();
glBindTexture(GL_TEXTURE_2D, this.texture_gl);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
// Load the texture into opengl
Texture texture = new Texture(path);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
texture.getWidth(), texture.getHeight(),
0, GL_RGBA, GL_UNSIGNED_BYTE, texture.getByteBuffer());
// Store the width and height variables
this.max_x = texture.getWidth();
this.max_y = texture.getHeight();
System.out.println("texmap: "+texture_gl);
// Free the texture
//texture.free();
}
public TextureReference getTextureReference(int start_x, int start_y, int end_x, int end_y) {
return new TextureReference(start_x, start_y, end_x, end_y)
{
@Override
public int getMaxX() {
return max_x;
}
@Override
public int getMaxY() {
return max_y;
}
};
}
public void bindTexture() {
glBindTexture(GL_TEXTURE_2D, texture_gl);
}
public void unbindTexture() {
glBindTexture(GL_TEXTURE_2D, 0);
}
}

View File

@ -0,0 +1,38 @@
package shootergame.util.gl.texture;
import static org.lwjgl.opengl.GL11.*;
import shootergame.util.math.MathHelpers;
public abstract class TextureReference
{
private int start_x;
private int start_y;
private int end_x;
private int end_y;
TextureReference() {
}
public TextureReference(int start_x, int end_x, int start_y, int end_y)
{
// Save all the specified values
this.start_x = start_x;
this.start_y = start_y;
this.end_x = end_x;
this.end_y = end_y;
}
public void texCoord(float x, float y)
{
// Create texture coordinates
float cx = (float) ( MathHelpers.map(x, 0, 1, start_x, end_x) / (double) this.getMaxX() );
float cy = (float) ( MathHelpers.map(y, 0, 1, start_y, end_y) / (double) this.getMaxY() );
// Send the coordinates from the texture map to opengl
glTexCoord2f(cx, cy);
}
public abstract int getMaxX();
public abstract int getMaxY();
}

View File

@ -0,0 +1,25 @@
package shootergame.util.gl.texture;
public abstract class TextureReferenceAnimation extends TextureReference
{
private TextureReference[] references;
private int upto = 0;
public TextureReferenceAnimation(TextureReference[] references)
{
this.references = references;
}
@Override
public void texCoord(float x, float y) {
references[upto].texCoord(x, y);
}
public void tick()
{
// Cycle through all the textures
upto += 1;
upto %= references.length;
}
}

View File

@ -0,0 +1,37 @@
package shootergame.util.math;
import shootergame.util.math.vec.Vec2d;
public class MathHelpers
{
public static double squared(double x) {
return x*x;
}
public static double pow(int c, double x)
{
double res = 1;
for(int i=0;i<c;i++) {
res *= x;
}
return res;
}
public static double distance3d(double x1, double y1, double z1, double x2, double y2, double z2) {
return Math.sqrt( squared(x2 - x1) + squared(y2 - y1) + squared(z2 - z1) );
}
public static double distance2d(double x1, double y1, double x2, double y2) {
return Math.sqrt( squared(x2 - x1) + squared(y2 - y1) );
}
public static double map(double x, double in_min, double in_max, double out_min, double out_max) {
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}
public static Vec2d moveTowards2(double amount, double angle) {
return new Vec2d(Math.sin(angle), Math.cos(angle));
}
}

View File

@ -0,0 +1,8 @@
package shootergame.util.math.map;
import shootergame.util.math.vec.Vec2i;
public interface IMap2D<T>
{
public T getEmpty(Vec2i pos);
}

View File

@ -0,0 +1,88 @@
package shootergame.util.math.map;
import java.util.ArrayList;
import java.util.Iterator;
import shootergame.util.math.vec.Vec2i;
public class Map2D<T> implements Iterable<Map2DElement<T>>
{
private ArrayList<Map2DElement<T>> elements;
private IMap2D<T> map2d_i;
public Map2D(IMap2D<T> map2d_i)
{
// Store some values
this.map2d_i = map2d_i;
this.elements = new ArrayList<Map2DElement<T>>();
}
public void set(Vec2i pos, T o)
{
// Loop over the elements
for(Map2DElement<T> e : this.elements)
{
// Set the object if these positions are the same
if(e.pos.equal(pos)) {
e.o = o;
return;
}
}
// Create an element and add it
Map2DElement<T> e = new Map2DElement<T>(pos, o);
this.elements.add(e);
}
public T get(Vec2i pos)
{
// Loop over the elements
for(Map2DElement<T> e : this.elements)
{
// Send back the object if these positions are the same
if(e.pos.equal(pos)) {
//System.out.println(1);
return e.o;
}
}
// Send back an empty (unloaded) chunk
return this.map2d_i.getEmpty(pos);
}
public void remove(Vec2i pos)
{
// Loop over the elements
for(int i=0;i<elements.size();i++)
{
// Get the element
Map2DElement<T> e = this.elements.get(i);
// Delete the item if the position is the same
if(e.pos.equal(pos)) {
this.elements.remove(e);
}
}
}
@Override
public Iterator<Map2DElement<T>> iterator() {
return new Iterator<Map2DElement<T>>()
{
private int i = 0;
@Override
public boolean hasNext() {
return i < elements.size();
}
@Override
public Map2DElement<T> next() {
Map2DElement<T> o = elements.get(i);
i++;
return o;
}
};
}
}

View File

@ -0,0 +1,16 @@
package shootergame.util.math.map;
import shootergame.util.math.vec.Vec2i;
public class Map2DElement<T>
{
public Vec2i pos;
public T o;
public Map2DElement(Vec2i pos, T o)
{
// Store the specified values
this.pos = pos;
this.o = o;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,14 @@
package shootergame.util.math.random;
import java.util.Random;
public class RandomHelpers
{
public static int randrange(Random rand, int min, int max) {
return randrange(rand, max - min) + min;
}
public static int randrange(Random rand, int max) {
return (int)(rand.nextDouble() * max);
}
}

View File

@ -0,0 +1,13 @@
package shootergame.util.math.range;
public class Range2i
{
public int mx;
public int my;
public Range2i(int mx, int my)
{
this.mx = mx;
this.my = my;
}
}

View File

@ -0,0 +1,15 @@
package shootergame.util.math.range;
public class Range3i
{
public int mx;
public int my;
public int mz;
public Range3i(int mx, int my, int mz)
{
this.mx = mx;
this.my = my;
this.mz = mz;
}
}

View File

@ -0,0 +1,27 @@
package shootergame.util.math.vec;
import shootergame.util.math.MathHelpers;
public class Vec2d
{
public double x;
public double y;
public Vec2d(double x, double y)
{
this.x = x;
this.y = y;
}
public double distance(Vec2d other) {
return MathHelpers.distance2d(x, y, other.x, other.y);
}
public static double distance(Vec2d v1, Vec2d v2) {
return v1.distance(v2);
}
public boolean equal(Vec2d other) {
return x == other.x && y == other.y;
}
}

View File

@ -0,0 +1,50 @@
package shootergame.util.math.vec;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.range.Range2i;
public class Vec2i
{
public int x;
public int y;
public Vec2i(int x, int y)
{
this.x = x;
this.y = y;
}
public double distance(Vec2i other) {
return MathHelpers.distance2d(x, y, other.x, other.y);
}
public static double distance(Vec2i v1, Vec2i v2) {
return v1.distance(v2);
}
public int getId(Range2i range)
{
int id = 0;
int m = 1;
id += x;
m = range.mx;
id += y*m;
return id;
}
public static Vec2i fromId(Range2i range, int id)
{
int x = id % range.mx;
id -= x;
id /= range.mx;
int y = id % range.my;
return new Vec2i(x, y);
}
public boolean equal(Vec2i other) {
return x == other.x && y == other.y;
}
}

View File

@ -0,0 +1,29 @@
package shootergame.util.math.vec;
import shootergame.util.math.MathHelpers;
public class Vec3d
{
public double x;
public double y;
public double z;
public Vec3d(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public double distance(Vec3d other) {
return MathHelpers.distance3d(x, y, z, other.x, other.y, other.z);
}
public static double distance(Vec3d v1, Vec3d v2) {
return v1.distance(v2);
}
public boolean equal(Vec3d other) {
return x == other.x && y == other.y && z == other.z;
}
}

View File

@ -0,0 +1,57 @@
package shootergame.util.math.vec;
import shootergame.util.math.MathHelpers;
import shootergame.util.math.range.Range3i;
public class Vec3i
{
public int x;
public int y;
public int z;
public Vec3i(int x, int y, int z)
{
this.x = x;
this.y = y;
this.z = z;
}
public double distance(Vec3i other) {
return MathHelpers.distance3d(x, y, z, other.x, other.y, other.z);
}
public static double distance(Vec3i v1, Vec3i v2) {
return v1.distance(v2);
}
public int getId(Range3i range)
{
int id = 0;
int m = 1;
id += x;
m = range.mx;
id += y*m;
m *= range.my;
id += z*m;
return id;
}
public static Vec3i fromId(Range3i range, int id)
{
int x = id % range.mx;
id -= x;
id /= range.mx;
int y = id % range.my;
id -= y;
id /= range.my;
int z = id % range.mz;
return new Vec3i(x, y, z);
}
public boolean equal(Vec3i other) {
return x == other.x && y == other.y && z == other.z;
}
}