Progress on UI Renderer

This commit is contained in:
2026-08-16 21:22:28 +02:00
parent 3b074a2684
commit 56eae46176
28 changed files with 1329 additions and 1070 deletions
@@ -2,11 +2,11 @@ package speiger.src.coreengine.platform.graphics.api.core;
import speiger.src.coreengine.platform.graphics.api.buffer.VertexBuffer; import speiger.src.coreengine.platform.graphics.api.buffer.VertexBuffer;
import speiger.src.coreengine.platform.graphics.api.mesh.Mesh; import speiger.src.coreengine.platform.graphics.api.mesh.Mesh;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline; import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.texture.Texture; import speiger.src.coreengine.platform.graphics.api.texture.Texture;
import speiger.src.coreengine.platform.graphics.api.utils.AccessType; import speiger.src.coreengine.platform.graphics.api.utils.AccessType;
import speiger.src.coreengine.platform.graphics.api.utils.GraphicsResource; import speiger.src.coreengine.platform.graphics.api.utils.GraphicsResource;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer { public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer {
GraphicsCommandBuffer begin(); GraphicsCommandBuffer begin();
@@ -14,7 +14,7 @@ public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer {
GraphicsCommandBuffer pipeline(ShaderPipeline pipeline); GraphicsCommandBuffer pipeline(ShaderPipeline pipeline);
GraphicsCommandBuffer mesh(Mesh mesh); GraphicsCommandBuffer mesh(Mesh mesh);
GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler); GraphicsCommandBuffer texture(int binding, SampledTexture texture);
GraphicsCommandBuffer texture(int binding, Texture texture, AccessType access); GraphicsCommandBuffer texture(int binding, Texture texture, AccessType access);
GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer); GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer);
@@ -0,0 +1,13 @@
package speiger.src.coreengine.platform.graphics.api.utils;
import java.util.Objects;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.texture.Texture;
public record SampledTexture(Texture texture, Sampler sampler) {
public SampledTexture {
Objects.requireNonNull(texture);
Objects.requireNonNull(sampler);
}
}
@@ -1,7 +1,5 @@
package speiger.src.coreengine.platform.graphics.api.vertex.builder; package speiger.src.coreengine.platform.graphics.api.vertex.builder;
import java.util.List;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode; import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType; import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType;
@@ -11,8 +9,7 @@ import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage;
public interface IVertexBuffer extends IVertexBuilder { public interface IVertexBuffer extends IVertexBuilder {
Element current(); Element current();
IVertexBuffer next(); IVertexBuffer next();
IVertexBuffer finish(); BufferResult finish();
List<BufferResult> results();
default IVertexBuffer validate(Usage usage, GraphicsDataType type, int size) { return validate(this, usage, type, size); } default IVertexBuffer validate(Usage usage, GraphicsDataType type, int size) { return validate(this, usage, type, size); }
@@ -1,13 +1,9 @@
package speiger.src.coreengine.platform.graphics.api.vertex.builder; package speiger.src.coreengine.platform.graphics.api.vertex.builder;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.util.List;
import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.MemoryUtil;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode; import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout; import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Element; import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Element;
@@ -24,7 +20,6 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
int vertexBytes; int vertexBytes;
int elementBytes; int elementBytes;
int lastVertecies = 0; int lastVertecies = 0;
ObjectList<BufferResult> results;
public VertexBuilder(int size) { public VertexBuilder(int size) {
this(MemoryUtil.memAlloc(size)); this(MemoryUtil.memAlloc(size));
@@ -40,6 +35,7 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
} }
public VertexBuilder start(DrawMode mode, VertexLayout layout) { public VertexBuilder start(DrawMode mode, VertexLayout layout) {
if(index != 0) throw new IllegalStateException("Can't change Layout mid Writing");
this.mode = mode; this.mode = mode;
this.layout = layout; this.layout = layout;
return this; return this;
@@ -52,10 +48,10 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
totalStoredBytes = 0; totalStoredBytes = 0;
vertexBytes = 0; vertexBytes = 0;
lastVertecies = 0; lastVertecies = 0;
results = null;
return this; return this;
} }
public boolean hasVertecies() { return lastVertecies < vertecies; }
public boolean is(DrawMode mode, VertexLayout layout) { return this.mode == mode && this.layout == layout; } public boolean is(DrawMode mode, VertexLayout layout) { return this.mode == mode && this.layout == layout; }
public DrawMode mode() { return mode; } public DrawMode mode() { return mode; }
public VertexLayout getFormat() { return layout; } public VertexLayout getFormat() { return layout; }
@@ -73,16 +69,10 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
} }
@Override @Override
public IVertexBuffer finish() { public BufferResult finish() {
if(results == null) results = new ObjectArrayList<>(); BufferResult result = new BufferResult(mode, lastVertecies, vertecies);
results.add(new BufferResult(mode, lastVertecies, vertecies));
lastVertecies = vertecies; lastVertecies = vertecies;
return this; return result;
}
@Override
public List<BufferResult> results() {
return results == null ? ObjectLists.empty() : results.unmodifiable();
} }
@Override @Override
@@ -93,12 +83,8 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
elementBytes = 0; elementBytes = 0;
if(index == 0) { if(index == 0) {
vertecies++; vertecies++;
if(mode == DrawMode.LINES || mode == DrawMode.LINE_STRIP) {
buffer.put(totalStoredBytes, buffer, totalStoredBytes - vertexBytes, vertexBytes);
vertecies++;
}
vertexBytes = 0; vertexBytes = 0;
ensureCapacity(totalStoredBytes + layout.bytes()); ensureCapacity(totalStoredBytes + (layout.bytes() * mode.primitiveLength()));
} }
return this; return this;
} }
@@ -136,8 +122,6 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
return vertecies; return vertecies;
} }
public VertexBuilder putBulk(byte[] source) { public VertexBuilder putBulk(byte[] source) {
if(index != 0) throw new IllegalStateException("Can't do bulk iterations when mid Building"); if(index != 0) throw new IllegalStateException("Can't do bulk iterations when mid Building");
ensureCapacity(source.length + layout.bytes()); ensureCapacity(source.length + layout.bytes());
@@ -12,13 +12,13 @@ import speiger.src.coreengine.platform.graphics.api.buffer.VertexBuffer;
import speiger.src.coreengine.platform.graphics.api.buffer.states.BufferType; import speiger.src.coreengine.platform.graphics.api.buffer.states.BufferType;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer; import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer;
import speiger.src.coreengine.platform.graphics.api.mesh.Mesh; import speiger.src.coreengine.platform.graphics.api.mesh.Mesh;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget; import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget;
import speiger.src.coreengine.platform.graphics.api.shader.DepthTarget; import speiger.src.coreengine.platform.graphics.api.shader.DepthTarget;
import speiger.src.coreengine.platform.graphics.api.shader.RasterizerState; import speiger.src.coreengine.platform.graphics.api.shader.RasterizerState;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline; import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.texture.Texture; import speiger.src.coreengine.platform.graphics.api.texture.Texture;
import speiger.src.coreengine.platform.graphics.api.utils.AccessType; import speiger.src.coreengine.platform.graphics.api.utils.AccessType;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager; import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager;
import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer; import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer;
import speiger.src.coreengine.platform.graphics.opengl.mesh.GLMesh; import speiger.src.coreengine.platform.graphics.opengl.mesh.GLMesh;
@@ -118,15 +118,14 @@ public class GLImmidateCommandBuffer implements GraphicsCommandBuffer {
} }
@Override @Override
public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) { public GraphicsCommandBuffer texture(int binding, SampledTexture texture) {
Objects.requireNonNull(texture); Objects.requireNonNull(texture);
Objects.requireNonNull(sampler);
ensureDrawing(); ensureDrawing();
Objects.requireNonNull(shader, "No Pipeline found"); Objects.requireNonNull(shader, "No Pipeline found");
Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found"); Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found");
GLStates states = device.states; GLStates states = device.states;
states.textures.bind(binding, ((GLTexture)texture).id()); states.textures.bind(binding, ((GLTexture)texture.texture()).id());
states.samplers.bind(binding, ((GLSampler)sampler).id()); states.samplers.bind(binding, ((GLSampler)texture.sampler()).id());
recorded++; recorded++;
return this; return this;
} }
@@ -16,7 +16,6 @@ import speiger.src.coreengine.platform.graphics.api.buffer.states.BufferType;
import speiger.src.coreengine.platform.graphics.api.buffer.states.IndeciesType; import speiger.src.coreengine.platform.graphics.api.buffer.states.IndeciesType;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer; import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer;
import speiger.src.coreengine.platform.graphics.api.mesh.Mesh; import speiger.src.coreengine.platform.graphics.api.mesh.Mesh;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget; import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget;
import speiger.src.coreengine.platform.graphics.api.shader.DepthTarget; import speiger.src.coreengine.platform.graphics.api.shader.DepthTarget;
import speiger.src.coreengine.platform.graphics.api.shader.RasterizerState; import speiger.src.coreengine.platform.graphics.api.shader.RasterizerState;
@@ -24,6 +23,7 @@ import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode; import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.texture.Texture; import speiger.src.coreengine.platform.graphics.api.texture.Texture;
import speiger.src.coreengine.platform.graphics.api.utils.AccessType; import speiger.src.coreengine.platform.graphics.api.utils.AccessType;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager; import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager;
import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager.NoOp; import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager.NoOp;
import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer; import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer;
@@ -110,13 +110,12 @@ public class GLRecordingCommandBuffer implements GraphicsCommandBuffer {
} }
@Override @Override
public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) { public GraphicsCommandBuffer texture(int binding, SampledTexture texture) {
Objects.requireNonNull(texture); Objects.requireNonNull(texture);
Objects.requireNonNull(sampler);
ensureDrawing(); ensureDrawing();
Objects.requireNonNull(shader, "No Pipeline found"); Objects.requireNonNull(shader, "No Pipeline found");
Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found"); Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found");
tasks.add(new SetTexture(binding, (GLTexture)texture, (GLSampler)sampler, device.states)); tasks.add(new SetTexture(binding, (GLTexture)texture.texture(), (GLSampler)texture.sampler(), device.states));
return this; return this;
} }
@@ -94,14 +94,14 @@ public abstract non-sealed class GuiComponent extends FlagObject implements ICas
if(!comp.isVisible()) return false; if(!comp.isVisible()) return false;
comp.updateAnimations(partialTicks); comp.updateAnimations(partialTicks);
if(comp.isScissored()) { if(comp.isScissored()) {
if(!renderer.isInScissors(comp.getBox())) return false; if(!renderer.isClipping(comp.getBox())) return false;
renderer.pushScissors(comp.getBox()); renderer.pushClip(comp.getBox());
if(comp.renderer != null) { if(comp.renderer != null) {
comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks); comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks);
comp.renderChildren(renderer, mouseX, mouseY, partialTicks); comp.renderChildren(renderer, mouseX, mouseY, partialTicks);
} }
else comp.renderComponent(renderer, mouseX, mouseY, partialTicks); else comp.renderComponent(renderer, mouseX, mouseY, partialTicks);
renderer.popScissors(); renderer.popClip();
} }
else if(comp.renderer != null) { else if(comp.renderer != null) {
comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks); comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks);
@@ -16,6 +16,8 @@ public interface IGuiBox extends IScreenBox
public IGuiBox onChanged(); public IGuiBox onChanged();
public static IGuiBox of(float x, float y, float width, float height) { return new GuiBox(x, y, width, height); } public static IGuiBox of(float x, float y, float width, float height) { return new GuiBox(x, y, width, height); }
public static IGuiBox parent(float padding) { return new ParentBox(padding); }
public static IGuiBox parent(float left, float top, float right, float bottom) { return new ParentBox(left, top, right, bottom); }
public default IGuiBox copy() { return GuiBox.clone(this); } public default IGuiBox copy() { return GuiBox.clone(this); }
public default IGuiBox copy(float padding) { return GuiBox.clonePadded(this, padding); } public default IGuiBox copy(float padding) { return GuiBox.clonePadded(this, padding); }
@@ -22,7 +22,7 @@ public class ParentBox implements IGuiBox
maxY = -value; maxY = -value;
} }
public ParentBox(float paddingTop, float paddingLeft, float paddingBottom, float paddingRight) { public ParentBox(float paddingLeft, float paddingTop, float paddingRight, float paddingBottom) {
minX = paddingLeft; minX = paddingLeft;
minY = paddingTop; minY = paddingTop;
maxX = paddingRight; maxX = paddingRight;
@@ -1,24 +1,38 @@
package speiger.src.coreengine.ui.gui.renderer; package speiger.src.coreengine.ui.gui.renderer;
import speiger.src.coreengine.math.vector.quaternion.Quaternion; import speiger.src.coreengine.math.vector.quaternion.Quaternion;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.ui.gui.layout.box.IGuiBox; import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;
import speiger.src.coreengine.ui.gui.utils.Align;
public interface IUIRenderer { public interface IUIRenderer {
public boolean isInScissors(IGuiBox box); boolean isClipping(IGuiBox box);
public void pushScissors(IGuiBox box); void pushClip(IGuiBox box);
public void popScissors(); void popClip();
public void flush(); void pushTransform();
void popTransform();
public void pushTransform(); void translate(float z);
public void popTransform(); void translate(float x, float y);
public void translate(float z); void scale(float scale);
public void translate(float x, float y); void scale(float x, float y);
public void translate(float x, float y, float z);
public void scale(float scale); void rotate(Quaternion rotation);
public void scale(float x, float y);
public void rotate(Quaternion rotation); void align(Align vertical, Align horizontal);
void alignV(Align align);
void alignH(Align align);
void pushLayer(LayerType type);
void popLayer();
void drawLine(float startX, float startY, float endX, float endY, float lineWidth, int color);
void drawFrame(IGuiBox box, int color);
void drawRect(IGuiBox box, int color);
void drawImage(IGuiBox box, SampledTexture texture, int color);
void drawImage(IGuiBox box, SampledTexture texture, float minU, float minV, float maxU, float maxV, int color);
void drawCustom(UIDrawer drawer);
} }
@@ -0,0 +1,7 @@
package speiger.src.coreengine.ui.gui.renderer;
public enum LayerType {
COMPONENT,
COMPONENT_STACK,
WINDOW;
}
@@ -0,0 +1,12 @@
package speiger.src.coreengine.ui.gui.renderer;
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.IVertexBuilder;
public interface UIDrawer {
ShaderPipeline pipeline();
void buildVertecies(IVertexBuilder builder, Matrix4f matrix);
void setupExtra(GraphicsCommandBuffer buffer);
}
@@ -0,0 +1,215 @@
package speiger.src.coreengine.ui.gui.renderer;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.vector.matrix.Matrix4fStack;
import speiger.src.coreengine.math.vector.quaternion.Quaternion;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsDevice;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.IVertexBuffer.BufferResult;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.IVertexBuilder;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.VertexBuilder;
import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;
import speiger.src.coreengine.ui.gui.utils.Align;
import speiger.src.coreengine.ui.gui.utils.UIConstants;
public class UIRenderer implements IUIRenderer {
GraphicsDevice device;
Matrix4fStack matrix = new Matrix4fStack();
VertexBuilder builder = new VertexBuilder(100);
List<UIDraw> draws = new ObjectArrayList<>();
Align[] alignment = new Align[] { Align.CENTER, Align.CENTER };
ShaderPipeline currentPipeline;
SampledTexture currentTexture;
public UIRenderer(GraphicsDevice device) {
this.device = device;
}
@Override
public boolean isClipping(IGuiBox box) {
return false;
}
@Override
public void pushClip(IGuiBox box) {
}
@Override
public void popClip() {
}
@Override
public void pushTransform() {
matrix.push();
}
@Override
public void popTransform() {
matrix.pop();
}
@Override
public void translate(float z) {
matrix.translateZ(z);
}
@Override
public void translate(float x, float y) {
matrix.translate(x, y);
}
@Override
public void scale(float scale) {
matrix.scale(scale);
}
@Override
public void scale(float x, float y) {
matrix.scale(x, y, 1F);
}
@Override
public void rotate(Quaternion rotation) {
matrix.rotate(rotation);
}
@Override
public void align(Align vertical, Align horizontal) {
alignment[0] = vertical;
alignment[1] = horizontal;
}
@Override
public void alignV(Align align) {
alignment[0] = align;
}
@Override
public void alignH(Align align) {
alignment[1] = align;
}
@Override
public void pushLayer(LayerType type) {
}
@Override
public void popLayer() {
}
@Override
public void drawLine(float startX, float startY, float endX, float endY, float lineWidth, int color) {
ensureType(UIConstants.GUI, null);
float dx = endX - startX;
float dy = endY - startY;
float xOffset = alignment[0].align(dx);
float yOffset = alignment[1].align(dy);
float length = (float)Math.sqrt(dx*dx + dy*dy);
dx /= length;
dy /= length;
float px = -dy * (lineWidth * 0.5F);
float py = dx * (lineWidth * 0.5F);
float x1 = startX + px;
float y1 = startY + py;
float x2 = startX - px;
float y2 = startY - py;
float x3 = endX + px;
float y3 = endY + py;
float x4 = endX - px;
float y4 = endY - py;
pos(x3, y3, 0F, xOffset, yOffset).rgba(color);
pos(x2, y2, 0F, xOffset, yOffset).rgba(color);
pos(x1, y1, 0F, xOffset, yOffset).rgba(color);
pos(x4, y4, 0F, xOffset, yOffset).rgba(color);
pos(x2, y2, 0F, xOffset, yOffset).rgba(color);
pos(x3, y3, 0F, xOffset, yOffset).rgba(color);
}
@Override
public void drawFrame(IGuiBox box, int color) {
ensureType(UIConstants.GUI, null);
float xOffset = alignment[0].align(box.getWidth());
float yOffset = alignment[1].align(box.getHeight());
float minX = box.getMinX();
float minY = box.getMinY();
float maxX = box.getMaxX();
float maxY = box.getMaxY();
drawQuad(maxX-1F, minY, maxX, maxY, xOffset, yOffset, color);
drawQuad(minX, maxY-1F, maxX, maxY, xOffset, yOffset, color);
drawQuad(minX, minY, minX+1F, maxY, xOffset, yOffset, color);
drawQuad(minX, minY, maxX, minY+1F, xOffset, yOffset, color);
}
@Override
public void drawRect(IGuiBox box, int color) {
ensureType(UIConstants.GUI, null);
float xOffset = alignment[0].align(box.getWidth());
float yOffset = alignment[1].align(box.getHeight());
drawQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), xOffset, yOffset, color);
}
@Override
public void drawImage(IGuiBox box, SampledTexture texture, int color) {
drawImage(box, texture, 0F, 0F, 1F, 1F, color);
}
@Override
public void drawImage(IGuiBox box, SampledTexture texture, float minU, float minV, float maxU, float maxV, int color) {
ensureType(UIConstants.GUI_TEXTURED, texture);
float xOff = alignment[0].align(box.getWidth());
float yOff = alignment[1].align(box.getHeight());
float minX = box.getMinX();
float minY = box.getMinY();
float maxX = box.getMaxX();
float maxY = box.getMaxY();
pos(minX, maxY, 0F, xOff, yOff).tex(minU, maxV).rgba(color);
pos(minX, minY, 0F, xOff, yOff).tex(minU, minV).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).tex(maxU, maxV).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).tex(maxU, maxV).rgba(color);
pos(minX, minY, 0F, xOff, yOff).tex(minU, minV).rgba(color);
pos(maxX, minY, 0F, xOff, yOff).tex(maxU, minV).rgba(color);
}
@Override
public void drawCustom(UIDrawer drawer) {
//TDOO ensure the draw type isn't present
drawer.buildVertecies(builder, matrix);
}
protected void drawQuad(float minX, float minY, float maxX, float maxY, float xOff, float yOff, int color) {
pos(minX, maxY, 0F, xOff, yOff).rgba(color);
pos(minX, minY, 0F, xOff, yOff).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).rgba(color);
pos(minX, minY, 0F, xOff, yOff).rgba(color);
pos(maxX, minY, 0F, xOff, yOff).rgba(color);
}
protected IVertexBuilder pos(float x, float y, float z, float xOff, float yOff) {
matrix.transformOffset(x - xOff, y - yOff, z, xOff, yOff, 0F, builder::pos);
return builder;
}
protected void ensureType(ShaderPipeline pipeline, SampledTexture texture) {
if(currentPipeline == pipeline && currentTexture == texture) return;
if(builder.hasVertecies()) {
draws.add(new UIDraw(currentPipeline, currentTexture, builder.finish()));
}
currentPipeline = pipeline;
currentTexture = texture;
}
protected record UIDraw(ShaderPipeline pipeline, SampledTexture texture, BufferResult result) {}
}
@@ -0,0 +1,15 @@
package speiger.src.coreengine.ui.gui.utils;
public enum Align {
START,
CENTER,
END;
public float align(float width) {
return switch(this) {
case START -> 0;
case CENTER -> width * 0.5F;
case END -> width;
};
}
}
@@ -0,0 +1,33 @@
package speiger.src.coreengine.ui.gui.utils;
import speiger.src.coreengine.assets.api.ID;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType;
import speiger.src.coreengine.platform.graphics.api.shader.states.ShaderType;
import speiger.src.coreengine.platform.graphics.api.texture.states.TextureType;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage;
public class UIConstants {
public static final VertexLayout GUI_LAYOUT = VertexLayout.builder()
.element("pos", 0, 3, Usage.POS)
.element("color", 1, 4, Usage.COLOR, GraphicsDataType.BYTE)
.build();
public static final VertexLayout GUI_TEXTURED_LAYOUT = VertexLayout.builder()
.element("pos", 0, 3, Usage.POS)
.element("tex", 1, 2, Usage.UV)
.element("color", 2, 4, Usage.COLOR, GraphicsDataType.BYTE)
.build();
public static final ShaderPipeline GUI = ShaderPipeline.builder(ID.of("gui"))
.withStage(ShaderType.VERTEX, ID.of("shader/gui/guiVertex.txt"))
.withStage(ShaderType.FRAGMENT, ID.of("shader/gui/guiFragment.txt"))
.withFormat(GUI_LAYOUT)
.build();
public static final ShaderPipeline GUI_TEXTURED = ShaderPipeline.builder(ID.of("gui"))
.withStage(ShaderType.VERTEX, ID.of("shader/gui/guiVertex.txt"))
.withStage(ShaderType.FRAGMENT, ID.of("shader/gui/guiFragment.txt"))
.withTexture("texture", 0, 0, TextureType.TEXTURE_2D)
.withFormat(GUI_TEXTURED_LAYOUT)
.build();
}
@@ -24,6 +24,7 @@ import speiger.src.coreengine.platform.graphics.api.sampler.SamplerSettings;
import speiger.src.coreengine.platform.graphics.api.sampler.states.BorderMode; import speiger.src.coreengine.platform.graphics.api.sampler.states.BorderMode;
import speiger.src.coreengine.platform.graphics.api.sampler.states.SampleMode; import speiger.src.coreengine.platform.graphics.api.sampler.states.SampleMode;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline; import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType; import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType;
import speiger.src.coreengine.platform.graphics.api.shader.states.ShaderType; import speiger.src.coreengine.platform.graphics.api.shader.states.ShaderType;
import speiger.src.coreengine.platform.graphics.api.texture.Texture; import speiger.src.coreengine.platform.graphics.api.texture.Texture;
@@ -32,6 +33,7 @@ import speiger.src.coreengine.platform.graphics.api.texture.drawable.Drawable;
import speiger.src.coreengine.platform.graphics.api.texture.states.TextureFormat; import speiger.src.coreengine.platform.graphics.api.texture.states.TextureFormat;
import speiger.src.coreengine.platform.graphics.api.texture.states.TextureType; import speiger.src.coreengine.platform.graphics.api.texture.states.TextureType;
import speiger.src.coreengine.platform.graphics.api.utils.ExecutionType; import speiger.src.coreengine.platform.graphics.api.utils.ExecutionType;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout; import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage; import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.VertexBuilder; import speiger.src.coreengine.platform.graphics.api.vertex.builder.VertexBuilder;
@@ -84,7 +86,7 @@ public class NewRenderEngineTest {
.build(); .build();
VertexBuilder builder = new VertexBuilder(255); VertexBuilder builder = new VertexBuilder(255);
builder.start(null, layout); builder.start(DrawMode.TRIANGLES, layout);
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1); builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1);
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1); builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1);
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1); builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1);
@@ -123,7 +125,7 @@ public class NewRenderEngineTest {
queue.begin() queue.begin()
.pipeline(pipeline) .pipeline(pipeline)
.mesh(mesh) .mesh(mesh)
.texture(0, texture, sampler) .texture(0, new SampledTexture(texture, sampler))
.uniform(0, buffer) .uniform(0, buffer)
.drawArrays(0, 6) .drawArrays(0, 6)
.end(); .end();
@@ -1,27 +1,27 @@
package speiger.src.coreengine.rendering.gui.renderer; package speiger.src.coreengine.rendering.gui.renderer;
import speiger.src.coreengine.assets.AssetLocation; import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.base.IAssetProvider; import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.math.vector.floats.Vec4f; import speiger.src.coreengine.math.vector.floats.Vec4f;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.shader.SimpleShader; import speiger.src.coreengine.rendering.shader.SimpleShader;
import speiger.src.coreengine.rendering.shader.uniform.base.BufferUniform; import speiger.src.coreengine.rendering.shader.uniform.base.BufferUniform;
import speiger.src.coreengine.rendering.shader.uniform.base.FloatUniform; import speiger.src.coreengine.rendering.shader.uniform.base.FloatUniform;
import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform; import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform; import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform; import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform;
public class SimpleUIShader extends SimpleShader { public class SimpleUIShader extends SimpleShader {
public BufferUniform camera = uniforms.addBuffer("cameraTransform", 0); public BufferUniform camera = uniforms.addBuffer("cameraTransform", 0);
public Matrix4fUniform modelMatrix = uniforms.addMat("modelMatrix", new Matrix4f()); public Matrix4fUniform modelMatrix = uniforms.addMat("modelMatrix", new Matrix4f());
public TextureUniform texture = uniforms.addTexture("texture", 0); public TextureUniform texture = uniforms.addTexture("texture", 0);
public FloatUniform useTexture = uniforms.addFloat("use_texture", 0); public FloatUniform useTexture = uniforms.addFloat("use_texture", 0);
public Vec4fUniform bounds = uniforms.addVec4("bounds", Vec4f.ZERO); public Vec4fUniform bounds = uniforms.addVec4("bounds", Vec4f.ZERO);
public FloatUniform roundness = uniforms.addFloat("roundness", 0); public FloatUniform roundness = uniforms.addFloat("roundness", 0);
public SimpleUIShader(IAssetProvider provider) { public SimpleUIShader(IAssetProvider provider) {
super(provider, "gui_simple", AssetLocation.of("shader/gui/simple/vertex.vs"), AssetLocation.of("shader/gui/simple/fragment.vs"), "in_position", "in_tex", "in_color"); super(provider, "gui_simple", AssetLocation.of("shader/gui/simple/vertex.vs"), AssetLocation.of("shader/gui/simple/fragment.vs"), "in_position", "in_tex", "in_color");
} }
} }
@@ -1,50 +1,50 @@
package speiger.src.coreengine.rendering.guiOld.renderer; package speiger.src.coreengine.rendering.guiOld.renderer;
import speiger.src.coreengine.assets.AssetLocation; import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.models.buffers.UniformBuffer; import speiger.src.coreengine.rendering.models.buffers.UniformBuffer;
import speiger.src.coreengine.rendering.shaderOld.ShaderProgram; import speiger.src.coreengine.rendering.shaderOld.ShaderProgram;
import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformBufferBlock; import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformBufferBlock;
import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformFloat; import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformFloat;
import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformMatrix; import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformMatrix;
import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformTexture; import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformTexture;
import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformVec4f; import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformVec4f;
public class GuiShader extends ShaderProgram public class GuiShader extends ShaderProgram
{ {
public UniformBufferBlock proViewMatrix = new UniformBufferBlock("cameraTransform", 1); public UniformBufferBlock proViewMatrix = new UniformBufferBlock("cameraTransform", 1);
public UniformMatrix modelMatrix = new UniformMatrix("modelMatrix"); public UniformMatrix modelMatrix = new UniformMatrix("modelMatrix");
public UniformTexture texture = new UniformTexture("texture", 0); public UniformTexture texture = new UniformTexture("texture", 0);
public UniformFloat useTexture = new UniformFloat("use_texture"); public UniformFloat useTexture = new UniformFloat("use_texture");
public UniformFloat roundeness = new UniformFloat("roundness"); public UniformFloat roundeness = new UniformFloat("roundness");
public UniformVec4f bounds = new UniformVec4f("bounds"); public UniformVec4f bounds = new UniformVec4f("bounds");
public GuiShader(AssetLocation vertex, AssetLocation fragment, String...args) public GuiShader(AssetLocation vertex, AssetLocation fragment, String...args)
{ {
super(vertex, fragment, args); super(vertex, fragment, args);
addUniforms(proViewMatrix, modelMatrix, texture, useTexture, roundeness, bounds); addUniforms(proViewMatrix, modelMatrix, texture, useTexture, roundeness, bounds);
} }
public static GuiShader create() public static GuiShader create()
{ {
return new GuiShader(AssetLocation.of("shader/gui/guiVertex.txt"), AssetLocation.of("shader/gui/guiFragment.txt"), "in_position", "in_tex", "in_color"); return new GuiShader(AssetLocation.of("shader/gui/guiVertex.txt"), AssetLocation.of("shader/gui/guiFragment.txt"), "in_position", "in_tex", "in_color");
} }
public void bind(UniformBuffer view) public void bind(UniformBuffer view)
{ {
if(isShaderRunning()) return; if(isShaderRunning()) return;
startShader(); startShader();
proViewMatrix.bindBuffer(view); proViewMatrix.bindBuffer(view);
} }
@Override @Override
public GuiShader init() public GuiShader init()
{ {
startShader(); startShader();
modelMatrix.storeData(new Matrix4f()); modelMatrix.storeData(new Matrix4f());
bounds.storeData(0F, 0F, 0F, 0F); bounds.storeData(0F, 0F, 0F, 0F);
stopShader(); stopShader();
return this; return this;
} }
} }
@@ -1,111 +1,111 @@
package speiger.src.coreengine.rendering.shader.uniform; package speiger.src.coreengine.rendering.shader.uniform;
import java.util.List; import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.vector.floats.Vec2f; import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.floats.Vec3f; import speiger.src.coreengine.math.vector.floats.Vec3f;
import speiger.src.coreengine.math.vector.floats.Vec4f; import speiger.src.coreengine.math.vector.floats.Vec4f;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.shader.ShaderProgram; import speiger.src.coreengine.rendering.shader.ShaderProgram;
import speiger.src.coreengine.rendering.shader.uniform.base.BoolUniform; import speiger.src.coreengine.rendering.shader.uniform.base.BoolUniform;
import speiger.src.coreengine.rendering.shader.uniform.base.BufferUniform; import speiger.src.coreengine.rendering.shader.uniform.base.BufferUniform;
import speiger.src.coreengine.rendering.shader.uniform.base.FloatUniform; import speiger.src.coreengine.rendering.shader.uniform.base.FloatUniform;
import speiger.src.coreengine.rendering.shader.uniform.base.IntUniform; import speiger.src.coreengine.rendering.shader.uniform.base.IntUniform;
import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform; import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform; import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec2fUniform; import speiger.src.coreengine.rendering.shader.uniform.vec.Vec2fUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec3fUniform; import speiger.src.coreengine.rendering.shader.uniform.vec.Vec3fUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform; import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform;
import speiger.src.coreengine.rendering.utils.GLStateTracker; import speiger.src.coreengine.rendering.utils.GLStateTracker;
public class UniformManager { public class UniformManager {
List<IUniform> uniforms = new ObjectArrayList<>(); List<IUniform> uniforms = new ObjectArrayList<>();
List<IAutoUniform> autoUniforms = new ObjectArrayList<>(); List<IAutoUniform> autoUniforms = new ObjectArrayList<>();
ShaderProgram owner; ShaderProgram owner;
public UniformManager(ShaderProgram owner) { public UniformManager(ShaderProgram owner) {
this.owner = owner; this.owner = owner;
} }
public <T extends IUniform> T addGlobalUniform(String name) { public <T extends IUniform> T addGlobalUniform(String name) {
return addUniform(GLStateTracker.instance().uniforms.get(name)); return addUniform(GLStateTracker.instance().uniforms.get(name));
} }
public <T extends IUniform> T addGlobalUniform(String name, T defaultValue) { public <T extends IUniform> T addGlobalUniform(String name, T defaultValue) {
return addUniform(GLStateTracker.instance().uniforms.getOrDefault(name, defaultValue)); return addUniform(GLStateTracker.instance().uniforms.getOrDefault(name, defaultValue));
} }
public BoolUniform addBool(String name, boolean defaultValue) { public BoolUniform addBool(String name, boolean defaultValue) {
return addUniform(new BoolUniform(name, defaultValue)); return addUniform(new BoolUniform(name, defaultValue));
} }
public IntUniform addInt(String name, int defaultValue) { public IntUniform addInt(String name, int defaultValue) {
return addUniform(new IntUniform(name, defaultValue)); return addUniform(new IntUniform(name, defaultValue));
} }
public FloatUniform addFloat(String name, float defaultValue) { public FloatUniform addFloat(String name, float defaultValue) {
return addUniform(new FloatUniform(name, defaultValue)); return addUniform(new FloatUniform(name, defaultValue));
} }
public Vec2fUniform addVec2(String name, Vec2f defaultValue) { public Vec2fUniform addVec2(String name, Vec2f defaultValue) {
return addUniform(new Vec2fUniform(name, defaultValue.copyAsMutable())); return addUniform(new Vec2fUniform(name, defaultValue.copyAsMutable()));
} }
public Vec3fUniform addVec3(String name, Vec3f defaultValue) { public Vec3fUniform addVec3(String name, Vec3f defaultValue) {
return addUniform(new Vec3fUniform(name, defaultValue.copyAsMutable())); return addUniform(new Vec3fUniform(name, defaultValue.copyAsMutable()));
} }
public Vec4fUniform addVec4(String name, Vec4f defaultValue) { public Vec4fUniform addVec4(String name, Vec4f defaultValue) {
return addUniform(new Vec4fUniform(name, defaultValue.copyAsMutable())); return addUniform(new Vec4fUniform(name, defaultValue.copyAsMutable()));
} }
public Matrix4fUniform addMat(String name, Matrix4f defaultValue) { public Matrix4fUniform addMat(String name, Matrix4f defaultValue) {
return addUniform(new Matrix4fUniform(name, new Matrix4f(defaultValue))); return addUniform(new Matrix4fUniform(name, new Matrix4f(defaultValue)));
} }
public BufferUniform addBuffer(String name, int slot) { public BufferUniform addBuffer(String name, int slot) {
return addUniform(new BufferUniform(name, slot)); return addUniform(new BufferUniform(name, slot));
} }
public TextureUniform addTexture(String name, int unit) { public TextureUniform addTexture(String name, int unit) {
return addUniform(new TextureUniform(name, unit)); return addUniform(new TextureUniform(name, unit));
} }
public <T extends IUniform> T addUniform(T uniform) { public <T extends IUniform> T addUniform(T uniform) {
uniforms.add(uniform); uniforms.add(uniform);
uniform.registerShader(owner); uniform.registerShader(owner);
if(uniform instanceof IAutoUniform auto) { if(uniform instanceof IAutoUniform auto) {
autoUniforms.add(auto); autoUniforms.add(auto);
} }
return uniform; return uniform;
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T extends IUniform> T getUniform(String name) { public <T extends IUniform> T getUniform(String name) {
for(int i = 0,m=uniforms.size();i<m;i++) { for(int i = 0,m=uniforms.size();i<m;i++) {
IUniform uni = uniforms.get(i); IUniform uni = uniforms.get(i);
if(uni.name().equals(name)) return (T)uni; if(uni.name().equals(name)) return (T)uni;
} }
return null; return null;
} }
public void validate() { public void validate() {
for(int i = 0,m=uniforms.size();i<m;i++) { for(int i = 0,m=uniforms.size();i<m;i++) {
uniforms.get(i).registerShader(owner); uniforms.get(i).registerShader(owner);
} }
} }
public void bind() { public void bind() {
if(autoUniforms.isEmpty()) return; if(autoUniforms.isEmpty()) return;
for(int i = 0,m=autoUniforms.size();i<m;i++) { for(int i = 0,m=autoUniforms.size();i<m;i++) {
autoUniforms.get(i).bind(owner.id()); autoUniforms.get(i).bind(owner.id());
} }
} }
public void remove() { public void remove() {
for(int i = 0,m=uniforms.size();i<m;i++) { for(int i = 0,m=uniforms.size();i<m;i++) {
uniforms.get(i).removeShader(owner); uniforms.get(i).removeShader(owner);
} }
} }
} }
@@ -1,37 +1,37 @@
package speiger.src.coreengine.rendering.shader.uniform.vec; package speiger.src.coreengine.rendering.shader.uniform.vec;
import java.util.Arrays; import java.util.Arrays;
import org.lwjgl.opengl.GL41; import org.lwjgl.opengl.GL41;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.shader.uniform.Uniform; import speiger.src.coreengine.rendering.shader.uniform.Uniform;
import speiger.src.coreengine.rendering.utils.AllocationTracker; import speiger.src.coreengine.rendering.utils.AllocationTracker;
public class Matrix4fUniform extends Uniform { public class Matrix4fUniform extends Uniform {
Matrix4f value; Matrix4f value;
public Matrix4fUniform(String name, Matrix4f value) { public Matrix4fUniform(String name, Matrix4f value) {
super(name); super(name);
this.value = value; this.value = value;
} }
public Matrix4fUniform set(Matrix4f newMat) { public Matrix4fUniform set(Matrix4f newMat) {
if(hasChanged(newMat)) { if(hasChanged(newMat)) {
value.load(newMat); value.load(newMat);
update(); update();
} }
return this; return this;
} }
protected boolean hasChanged(Matrix4f input) { protected boolean hasChanged(Matrix4f input) {
if(value.properties() != input.properties()) return true; if(value.properties() != input.properties()) return true;
return !Arrays.equals(value.getData(), input.getData()); return !Arrays.equals(value.getData(), input.getData());
} }
@Override @Override
protected void processChanges(int programId, int location) { protected void processChanges(int programId, int location) {
GL41.glProgramUniformMatrix4fv(programId, location, false, value.getData()); GL41.glProgramUniformMatrix4fv(programId, location, false, value.getData());
AllocationTracker.INSTANCE.addGPUBytes(64L); AllocationTracker.INSTANCE.addGPUBytes(64L);
} }
} }
@@ -1,27 +1,27 @@
package speiger.src.coreengine.rendering.shaderOld.uniforms; package speiger.src.coreengine.rendering.shaderOld.uniforms;
import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL20;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.utils.AllocationTracker; import speiger.src.coreengine.rendering.utils.AllocationTracker;
public class UniformMatrix extends UniformBase<Matrix4f> { public class UniformMatrix extends UniformBase<Matrix4f> {
public UniformMatrix(String id) { public UniformMatrix(String id) {
super(id); super(id);
} }
public void storeData(Matrix4f data) { public void storeData(Matrix4f data) {
if (hasChanged(data)) { if (hasChanged(data)) {
GL20.glUniformMatrix4fv(getPosition(), false, data.getData()); GL20.glUniformMatrix4fv(getPosition(), false, data.getData());
AllocationTracker.INSTANCE.addGPUBytes(64L); AllocationTracker.INSTANCE.addGPUBytes(64L);
} }
} }
@Override @Override
protected Matrix4f setValue(Matrix4f oldValue, Matrix4f newValue) { protected Matrix4f setValue(Matrix4f oldValue, Matrix4f newValue) {
if (oldValue != null) { if (oldValue != null) {
return oldValue.load(newValue); return oldValue.load(newValue);
} }
return new Matrix4f(newValue); return new Matrix4f(newValue);
} }
} }
@@ -1,12 +1,12 @@
package speiger.src.coreengine.utils.helpers; package speiger.src.coreengine.utils.helpers;
import speiger.src.coreengine.math.vector.floats.Vec2f; import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.utils.collections.pools.IPool; import speiger.src.coreengine.utils.collections.pools.IPool;
import speiger.src.coreengine.utils.collections.pools.ThreadPool; import speiger.src.coreengine.utils.collections.pools.ThreadPool;
public class InternalThreadPools public class InternalThreadPools
{ {
public static final IPool<Matrix4f> MATRIX = new ThreadPool<Matrix4f>(100, Matrix4f::new); public static final IPool<Matrix4f> MATRIX = new ThreadPool<Matrix4f>(100, Matrix4f::new);
public static final IPool<Vec2f> VEC2F = new ThreadPool<Vec2f>(100, Vec2f::mutable); public static final IPool<Vec2f> VEC2F = new ThreadPool<Vec2f>(100, Vec2f::mutable);
} }
@@ -1,236 +1,236 @@
package speiger.src.coreengine.math.vector.floats; package speiger.src.coreengine.math.vector.floats;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import speiger.src.coreengine.math.MathUtils; import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.vector.bytes.Vec3b; import speiger.src.coreengine.math.vector.bytes.Vec3b;
import speiger.src.coreengine.math.vector.doubles.Vec3d; import speiger.src.coreengine.math.vector.doubles.Vec3d;
import speiger.src.coreengine.math.vector.ints.Vec3i; import speiger.src.coreengine.math.vector.ints.Vec3i;
import speiger.src.coreengine.math.vector.longs.Vec3l; import speiger.src.coreengine.math.vector.longs.Vec3l;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.math.vector.shorts.Vec3s; import speiger.src.coreengine.math.vector.shorts.Vec3s;
public interface Vec3f extends Vecf { public interface Vec3f extends Vecf {
public static final Vec3f ZERO = of(); public static final Vec3f ZERO = of();
public static final Vec3f MINUS_ONE = of(-1F); public static final Vec3f MINUS_ONE = of(-1F);
public static final Vec3f ONE = of(1F); public static final Vec3f ONE = of(1F);
public static Vec3f mutable() { return new Vec3fMutable(); } public static Vec3f mutable() { return new Vec3fMutable(); }
public static Vec3f mutable(float value) { return new Vec3fMutable(value); } public static Vec3f mutable(float value) { return new Vec3fMutable(value); }
public static Vec3f mutable(float x, float y, float z) { return new Vec3fMutable(x, y, z); } public static Vec3f mutable(float x, float y, float z) { return new Vec3fMutable(x, y, z); }
public static Vec3f mutable(Vec3f vec) { return mutable(vec.x(), vec.y(), vec.z()); } public static Vec3f mutable(Vec3f vec) { return mutable(vec.x(), vec.y(), vec.z()); }
public static Vec3f of() { return new Vec3fImmutable(); } public static Vec3f of() { return new Vec3fImmutable(); }
public static Vec3f of(float value) { return new Vec3fImmutable(value); } public static Vec3f of(float value) { return new Vec3fImmutable(value); }
public static Vec3f of(float x, float y, float z) { return new Vec3fImmutable(x, y, z); } public static Vec3f of(float x, float y, float z) { return new Vec3fImmutable(x, y, z); }
public static Vec3f of(Vec3f vec) { return of(vec.x(), vec.y(), vec.z()); } public static Vec3f of(Vec3f vec) { return of(vec.x(), vec.y(), vec.z()); }
public float x(); public float x();
public float y(); public float y();
public float z(); public float z();
public Vec3f x(float x); public Vec3f x(float x);
public Vec3f y(float y); public Vec3f y(float y);
public Vec3f z(float z); public Vec3f z(float z);
@Override @Override
public default float[] asArray() { return new float[] {x(), y(), z()}; } public default float[] asArray() { return new float[] {x(), y(), z()}; }
@Override @Override
public Vec3f copy(); public Vec3f copy();
@Override @Override
public default Vec3f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z())); } public default Vec3f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z())); }
@Override @Override
public default Vec3f negate() { return set(0F, 0F, 0F); } public default Vec3f negate() { return set(0F, 0F, 0F); }
@Override @Override
public default Vec3f invert() { return set(-x(), -y(), -z()); } public default Vec3f invert() { return set(-x(), -y(), -z()); }
public default Vec3f normalize() { public default Vec3f normalize() {
float l = length(); float l = length();
return l == 0F ? this : multiply(1.0F / l); return l == 0F ? this : multiply(1.0F / l);
} }
@Override @Override
public default Vec3f add(float value) { return add(value, value, value); } public default Vec3f add(float value) { return add(value, value, value); }
public default Vec3f add(Vec3f value) { return add(value.x(), value.y(), value.z()); } public default Vec3f add(Vec3f value) { return add(value.x(), value.y(), value.z()); }
public default Vec3f add(float x, float y, float z) { return set(x() + x, y() + y, z() + z); } public default Vec3f add(float x, float y, float z) { return set(x() + x, y() + y, z() + z); }
@Override @Override
public default Vec3f sub(float value) { return sub(value, value, value); } public default Vec3f sub(float value) { return sub(value, value, value); }
public default Vec3f sub(Vec3f value) { return sub(value.x(), value.y(), value.z()); } public default Vec3f sub(Vec3f value) { return sub(value.x(), value.y(), value.z()); }
public default Vec3f sub(float x, float y, float z) { return set(x() - x, y() - y, z() - z); } public default Vec3f sub(float x, float y, float z) { return set(x() - x, y() - y, z() - z); }
@Override @Override
public default Vec3f multiply(float value) { return multiply(value, value, value); } public default Vec3f multiply(float value) { return multiply(value, value, value); }
public default Vec3f multiply(Vec3f value) { return multiply(value.x(), value.y(), value.z()); } public default Vec3f multiply(Vec3f value) { return multiply(value.x(), value.y(), value.z()); }
public default Vec3f multiply(float x, float y, float z) { return set(x() * x, y() * y, z() * z); } public default Vec3f multiply(float x, float y, float z) { return set(x() * x, y() * y, z() * z); }
@Override @Override
public default Vec3f devide(float value) { return devide(value, value, value); } public default Vec3f devide(float value) { return devide(value, value, value); }
public default Vec3f devide(Vec3f value) { return devide(value.x(), value.y(), value.z()); } public default Vec3f devide(Vec3f value) { return devide(value.x(), value.y(), value.z()); }
public default Vec3f devide(float x, float y, float z) { return set(x() / x, y() / y, z() / z); } public default Vec3f devide(float x, float y, float z) { return set(x() / x, y() / y, z() / z); }
@Override @Override
public default Vec3f set(float value) { return set(value, value, value); } public default Vec3f set(float value) { return set(value, value, value); }
public default Vec3f set(Vec3f value) { return set(value.x(), value.y(), value.z()); } public default Vec3f set(Vec3f value) { return set(value.x(), value.y(), value.z()); }
public Vec3f set(float x, float y, float z); public Vec3f set(float x, float y, float z);
public default double distanceTo(Vec3f value) { return distanceTo(value.x(), value.y(), value.z()); } public default double distanceTo(Vec3f value) { return distanceTo(value.x(), value.y(), value.z()); }
public default double distanceTo(float x, float y, float z) { return Math.sqrt(distanceToSquared(x, y, z)); } public default double distanceTo(float x, float y, float z) { return Math.sqrt(distanceToSquared(x, y, z)); }
public default double distanceToSquared(Vec3f value) { return distanceToSquared(value.x(), value.y(), value.z()); } public default double distanceToSquared(Vec3f value) { return distanceToSquared(value.x(), value.y(), value.z()); }
public default double distanceToSquared(float x, float y, float z) { public default double distanceToSquared(float x, float y, float z) {
double xPos = x() - x; double xPos = x() - x;
double yPos = y() - y; double yPos = y() - y;
double zPos = z() - z; double zPos = z() - z;
return (xPos * xPos) + (yPos * yPos) + (zPos * zPos); return (xPos * xPos) + (yPos * yPos) + (zPos * zPos);
} }
@Override @Override
public default float lengthSquared() { return (x() * x()) + (y() * y()) + (z() * z()); } public default float lengthSquared() { return (x() * x()) + (y() * y()) + (z() * z()); }
public default double dotProduct(Vec3f value) { return dotProduct(value.x(), value.y(), value.z()); } public default double dotProduct(Vec3f value) { return dotProduct(value.x(), value.y(), value.z()); }
public default double dotProduct(float x, float y, float z) { return (x() * x) + (y() * y) + (z() * z); } public default double dotProduct(float x, float y, float z) { return (x() * x) + (y() * y) + (z() * z); }
public default Vec3f lerp(Vec3f value, float progress, Vec3f result) { return lerp(value.x(), value.y(), value.z(), progress, result); } public default Vec3f lerp(Vec3f value, float progress, Vec3f result) { return lerp(value.x(), value.y(), value.z(), progress, result); }
public default Vec3f lerp(float x, float y, float z, float progress, Vec3f result) { return result.set(MathUtils.lerp(x(), x, progress), MathUtils.lerp(y(), y, progress), MathUtils.lerp(z(), z, progress)); } public default Vec3f lerp(float x, float y, float z, float progress, Vec3f result) { return result.set(MathUtils.lerp(x(), x, progress), MathUtils.lerp(y(), y, progress), MathUtils.lerp(z(), z, progress)); }
public default float angle(Vec3f value) { return angle(value.x(), value.y(), value.z()); } public default float angle(Vec3f value) { return angle(value.x(), value.y(), value.z()); }
public default float angle(float x, float y, float z) { return (float)Math.acos(MathUtils.clamp(-1, 1, angleCos(x, y, z))); } public default float angle(float x, float y, float z) { return (float)Math.acos(MathUtils.clamp(-1, 1, angleCos(x, y, z))); }
public default float angleCos(Vec3f value) { return angleCos(value.x(), value.y(), value.z()); } public default float angleCos(Vec3f value) { return angleCos(value.x(), value.y(), value.z()); }
public default float angleCos(float x, float y, float z) { public default float angleCos(float x, float y, float z) {
double myLength = (x() * x()) + (y() * y()) + (z() * z()); double myLength = (x() * x()) + (y() * y()) + (z() * z());
double otherLength = (x * x) + (y * y) + (z * z); double otherLength = (x * x) + (y * y) + (z * z);
float dot = (x() * x) + (y() * y) + (z() * z); float dot = (x() * x) + (y() * y) + (z() * z);
return dot / (float)(Math.sqrt(myLength * otherLength)); return dot / (float)(Math.sqrt(myLength * otherLength));
} }
public default Vec3f crossProduct(Vec3f value) { return crossProduct(value.x(), value.y(), value.z(), this); } public default Vec3f crossProduct(Vec3f value) { return crossProduct(value.x(), value.y(), value.z(), this); }
public default Vec3f crossProduct(Vec3f value, Vec3f result) { return crossProduct(value.x(), value.y(), value.z(), result); } public default Vec3f crossProduct(Vec3f value, Vec3f result) { return crossProduct(value.x(), value.y(), value.z(), result); }
public default Vec3f crossProduct(float x, float y, float z) { return crossProduct(x, y, z, this); } public default Vec3f crossProduct(float x, float y, float z) { return crossProduct(x, y, z, this); }
public default Vec3f crossProduct(float x, float y, float z, Vec3f result) { return result.set((y() * z) - (z() * y), (z() * x) - (x() * z), (x() * y) - (y() * x)); } public default Vec3f crossProduct(float x, float y, float z, Vec3f result) { return result.set((y() * z) - (z() * y), (z() * x) - (x() * z), (x() * y) - (y() * x)); }
public default Vec3f reflect(Vec3f value) { return reflect(value.x(), value.y(), value.z(), this); } public default Vec3f reflect(Vec3f value) { return reflect(value.x(), value.y(), value.z(), this); }
public default Vec3f reflect(Vec3f value, Vec3f result) { return reflect(value.x(), value.y(), value.z(), result); } public default Vec3f reflect(Vec3f value, Vec3f result) { return reflect(value.x(), value.y(), value.z(), result); }
public default Vec3f reflect(float x, float y, float z) { return reflect(x, y, z, this); } public default Vec3f reflect(float x, float y, float z) { return reflect(x, y, z, this); }
public default Vec3f reflect(float x, float y, float z, Vec3f result) { public default Vec3f reflect(float x, float y, float z, Vec3f result) {
double dot = dotProduct(x, y, z) * 2D; double dot = dotProduct(x, y, z) * 2D;
return result.set(x() - (float)(dot * x), y() - (float)(dot * y), z() - (float)(dot * z)); return result.set(x() - (float)(dot * x), y() - (float)(dot * y), z() - (float)(dot * z));
} }
public default Vec3f rotate(float angle, Vec3f axis) { return rotate(angle, axis.x(), axis.y(), axis.z()); } public default Vec3f rotate(float angle, Vec3f axis) { return rotate(angle, axis.x(), axis.y(), axis.z()); }
public default Vec3f rotate(float angle, Vec3f axis, Vec3f result) { return rotate(angle, axis.x(), axis.y(), axis.z(), result); } public default Vec3f rotate(float angle, Vec3f axis, Vec3f result) { return rotate(angle, axis.x(), axis.y(), axis.z(), result); }
public default Vec3f rotate(float angle, float x, float y, float z) { return rotate(angle, x, y, z, this); } public default Vec3f rotate(float angle, float x, float y, float z) { return rotate(angle, x, y, z, this); }
public default Vec3f rotate(float angle, float x, float y, float z, Vec3f result) { public default Vec3f rotate(float angle, float x, float y, float z, Vec3f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double dot = dotProduct(x, y, z); double dot = dotProduct(x, y, z);
double xPos = x * dot * (1D - cos) + (x() * cos) + (-z * y() + y * z()) * sin; double xPos = x * dot * (1D - cos) + (x() * cos) + (-z * y() + y * z()) * sin;
double yPos = y * dot * (1D - cos) + (y() * cos) + (z * x() - x * z()) * sin; double yPos = y * dot * (1D - cos) + (y() * cos) + (z * x() - x * z()) * sin;
double zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin; double zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin;
return result.set((float)xPos, (float)yPos, (float)zPos); return result.set((float)xPos, (float)yPos, (float)zPos);
} }
public default Vec3f rotateX(float angle) { return rotateX(angle, this); } public default Vec3f rotateX(float angle) { return rotateX(angle, this); }
public default Vec3f rotateX(float angle, Vec3f result) { public default Vec3f rotateX(float angle, Vec3f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double y = y() * cos + z() * sin; double y = y() * cos + z() * sin;
double z = z() * cos - y() * sin; double z = z() * cos - y() * sin;
return result.set(x(), (float)y, (float)z); return result.set(x(), (float)y, (float)z);
} }
public default Vec3f rotateY(float angle) { return rotateY(angle, this); } public default Vec3f rotateY(float angle) { return rotateY(angle, this); }
public default Vec3f rotateY(float angle, Vec3f result) { public default Vec3f rotateY(float angle, Vec3f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double x = x() * cos + z() * sin; double x = x() * cos + z() * sin;
double z = z() * cos - x() * sin; double z = z() * cos - x() * sin;
return result.set((float)x, y(), (float)z); return result.set((float)x, y(), (float)z);
} }
public default Vec3f rotateZ(float angle) { return rotateZ(angle, this); } public default Vec3f rotateZ(float angle) { return rotateZ(angle, this); }
public default Vec3f rotateZ(float angle, Vec3f result) { public default Vec3f rotateZ(float angle, Vec3f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double x = cos * x() - sin * y(); double x = cos * x() - sin * y();
double y = sin * x() + cos * y(); double y = sin * x() + cos * y();
return result.set((float)x, (float)y, z()); return result.set((float)x, (float)y, z());
} }
public default Vec3f transform(Matrix4f matrix) { return transform(matrix, true, this); } public default Vec3f transform(Matrix4f matrix) { return transform(matrix, true, this); }
public default Vec3f transofrm(Matrix4f matrix, boolean pos) { return transform(matrix, pos, this); } public default Vec3f transofrm(Matrix4f matrix, boolean pos) { return transform(matrix, pos, this); }
public default Vec3f transform(Matrix4f matrix, boolean pos, Vec3f result) { public default Vec3f transform(Matrix4f matrix, boolean pos, Vec3f result) {
if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) { if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) {
return result.set(this); return result.set(this);
} }
if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) { if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) {
float w = pos ? 1F : 0F; float w = pos ? 1F : 0F;
return result.set( return result.set(
matrix.fma(Matrix4f.M00, Matrix4f.M10, Matrix4f.M20, Matrix4f.M30, x(), y(), z(), w), matrix.fma(Matrix4f.M00, Matrix4f.M10, Matrix4f.M20, Matrix4f.M30, x(), y(), z(), w),
matrix.fma(Matrix4f.M01, Matrix4f.M11, Matrix4f.M21, Matrix4f.M31, x(), y(), z(), w), matrix.fma(Matrix4f.M01, Matrix4f.M11, Matrix4f.M21, Matrix4f.M31, x(), y(), z(), w),
matrix.fma(Matrix4f.M02, Matrix4f.M12, Matrix4f.M22, Matrix4f.M32, x(), y(), z(), w)); matrix.fma(Matrix4f.M02, Matrix4f.M12, Matrix4f.M22, Matrix4f.M32, x(), y(), z(), w));
} }
if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) { if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) {
if(pos) return set( if(pos) return set(
Math.fma(matrix.get(Matrix4f.M00), x(), matrix.get(Matrix4f.M30)), Math.fma(matrix.get(Matrix4f.M00), x(), matrix.get(Matrix4f.M30)),
Math.fma(matrix.get(Matrix4f.M01), y(), matrix.get(Matrix4f.M31)), Math.fma(matrix.get(Matrix4f.M01), y(), matrix.get(Matrix4f.M31)),
Math.fma(matrix.get(Matrix4f.M02), z(), matrix.get(Matrix4f.M32))); Math.fma(matrix.get(Matrix4f.M02), z(), matrix.get(Matrix4f.M32)));
return set(matrix.get(Matrix4f.M00) * x(), matrix.get(Matrix4f.M01) * y(), matrix.get(Matrix4f.M02) * z()); return set(matrix.get(Matrix4f.M00) * x(), matrix.get(Matrix4f.M01) * y(), matrix.get(Matrix4f.M02) * z());
} }
if(pos) return set(x() + matrix.get(Matrix4f.M30), y() + matrix.get(Matrix4f.M31), z() + matrix.get(Matrix4f.M32)); if(pos) return set(x() + matrix.get(Matrix4f.M30), y() + matrix.get(Matrix4f.M31), z() + matrix.get(Matrix4f.M32));
return result.set(this); return result.set(this);
} }
public default Vec3f smoothStep(Vec3f value, float progress, Vec3f result) { return smoothStep(value.x(), value.y(), value.z(), progress, result); } public default Vec3f smoothStep(Vec3f value, float progress, Vec3f result) { return smoothStep(value.x(), value.y(), value.z(), progress, result); }
public default Vec3f smoothStep(float x, float y, float z, float progress, Vec3f result) { public default Vec3f smoothStep(float x, float y, float z, float progress, Vec3f result) {
float t2 = progress * progress; float t2 = progress * progress;
float t3 = t2 * progress; float t3 = t2 * progress;
float xPos = ((x() + x() - x - x) * t3 + (3.0F * x - 3.0F * x()) * t2 + x() * progress + x()); float xPos = ((x() + x() - x - x) * t3 + (3.0F * x - 3.0F * x()) * t2 + x() * progress + x());
float yPos = ((y() + y() - y - y) * t3 + (3.0F * y - 3.0F * y()) * t2 + y() * progress + y()); float yPos = ((y() + y() - y - y) * t3 + (3.0F * y - 3.0F * y()) * t2 + y() * progress + y());
float zPos = ((z() + z() - z - z) * t3 + (3.0F * z - 3.0F * z()) * t2 + z() * progress + z()); float zPos = ((z() + z() - z - z) * t3 + (3.0F * z - 3.0F * z()) * t2 + z() * progress + z());
return result.set(xPos, yPos, zPos); return result.set(xPos, yPos, zPos);
} }
public default Vec3f min(Vec3f other) { return min(other, this); } public default Vec3f min(Vec3f other) { return min(other, this); }
public default Vec3f min(Vec3f other, Vec3f result) { return min(other.x(), other.y(), other.z(), result); } public default Vec3f min(Vec3f other, Vec3f result) { return min(other.x(), other.y(), other.z(), result); }
public default Vec3f min(float x, float y, float z) { return min(x, y, z, this); } public default Vec3f min(float x, float y, float z) { return min(x, y, z, this); }
public default Vec3f min(float x, float y, float z, Vec3f result) { return result.set(Math.min(x(), x), Math.min(y(), y), Math.min(z(), z)); } public default Vec3f min(float x, float y, float z, Vec3f result) { return result.set(Math.min(x(), x), Math.min(y(), y), Math.min(z(), z)); }
public default Vec3f max(Vec3f other) { return max(other, this); } public default Vec3f max(Vec3f other) { return max(other, this); }
public default Vec3f max(Vec3f other, Vec3f result) { return max(other.x(), other.y(), other.z(), result); } public default Vec3f max(Vec3f other, Vec3f result) { return max(other.x(), other.y(), other.z(), result); }
public default Vec3f max(float x, float y, float z) { return max(x, y, z, this); } public default Vec3f max(float x, float y, float z) { return max(x, y, z, this); }
public default Vec3f max(float x, float y, float z, Vec3f result) { return result.set(Math.max(x(), x), Math.max(y(), y), Math.max(z(), z)); } public default Vec3f max(float x, float y, float z, Vec3f result) { return result.set(Math.max(x(), x), Math.max(y(), y), Math.max(z(), z)); }
public default Vec3f difference(Vec3f other) { return difference(other, this); } public default Vec3f difference(Vec3f other) { return difference(other, this); }
public default Vec3f difference(Vec3f other, Vec3f result) { return difference(other.x(), other.y(), other.z(), result); } public default Vec3f difference(Vec3f other, Vec3f result) { return difference(other.x(), other.y(), other.z(), result); }
public default Vec3f difference(float x, float y, float z) { return difference(x, y, z, this); } public default Vec3f difference(float x, float y, float z) { return difference(x, y, z, this); }
public default Vec3f difference(float x, float y, float z, Vec3f result) { return result.set(x() - x, y() - y, z() - z); } public default Vec3f difference(float x, float y, float z, Vec3f result) { return result.set(x() - x, y() - y, z() - z); }
@Override @Override
public default Vec3f clamp(float min, float max) { return clamp(min, max, ALL); } public default Vec3f clamp(float min, float max) { return clamp(min, max, ALL); }
public default Vec3f clamp(float min, float max, Vec3f result) { return clamp(min, max, result, ALL); } public default Vec3f clamp(float min, float max, Vec3f result) { return clamp(min, max, result, ALL); }
@Override @Override
public default Vec3f clamp(float min, float max, int filter) { return clamp(min, max, this, filter); } public default Vec3f clamp(float min, float max, int filter) { return clamp(min, max, this, filter); }
public default Vec3f clamp(float min, float max, Vec3f result, int filter) { return result.set((filter & X) == 0 ? x() : MathUtils.clamp(min, max, x()), (filter & Y) == 0 ? y() : MathUtils.clamp(min, max, y()), (filter & Z) == 0 ? z() : MathUtils.clamp(min, max, z())); } public default Vec3f clamp(float min, float max, Vec3f result, int filter) { return result.set((filter & X) == 0 ? x() : MathUtils.clamp(min, max, x()), (filter & Y) == 0 ? y() : MathUtils.clamp(min, max, y()), (filter & Z) == 0 ? z() : MathUtils.clamp(min, max, z())); }
@Override @Override
public default Vec3f store(ByteBuffer buffer) { public default Vec3f store(ByteBuffer buffer) {
buffer.putFloat(x()).putFloat(y()).putFloat(z()); buffer.putFloat(x()).putFloat(y()).putFloat(z());
return this; return this;
} }
@Override @Override
public default Vec3f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } public default Vec3f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); }
@Override @Override
public default Vec3f store(FloatBuffer buffer) { public default Vec3f store(FloatBuffer buffer) {
buffer.put(x()).put(y()).put(z()); buffer.put(x()).put(y()).put(z());
return this; return this;
} }
@Override @Override
public default Vec3f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get()); } public default Vec3f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get()); }
@Override @Override
public default Vec3b asByte() { return isMutable() ? Vec3b.mutable((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z())) : Vec3b.of((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z())); } public default Vec3b asByte() { return isMutable() ? Vec3b.mutable((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z())) : Vec3b.of((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z())); }
@Override @Override
public default Vec3s asShort() { return isMutable() ? Vec3s.mutable((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z())) : Vec3s.of((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z())); } public default Vec3s asShort() { return isMutable() ? Vec3s.mutable((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z())) : Vec3s.of((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z())); }
@Override @Override
public default Vec3i asInt() { return isMutable() ? Vec3i.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())) : Vec3i.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())); } public default Vec3i asInt() { return isMutable() ? Vec3i.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())) : Vec3i.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())); }
@Override @Override
public default Vec3l asLong() { return isMutable() ? Vec3l.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())) : Vec3l.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())); } public default Vec3l asLong() { return isMutable() ? Vec3l.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())) : Vec3l.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z())); }
@Override @Override
public default Vec3d asDouble() { return isMutable() ? Vec3d.mutable(x(), y(), z()) : Vec3d.of(x(), y(), z()); } public default Vec3d asDouble() { return isMutable() ? Vec3d.mutable(x(), y(), z()) : Vec3d.of(x(), y(), z()); }
@Override @Override
public default Vec3f asMutable() { return isMutable() ? this : mutable(this); } public default Vec3f asMutable() { return isMutable() ? this : mutable(this); }
@Override @Override
public default Vec3f asImmutable() { return isMutable() ? of(this) : this; } public default Vec3f asImmutable() { return isMutable() ? of(this) : this; }
@Override @Override
public default Vec3f copyAsMutable() { return mutable(this); } public default Vec3f copyAsMutable() { return mutable(this); }
@Override @Override
public default Vec3f copyAsImmutable() { return of(this); } public default Vec3f copyAsImmutable() { return of(this); }
} }
@@ -1,226 +1,226 @@
package speiger.src.coreengine.math.vector.floats; package speiger.src.coreengine.math.vector.floats;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import speiger.src.coreengine.math.MathUtils; import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.vector.bytes.Vec4b; import speiger.src.coreengine.math.vector.bytes.Vec4b;
import speiger.src.coreengine.math.vector.doubles.Vec4d; import speiger.src.coreengine.math.vector.doubles.Vec4d;
import speiger.src.coreengine.math.vector.ints.Vec4i; import speiger.src.coreengine.math.vector.ints.Vec4i;
import speiger.src.coreengine.math.vector.longs.Vec4l; import speiger.src.coreengine.math.vector.longs.Vec4l;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.math.vector.shorts.Vec4s; import speiger.src.coreengine.math.vector.shorts.Vec4s;
public interface Vec4f extends Vecf { public interface Vec4f extends Vecf {
public static final Vec4f ZERO = of(); public static final Vec4f ZERO = of();
public static final Vec4f MINUS_ONE = of(-1F); public static final Vec4f MINUS_ONE = of(-1F);
public static final Vec4f ONE = of(1F); public static final Vec4f ONE = of(1F);
public static Vec4f mutable() { return new Vec4fMutable(); } public static Vec4f mutable() { return new Vec4fMutable(); }
public static Vec4f mutable(float value) { return new Vec4fMutable(value); } public static Vec4f mutable(float value) { return new Vec4fMutable(value); }
public static Vec4f mutable(float x, float y, float z, float w) { return new Vec4fMutable(x, y, z, w); } public static Vec4f mutable(float x, float y, float z, float w) { return new Vec4fMutable(x, y, z, w); }
public static Vec4f mutable(Vec4f vec) { return mutable(vec.x(), vec.y(), vec.z(), vec.w()); } public static Vec4f mutable(Vec4f vec) { return mutable(vec.x(), vec.y(), vec.z(), vec.w()); }
public static Vec4f of() { return new Vec4fImmutable(); } public static Vec4f of() { return new Vec4fImmutable(); }
public static Vec4f of(float value) { return new Vec4fImmutable(value); } public static Vec4f of(float value) { return new Vec4fImmutable(value); }
public static Vec4f of(float x, float y, float z, float w) { return new Vec4fImmutable(x, y, z, w); } public static Vec4f of(float x, float y, float z, float w) { return new Vec4fImmutable(x, y, z, w); }
public static Vec4f of(Vec4f vec) { return of(vec.x(), vec.y(), vec.z(), vec.w()); } public static Vec4f of(Vec4f vec) { return of(vec.x(), vec.y(), vec.z(), vec.w()); }
public float x(); public float x();
public float y(); public float y();
public float z(); public float z();
public float w(); public float w();
public Vec4f x(float x); public Vec4f x(float x);
public Vec4f y(float y); public Vec4f y(float y);
public Vec4f z(float z); public Vec4f z(float z);
public Vec4f w(float w); public Vec4f w(float w);
@Override @Override
public default float[] asArray() { return new float[] {x(), y(), z(), w()}; } public default float[] asArray() { return new float[] {x(), y(), z(), w()}; }
@Override @Override
public Vec4f copy(); public Vec4f copy();
@Override @Override
public default Vec4f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z()), Math.abs(w())); } public default Vec4f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z()), Math.abs(w())); }
@Override @Override
public default Vec4f negate() { return set(0F, 0F, 0F, 0F); } public default Vec4f negate() { return set(0F, 0F, 0F, 0F); }
@Override @Override
public default Vec4f invert() { return set(-x(), -y(), -z(), -w()); } public default Vec4f invert() { return set(-x(), -y(), -z(), -w()); }
public default Vec4f normalize() { public default Vec4f normalize() {
float l = length(); float l = length();
return l == 0F ? this : multiply(1.0F / l); return l == 0F ? this : multiply(1.0F / l);
} }
public default Vec4f normalize3D() { public default Vec4f normalize3D() {
float value = (x() * x()) + (y() * y()) + (z() * z()); float value = (x() * x()) + (y() * y()) + (z() * z());
return value == 0F ? this : multiply(1F / value); return value == 0F ? this : multiply(1F / value);
} }
@Override @Override
public default Vec4f add(float value) { return add(value, value, value, value); } public default Vec4f add(float value) { return add(value, value, value, value); }
public default Vec4f add(Vec4f value) { return add(value.x(), value.y(), value.z(), value.w()); } public default Vec4f add(Vec4f value) { return add(value.x(), value.y(), value.z(), value.w()); }
public default Vec4f add(float x, float y, float z, float w) { return set(x() + x, y() + y, z() + z, w() + w); } public default Vec4f add(float x, float y, float z, float w) { return set(x() + x, y() + y, z() + z, w() + w); }
@Override @Override
public default Vec4f sub(float value) { return sub(value, value, value, value); } public default Vec4f sub(float value) { return sub(value, value, value, value); }
public default Vec4f sub(Vec4f value) { return sub(value.x(), value.y(), value.z(), value.w()); } public default Vec4f sub(Vec4f value) { return sub(value.x(), value.y(), value.z(), value.w()); }
public default Vec4f sub(float x, float y, float z, float w) { return set(x() - x, y() - y, z() - z, w() - w); } public default Vec4f sub(float x, float y, float z, float w) { return set(x() - x, y() - y, z() - z, w() - w); }
@Override @Override
public default Vec4f multiply(float value) { return multiply(value, value, value, value); } public default Vec4f multiply(float value) { return multiply(value, value, value, value); }
public default Vec4f multiply(Vec4f value) { return multiply(value.x(), value.y(), value.z(), value.w()); } public default Vec4f multiply(Vec4f value) { return multiply(value.x(), value.y(), value.z(), value.w()); }
public default Vec4f multiply(float x, float y, float z, float w) { return set(x() * x, y() * y, z() * z, w() * w); } public default Vec4f multiply(float x, float y, float z, float w) { return set(x() * x, y() * y, z() * z, w() * w); }
@Override @Override
public default Vec4f devide(float value) { return devide(value, value, value, value); } public default Vec4f devide(float value) { return devide(value, value, value, value); }
public default Vec4f devide(Vec4f value) { return devide(value.x(), value.y(), value.z(), value.w()); } public default Vec4f devide(Vec4f value) { return devide(value.x(), value.y(), value.z(), value.w()); }
public default Vec4f devide(float x, float y, float z, float w) { return set(x() / x, y() / y, z() / z, w() / w); } public default Vec4f devide(float x, float y, float z, float w) { return set(x() / x, y() / y, z() / z, w() / w); }
@Override @Override
public default Vec4f set(float value) { return set(value, value, value, value); } public default Vec4f set(float value) { return set(value, value, value, value); }
public default Vec4f set(Vec4f value) { return set(value.x(), value.y(), value.z(), value.w()); } public default Vec4f set(Vec4f value) { return set(value.x(), value.y(), value.z(), value.w()); }
public Vec4f set(float x, float y, float z, float w); public Vec4f set(float x, float y, float z, float w);
public default double distanceTo(Vec4f value) { return distanceTo(value.x(), value.y(), value.z(), value.w()); } public default double distanceTo(Vec4f value) { return distanceTo(value.x(), value.y(), value.z(), value.w()); }
public default double distanceTo(float x, float y, float z, float w) { return Math.sqrt(distanceTo(x, y, z, w)); } public default double distanceTo(float x, float y, float z, float w) { return Math.sqrt(distanceTo(x, y, z, w)); }
public default double distanceToSquared(Vec4f value) { return distanceToSquared(value.x(), value.y(), value.z(), value.w()); } public default double distanceToSquared(Vec4f value) { return distanceToSquared(value.x(), value.y(), value.z(), value.w()); }
public default double distanceToSquared(float x, float y, float z, float w) { public default double distanceToSquared(float x, float y, float z, float w) {
double xPos = x() - x; double xPos = x() - x;
double yPos = y() - y; double yPos = y() - y;
double zPos = z() - z; double zPos = z() - z;
double wPos = w() - w; double wPos = w() - w;
return (xPos * xPos) + (yPos * yPos) + (zPos * zPos) + (wPos * wPos); return (xPos * xPos) + (yPos * yPos) + (zPos * zPos) + (wPos * wPos);
} }
@Override @Override
public default float lengthSquared() { return (x() * x()) + (y() * y()) + (z() * z()) + (w() * w()); } public default float lengthSquared() { return (x() * x()) + (y() * y()) + (z() * z()) + (w() * w()); }
public default double dotProduct(Vec4f value) { return dotProduct(value.x(), value.y(), value.z(), value.w()); } public default double dotProduct(Vec4f value) { return dotProduct(value.x(), value.y(), value.z(), value.w()); }
public default double dotProduct(float x, float y, float z, float w) { return (x() * x) + (y() * y) + (z() * z) + (w() * w); }; public default double dotProduct(float x, float y, float z, float w) { return (x() * x) + (y() * y) + (z() * z) + (w() * w); };
public default Vec4f lerp(Vec4f value, float progress, Vec4f result) { return lerp(value.x(), value.y(), value.z(), value.w(), progress, result); } public default Vec4f lerp(Vec4f value, float progress, Vec4f result) { return lerp(value.x(), value.y(), value.z(), value.w(), progress, result); }
public default Vec4f lerp(float x, float y, float z, float w, float progress, Vec4f result) { return result.set(MathUtils.lerp(x(), x, progress), MathUtils.lerp(y(), y, progress), MathUtils.lerp(z(), z, progress), MathUtils.lerp(w(), w, progress)); } public default Vec4f lerp(float x, float y, float z, float w, float progress, Vec4f result) { return result.set(MathUtils.lerp(x(), x, progress), MathUtils.lerp(y(), y, progress), MathUtils.lerp(z(), z, progress), MathUtils.lerp(w(), w, progress)); }
public default float angle(Vec4f value) { return angle(value.x(), value.y(), value.z(), value.w()); } public default float angle(Vec4f value) { return angle(value.x(), value.y(), value.z(), value.w()); }
public default float angle(float x, float y, float z, float w) { return (float)Math.acos(MathUtils.clamp(-1F, 1F, angleCos(x, y, z, w))); } public default float angle(float x, float y, float z, float w) { return (float)Math.acos(MathUtils.clamp(-1F, 1F, angleCos(x, y, z, w))); }
public default float angleCos(Vec4f value) { return angleCos(value.x(), value.y(), value.z(), value.w()); } public default float angleCos(Vec4f value) { return angleCos(value.x(), value.y(), value.z(), value.w()); }
public default float angleCos(float x, float y, float z, float w) { return (float)(dotProduct(x, y, z, w) / Math.sqrt(lengthSquared() * (x * x) + (y * y) + (z * z) + (w * w))); } public default float angleCos(float x, float y, float z, float w) { return (float)(dotProduct(x, y, z, w) / Math.sqrt(lengthSquared() * (x * x) + (y * y) + (z * z) + (w * w))); }
public default Vec4f rotate(float angle, Vec4f axis) { return rotate(angle, axis.x(), axis.y(), axis.z(), axis.w()); } public default Vec4f rotate(float angle, Vec4f axis) { return rotate(angle, axis.x(), axis.y(), axis.z(), axis.w()); }
public default Vec4f rotate(float angle, Vec4f axis, Vec4f result) { return rotate(angle, axis.x(), axis.y(), axis.z(), axis.w(), result); } public default Vec4f rotate(float angle, Vec4f axis, Vec4f result) { return rotate(angle, axis.x(), axis.y(), axis.z(), axis.w(), result); }
public default Vec4f rotate(float angle, float x, float y, float z, float w) { return rotate(angle, x, y, z, w, this); } public default Vec4f rotate(float angle, float x, float y, float z, float w) { return rotate(angle, x, y, z, w, this); }
public default Vec4f rotate(float angle, float x, float y, float z, float w, Vec4f result) { public default Vec4f rotate(float angle, float x, float y, float z, float w, Vec4f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double dot = dotProduct(x, y, z, w); double dot = dotProduct(x, y, z, w);
double xPos = x * dot * (1D - cos) + (x() * cos) + (-z * y() + y * z()) * sin; double xPos = x * dot * (1D - cos) + (x() * cos) + (-z * y() + y * z()) * sin;
double yPos = y * dot * (1D - cos) + (y() * cos) + (z * x() - x * z()) * sin; double yPos = y * dot * (1D - cos) + (y() * cos) + (z * x() - x * z()) * sin;
double zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin; double zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin;
return result.set((float)xPos, (float)yPos, (float)zPos, w()); return result.set((float)xPos, (float)yPos, (float)zPos, w());
} }
public default Vec4f rotateX(float angle) { return rotateX(angle, this); } public default Vec4f rotateX(float angle) { return rotateX(angle, this); }
public default Vec4f rotateX(float angle, Vec4f result) { public default Vec4f rotateX(float angle, Vec4f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double y = y() * cos + z() * sin; double y = y() * cos + z() * sin;
double z = z() * cos - y() * sin; double z = z() * cos - y() * sin;
return result.set(x(), (float)y, (float)z, w()); return result.set(x(), (float)y, (float)z, w());
} }
public default Vec4f rotateY(float angle) { return rotateY(angle, this); } public default Vec4f rotateY(float angle) { return rotateY(angle, this); }
public default Vec4f rotateY(float angle, Vec4f result) { public default Vec4f rotateY(float angle, Vec4f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double x = x() * cos + z() * sin; double x = x() * cos + z() * sin;
double z = z() * cos - x() * sin; double z = z() * cos - x() * sin;
return result.set((float)x, y(), (float)z, w()); return result.set((float)x, y(), (float)z, w());
} }
public default Vec4f rotateZ(float angle) { return rotateZ(angle, this); } public default Vec4f rotateZ(float angle) { return rotateZ(angle, this); }
public default Vec4f rotateZ(float angle, Vec4f result) { public default Vec4f rotateZ(float angle, Vec4f result) {
double cos = MathUtils.cos(angle); double cos = MathUtils.cos(angle);
double sin = MathUtils.sin(angle); double sin = MathUtils.sin(angle);
double x = cos * x() - sin * y(); double x = cos * x() - sin * y();
double y = sin * x() + cos * y(); double y = sin * x() + cos * y();
return result.set((float)x, (float)y, z(), w()); return result.set((float)x, (float)y, z(), w());
} }
public default Vec4f transform(Matrix4f matrix) { return transform(matrix, this); } public default Vec4f transform(Matrix4f matrix) { return transform(matrix, this); }
public default Vec4f transform(Matrix4f matrix, Vec4f result) { public default Vec4f transform(Matrix4f matrix, Vec4f result) {
if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) { if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) {
return result.set(this); return result.set(this);
} }
if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) { if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) {
return result.set( return result.set(
matrix.fma(Matrix4f.M00, Matrix4f.M10, Matrix4f.M20, Matrix4f.M30, x(), y(), z(), w()), matrix.fma(Matrix4f.M00, Matrix4f.M10, Matrix4f.M20, Matrix4f.M30, x(), y(), z(), w()),
matrix.fma(Matrix4f.M01, Matrix4f.M11, Matrix4f.M21, Matrix4f.M31, x(), y(), z(), w()), matrix.fma(Matrix4f.M01, Matrix4f.M11, Matrix4f.M21, Matrix4f.M31, x(), y(), z(), w()),
matrix.fma(Matrix4f.M02, Matrix4f.M12, Matrix4f.M22, Matrix4f.M32, x(), y(), z(), w()), matrix.fma(Matrix4f.M02, Matrix4f.M12, Matrix4f.M22, Matrix4f.M32, x(), y(), z(), w()),
matrix.fma(Matrix4f.M03, Matrix4f.M13, Matrix4f.M23, Matrix4f.M33, x(), y(), z(), w())); matrix.fma(Matrix4f.M03, Matrix4f.M13, Matrix4f.M23, Matrix4f.M33, x(), y(), z(), w()));
} }
if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) { if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) {
return set( return set(
Math.fma(matrix.get(Matrix4f.M00), x(), matrix.get(Matrix4f.M30)), Math.fma(matrix.get(Matrix4f.M00), x(), matrix.get(Matrix4f.M30)),
Math.fma(matrix.get(Matrix4f.M01), y(), matrix.get(Matrix4f.M31)), Math.fma(matrix.get(Matrix4f.M01), y(), matrix.get(Matrix4f.M31)),
Math.fma(matrix.get(Matrix4f.M02), z(), matrix.get(Matrix4f.M32)), Math.fma(matrix.get(Matrix4f.M02), z(), matrix.get(Matrix4f.M32)),
Math.fma(matrix.get(Matrix4f.M03), w(), matrix.get(Matrix4f.M33))); Math.fma(matrix.get(Matrix4f.M03), w(), matrix.get(Matrix4f.M33)));
} }
return set(x() + matrix.get(Matrix4f.M30), y() + matrix.get(Matrix4f.M31), z() + matrix.get(Matrix4f.M32), w() + matrix.get(Matrix4f.M33)); return set(x() + matrix.get(Matrix4f.M30), y() + matrix.get(Matrix4f.M31), z() + matrix.get(Matrix4f.M32), w() + matrix.get(Matrix4f.M33));
} }
public default Vec4f smoothStep(Vec4f value, float progress, Vec4f result) { return smoothStep(value.x(), value.y(), value.z(), value.w(), progress, result); } public default Vec4f smoothStep(Vec4f value, float progress, Vec4f result) { return smoothStep(value.x(), value.y(), value.z(), value.w(), progress, result); }
public default Vec4f smoothStep(float x, float y, float z, float w, float progress, Vec4f result) { public default Vec4f smoothStep(float x, float y, float z, float w, float progress, Vec4f result) {
float t2 = progress * progress; float t2 = progress * progress;
float t3 = t2 * progress; float t3 = t2 * progress;
float xPos = ((x() + x() - x - x) * t3 + (3.0F * x - 3.0F * x()) * t2 + x() * progress + x()); float xPos = ((x() + x() - x - x) * t3 + (3.0F * x - 3.0F * x()) * t2 + x() * progress + x());
float yPos = ((y() + y() - y - y) * t3 + (3.0F * y - 3.0F * y()) * t2 + y() * progress + y()); float yPos = ((y() + y() - y - y) * t3 + (3.0F * y - 3.0F * y()) * t2 + y() * progress + y());
float zPos = ((z() + z() - z - z) * t3 + (3.0F * z - 3.0F * z()) * t2 + z() * progress + z()); float zPos = ((z() + z() - z - z) * t3 + (3.0F * z - 3.0F * z()) * t2 + z() * progress + z());
float wPos = ((w() + w() - w - w) * t3 + (3.0F * w - 3.0F * w()) * t2 + w() * progress + w()); float wPos = ((w() + w() - w - w) * t3 + (3.0F * w - 3.0F * w()) * t2 + w() * progress + w());
return result.set(xPos, yPos, zPos, wPos); return result.set(xPos, yPos, zPos, wPos);
} }
public default Vec4f min(Vec4f other) { return min(other, this); } public default Vec4f min(Vec4f other) { return min(other, this); }
public default Vec4f min(Vec4f other, Vec4f result) { return min(other.x(), other.y(), other.z(), other.w(), result); } public default Vec4f min(Vec4f other, Vec4f result) { return min(other.x(), other.y(), other.z(), other.w(), result); }
public default Vec4f min(float x, float y, float z, float w) { return min(x, y, z, w, this); } public default Vec4f min(float x, float y, float z, float w) { return min(x, y, z, w, this); }
public default Vec4f min(float x, float y, float z, float w, Vec4f result) { return result.set(Math.min(x(), x), Math.min(y(), y), Math.min(z(), z), Math.min(w(), w)); } public default Vec4f min(float x, float y, float z, float w, Vec4f result) { return result.set(Math.min(x(), x), Math.min(y(), y), Math.min(z(), z), Math.min(w(), w)); }
public default Vec4f max(Vec4f other) { return max(other, this); } public default Vec4f max(Vec4f other) { return max(other, this); }
public default Vec4f max(Vec4f other, Vec4f result) { return max(other.x(), other.y(), other.z(), other.w(), result); } public default Vec4f max(Vec4f other, Vec4f result) { return max(other.x(), other.y(), other.z(), other.w(), result); }
public default Vec4f max(float x, float y, float z, float w) { return max(x, y, z, w, this); } public default Vec4f max(float x, float y, float z, float w) { return max(x, y, z, w, this); }
public default Vec4f max(float x, float y, float z, float w, Vec4f result) { return result.set(Math.max(x(), x), Math.max(y(), y), Math.max(z(), z), Math.max(z(), z)); } public default Vec4f max(float x, float y, float z, float w, Vec4f result) { return result.set(Math.max(x(), x), Math.max(y(), y), Math.max(z(), z), Math.max(z(), z)); }
public default Vec4f difference(Vec4f other) { return difference(other, this); } public default Vec4f difference(Vec4f other) { return difference(other, this); }
public default Vec4f difference(Vec4f other, Vec4f result) { return difference(other.x(), other.y(), other.z(), other.w(), result); } public default Vec4f difference(Vec4f other, Vec4f result) { return difference(other.x(), other.y(), other.z(), other.w(), result); }
public default Vec4f difference(float x, float y, float z, float w) { return difference(x, y, z, w, this); } public default Vec4f difference(float x, float y, float z, float w) { return difference(x, y, z, w, this); }
public default Vec4f difference(float x, float y, float z, float w, Vec4f result) { return result.set(x() - x, y() - y, z() - z, w() - w); } public default Vec4f difference(float x, float y, float z, float w, Vec4f result) { return result.set(x() - x, y() - y, z() - z, w() - w); }
@Override @Override
public default Vec4f clamp(float min, float max) { return clamp(min, max, ALL); } public default Vec4f clamp(float min, float max) { return clamp(min, max, ALL); }
public default Vec4f clamp(float min, float max, Vec4f result) { return clamp(min, max, result, ALL); } public default Vec4f clamp(float min, float max, Vec4f result) { return clamp(min, max, result, ALL); }
@Override @Override
public default Vec4f clamp(float min, float max, int filter) { return clamp(min, max, this, filter); } public default Vec4f clamp(float min, float max, int filter) { return clamp(min, max, this, filter); }
public default Vec4f clamp(float min, float max, Vec4f result, int filter) { return result.set((filter & X) == 0 ? x() : MathUtils.clamp(min, max, x()), (filter & Y) == 0 ? y() : MathUtils.clamp(min, max, y()), (filter & Z) == 0 ? z() : MathUtils.clamp(min, max, z()), (filter & W) == 0 ? w() : MathUtils.clamp(min, max, w())); } public default Vec4f clamp(float min, float max, Vec4f result, int filter) { return result.set((filter & X) == 0 ? x() : MathUtils.clamp(min, max, x()), (filter & Y) == 0 ? y() : MathUtils.clamp(min, max, y()), (filter & Z) == 0 ? z() : MathUtils.clamp(min, max, z()), (filter & W) == 0 ? w() : MathUtils.clamp(min, max, w())); }
@Override @Override
public default Vec4f store(ByteBuffer buffer) { public default Vec4f store(ByteBuffer buffer) {
buffer.putFloat(x()).putFloat(y()).putFloat(z()).putFloat(w()); buffer.putFloat(x()).putFloat(y()).putFloat(z()).putFloat(w());
return this; return this;
} }
@Override @Override
public default Vec4f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } public default Vec4f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); }
@Override @Override
public default Vec4f store(FloatBuffer buffer) { public default Vec4f store(FloatBuffer buffer) {
buffer.put(x()).put(y()).put(z()).put(w()); buffer.put(x()).put(y()).put(z()).put(w());
return this; return this;
} }
@Override @Override
public default Vec4f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); } public default Vec4f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); }
@Override @Override
public default Vec4b asByte() { return isMutable() ? Vec4b.mutable((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z()), (byte)MathUtils.floor(w())) : Vec4b.of((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z()), (byte)MathUtils.floor(w())); } public default Vec4b asByte() { return isMutable() ? Vec4b.mutable((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z()), (byte)MathUtils.floor(w())) : Vec4b.of((byte)MathUtils.floor(x()), (byte)MathUtils.floor(y()), (byte)MathUtils.floor(z()), (byte)MathUtils.floor(w())); }
@Override @Override
public default Vec4s asShort() { return isMutable() ? Vec4s.mutable((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z()), (short)MathUtils.floor(w())) : Vec4s.of((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z()), (short)MathUtils.floor(w())); } public default Vec4s asShort() { return isMutable() ? Vec4s.mutable((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z()), (short)MathUtils.floor(w())) : Vec4s.of((short)MathUtils.floor(x()), (short)MathUtils.floor(y()), (short)MathUtils.floor(z()), (short)MathUtils.floor(w())); }
@Override @Override
public default Vec4i asInt() { return isMutable() ? Vec4i.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())) : Vec4i.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())); } public default Vec4i asInt() { return isMutable() ? Vec4i.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())) : Vec4i.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())); }
@Override @Override
public default Vec4l asLong() { return isMutable() ? Vec4l.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())) : Vec4l.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())); } public default Vec4l asLong() { return isMutable() ? Vec4l.mutable(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())) : Vec4l.of(MathUtils.floor(x()), MathUtils.floor(y()), MathUtils.floor(z()), MathUtils.floor(w())); }
@Override @Override
public default Vec4d asDouble() { return isMutable() ? Vec4d.mutable(x(), y(), z(), w()) : Vec4d.of(x(), y(), z(), w()); } public default Vec4d asDouble() { return isMutable() ? Vec4d.mutable(x(), y(), z(), w()) : Vec4d.of(x(), y(), z(), w()); }
@Override @Override
public default Vec4f asMutable() { return isMutable() ? this : mutable(this); } public default Vec4f asMutable() { return isMutable() ? this : mutable(this); }
@Override @Override
public default Vec4f asImmutable() { return isMutable() ? of(this) : this; } public default Vec4f asImmutable() { return isMutable() ? of(this) : this; }
@Override @Override
public default Vec4f copyAsMutable() { return mutable(this); } public default Vec4f copyAsMutable() { return mutable(this); }
@Override @Override
public default Vec4f copyAsImmutable() { return of(this); } public default Vec4f copyAsImmutable() { return of(this); }
} }
@@ -1,5 +1,5 @@
package speiger.src.coreengine.math.vector.matrix; package speiger.src.coreengine.math.vector.matrix;
public interface ITransformOutput { public interface ITransformOutput {
public void accept(float...output); public void accept(float x, float y, float z);
} }
@@ -16,7 +16,6 @@ public class Matrix4f {
public static final int PROPERTY_TRANSLATION = 1 << 2; public static final int PROPERTY_TRANSLATION = 1 << 2;
public static final int PROPERTY_SCALE = 1 << 3; public static final int PROPERTY_SCALE = 1 << 3;
public static final int PROPERTY_ROTATION = 1 << 4; public static final int PROPERTY_ROTATION = 1 << 4;
private static final int PROPERTY_DEFAULT = 1;
public static final int M00 = 0; public static final int M00 = 0;
public static final int M01 = 1; public static final int M01 = 1;
@@ -137,13 +136,13 @@ public class Matrix4f {
} }
public Matrix4f setIdentity() { public Matrix4f setIdentity() {
if(properties == PROPERTY_DEFAULT) return this; if((properties & PROPERTY_IDENTITY) == PROPERTY_IDENTITY) return this;
Arrays.fill(data, 0F); Arrays.fill(data, 0F);
data[M00] = 1F; data[M00] = 1F;
data[M11] = 1F; data[M11] = 1F;
data[M22] = 1F; data[M22] = 1F;
data[M33] = 1F; data[M33] = 1F;
properties = PROPERTY_DEFAULT; properties = PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_AFFINE;
return this; return this;
} }
@@ -190,22 +189,9 @@ public class Matrix4f {
} }
public Matrix4f flip() { public Matrix4f flip() {
data[M00] = -data[M00]; for(int i = 0;i<16;i++) {
data[M01] = -data[M01]; data[i] = -data[i];
data[M02] = -data[M02]; }
data[M03] = -data[M03];
data[M10] = -data[M10];
data[M11] = -data[M11];
data[M12] = -data[M12];
data[M13] = -data[M13];
data[M20] = -data[M20];
data[M21] = -data[M21];
data[M22] = -data[M22];
data[M23] = -data[M23];
data[M30] = -data[M30];
data[M31] = -data[M31];
data[M32] = -data[M32];
data[M33] = -data[M33];
return evaluateProps(); return evaluateProps();
} }
@@ -215,42 +201,16 @@ public class Matrix4f {
} }
public Matrix4f add(Matrix4f other) { public Matrix4f add(Matrix4f other) {
data[M00] += other.data[M00]; for(int i = 0;i<16;i++) {
data[M01] += other.data[M01]; data[i] += other.data[i];
data[M02] += other.data[M02]; }
data[M03] += other.data[M03];
data[M10] += other.data[M10];
data[M11] += other.data[M11];
data[M12] += other.data[M12];
data[M13] += other.data[M13];
data[M20] += other.data[M20];
data[M21] += other.data[M21];
data[M22] += other.data[M22];
data[M23] += other.data[M23];
data[M30] += other.data[M30];
data[M31] += other.data[M31];
data[M32] += other.data[M32];
data[M33] += other.data[M33];
return evaluateProps(); return evaluateProps();
} }
public Matrix4f sub(Matrix4f other) { public Matrix4f sub(Matrix4f other) {
data[M00] -= other.data[M00]; for(int i = 0;i<16;i++) {
data[M01] -= other.data[M01]; data[i] -= other.data[i];
data[M02] -= other.data[M02]; }
data[M03] -= other.data[M03];
data[M10] -= other.data[M10];
data[M11] -= other.data[M11];
data[M12] -= other.data[M12];
data[M13] -= other.data[M13];
data[M20] -= other.data[M20];
data[M21] -= other.data[M21];
data[M22] -= other.data[M22];
data[M23] -= other.data[M23];
data[M30] -= other.data[M30];
data[M31] -= other.data[M31];
data[M32] -= other.data[M32];
data[M33] -= other.data[M33];
return evaluateProps(); return evaluateProps();
} }
@@ -371,6 +331,10 @@ public class Matrix4f {
data[M32] += z; data[M32] += z;
return evaluateProps(); return evaluateProps();
} }
if((properties & PROPERTY_ROTATION) == 0) {
data[M32] += data[M22] * z;
evaluateProps();
}
data[M30] += data[M20] * z; data[M30] += data[M20] * z;
data[M31] += data[M21] * z; data[M31] += data[M21] * z;
data[M32] += data[M22] * z; data[M32] += data[M22] * z;
@@ -385,6 +349,11 @@ public class Matrix4f {
data[M31] += y; data[M31] += y;
return evaluateProps(); return evaluateProps();
} }
if((properties & PROPERTY_ROTATION) == 0) {
data[M30] += data[M00] * x;
data[M31] += data[M11] * y;
evaluateProps();
}
data[M30] += data[M00] * x + data[M10] * y; data[M30] += data[M00] * x + data[M10] * y;
data[M31] += data[M01] * x + data[M11] * y; data[M31] += data[M01] * x + data[M11] * y;
data[M32] += data[M02] * x + data[M12] * y; data[M32] += data[M02] * x + data[M12] * y;
@@ -401,6 +370,12 @@ public class Matrix4f {
properties |= PROPERTY_TRANSLATION; properties |= PROPERTY_TRANSLATION;
return evaluateProps(); return evaluateProps();
} }
if((properties & PROPERTY_ROTATION) == 0) {
data[M30] += data[M00] * x;
data[M31] += data[M11] * y;
data[M32] += data[M22] * z;
evaluateProps();
}
data[M30] += data[M00] * x + data[M10] * y + data[M20] * z; data[M30] += data[M00] * x + data[M10] * y + data[M20] * z;
data[M31] += data[M01] * x + data[M11] * y + data[M21] * z; data[M31] += data[M01] * x + data[M11] * y + data[M21] * z;
data[M32] += data[M02] * x + data[M12] * y + data[M22] * z; data[M32] += data[M02] * x + data[M12] * y + data[M22] * z;
@@ -614,28 +589,20 @@ public class Matrix4f {
return this; return this;
} }
public void transform(Vec4f input, FloatBuffer buffer) { public void transformOffset(float x, float y, float z, float xOff, float yOff, float zOff, ITransformOutput output) {
transform(input.x(), input.y(), input.z(), input.w(), buffer::put);
}
public void transform(Vec3f input, boolean position, FloatBuffer buffer) {
transform(input.x(), input.y(), input.z(), position, buffer::put);
}
public void transform(float x, float y, float z, float w, ITransformOutput output) {
if((properties & PROPERTY_IDENTITY) != 0) { if((properties & PROPERTY_IDENTITY) != 0) {
output.accept(x, y, z, w); output.accept(x + xOff, y + yOff, z + zOff);
return; return;
} }
if((properties & PROPERTY_ROTATION) != 0) { if((properties & PROPERTY_ROTATION) != 0) {
output.accept(fma(M00, M10, M20, M30, x, y, z, w), fma(M01, M11, M21, M31, x, y, z, w), fma(M02, M12, M22, M32, x, y, z, w), fma(M03, M13, M23, M33, x, y, z, w)); output.accept(fma(M00, M10, M20, M30, x, y, z, 1F) + xOff, fma(M01, M11, M21, M31, x, y, z, 1F) + yOff, fma(M02, M12, M22, M32, x, y, z, 1F) + zOff);
return; return;
} }
if((properties & PROPERTY_SCALE) != 0) { if((properties & PROPERTY_SCALE) != 0) {
output.accept(Math.fma(data[M00], x, data[M30]), Math.fma(data[M01], y, data[M31]), Math.fma(data[M02], z, data[M32]), Math.fma(data[M03], w, data[M33])); output.accept(Math.fma(data[M00], x, data[M30]) + xOff, Math.fma(data[M01], y, data[M31]) + yOff, Math.fma(data[M02], z, data[M32]) + zOff);
return; return;
} }
output.accept(x + data[M30], y + data[M31], z + data[M32], w + data[M33]); output.accept(x + data[M30] + xOff, y + data[M31] + yOff, z + data[M32] + zOff);
} }
public void transform(float x, float y, float z, boolean pos, ITransformOutput output) { public void transform(float x, float y, float z, boolean pos, ITransformOutput output) {
@@ -1,31 +1,31 @@
package speiger.src.coreengine.math.vector.matrix; package speiger.src.coreengine.math.vector.matrix;
import speiger.src.collections.objects.lists.ObjectArrayList; import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.utils.Stack; import speiger.src.collections.utils.Stack;
public class Matrix4fStack extends Matrix4f { public class Matrix4fStack extends Matrix4f {
Stack<Matrix4f> stack = new ObjectArrayList<>(); Stack<Matrix4f> stack = new ObjectArrayList<>();
public Matrix4f push() { public Matrix4f push() {
Matrix4f matrix = new Matrix4f(this); Matrix4f matrix = new Matrix4f(this);
stack.push(matrix); stack.push(matrix);
return matrix; return matrix;
} }
public void pop() { public void pop() {
load(stack.pop()); load(stack.pop());
} }
public void popRoot() { public void popRoot() {
load(stack.peek(stack.size()-1)); load(stack.peek(stack.size()-1));
stack.clear(); stack.clear();
} }
public int size() { public int size() {
return stack.size(); return stack.size();
} }
public Matrix4f copyCurrent() { public Matrix4f copyCurrent() {
return new Matrix4f(this); return new Matrix4f(this);
} }
} }
@@ -1,191 +1,191 @@
package speiger.src.coreengine.math.vector.quaternion; package speiger.src.coreengine.math.vector.quaternion;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.FloatBuffer; import java.nio.FloatBuffer;
import speiger.src.coreengine.math.MathUtils; import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.vector.floats.Vec4f; import speiger.src.coreengine.math.vector.floats.Vec4f;
import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f;
public interface Quaternion { public interface Quaternion {
public static final Quaternion ZERO = of(0F, 0F, 0F, 0F); public static final Quaternion ZERO = of(0F, 0F, 0F, 0F);
public static final Quaternion IDENTITY = of(); public static final Quaternion IDENTITY = of();
public static Quaternion mutable() { return new QuaternionMutable(); } public static Quaternion mutable() { return new QuaternionMutable(); }
public static Quaternion mutable(Quaternion source) { return mutable(source.getX(), source.getY(), source.getZ(), source.getW()); } public static Quaternion mutable(Quaternion source) { return mutable(source.getX(), source.getY(), source.getZ(), source.getW()); }
public static Quaternion mutable(float x, float y, float z, float w) { return new QuaternionMutable(x, y, z, w); } public static Quaternion mutable(float x, float y, float z, float w) { return new QuaternionMutable(x, y, z, w); }
public static Quaternion mutableRad(float x, float y, float z, float angle) { return mutable().setAxisRad(x, y, z, angle); } public static Quaternion mutableRad(float x, float y, float z, float angle) { return mutable().setAxisRad(x, y, z, angle); }
public static Quaternion mutableDeg(float x, float y, float z, float angle) { return mutable().setAxisDeg(x, y, z, angle); } public static Quaternion mutableDeg(float x, float y, float z, float angle) { return mutable().setAxisDeg(x, y, z, angle); }
public static Quaternion of() { return new QuaternionImmutable(); } public static Quaternion of() { return new QuaternionImmutable(); }
public static Quaternion of(Quaternion source) { return of(source.getX(), source.getY(), source.getZ(), source.getW()); } public static Quaternion of(Quaternion source) { return of(source.getX(), source.getY(), source.getZ(), source.getW()); }
public static Quaternion of(float x, float y, float z, float w) { return new QuaternionImmutable(x, y, z, w); } public static Quaternion of(float x, float y, float z, float w) { return new QuaternionImmutable(x, y, z, w); }
public static Quaternion ofRad(float x, float y, float z, float angle) { return ZERO.setAxisRad(x, y, z, angle); } public static Quaternion ofRad(float x, float y, float z, float angle) { return ZERO.setAxisRad(x, y, z, angle); }
public static Quaternion ofDeg(float x, float y, float z, float angle) { return ZERO.setAxisDeg(x, y, z, angle); } public static Quaternion ofDeg(float x, float y, float z, float angle) { return ZERO.setAxisDeg(x, y, z, angle); }
public static double acos(double v) { return v < -1D ? 3.141592653589793D : (v > 1D ? 0D : Math.acos(v)); } public static double acos(double v) { return v < -1D ? 3.141592653589793D : (v > 1D ? 0D : Math.acos(v)); }
public Quaternion setX(float x); public Quaternion setX(float x);
public Quaternion setY(float y); public Quaternion setY(float y);
public Quaternion setZ(float z); public Quaternion setZ(float z);
public Quaternion setW(float w); public Quaternion setW(float w);
public float getX(); public float getX();
public float getY(); public float getY();
public float getZ(); public float getZ();
public float getW(); public float getW();
public default float[] asArray() { return new float[] {getX(), getY(), getZ(), getW()}; } public default float[] asArray() { return new float[] {getX(), getY(), getZ(), getW()}; }
public default Quaternion negate() { return set(0F, 0F, 0F, 0F); } public default Quaternion negate() { return set(0F, 0F, 0F, 0F); }
public default Quaternion invert() { return set(-getX(), -getY(), -getZ(), -getW()); } public default Quaternion invert() { return set(-getX(), -getY(), -getZ(), -getW()); }
public default Quaternion normalize() { return scale(1.0F / length()); } public default Quaternion normalize() { return scale(1.0F / length()); }
public default Quaternion conjugate() { return set(-getX(), -getY(), -getZ(), getW()); } public default Quaternion conjugate() { return set(-getX(), -getY(), -getZ(), getW()); }
public default Quaternion setIdentity() { return set(0F, 0F, 0F, 1F); } public default Quaternion setIdentity() { return set(0F, 0F, 0F, 1F); }
public default Quaternion multiply(Quaternion other) { return set(getX() * other.getW() + getW() * other.getX() + getY() * other.getZ() - getZ() * other.getY(), getY() * other.getW() + getW() * other.getY() + getZ() * other.getX() - getX() * other.getZ(), getZ() * other.getW() + getW() * other.getZ() + getX() * other.getY() - getY() * other.getX(), getW() * other.getW() - getX() * other.getX() - getY() * other.getY() - getZ() * other.getZ()); } public default Quaternion multiply(Quaternion other) { return set(getX() * other.getW() + getW() * other.getX() + getY() * other.getZ() - getZ() * other.getY(), getY() * other.getW() + getW() * other.getY() + getZ() * other.getX() - getX() * other.getZ(), getZ() * other.getW() + getW() * other.getZ() + getX() * other.getY() - getY() * other.getX(), getW() * other.getW() - getX() * other.getX() - getY() * other.getY() - getZ() * other.getZ()); }
public default Quaternion scale(float scale) { return set(getX() * scale, getY() * scale, getZ() * scale, getW() * scale); } public default Quaternion scale(float scale) { return set(getX() * scale, getY() * scale, getZ() * scale, getW() * scale); }
public default Quaternion rotateX(float angle) { public default Quaternion rotateX(float angle) {
angle = (float)Math.toRadians(angle); angle = (float)Math.toRadians(angle);
float sin = MathUtils.sin(angle * 0.5D); float sin = MathUtils.sin(angle * 0.5D);
float cos = MathUtils.cos(angle * 0.5D); float cos = MathUtils.cos(angle * 0.5D);
return set(getW() * sin + getX() * cos, getY() * cos + getZ() * sin, getZ() * cos - getY() * sin, getW() * cos - getX() * sin); return set(getW() * sin + getX() * cos, getY() * cos + getZ() * sin, getZ() * cos - getY() * sin, getW() * cos - getX() * sin);
} }
public default Quaternion rotateY(float angle) { public default Quaternion rotateY(float angle) {
angle = (float)Math.toRadians(angle); angle = (float)Math.toRadians(angle);
float sin = MathUtils.sin(angle * 0.5D); float sin = MathUtils.sin(angle * 0.5D);
float cos = MathUtils.cos(angle * 0.5D); float cos = MathUtils.cos(angle * 0.5D);
return set(getX() * cos - getZ() * sin, getW() * sin + getY() * cos, getX() * sin + getZ() * cos, getW() * cos - getY() * sin); return set(getX() * cos - getZ() * sin, getW() * sin + getY() * cos, getX() * sin + getZ() * cos, getW() * cos - getY() * sin);
} }
public default Quaternion rotateZ(float angle) { public default Quaternion rotateZ(float angle) {
angle = (float)Math.toRadians(angle); angle = (float)Math.toRadians(angle);
float sin = MathUtils.sin(angle * 0.5D); float sin = MathUtils.sin(angle * 0.5D);
float cos = MathUtils.cos(angle * 0.5D); float cos = MathUtils.cos(angle * 0.5D);
return set(getX() * cos + getY() * sin, getY() * cos - getX() * sin, getW() * sin + getZ() * cos, getW() * cos - getZ() * sin); return set(getX() * cos + getY() * sin, getY() * cos - getX() * sin, getW() * sin + getZ() * cos, getW() * cos - getZ() * sin);
} }
public default Quaternion set(Vec4f value) { return set(value.x(), value.y(), value.z(), value.w()); } public default Quaternion set(Vec4f value) { return set(value.x(), value.y(), value.z(), value.w()); }
public default Quaternion set(Quaternion value) { return set(value.getX(), value.getY(), value.getZ(), value.getW()); } public default Quaternion set(Quaternion value) { return set(value.getX(), value.getY(), value.getZ(), value.getW()); }
public default Quaternion set(Matrix4f matrix) { public default Quaternion set(Matrix4f matrix) {
float tr = matrix.get(0, 0) + matrix.get(1, 1) + matrix.get(2, 2); float tr = matrix.get(0, 0) + matrix.get(1, 1) + matrix.get(2, 2);
if(tr >= 0.0D) { if(tr >= 0.0D) {
float s = (float)Math.sqrt(tr + 1.0D); float s = (float)Math.sqrt(tr + 1.0D);
float w = s * 0.5F; float w = s * 0.5F;
s = 0.5F / s; s = 0.5F / s;
float x = (matrix.get(2, 1) - matrix.get(1, 2)) * s; float x = (matrix.get(2, 1) - matrix.get(1, 2)) * s;
float y = (matrix.get(0, 2) - matrix.get(2, 0)) * s; float y = (matrix.get(0, 2) - matrix.get(2, 0)) * s;
float z = (matrix.get(1, 0) - matrix.get(0, 1)) * s; float z = (matrix.get(1, 0) - matrix.get(0, 1)) * s;
return set(x, y, z, w); return set(x, y, z, w);
} }
else { else {
float max = Math.max(Math.max(matrix.get(0, 0), matrix.get(1, 1)), matrix.get(2, 2)); float max = Math.max(Math.max(matrix.get(0, 0), matrix.get(1, 1)), matrix.get(2, 2));
if(max == matrix.get(0, 0)) { if(max == matrix.get(0, 0)) {
float s = (float)Math.sqrt(matrix.get(0, 0) - (matrix.get(1, 1) + matrix.get(2, 2)) + 1.0D); float s = (float)Math.sqrt(matrix.get(0, 0) - (matrix.get(1, 1) + matrix.get(2, 2)) + 1.0D);
float x = s * 0.5F; float x = s * 0.5F;
s = 0.5F / s; s = 0.5F / s;
float y = (matrix.get(0, 1) + matrix.get(1, 0)) * s; float y = (matrix.get(0, 1) + matrix.get(1, 0)) * s;
float z = (matrix.get(2, 0) + matrix.get(0, 2)) * s; float z = (matrix.get(2, 0) + matrix.get(0, 2)) * s;
float w = (matrix.get(2, 1) - matrix.get(1, 2)) * s; float w = (matrix.get(2, 1) - matrix.get(1, 2)) * s;
return set(x, y, z, w); return set(x, y, z, w);
} }
else if(max == matrix.get(1, 1)) { else if(max == matrix.get(1, 1)) {
float s = (float)Math.sqrt(matrix.get(1, 1) - (matrix.get(2, 2) + matrix.get(0, 0)) + 1.0D); float s = (float)Math.sqrt(matrix.get(1, 1) - (matrix.get(2, 2) + matrix.get(0, 0)) + 1.0D);
float y = s * 0.5F; float y = s * 0.5F;
s = 0.5F / s; s = 0.5F / s;
float z = (matrix.get(1, 2) + matrix.get(2, 1)) * s; float z = (matrix.get(1, 2) + matrix.get(2, 1)) * s;
float x = (matrix.get(0, 1) + matrix.get(1, 0)) * s; float x = (matrix.get(0, 1) + matrix.get(1, 0)) * s;
float w = (matrix.get(0, 2) - matrix.get(2, 0)) * s; float w = (matrix.get(0, 2) - matrix.get(2, 0)) * s;
return set(x, y, z, w); return set(x, y, z, w);
} }
else { else {
float s = (float)Math.sqrt(matrix.get(2, 2) - (matrix.get(0, 0) + matrix.get(1, 1)) + 1.0D); float s = (float)Math.sqrt(matrix.get(2, 2) - (matrix.get(0, 0) + matrix.get(1, 1)) + 1.0D);
float z = s * 0.5F; float z = s * 0.5F;
s = 0.5F / s; s = 0.5F / s;
float x = (matrix.get(2, 0) + matrix.get(0, 2)) * s; float x = (matrix.get(2, 0) + matrix.get(0, 2)) * s;
float y = (matrix.get(1, 2) + matrix.get(2, 1)) * s; float y = (matrix.get(1, 2) + matrix.get(2, 1)) * s;
float w = (matrix.get(1, 0) - matrix.get(0, 1)) * s; float w = (matrix.get(1, 0) - matrix.get(0, 1)) * s;
return set(x, y, z, w); return set(x, y, z, w);
} }
} }
} }
public default Quaternion setAxisRad(float x, float y, float z, float angle) { public default Quaternion setAxisRad(float x, float y, float z, float angle) {
float sin = MathUtils.sin(angle * 0.5D); float sin = MathUtils.sin(angle * 0.5D);
float cos = MathUtils.cos(angle * 0.5D); float cos = MathUtils.cos(angle * 0.5D);
return set(x * sin, y * sin, z * sin, cos); return set(x * sin, y * sin, z * sin, cos);
} }
public default Quaternion setAxisDeg(float x, float y, float z, float angle) { public default Quaternion setAxisDeg(float x, float y, float z, float angle) {
angle = (float)Math.toRadians(angle); angle = (float)Math.toRadians(angle);
float sin = MathUtils.sin(angle * 0.5D); float sin = MathUtils.sin(angle * 0.5D);
float cos = MathUtils.cos(angle * 0.5D); float cos = MathUtils.cos(angle * 0.5D);
return set(x * sin, y * sin, z * sin, cos); return set(x * sin, y * sin, z * sin, cos);
} }
public Quaternion set(float x, float y, float z, float w); public Quaternion set(float x, float y, float z, float w);
public default float dot(Quaternion other) { return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ() + getW() * other.getW(); } public default float dot(Quaternion other) { return getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ() + getW() * other.getW(); }
public default Quaternion difference(Quaternion other) { return difference(other, this); } public default Quaternion difference(Quaternion other) { return difference(other, this); }
public default Quaternion difference(Quaternion other, Quaternion result) { public default Quaternion difference(Quaternion other, Quaternion result) {
float invNorm = 1.0F / (getX() * getX() + getY() * getY() + getZ() * getZ() + getW() * getW()); float invNorm = 1.0F / (getX() * getX() + getY() * getY() + getZ() * getZ() + getW() * getW());
float x = -getX() * invNorm; float x = -getX() * invNorm;
float y = -getY() * invNorm; float y = -getY() * invNorm;
float z = -getZ() * invNorm; float z = -getZ() * invNorm;
float w = getW() * invNorm; float w = getW() * invNorm;
return set(w * other.getX() + x * other.getW() + y * other.getZ() - z * other.getY(), w * other.getY() - x * other.getZ() + y * other.getW() + z * other.getX(), w * other.getZ() + x * other.getY() - y * other.getX() + z * other.getW(), w * other.getW() - x * other.getX() - y * other.getY() - z * other.getZ()); return set(w * other.getX() + x * other.getW() + y * other.getZ() - z * other.getY(), w * other.getY() - x * other.getZ() + y * other.getW() + z * other.getX(), w * other.getZ() + x * other.getY() - y * other.getX() + z * other.getW(), w * other.getW() - x * other.getX() - y * other.getY() - z * other.getZ());
} }
public default Quaternion lerp(Quaternion other, float progress) { return lerp(other, progress, this); } public default Quaternion lerp(Quaternion other, float progress) { return lerp(other, progress, this); }
public default Quaternion lerp(Quaternion other, float progress, Quaternion result) { public default Quaternion lerp(Quaternion other, float progress, Quaternion result) {
float cosom = getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ() + getW() * other.getW(); float cosom = getX() * other.getX() + getY() * other.getY() + getZ() * other.getZ() + getW() * other.getW();
float absCosom = Math.abs(cosom); float absCosom = Math.abs(cosom);
float scale1; float scale1;
float scale0; float scale0;
if(1.0F - absCosom > 1.0E-006F) { if(1.0F - absCosom > 1.0E-006F) {
float sinSqr = 1.0F - absCosom * absCosom; float sinSqr = 1.0F - absCosom * absCosom;
float sinom = (float)(1.0D / Math.sqrt(sinSqr)); float sinom = (float)(1.0D / Math.sqrt(sinSqr));
float omega = (float)Math.atan2(sinSqr * sinom, absCosom); float omega = (float)Math.atan2(sinSqr * sinom, absCosom);
scale0 = MathUtils.sin((1.0D - progress) * omega) * sinom; scale0 = MathUtils.sin((1.0D - progress) * omega) * sinom;
scale1 = MathUtils.sin(progress * omega) * sinom; scale1 = MathUtils.sin(progress * omega) * sinom;
} }
else { else {
scale0 = 1.0F - progress; scale0 = 1.0F - progress;
scale1 = progress; scale1 = progress;
} }
scale1 = cosom >= 0.0F ? scale1 : -scale1; scale1 = cosom >= 0.0F ? scale1 : -scale1;
return result.set(scale0 * getX() + scale1 * other.getX(), scale0 * getY() + scale1 * other.getY(), scale0 * getZ() + scale1 * other.getZ(), scale0 * getW() + scale1 * other.getW()); return result.set(scale0 * getX() + scale1 * other.getX(), scale0 * getY() + scale1 * other.getY(), scale0 * getZ() + scale1 * other.getZ(), scale0 * getW() + scale1 * other.getW());
} }
public default float length() { return (float)Math.sqrt(lengthSquared()); } public default float length() { return (float)Math.sqrt(lengthSquared()); }
public default double lengthSquared() { return (getX() * getX()) + (getY() * getY()) + (getZ() * getZ()) + (getW() * getW()); } public default double lengthSquared() { return (getX() * getX()) + (getY() * getY()) + (getZ() * getZ()) + (getW() * getW()); }
public default Matrix4f asRotationMatrix() { return new Matrix4f().rotate(this); } public default Matrix4f asRotationMatrix() { return new Matrix4f().rotate(this); }
public default Vec4f toAxisDegreeRotation() { return toAxisDegreeRotation(Vec4f.mutable()); } public default Vec4f toAxisDegreeRotation() { return toAxisDegreeRotation(Vec4f.mutable()); }
public default Vec4f toAxisDegreeRotation(Vec4f input) { public default Vec4f toAxisDegreeRotation(Vec4f input) {
double invSqrt = 1.0D / Math.sqrt(1.0D - getW() * getW()); double invSqrt = 1.0D / Math.sqrt(1.0D - getW() * getW());
return input.set((float)(getX() * invSqrt), (float)(getY() * invSqrt), (float)(getZ() * invSqrt), (float)Math.toDegrees(acos(getW()) * 2F)); return input.set((float)(getX() * invSqrt), (float)(getY() * invSqrt), (float)(getZ() * invSqrt), (float)Math.toDegrees(acos(getW()) * 2F));
} }
public default Vec4f toAxisRotation() { return toAxisRotation(Vec4f.mutable()); } public default Vec4f toAxisRotation() { return toAxisRotation(Vec4f.mutable()); }
public default Vec4f toAxisRotation(Vec4f input) { public default Vec4f toAxisRotation(Vec4f input) {
double invSqrt = 1.0D / Math.sqrt(1.0D - getW() * getW()); double invSqrt = 1.0D / Math.sqrt(1.0D - getW() * getW());
return input.set((float)(getX() * invSqrt), (float)(getY() * invSqrt), (float)(getZ() * invSqrt), (float)acos(getW()) * 2F); return input.set((float)(getX() * invSqrt), (float)(getY() * invSqrt), (float)(getZ() * invSqrt), (float)acos(getW()) * 2F);
} }
public default Quaternion store(ByteBuffer buffer) { public default Quaternion store(ByteBuffer buffer) {
buffer.putFloat(getX()).putFloat(getY()).putFloat(getZ()).putFloat(getW()); buffer.putFloat(getX()).putFloat(getY()).putFloat(getZ()).putFloat(getW());
return this; return this;
} }
public default Quaternion load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } public default Quaternion load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); }
public default Quaternion store(FloatBuffer buffer) { public default Quaternion store(FloatBuffer buffer) {
buffer.put(getX()).put(getY()).put(getZ()).put(getW()); buffer.put(getX()).put(getY()).put(getZ()).put(getW());
return this; return this;
} }
public default Quaternion load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); } public default Quaternion load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); }
public Quaternion copy(); public Quaternion copy();
public boolean isMutable(); public boolean isMutable();
public default Quaternion asMutable() { return isMutable() ? this : of(this); } public default Quaternion asMutable() { return isMutable() ? this : of(this); }
public default Quaternion asImmutable() { return isMutable() ? mutable(this) : this; } public default Quaternion asImmutable() { return isMutable() ? mutable(this) : this; }
public default Quaternion copyAsMutable() { return mutable(this); } public default Quaternion copyAsMutable() { return mutable(this); }
public default Quaternion copyAsImmutable() { return of(this); } public default Quaternion copyAsImmutable() { return of(this); }
} }