Initial commit
This commit is contained in:
commit
59d2f2cae8
|
|
@ -0,0 +1,2 @@
|
|||
bin/
|
||||
.classpath
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>GlEngine</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>
|
||||
|
|
@ -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
|
||||
|
|
@ -0,0 +1,134 @@
|
|||
package gl_engine;
|
||||
|
||||
import gl_engine.vec.Vec2d;
|
||||
import gl_engine.vec.Vec3d;
|
||||
|
||||
public class MathHelpers
|
||||
{
|
||||
public static final double FallSpeed = 0.00098;
|
||||
|
||||
public static double nextPowerOf(double x, double n)
|
||||
{
|
||||
double i = 1;
|
||||
|
||||
while(i < x) {
|
||||
i *= n;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public static int nextPowerOf(double x, int n)
|
||||
{
|
||||
int i = 1;
|
||||
|
||||
while(i < x) {
|
||||
i *= n;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
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) * amount, Math.cos(angle) * amount);
|
||||
}
|
||||
|
||||
public static Vec3d moveTowards3(double amount, Vec2d angles)
|
||||
{
|
||||
// Create some varibles
|
||||
Vec3d points = new Vec3d(0, 0, 0);
|
||||
double m;
|
||||
|
||||
points.z = Math.sin(angles.y) * amount;
|
||||
m = Math.cos(angles.y);
|
||||
points.x = Math.sin(angles.x) * m * amount;
|
||||
m = Math.cos(angles.x) * m;
|
||||
points.y = m * amount;
|
||||
|
||||
return points;
|
||||
}
|
||||
|
||||
public static double mod(double a, double b) {
|
||||
return (((a % b) + b) % b);
|
||||
}
|
||||
|
||||
public static int mod(int a, int b) {
|
||||
return (((a % b) + b) % b);
|
||||
}
|
||||
|
||||
public static int floor(double a)
|
||||
{
|
||||
if((int)a == a) {
|
||||
return (int) a;
|
||||
}
|
||||
|
||||
else if(a < 0) {
|
||||
return (int)(a - 1);
|
||||
}
|
||||
|
||||
else {
|
||||
return (int)a;
|
||||
}
|
||||
}
|
||||
|
||||
public static double positive(double a) {
|
||||
if(a < 0) return -a;
|
||||
else return a;
|
||||
}
|
||||
|
||||
public static int positive(int a) {
|
||||
if(a < 0) return -a;
|
||||
else return a;
|
||||
}
|
||||
|
||||
public static Vec2d rotate2(Vec2d pos, double angle)
|
||||
{
|
||||
// Calculate 2 sin and cos values
|
||||
double s = Math.sin(angle);
|
||||
double c = Math.cos(angle);
|
||||
|
||||
// Return and calculate the new positions
|
||||
return new Vec2d(
|
||||
pos.x * c - pos.y * s,
|
||||
pos.x * s + pos.y * c);
|
||||
}
|
||||
|
||||
public static double biggest(double a, double b)
|
||||
{
|
||||
if(a > b) return a;
|
||||
else return b;
|
||||
}
|
||||
|
||||
public static double smallest(double a, double b)
|
||||
{
|
||||
if(a < b) return a;
|
||||
else return b;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,150 @@
|
|||
package gl_engine;
|
||||
import static org.lwjgl.opengl.GL20.GL_COMPILE_STATUS;
|
||||
import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER;
|
||||
import static org.lwjgl.opengl.GL20.GL_LINK_STATUS;
|
||||
import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER;
|
||||
import static org.lwjgl.opengl.GL20.glAttachShader;
|
||||
import static org.lwjgl.opengl.GL20.glCompileShader;
|
||||
import static org.lwjgl.opengl.GL20.glCreateProgram;
|
||||
import static org.lwjgl.opengl.GL20.glCreateShader;
|
||||
import static org.lwjgl.opengl.GL20.glDeleteShader;
|
||||
import static org.lwjgl.opengl.GL20.glGetProgramInfoLog;
|
||||
import static org.lwjgl.opengl.GL20.glGetProgramiv;
|
||||
import static org.lwjgl.opengl.GL20.glGetShaderInfoLog;
|
||||
import static org.lwjgl.opengl.GL20.glGetShaderiv;
|
||||
import static org.lwjgl.opengl.GL20.glLinkProgram;
|
||||
import static org.lwjgl.opengl.GL20.glShaderSource;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ResourceLoader
|
||||
{
|
||||
public static byte[] loadResource(String name)
|
||||
{
|
||||
try
|
||||
{
|
||||
InputStream in = ResourceLoader.class.getResourceAsStream(name);
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
|
||||
if(in == null) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
byte buffer[] = new byte[1024];
|
||||
int size = 0;
|
||||
|
||||
while((size = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, size);
|
||||
}
|
||||
|
||||
in.close();
|
||||
|
||||
return out.toByteArray();
|
||||
}
|
||||
|
||||
catch(IOException e) {
|
||||
e.printStackTrace();
|
||||
return new byte[0];
|
||||
}
|
||||
}
|
||||
|
||||
/*private static int countDp(String str)
|
||||
{
|
||||
byte[] str_b = str.getBytes();
|
||||
int count = 0;
|
||||
|
||||
for(int i=0;i<str.length();i++) {
|
||||
if(str_b[i] == '.') {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
public static String[] resourceTree(String path)
|
||||
{
|
||||
ArrayList<String> tree = new ArrayList<String>();
|
||||
String data = new String(loadResource(path));
|
||||
String[] resources = data.split("\n");
|
||||
|
||||
for(int i=0;i<resources.length;i++)
|
||||
{
|
||||
String resource = path + "/" + resources[i];
|
||||
String resource_s[] = resource.split("/");
|
||||
|
||||
if(countDp(resource_s[resource_s.length - 1]) == 0)
|
||||
{
|
||||
if(resource.endsWith("/")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for(String r : resourceTree(resource)) {
|
||||
tree.add(r);
|
||||
}
|
||||
|
||||
} else {
|
||||
tree.add(resource);
|
||||
}
|
||||
}
|
||||
|
||||
String[] tree_array = new String[tree.size()];
|
||||
|
||||
for(int i=0;i<tree.size();i++) {
|
||||
tree_array[i] = tree.get(i);
|
||||
}
|
||||
|
||||
return tree_array;
|
||||
}*/
|
||||
|
||||
public static int loadShader(String name)
|
||||
{
|
||||
int vsh = glCreateShader(GL_VERTEX_SHADER);
|
||||
int fsh = glCreateShader(GL_FRAGMENT_SHADER);
|
||||
|
||||
byte[] vsh_source = loadResource(name + ".vsh");
|
||||
byte[] fsh_source = loadResource(name + ".fsh");
|
||||
|
||||
StringBuilder vsh_sb = new StringBuilder(new String(vsh_source));
|
||||
StringBuilder fsh_sb = new StringBuilder(new String(fsh_source));
|
||||
glShaderSource(vsh, vsh_sb);
|
||||
glShaderSource(fsh, fsh_sb);
|
||||
glCompileShader(vsh);
|
||||
glCompileShader(fsh);
|
||||
int vsh_success[] = new int[1];
|
||||
int fsh_success[] = new int[1];
|
||||
|
||||
glGetShaderiv(vsh, GL_COMPILE_STATUS, vsh_success);
|
||||
glGetShaderiv(fsh, GL_COMPILE_STATUS, fsh_success);
|
||||
|
||||
if(vsh_success[0] == 0) {
|
||||
System.err.println("ERROR:SHADER:VERTEX:" + name + ":" + glGetShaderInfoLog(vsh));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if(fsh_success[0] == 0) {
|
||||
System.err.println("ERROR:SHADER:FRAGMENT:" + name + ":" + glGetShaderInfoLog(fsh));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
int program = glCreateProgram();
|
||||
glAttachShader(program, vsh);
|
||||
glAttachShader(program, fsh);
|
||||
glLinkProgram(program);
|
||||
|
||||
int success[] = {0};
|
||||
glGetProgramiv(program, GL_LINK_STATUS, success);
|
||||
|
||||
if(success[0] == 0) {
|
||||
System.err.println("ERROR:PROGRAM:LINKING:" + name + ":" + glGetProgramInfoLog(program));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
glDeleteShader(vsh);
|
||||
glDeleteShader(fsh);
|
||||
|
||||
return program;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
package gl_engine.graphics;
|
||||
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_FORWARD_COMPAT;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE;
|
||||
import static org.lwjgl.glfw.GLFW.GLFW_TRUE;
|
||||
import static org.lwjgl.glfw.GLFW.glfwCreateWindow;
|
||||
import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent;
|
||||
import static org.lwjgl.glfw.GLFW.glfwShowWindow;
|
||||
import static org.lwjgl.glfw.GLFW.glfwTerminate;
|
||||
import static org.lwjgl.glfw.GLFW.glfwWindowHint;
|
||||
import static org.lwjgl.opengl.GL11.GL_BLEND;
|
||||
import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA;
|
||||
import static org.lwjgl.opengl.GL11.glBlendFunc;
|
||||
import static org.lwjgl.opengl.GL11.glEnable;
|
||||
import static org.lwjgl.opengl.GL11.glViewport;
|
||||
|
||||
import org.lwjgl.opengl.GL;
|
||||
|
||||
public class GraphicsHelpers
|
||||
{
|
||||
public static long initWindow(String title, int width, int height, long monitor)
|
||||
{
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
|
||||
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
|
||||
|
||||
long window = glfwCreateWindow(width, height, title, monitor, 0);
|
||||
|
||||
if(window == 0) {
|
||||
glfwTerminate();
|
||||
throw new RuntimeException("GLFW window initialization failed");
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
glfwShowWindow(window);
|
||||
|
||||
GL.createCapabilities();
|
||||
glViewport(0, 0, width, height);
|
||||
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
return window;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package gl_engine.graphics;
|
||||
|
||||
import org.lwjgl.opengl.GL33;
|
||||
|
||||
import gl_engine.ResourceLoader;
|
||||
|
||||
public class GraphicsShader
|
||||
{
|
||||
public int program;
|
||||
|
||||
public void use() {
|
||||
GL33.glUseProgram(program);
|
||||
}
|
||||
|
||||
public GraphicsShader(String name) {
|
||||
program = ResourceLoader.loadShader(name);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
package gl_engine.matrix;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.vec.Vec3d;
|
||||
|
||||
public class Matrix4 implements IBdfClassManager
|
||||
{
|
||||
public static final int SIZE = 4;
|
||||
|
||||
private float[] elements;
|
||||
|
||||
public Matrix4() {
|
||||
elements = new float[SIZE * SIZE];
|
||||
}
|
||||
|
||||
public float[] getArray() {
|
||||
return elements;
|
||||
}
|
||||
|
||||
public static Matrix4 identity()
|
||||
{
|
||||
Matrix4 mat = new Matrix4();
|
||||
|
||||
for(int i=0;i<SIZE;i++) {
|
||||
for(int j=0;j<SIZE;j++) {
|
||||
mat.set(i, j, i == j ? 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
return mat;
|
||||
}
|
||||
|
||||
public static Matrix4 translate(Vec3d vec) {
|
||||
return translate(vec.x, vec.y, vec.z);
|
||||
}
|
||||
|
||||
public static Matrix4 translate(double x, double y, double z)
|
||||
{
|
||||
Matrix4 result = identity();
|
||||
|
||||
result.set(3, 0, x);
|
||||
result.set(3, 1, y);
|
||||
result.set(3, 2, z);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4 rotate(double angle, double x, double y, double z)
|
||||
{
|
||||
Matrix4 result = identity();
|
||||
|
||||
double angle_rad = Math.toRadians(angle);
|
||||
double sin = Math.sin(angle_rad);
|
||||
double cos = Math.cos(angle_rad);
|
||||
double icos = 1 - cos;
|
||||
|
||||
result.set(0, 0, cos + x * x * icos);
|
||||
result.set(0, 1, x * y * icos - z * sin);
|
||||
result.set(0, 2, x * z * icos + y * sin);
|
||||
result.set(1, 0, y * x * icos + z * sin);
|
||||
result.set(1, 1, cos + y * y * icos);
|
||||
result.set(1, 2, y * z * icos - x * sin);
|
||||
result.set(2, 0, z * x * icos - y * sin);
|
||||
result.set(2, 1, z * y * icos + x * sin);
|
||||
result.set(2, 2, cos + z * z * icos);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4 rotate(double angle, Vec3d axis) {
|
||||
return rotate(angle, axis.x, axis.y, axis.z);
|
||||
}
|
||||
|
||||
public static Matrix4 scale(Vec3d vec)
|
||||
{
|
||||
Matrix4 result = identity();
|
||||
|
||||
result.set(0, 0, vec.x);
|
||||
result.set(1, 1, vec.y);
|
||||
result.set(2, 2, vec.z);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4 multiply(Matrix4 mat1, Matrix4 mat2)
|
||||
{
|
||||
Matrix4 result = new Matrix4();
|
||||
|
||||
for(int i=0;i<SIZE;i++) {
|
||||
for(int j=0;j<SIZE;j++) {
|
||||
result.set(i, j, mat1.get(i, 0) * mat2.get(0, j) +
|
||||
mat1.get(i, 1) * mat2.get(1, j) +
|
||||
mat1.get(i, 2) * mat2.get(2, j) +
|
||||
mat1.get(i, 3) * mat2.get(3, j));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4 transform(Vec3d position, Vec3d rotation, Vec3d scale)
|
||||
{
|
||||
Matrix4 scaleMatrix = scale(scale);
|
||||
Matrix4 translationMatrix = translate(position);
|
||||
|
||||
Matrix4 rotationXMatrix = rotate(rotation.x, 1, 0, 0);
|
||||
Matrix4 rotationYMatrix = rotate(rotation.y, 0, 1, 0);
|
||||
Matrix4 rotationZMatrix = rotate(rotation.z, 0, 0, 1);
|
||||
|
||||
Matrix4 rotationMatrix = multiply(rotationXMatrix, multiply(rotationYMatrix, rotationZMatrix));
|
||||
Matrix4 result = multiply(translationMatrix, multiply(rotationMatrix, scaleMatrix));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Matrix4 projection(double aspect, double fov, double near, double far)
|
||||
{
|
||||
double tan = Math.tan(Math.toRadians(fov / 2.0));
|
||||
double diff = far - near;
|
||||
|
||||
Matrix4 result = identity();
|
||||
|
||||
result.set(0, 0, 1 / (aspect * tan));
|
||||
result.set(1, 1, 1 / tan);
|
||||
result.set(2, 2, -(far + near) / diff);
|
||||
result.set(3, 2, -(2 * far * near) / diff);
|
||||
result.set(2, 3, -1);
|
||||
result.set(3, 3, 0);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public void set(int x, int y, double v) {
|
||||
set(x, y, (float)v);
|
||||
}
|
||||
|
||||
public void set(int x, int y, float v)
|
||||
{
|
||||
int id = x * 4 + y;
|
||||
elements[id] = v;
|
||||
}
|
||||
|
||||
public double get(int x, int y)
|
||||
{
|
||||
int id = x * 4 + y;
|
||||
return elements[id];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf)
|
||||
{
|
||||
elements = bdf.getFloatArray();
|
||||
|
||||
if(elements.length != 16) {
|
||||
elements = identity().elements;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setFloatArray(elements);
|
||||
}
|
||||
|
||||
public Matrix4(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package gl_engine.range;
|
||||
|
||||
public class Range2i
|
||||
{
|
||||
public int mx;
|
||||
public int my;
|
||||
|
||||
public Range2i(int mx, int my)
|
||||
{
|
||||
this.mx = mx;
|
||||
this.my = my;
|
||||
}
|
||||
|
||||
public int maxValue() {
|
||||
return mx * my;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package gl_engine.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;
|
||||
}
|
||||
|
||||
public int maxValue() {
|
||||
return mx * my * mz;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
package gl_engine.range;
|
||||
|
||||
public class Range4i
|
||||
{
|
||||
public int mx;
|
||||
public int my;
|
||||
public int mz;
|
||||
public int mm;
|
||||
|
||||
public Range4i(int mx, int my, int mz, int mm)
|
||||
{
|
||||
this.mx = mx;
|
||||
this.my = my;
|
||||
this.mz = mz;
|
||||
this.mm = mm;
|
||||
}
|
||||
|
||||
public int maxValue() {
|
||||
return mx * my * mz * mm;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,338 @@
|
|||
package gl_engine.texture;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_NEAREST;
|
||||
import static org.lwjgl.opengl.GL11.GL_RGBA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL11.glGenTextures;
|
||||
import static org.lwjgl.opengl.GL11.glTexImage2D;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameteri;
|
||||
import static org.lwjgl.opengl.GL30.glGenerateMipmap;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
import gl_engine.ResourceLoader;
|
||||
import gl_engine.range.Range2i;
|
||||
import gl_engine.vec.Vec2i;
|
||||
|
||||
public class TextureAtlas2D
|
||||
{
|
||||
int texture;
|
||||
public int width, height;
|
||||
public ArrayList<TextureRaw> raw_textures;
|
||||
public ArrayList<TextureRef2D> tex_refs;
|
||||
|
||||
public TextureAtlas2D()
|
||||
{
|
||||
raw_textures = new ArrayList<TextureRaw>();
|
||||
tex_refs = new ArrayList<TextureRef2D>();
|
||||
raw_textures.add(TextureRaw.createEmpty());
|
||||
|
||||
width = 0;
|
||||
height = 0;
|
||||
}
|
||||
|
||||
public void add(TextureRaw tex) {
|
||||
raw_textures.add(tex);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
raw_textures.clear();
|
||||
raw_textures.add(TextureRaw.createEmpty());
|
||||
}
|
||||
|
||||
private static String getParentPath(String path)
|
||||
{
|
||||
int at = 0;
|
||||
byte[] path_b = path.getBytes();
|
||||
|
||||
for(int i=0;i<path_b.length;i++) {
|
||||
if(path_b[i] == '/') {
|
||||
at = i;
|
||||
}
|
||||
}
|
||||
|
||||
return path.substring(0, at + 1);
|
||||
}
|
||||
|
||||
public static TextureAtlas2D loadAll(String path)
|
||||
{
|
||||
String path_parent = getParentPath(path);
|
||||
String[] tree = new String(ResourceLoader.loadResource(path)).split("\n");
|
||||
TextureAtlas2D texmap = new TextureAtlas2D();
|
||||
|
||||
for(String dir : tree) {
|
||||
if(dir.endsWith(".png"))
|
||||
{
|
||||
while(dir.startsWith("./")) {
|
||||
dir = dir.substring(2, dir.length());
|
||||
}
|
||||
|
||||
TextureRaw tex = TextureRaw.loadFromFile(path_parent + dir);
|
||||
|
||||
if(tex == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tex.ref = "/" + dir;
|
||||
texmap.add(tex);
|
||||
}
|
||||
}
|
||||
|
||||
return texmap;
|
||||
}
|
||||
|
||||
public TextureRef2D get(String ref)
|
||||
{
|
||||
for(TextureRef2D tex_ref : tex_refs) {
|
||||
if(tex_ref.ref.contentEquals(ref)) {
|
||||
return tex_ref;
|
||||
}
|
||||
}
|
||||
|
||||
for(TextureRef2D tex_ref : tex_refs) {
|
||||
if(tex_ref.ref.contentEquals("EMPTY")) {
|
||||
return get("EMPTY");
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("Error: atlas not generated");
|
||||
System.exit(0);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean refHasCollision(TextureRect check, TextureRect other)
|
||||
{
|
||||
if(check.y >= other.y + other.h || other.y >= check.y + check.h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check.x >= other.x + other.w || other.x >= check.x + check.w) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private TextureRect refHasCollision(ArrayList<TextureRect> refs, TextureRect other)
|
||||
{
|
||||
for(TextureRect ref : refs) {
|
||||
if(refHasCollision(ref, other)) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
public void generate()
|
||||
{
|
||||
tex_refs.clear();
|
||||
|
||||
int size = 1;
|
||||
|
||||
ArrayList<TextureRect> tex_rects = new ArrayList<TextureRect>();
|
||||
TextureRect lastRect = null;
|
||||
|
||||
raw_textures.sort(new Comparator<TextureRaw>() {
|
||||
|
||||
@Override
|
||||
public int compare(TextureRaw o1, TextureRaw o2)
|
||||
{
|
||||
if(o1.height < o2.height) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(o1.height > o2.height) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(o1.width > o2.width) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(o1.width < o2.width) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
long millis_now = System.currentTimeMillis();
|
||||
long millis_last = millis_now;
|
||||
|
||||
// Work out the positions of each rect
|
||||
for(int i=0;i<raw_textures.size();i++)
|
||||
{
|
||||
millis_now = System.currentTimeMillis();
|
||||
if(millis_now - millis_last > 1000) {
|
||||
millis_last += 1000;
|
||||
System.out.println("Generating atlas " + i + "/" + raw_textures.size());
|
||||
}
|
||||
|
||||
TextureRaw tex = raw_textures.get(i);
|
||||
|
||||
TextureRect rect = new TextureRect();
|
||||
rect.r = tex;
|
||||
rect.w = tex.width;
|
||||
rect.h = tex.height;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
|
||||
if(lastRect != null) {
|
||||
if(lastRect.h <= rect.h && lastRect.w <= rect.w) {
|
||||
rect.x = lastRect.x;
|
||||
rect.y = lastRect.y;
|
||||
}
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
TextureRect collision = refHasCollision(tex_rects, rect);
|
||||
|
||||
if(collision == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
int change = collision.x + collision.w;
|
||||
|
||||
if(change != rect.x) {
|
||||
rect.x = change;
|
||||
} else {
|
||||
rect.x += 1;
|
||||
}
|
||||
|
||||
if(rect.x + rect.w > size) {
|
||||
rect.y += 1;
|
||||
rect.x = 0;
|
||||
}
|
||||
|
||||
if(rect.y + rect.h > size) {
|
||||
size *= 2;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
TextureRef2D ref = new TextureRef2D();
|
||||
ref.texmap = this;
|
||||
ref.ref = tex.ref;
|
||||
ref.sx = rect.x;
|
||||
ref.sy = rect.y;
|
||||
ref.ex = rect.x + rect.w;
|
||||
ref.ey = rect.y + rect.h;
|
||||
|
||||
lastRect = rect;
|
||||
tex_rects.add(rect);
|
||||
tex_refs.add(ref);
|
||||
|
||||
if(rect.h > height) {
|
||||
height = rect.h;
|
||||
}
|
||||
}
|
||||
|
||||
for(TextureRef2D ref : tex_refs) {
|
||||
ref.sx /= size;
|
||||
ref.ex /= size;
|
||||
ref.sy /= size;
|
||||
ref.ey /= size;
|
||||
}
|
||||
|
||||
width = size;
|
||||
height = size;
|
||||
|
||||
byte[] texmap_b = new byte[width*height*4];
|
||||
Range2i texmap_r = new Range2i(width, height);
|
||||
TextureRect last_rect = null;
|
||||
|
||||
for(int i=0;i<width*height;i++)
|
||||
{
|
||||
Vec2i pos = Vec2i.fromId(texmap_r, i);
|
||||
TextureRect r = null;
|
||||
|
||||
boolean found = false;
|
||||
|
||||
if(millis_now - millis_last > 1000) {
|
||||
millis_last += 1000;
|
||||
System.out.println("Rendering atlas " + ((int)(i / ((double)width*height) * 1000)) / (double)10 + "%");
|
||||
}
|
||||
|
||||
if(
|
||||
last_rect != null &&
|
||||
pos.x >= last_rect.x && pos.x < last_rect.x + last_rect.w &&
|
||||
pos.y >= last_rect.y && pos.y < last_rect.y + last_rect.h
|
||||
) {
|
||||
found = true;
|
||||
r = last_rect;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
//System.out.println("hi");
|
||||
|
||||
for(TextureRect rect : tex_rects) {
|
||||
if(
|
||||
pos.x >= rect.x && pos.x < rect.x + rect.w &&
|
||||
pos.y >= rect.y && pos.y < rect.y + rect.h
|
||||
) {
|
||||
r = rect;
|
||||
last_rect = rect;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(r == null) {
|
||||
texmap_b[i*4+0] = 0;
|
||||
texmap_b[i*4+1] = 0;
|
||||
texmap_b[i*4+2] = 0;
|
||||
texmap_b[i*4+3] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
Range2i tex_r = new Range2i(r.w, r.h);
|
||||
Vec2i tex_p = new Vec2i(pos.x - r.x, pos.y - r.y);
|
||||
int tex_id = tex_p.getId(tex_r);
|
||||
|
||||
if(tex_p.x == r.w - 1 && tex_p.y == r.h - 1) {
|
||||
tex_rects.remove(r);
|
||||
}
|
||||
|
||||
texmap_b[i*4+0] = r.r.bytes[tex_id*4+0];
|
||||
texmap_b[i*4+1] = r.r.bytes[tex_id*4+1];
|
||||
texmap_b[i*4+2] = r.r.bytes[tex_id*4+2];
|
||||
texmap_b[i*4+3] = r.r.bytes[tex_id*4+3];
|
||||
|
||||
millis_now = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
//System.out.println(Arrays.toString(texmap_b));
|
||||
System.out.println("Atlas size: "+size+" x "+size);
|
||||
|
||||
ByteBuffer texmap_buff = ByteBuffer.allocateDirect(texmap_b.length);
|
||||
texmap_buff.put(texmap_b);
|
||||
texmap_buff.position(0);
|
||||
|
||||
texture = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texmap_buff);
|
||||
glGenerateMipmap(GL_TEXTURE_2D);
|
||||
|
||||
raw_textures.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,375 @@
|
|||
package gl_engine.texture;
|
||||
|
||||
import static org.lwjgl.opengl.GL11.GL_NEAREST;
|
||||
import static org.lwjgl.opengl.GL11.GL_RGBA;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_2D;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MAG_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_TEXTURE_MIN_FILTER;
|
||||
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_BYTE;
|
||||
import static org.lwjgl.opengl.GL11.glBindTexture;
|
||||
import static org.lwjgl.opengl.GL11.glGenTextures;
|
||||
import static org.lwjgl.opengl.GL11.glTexParameteri;
|
||||
import static org.lwjgl.opengl.GL12.GL_TEXTURE_3D;
|
||||
import static org.lwjgl.opengl.GL12.glTexImage3D;
|
||||
import static org.lwjgl.opengl.GL30.glGenerateMipmap;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
import gl_engine.ResourceLoader;
|
||||
import gl_engine.range.Range2i;
|
||||
import gl_engine.range.Range3i;
|
||||
import gl_engine.vec.Vec2i;
|
||||
import gl_engine.vec.Vec3i;
|
||||
|
||||
public class TextureAtlas3D
|
||||
{
|
||||
int texture;
|
||||
public int size, depth;
|
||||
public ArrayList<TextureRaw> raw_textures;
|
||||
public ArrayList<TextureRef3D> tex_refs;
|
||||
|
||||
public TextureAtlas3D()
|
||||
{
|
||||
raw_textures = new ArrayList<TextureRaw>();
|
||||
tex_refs = new ArrayList<TextureRef3D>();
|
||||
raw_textures.add(TextureRaw.createEmpty());
|
||||
|
||||
size = 0;
|
||||
}
|
||||
|
||||
public void add(TextureRaw tex) {
|
||||
raw_textures.add(tex);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
raw_textures.clear();
|
||||
raw_textures.add(TextureRaw.createEmpty());
|
||||
}
|
||||
|
||||
private static String getParentPath(String path)
|
||||
{
|
||||
int at = 0;
|
||||
byte[] path_b = path.getBytes();
|
||||
|
||||
for(int i=0;i<path_b.length;i++) {
|
||||
if(path_b[i] == '/') {
|
||||
at = i;
|
||||
}
|
||||
}
|
||||
|
||||
return path.substring(0, at + 1);
|
||||
}
|
||||
|
||||
public static TextureAtlas3D loadAll(String path)
|
||||
{
|
||||
String path_parent = getParentPath(path);
|
||||
String[] tree = new String(ResourceLoader.loadResource(path)).split("\n");
|
||||
TextureAtlas3D texmap = new TextureAtlas3D();
|
||||
|
||||
for(String dir : tree) {
|
||||
if(dir.endsWith(".png"))
|
||||
{
|
||||
while(dir.startsWith("./")) {
|
||||
dir = dir.substring(2, dir.length());
|
||||
}
|
||||
|
||||
TextureRaw tex = TextureRaw.loadFromFile(path_parent + dir);
|
||||
|
||||
if(tex == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
tex.ref = "/" + dir;
|
||||
texmap.add(tex);
|
||||
}
|
||||
}
|
||||
|
||||
return texmap;
|
||||
}
|
||||
|
||||
public TextureRef3D get(String ref)
|
||||
{
|
||||
for(TextureRef3D tex_ref : tex_refs) {
|
||||
if(tex_ref.ref.contentEquals(ref)) {
|
||||
return tex_ref;
|
||||
}
|
||||
}
|
||||
|
||||
for(TextureRef3D tex_ref : tex_refs) {
|
||||
if(tex_ref.ref.contentEquals("EMPTY")) {
|
||||
return get("EMPTY");
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("Error: atlas not generated");
|
||||
System.exit(0);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean refHasCollision(TextureRect check, TextureRect other)
|
||||
{
|
||||
if(check.z != other.z) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check.y >= other.y + other.h || other.y >= check.y + check.h) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(check.x >= other.x + other.w || other.x >= check.x + check.w) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private TextureRect refHasCollision(ArrayList<TextureRect> refs, TextureRect other)
|
||||
{
|
||||
for(TextureRect ref : refs) {
|
||||
if(refHasCollision(ref, other)) {
|
||||
return ref;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public void bind() {
|
||||
glBindTexture(GL_TEXTURE_2D, texture);
|
||||
}
|
||||
|
||||
public void generate()
|
||||
{
|
||||
tex_refs.clear();
|
||||
depth = 1;
|
||||
size = 1;
|
||||
|
||||
ArrayList<TextureRect> tex_rects = new ArrayList<TextureRect>();
|
||||
TextureRect lastRect = null;
|
||||
|
||||
raw_textures.sort(new Comparator<TextureRaw>() {
|
||||
|
||||
@Override
|
||||
public int compare(TextureRaw o1, TextureRaw o2)
|
||||
{
|
||||
if(o1.height < o2.height) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(o1.height > o2.height) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(o1.width > o2.width) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(o1.width < o2.width) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
|
||||
long millis_now = System.currentTimeMillis();
|
||||
long millis_last = millis_now;
|
||||
|
||||
// Work out the positions of each rect
|
||||
for(int i=0;i<raw_textures.size();i++)
|
||||
{
|
||||
millis_now = System.currentTimeMillis();
|
||||
if(millis_now - millis_last > 1000) {
|
||||
millis_last += 1000;
|
||||
System.out.println("Generating atlas " + i + "/" + raw_textures.size());
|
||||
}
|
||||
|
||||
TextureRaw tex = raw_textures.get(i);
|
||||
|
||||
TextureRect rect = new TextureRect();
|
||||
rect.r = tex;
|
||||
rect.w = tex.width;
|
||||
rect.h = tex.height;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.z = 0;
|
||||
|
||||
if(lastRect != null) {
|
||||
if(lastRect.h <= rect.h && lastRect.w <= rect.w) {
|
||||
rect.x = lastRect.x;
|
||||
rect.y = lastRect.y;
|
||||
rect.z = lastRect.z;
|
||||
}
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
TextureRect collision = refHasCollision(tex_rects, rect);
|
||||
|
||||
while(rect.w > size || rect.h > size) {
|
||||
size *= 2;
|
||||
}
|
||||
|
||||
if(
|
||||
collision == null &&
|
||||
rect.x + rect.w <= size &&
|
||||
rect.y + rect.h <= size
|
||||
) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(collision == null) {
|
||||
collision = rect;
|
||||
}
|
||||
|
||||
int change = collision.x + collision.w;
|
||||
|
||||
if(change != rect.x) {
|
||||
rect.x = change;
|
||||
} else {
|
||||
rect.x += 1;
|
||||
}
|
||||
|
||||
if(rect.x + rect.w > size) {
|
||||
rect.y += 1;
|
||||
rect.x = 0;
|
||||
}
|
||||
|
||||
if(rect.y + rect.h > size) {
|
||||
rect.z += 1;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
}
|
||||
|
||||
if(rect.z > size) {
|
||||
size *= 2;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.z = 0;
|
||||
}
|
||||
}
|
||||
|
||||
while(rect.z >= depth) {
|
||||
depth *= 2;
|
||||
}
|
||||
|
||||
TextureRef3D ref = new TextureRef3D();
|
||||
ref.texmap = this;
|
||||
ref.ref = tex.ref;
|
||||
ref.sx = rect.x;
|
||||
ref.sy = rect.y;
|
||||
ref.ex = rect.x + rect.w;
|
||||
ref.ey = rect.y + rect.h;
|
||||
ref.z = rect.z;
|
||||
|
||||
lastRect = rect;
|
||||
tex_rects.add(rect);
|
||||
tex_refs.add(ref);
|
||||
}
|
||||
|
||||
for(TextureRef3D ref : tex_refs) {
|
||||
ref.sx /= size;
|
||||
ref.ex /= size;
|
||||
ref.sy /= size;
|
||||
ref.ey /= size;
|
||||
|
||||
ref.z = (ref.z + 0.5f) / depth;
|
||||
}
|
||||
|
||||
int pixels = size * size * depth;
|
||||
|
||||
if(((long)pixels) * 4 > 2147483647) {
|
||||
System.err.println("Texture atlas is too big.");
|
||||
System.err.println("Atlas size: "+size+" x "+size+" x "+depth);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
byte[] texmap_b = new byte[pixels*4];
|
||||
Range3i texmap_r = new Range3i(size, size, depth);
|
||||
TextureRect last_rect = null;
|
||||
|
||||
for(int i=0;i<pixels;i++)
|
||||
{
|
||||
Vec3i pos = Vec3i.fromId(texmap_r, i);
|
||||
TextureRect r = null;
|
||||
|
||||
boolean found = false;
|
||||
|
||||
if(millis_now - millis_last > 1000) {
|
||||
millis_last += 1000;
|
||||
System.out.println("Rendering atlas " + ((int)(i / ((double)pixels) * 1000)) / (double)10 + "%");
|
||||
}
|
||||
|
||||
if(
|
||||
last_rect != null &&
|
||||
pos.x >= last_rect.x && pos.x < last_rect.x + last_rect.w &&
|
||||
pos.y >= last_rect.y && pos.y < last_rect.y + last_rect.h &&
|
||||
pos.z == last_rect.z
|
||||
) {
|
||||
found = true;
|
||||
r = last_rect;
|
||||
}
|
||||
|
||||
if(!found)
|
||||
{
|
||||
//System.out.println("hi");
|
||||
|
||||
for(TextureRect rect : tex_rects) {
|
||||
if(
|
||||
pos.x >= rect.x && pos.x < rect.x + rect.w &&
|
||||
pos.y >= rect.y && pos.y < rect.y + rect.h &&
|
||||
pos.z == rect.z
|
||||
) {
|
||||
r = rect;
|
||||
last_rect = rect;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(r == null) {
|
||||
texmap_b[i*4+0] = 0;
|
||||
texmap_b[i*4+1] = 0;
|
||||
texmap_b[i*4+2] = 0;
|
||||
texmap_b[i*4+3] = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
Range2i tex_r = new Range2i(r.w, r.h);
|
||||
Vec2i tex_p = new Vec2i(pos.x - r.x, pos.y - r.y);
|
||||
int tex_id = tex_p.getId(tex_r);
|
||||
|
||||
if(tex_p.x == r.w - 1 && tex_p.y == r.h - 1) {
|
||||
tex_rects.remove(r);
|
||||
}
|
||||
|
||||
texmap_b[i*4+0] = r.r.bytes[tex_id*4+0];
|
||||
texmap_b[i*4+1] = r.r.bytes[tex_id*4+1];
|
||||
texmap_b[i*4+2] = r.r.bytes[tex_id*4+2];
|
||||
texmap_b[i*4+3] = r.r.bytes[tex_id*4+3];
|
||||
|
||||
millis_now = System.currentTimeMillis();
|
||||
}
|
||||
|
||||
//System.out.println(Arrays.toString(texmap_b));
|
||||
System.out.println("Atlas size: "+size+" x "+size+" x "+depth);
|
||||
|
||||
ByteBuffer texmap_buff = ByteBuffer.allocateDirect(texmap_b.length);
|
||||
texmap_buff.put(texmap_b);
|
||||
texmap_buff.position(0);
|
||||
|
||||
texture = glGenTextures();
|
||||
glBindTexture(GL_TEXTURE_3D, texture);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||
glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA, size, size, depth, 0, GL_RGBA, GL_UNSIGNED_BYTE, texmap_buff);
|
||||
glGenerateMipmap(GL_TEXTURE_3D);
|
||||
|
||||
raw_textures.clear();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
package gl_engine.texture;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
import org.lwjgl.stb.STBImage;
|
||||
|
||||
import gl_engine.ResourceLoader;
|
||||
|
||||
public class TextureRaw
|
||||
{
|
||||
public byte[] bytes;
|
||||
public int width, height;
|
||||
public String ref;
|
||||
|
||||
public TextureRaw(String ref, byte[] bytes, int width, int height)
|
||||
{
|
||||
this.ref = ref;
|
||||
this.bytes = bytes;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public static TextureRaw createEmpty()
|
||||
{
|
||||
return new TextureRaw("EMPTY", new byte[] {
|
||||
(byte)255, (byte)0, (byte)255, (byte)255,
|
||||
(byte)0, (byte)0, (byte)0, (byte)255,
|
||||
(byte)0, (byte)0, (byte)0, (byte)255,
|
||||
(byte)255, (byte)0, (byte)255, (byte)255,
|
||||
}, 2, 2);
|
||||
}
|
||||
|
||||
public static TextureRaw loadFromFile(String src)
|
||||
{
|
||||
int width[] = {0};
|
||||
int height[] = {0};
|
||||
int channels[] = {0};
|
||||
|
||||
byte[] png = ResourceLoader.loadResource(src);
|
||||
|
||||
// Send back a "checkerboard" texture if the texture is invalid
|
||||
if(png.length == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
STBImage.stbi_set_flip_vertically_on_load(true);
|
||||
ByteBuffer texture = STBImage.stbi_load_from_memory(
|
||||
getByteBuffer(png),
|
||||
width, height, channels,
|
||||
STBImage.STBI_rgb_alpha);
|
||||
|
||||
if(texture == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
byte[] texture_b = new byte[texture.remaining()];
|
||||
texture.get(texture_b);
|
||||
|
||||
return new TextureRaw(src, texture_b, width[0], height[0]);
|
||||
}
|
||||
|
||||
private static ByteBuffer getByteBuffer(byte[] bytes)
|
||||
{
|
||||
ByteBuffer buffer = ByteBuffer.allocateDirect(bytes.length);
|
||||
|
||||
for(int i=0;i<bytes.length;i++) {
|
||||
buffer.put(i, bytes[i]);
|
||||
}
|
||||
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package gl_engine.texture;
|
||||
|
||||
class TextureRect {
|
||||
int x, y, w, h, z;
|
||||
TextureRaw r;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package gl_engine.texture;
|
||||
|
||||
public class TextureRef2D
|
||||
{
|
||||
public String ref;
|
||||
public TextureAtlas2D texmap;
|
||||
public float sx, sy, ex, ey;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
package gl_engine.texture;
|
||||
|
||||
public class TextureRef3D
|
||||
{
|
||||
public String ref;
|
||||
public TextureAtlas3D texmap;
|
||||
public float sx, sy, ex, ey, z;
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
package gl_engine.vec;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
|
||||
public class Vec2d implements IBdfClassManager
|
||||
{
|
||||
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 double dot(Vec2d other) {
|
||||
return x * other.x + y * other.y;
|
||||
}
|
||||
|
||||
public double length() {
|
||||
return Math.sqrt(x*x + y*y);
|
||||
}
|
||||
|
||||
public Vec2d normalize() {
|
||||
double len = length();
|
||||
return divide(len);
|
||||
}
|
||||
|
||||
public boolean equal(Vec2d other) {
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
public Vec2d add(Vec2d other) {
|
||||
return new Vec2d(this.x + other.x, this.y + other.y);
|
||||
}
|
||||
|
||||
public Vec2d subtract(Vec2d other) {
|
||||
return new Vec2d(this.x - other.x, this.y - other.y);
|
||||
}
|
||||
|
||||
public Vec2d multiply(Vec2d other) {
|
||||
return new Vec2d(this.x * other.x, this.y * other.y);
|
||||
}
|
||||
|
||||
public Vec2d divide(Vec2d other) {
|
||||
return new Vec2d(this.x / other.x, this.y / other.y);
|
||||
}
|
||||
|
||||
public Vec2d add(double v) {
|
||||
return new Vec2d(this.x + v, this.y + v);
|
||||
}
|
||||
|
||||
public Vec2d subtract(double v) {
|
||||
return new Vec2d(this.x - v, this.y - v);
|
||||
}
|
||||
|
||||
public Vec2d multiply(double v) {
|
||||
return new Vec2d(this.x * v, this.y * v);
|
||||
}
|
||||
|
||||
public Vec2d divide(double v) {
|
||||
return new Vec2d(this.x / v, this.y / v);
|
||||
}
|
||||
|
||||
public Vec2d copy() {
|
||||
return new Vec2d(x, y);
|
||||
}
|
||||
|
||||
public double squareDistance(Vec2d other)
|
||||
{
|
||||
double dx = MathHelpers.positive(other.x - x);
|
||||
double dy = MathHelpers.positive(other.y - y);
|
||||
return MathHelpers.biggest(dx, dy);
|
||||
}
|
||||
|
||||
public Vec2i toInt() {
|
||||
return new Vec2i(MathHelpers.floor(x), MathHelpers.floor(y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf) {
|
||||
double data[] = bdf.getDoubleArray();
|
||||
if(data.length != 2) return;
|
||||
x = data[0];
|
||||
y = data[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setDoubleArray(new double[] {x, y});
|
||||
};
|
||||
|
||||
public Vec2d(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
package gl_engine.vec;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
import gl_engine.range.Range2i;
|
||||
|
||||
public class Vec2i implements IBdfClassManager
|
||||
{
|
||||
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 x = MathHelpers.mod(this.x, range.mx);
|
||||
int y = MathHelpers.mod(this.y, range.my);
|
||||
|
||||
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 = MathHelpers.mod(id, range.mx);
|
||||
id -= x;
|
||||
id /= range.mx;
|
||||
int y = MathHelpers.mod(id, range.my);
|
||||
|
||||
return new Vec2i(x, y);
|
||||
}
|
||||
|
||||
public boolean equal(Vec2i other) {
|
||||
return x == other.x && y == other.y;
|
||||
}
|
||||
|
||||
public Vec2i add(Vec2i other) {
|
||||
return new Vec2i(this.x + other.x, this.y + other.y);
|
||||
}
|
||||
|
||||
public Vec2i subtract(Vec2i other) {
|
||||
return new Vec2i(this.x - other.x, this.y - other.y);
|
||||
}
|
||||
|
||||
public Vec2i multiply(Vec2i other) {
|
||||
return new Vec2i(this.x * other.x, this.y * other.y);
|
||||
}
|
||||
|
||||
public Vec2i divide(Vec2i other) {
|
||||
return new Vec2i(this.x / other.x, this.y / other.y);
|
||||
}
|
||||
|
||||
public Vec2i add(int v) {
|
||||
return new Vec2i(this.x + v, this.y + v);
|
||||
}
|
||||
|
||||
public Vec2i subtract(int v) {
|
||||
return new Vec2i(this.x - v, this.y - v);
|
||||
}
|
||||
|
||||
public Vec2i multiply(int v) {
|
||||
return new Vec2i(this.x * v, this.y * v);
|
||||
}
|
||||
|
||||
public Vec2i divide(int v) {
|
||||
return new Vec2i(this.x / v, this.y / v);
|
||||
}
|
||||
|
||||
public Vec2i copy() {
|
||||
return new Vec2i(x, y);
|
||||
}
|
||||
|
||||
public double squareDistance(Vec2i other)
|
||||
{
|
||||
int dx = MathHelpers.positive(other.x - x);
|
||||
int dy = MathHelpers.positive(other.y - y);
|
||||
return MathHelpers.biggest(dx, dy);
|
||||
}
|
||||
|
||||
public Vec2d toDouble() {
|
||||
return new Vec2d(x, y);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf) {
|
||||
int data[] = bdf.getIntegerArray();
|
||||
if(data.length != 2) return;
|
||||
x = data[0];
|
||||
y = data[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setIntegerArray(new int[] {x, y});
|
||||
};
|
||||
|
||||
public Vec2i(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
package gl_engine.vec;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
|
||||
public class Vec3d implements IBdfClassManager
|
||||
{
|
||||
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 double dot(Vec3d other) {
|
||||
return x * other.x + y * other.y + z * other.z;
|
||||
}
|
||||
|
||||
public double length() {
|
||||
return Math.sqrt(x*x + y*y + z*z);
|
||||
}
|
||||
|
||||
public Vec3d normalize() {
|
||||
double len = length();
|
||||
return divide(len);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public Vec3d add(Vec3d other) {
|
||||
return new Vec3d(this.x + other.x, this.y + other.y, this.z + other.z);
|
||||
}
|
||||
|
||||
public Vec3d subtract(Vec3d other) {
|
||||
return new Vec3d(this.x - other.x, this.y - other.y, this.z - other.z);
|
||||
}
|
||||
|
||||
public Vec3d multiply(Vec3d other) {
|
||||
return new Vec3d(this.x * other.x, this.y * other.y, this.z * other.z);
|
||||
}
|
||||
|
||||
public Vec3d divide(Vec3d other) {
|
||||
return new Vec3d(this.x / other.x, this.y / other.y, this.z / other.z);
|
||||
}
|
||||
|
||||
public Vec3d add(double v) {
|
||||
return new Vec3d(this.x + v, this.y + v, this.z + v);
|
||||
}
|
||||
|
||||
public Vec3d subtract(double v) {
|
||||
return new Vec3d(this.x - v, this.y - v, this.z - v);
|
||||
}
|
||||
|
||||
public Vec3d multiply(double v) {
|
||||
return new Vec3d(this.x * v, this.y * v, this.z * v);
|
||||
}
|
||||
|
||||
public Vec3d divide(double v) {
|
||||
return new Vec3d(this.x / v, this.y / v, this.z / v);
|
||||
}
|
||||
|
||||
public Vec3d copy() {
|
||||
return new Vec3d(x, y, z);
|
||||
}
|
||||
|
||||
public double squareDistance(Vec3d other)
|
||||
{
|
||||
double dx = MathHelpers.positive(other.x - x);
|
||||
double dy = MathHelpers.positive(other.y - y);
|
||||
double dz = MathHelpers.positive(other.z - z);
|
||||
|
||||
if(dx > dy) return dx;
|
||||
if(dy > dz) return dy;
|
||||
else return dz;
|
||||
}
|
||||
|
||||
public Vec3i toInt() {
|
||||
return new Vec3i(MathHelpers.floor(x), MathHelpers.floor(y), MathHelpers.floor(z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf) {
|
||||
double data[] = bdf.getDoubleArray();
|
||||
if(data.length != 3) return;
|
||||
x = data[0];
|
||||
y = data[1];
|
||||
z = data[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setDoubleArray(new double[] {x, y, z});
|
||||
};
|
||||
|
||||
public Vec3d(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,132 @@
|
|||
package gl_engine.vec;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
import gl_engine.range.Range3i;
|
||||
|
||||
public class Vec3i implements IBdfClassManager
|
||||
{
|
||||
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 x = MathHelpers.mod(this.x, range.mx);
|
||||
int y = MathHelpers.mod(this.y, range.my);
|
||||
int z = MathHelpers.mod(this.z, range.mz);
|
||||
|
||||
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 = MathHelpers.mod(id, range.mx);
|
||||
id -= x;
|
||||
id /= range.mx;
|
||||
int y = MathHelpers.mod(id, range.my);
|
||||
id -= y;
|
||||
id /= range.my;
|
||||
int z = MathHelpers.mod(id, range.mz);
|
||||
|
||||
return new Vec3i(x, y, z);
|
||||
}
|
||||
|
||||
public boolean equal(Vec3i other) {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
public Vec3i add(Vec3i other) {
|
||||
return new Vec3i(this.x + other.x, this.y + other.y, this.z + other.z);
|
||||
}
|
||||
|
||||
public Vec3i subtract(Vec3i other) {
|
||||
return new Vec3i(this.x - other.x, this.y - other.y, this.z - other.z);
|
||||
}
|
||||
|
||||
public Vec3i multiply(Vec3i other) {
|
||||
return new Vec3i(this.x * other.x, this.y * other.y, this.z * other.z);
|
||||
}
|
||||
|
||||
public Vec3i divide(Vec3i other) {
|
||||
return new Vec3i(this.x / other.x, this.y / other.y, this.z / other.z);
|
||||
}
|
||||
|
||||
public Vec3i add(int v) {
|
||||
return new Vec3i(this.x + v, this.y + v, this.z + v);
|
||||
}
|
||||
|
||||
public Vec3i subtract(int v) {
|
||||
return new Vec3i(this.x - v, this.y - v, this.z - v);
|
||||
}
|
||||
|
||||
public Vec3i multiply(int v) {
|
||||
return new Vec3i(this.x * v, this.y * v, this.z * v);
|
||||
}
|
||||
|
||||
public Vec3i divide(int v) {
|
||||
return new Vec3i(this.x / v, this.y / v, this.z / v);
|
||||
}
|
||||
|
||||
public Vec3i copy() {
|
||||
return new Vec3i(x, y, z);
|
||||
}
|
||||
|
||||
public int squareDistance(Vec3i other)
|
||||
{
|
||||
int dx = MathHelpers.positive(other.x - x);
|
||||
int dy = MathHelpers.positive(other.y - y);
|
||||
int dz = MathHelpers.positive(other.z - z);
|
||||
|
||||
if(dx > dy) return dx;
|
||||
if(dy > dz) return dy;
|
||||
else return dz;
|
||||
}
|
||||
|
||||
public Vec3d toDouble() {
|
||||
return new Vec3d(x, y, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf) {
|
||||
int data[] = bdf.getIntegerArray();
|
||||
if(data.length != 3) return;
|
||||
x = data[0];
|
||||
y = data[1];
|
||||
z = data[2];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setIntegerArray(new int[] {x, y, z});
|
||||
};
|
||||
|
||||
public Vec3i(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
package gl_engine.vec;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
|
||||
public class Vec4d implements IBdfClassManager
|
||||
{
|
||||
public double x;
|
||||
public double y;
|
||||
public double z;
|
||||
public double m;
|
||||
|
||||
public Vec4d(double x, double y, double z, double m)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
public double distance(Vec4d other) {
|
||||
return Math.sqrt(
|
||||
MathHelpers.squared(this.x - other.x) +
|
||||
MathHelpers.squared(this.y - other.y) +
|
||||
MathHelpers.squared(this.z - other.z) +
|
||||
MathHelpers.squared(this.m - other.m));
|
||||
}
|
||||
|
||||
public double dot(Vec4d other) {
|
||||
return x * other.x + y * other.y + z * other.z + m * other.m;
|
||||
}
|
||||
|
||||
public double length() {
|
||||
return Math.sqrt(x*x + y*y + z*z + m*m);
|
||||
}
|
||||
|
||||
public Vec4d normalize() {
|
||||
double len = length();
|
||||
return divide(len);
|
||||
}
|
||||
|
||||
public static double distance(Vec4d v1, Vec4d v2) {
|
||||
return v1.distance(v2);
|
||||
}
|
||||
|
||||
public boolean equal(Vec4d other) {
|
||||
return x == other.x && y == other.y && z == other.z && m == other.m;
|
||||
}
|
||||
|
||||
public Vec4d add(Vec4d other) {
|
||||
return new Vec4d(this.x + other.x, this.y + other.y, this.z + other.z, this.m + other.m);
|
||||
}
|
||||
|
||||
public Vec4d subtract(Vec4d other) {
|
||||
return new Vec4d(this.x - other.x, this.y - other.y, this.z - other.z, this.m - other.m);
|
||||
}
|
||||
|
||||
public Vec4d multiply(Vec4d other) {
|
||||
return new Vec4d(this.x * other.x, this.y * other.y, this.z * other.z, this.m * other.m);
|
||||
}
|
||||
|
||||
public Vec4d divide(Vec4d other) {
|
||||
return new Vec4d(this.x / other.x, this.y / other.y, this.z / other.z, this.m / other.m);
|
||||
}
|
||||
|
||||
public Vec4d add(double v) {
|
||||
return new Vec4d(this.x + v, this.y + v, this.z + v, this.m + v);
|
||||
}
|
||||
|
||||
public Vec4d subtract(double v) {
|
||||
return new Vec4d(this.x - v, this.y - v, this.z - v, this.m - v);
|
||||
}
|
||||
|
||||
public Vec4d multiply(double v) {
|
||||
return new Vec4d(this.x * v, this.y * v, this.z * v, this.m * v);
|
||||
}
|
||||
|
||||
public Vec4d divide(double v) {
|
||||
return new Vec4d(this.x / v, this.y / v, this.z / v, this.m / v);
|
||||
}
|
||||
|
||||
public Vec4d copy() {
|
||||
return new Vec4d(x, y, z, m);
|
||||
}
|
||||
|
||||
public double squareDistance(Vec4d other)
|
||||
{
|
||||
double dx = MathHelpers.positive(other.x - x);
|
||||
double dy = MathHelpers.positive(other.y - y);
|
||||
double dz = MathHelpers.positive(other.z - z);
|
||||
double dm = MathHelpers.positive(other.m - m);
|
||||
|
||||
if(dx > dy) return dx;
|
||||
if(dy > dz) return dy;
|
||||
if(dz > dm) return dz;
|
||||
else return dm;
|
||||
}
|
||||
|
||||
public Vec4i toInt() {
|
||||
return new Vec4i(MathHelpers.floor(x), MathHelpers.floor(y), MathHelpers.floor(z), MathHelpers.floor(m));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf) {
|
||||
double data[] = bdf.getDoubleArray();
|
||||
if(data.length != 4) return;
|
||||
x = data[0];
|
||||
y = data[1];
|
||||
z = data[2];
|
||||
m = data[3];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setDoubleArray(new double[] {x, y, z, m});
|
||||
};
|
||||
|
||||
public Vec4d(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
package gl_engine.vec;
|
||||
|
||||
import bdf.classes.IBdfClassManager;
|
||||
import bdf.types.BdfObject;
|
||||
import gl_engine.MathHelpers;
|
||||
import gl_engine.range.Range4i;
|
||||
|
||||
public class Vec4i implements IBdfClassManager
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
public int z;
|
||||
public int m;
|
||||
|
||||
public Vec4i(int x, int y, int z, int m)
|
||||
{
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
this.m = m;
|
||||
}
|
||||
|
||||
public double distance(Vec4i other) {
|
||||
return Math.sqrt(
|
||||
MathHelpers.squared(this.x - other.x) +
|
||||
MathHelpers.squared(this.y - other.y) +
|
||||
MathHelpers.squared(this.z - other.z) +
|
||||
MathHelpers.squared(this.m - other.m));
|
||||
}
|
||||
|
||||
public static double distance(Vec4i v1, Vec4i v2) {
|
||||
return v1.distance(v2);
|
||||
}
|
||||
|
||||
public int getId(Range4i range)
|
||||
{
|
||||
int x = MathHelpers.mod(this.x, range.mx);
|
||||
int y = MathHelpers.mod(this.y, range.my);
|
||||
int z = MathHelpers.mod(this.z, range.mz);
|
||||
int m = MathHelpers.mod(this.m, range.mm);
|
||||
|
||||
int id = 0;
|
||||
int mu = 1;
|
||||
|
||||
id += x;
|
||||
mu = range.mx;
|
||||
id += y*mu;
|
||||
mu *= range.my;
|
||||
id += z*mu;
|
||||
mu *= range.mz;
|
||||
id += m*mu;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public static Vec4i fromId(Range4i range, int id)
|
||||
{
|
||||
int x = MathHelpers.mod(id, range.mx);
|
||||
id -= x;
|
||||
id /= range.mx;
|
||||
int y = MathHelpers.mod(id, range.my);
|
||||
id -= y;
|
||||
id /= range.my;
|
||||
int z = MathHelpers.mod(id, range.mz);
|
||||
id -= z;
|
||||
id /= range.mz;
|
||||
int m = MathHelpers.mod(id, range.mm);
|
||||
|
||||
return new Vec4i(x, y, z, m);
|
||||
}
|
||||
|
||||
public boolean equal(Vec4i other) {
|
||||
return x == other.x && y == other.y && z == other.z;
|
||||
}
|
||||
|
||||
public Vec4i add(Vec4i other) {
|
||||
return new Vec4i(this.x + other.x, this.y + other.y, this.z + other.z, this.m + other.m);
|
||||
}
|
||||
|
||||
public Vec4i subtract(Vec4i other) {
|
||||
return new Vec4i(this.x - other.x, this.y - other.y, this.z - other.z, this.m - other.m);
|
||||
}
|
||||
|
||||
public Vec4i multiply(Vec4i other) {
|
||||
return new Vec4i(this.x * other.x, this.y * other.y, this.z * other.z, this.m * other.m);
|
||||
}
|
||||
|
||||
public Vec4i divide(Vec4i other) {
|
||||
return new Vec4i(this.x / other.x, this.y / other.y, this.z / other.z, this.m / other.m);
|
||||
}
|
||||
|
||||
public Vec4i add(int v) {
|
||||
return new Vec4i(this.x + v, this.y + v, this.z + v, this.m + v);
|
||||
}
|
||||
|
||||
public Vec4i subtract(int v) {
|
||||
return new Vec4i(this.x - v, this.y - v, this.z - v, this.m - v);
|
||||
}
|
||||
|
||||
public Vec4i multiply(int v) {
|
||||
return new Vec4i(this.x * v, this.y * v, this.z * v, this.m * v);
|
||||
}
|
||||
|
||||
public Vec4i divide(int v) {
|
||||
return new Vec4i(this.x / v, this.y / v, this.z / v, this.m / v);
|
||||
}
|
||||
|
||||
public Vec4i copy() {
|
||||
return new Vec4i(x, y, z, m);
|
||||
}
|
||||
|
||||
public int squareDistance(Vec4i other)
|
||||
{
|
||||
int dx = MathHelpers.positive(other.x - x);
|
||||
int dy = MathHelpers.positive(other.y - y);
|
||||
int dz = MathHelpers.positive(other.z - z);
|
||||
int dm = MathHelpers.positive(other.m - m);
|
||||
|
||||
if(dx > dy) return dx;
|
||||
if(dy > dz) return dy;
|
||||
if(dz > dm) return dz;
|
||||
else return dm;
|
||||
}
|
||||
|
||||
public Vec4d toDouble() {
|
||||
return new Vec4d(x, y, z, m);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassLoad(BdfObject bdf) {
|
||||
int data[] = bdf.getIntegerArray();
|
||||
if(data.length != 4) return;
|
||||
x = data[0];
|
||||
y = data[1];
|
||||
z = data[2];
|
||||
m = data[3];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void BdfClassSave(BdfObject bdf) {
|
||||
bdf.setIntegerArray(new int[] {x, y, z, m});
|
||||
};
|
||||
|
||||
public Vec4i(BdfObject bdf) {
|
||||
BdfClassLoad(bdf);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue