From 56eae46176b5f4e229c3fadc1ca62e88a35ca55c Mon Sep 17 00:00:00 2001 From: Speiger Date: Sun, 16 Aug 2026 21:22:28 +0200 Subject: [PATCH] Progress on UI Renderer --- .../api/core/GraphicsCommandBuffer.java | 4 +- .../graphics/api/utils/SampledTexture.java | 13 + .../api/vertex/builder/IVertexBuffer.java | 5 +- .../api/vertex/builder/VertexBuilder.java | 28 +- .../opengl/core/GLImmidateCommandBuffer.java | 9 +- .../opengl/core/GLRecordingCommandBuffer.java | 7 +- .../ui/gui/component/base/GuiComponent.java | 6 +- .../coreengine/ui/gui/layout/box/IGuiBox.java | 2 + .../ui/gui/layout/box/ParentBox.java | 2 +- .../ui/gui/renderer/IUIRenderer.java | 38 +- .../coreengine/ui/gui/renderer/LayerType.java | 7 + .../coreengine/ui/gui/renderer/UIDrawer.java | 12 + .../ui/gui/renderer/UIRenderer.java | 215 ++++++++ .../src/coreengine/ui/gui/utils/Align.java | 15 + .../coreengine/ui/gui/utils/UIConstants.java | 33 ++ .../src/coreengine/NewRenderEngineTest.java | 6 +- .../gui/renderer/SimpleUIShader.java | 54 +- .../rendering/guiOld/renderer/GuiShader.java | 98 ++-- .../shader/uniform/UniformManager.java | 220 ++++---- .../shader/uniform/vec/Matrix4fUniform.java | 74 +-- .../shaderOld/uniforms/UniformMatrix.java | 54 +- .../utils/helpers/InternalThreadPools.java | 24 +- .../coreengine/math/vector/floats/Vec3f.java | 472 +++++++++--------- .../coreengine/math/vector/floats/Vec4f.java | 452 ++++++++--------- .../math/vector/matrix/ITransformOutput.java | 10 +- .../math/vector/matrix/Matrix4f.java | 95 ++-- .../math/vector/matrix/Matrix4fStack.java | 62 +-- .../math/vector/quaternion/Quaternion.java | 382 +++++++------- 28 files changed, 1329 insertions(+), 1070 deletions(-) create mode 100644 src/graphics/java/speiger/src/coreengine/platform/graphics/api/utils/SampledTexture.java create mode 100644 src/gui/java/speiger/src/coreengine/ui/gui/renderer/LayerType.java create mode 100644 src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIDrawer.java create mode 100644 src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIRenderer.java create mode 100644 src/gui/java/speiger/src/coreengine/ui/gui/utils/Align.java create mode 100644 src/gui/java/speiger/src/coreengine/ui/gui/utils/UIConstants.java diff --git a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/core/GraphicsCommandBuffer.java b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/core/GraphicsCommandBuffer.java index 5cee375..cb3aebf 100644 --- a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/core/GraphicsCommandBuffer.java +++ b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/core/GraphicsCommandBuffer.java @@ -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.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.texture.Texture; 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.SampledTexture; public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer { GraphicsCommandBuffer begin(); @@ -14,7 +14,7 @@ public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer { GraphicsCommandBuffer pipeline(ShaderPipeline pipeline); 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 uniform(int binding, VertexBuffer buffer); diff --git a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/utils/SampledTexture.java b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/utils/SampledTexture.java new file mode 100644 index 0000000..6fef34d --- /dev/null +++ b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/utils/SampledTexture.java @@ -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); + } +} diff --git a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/IVertexBuffer.java b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/IVertexBuffer.java index 1b98beb..06018a8 100644 --- a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/IVertexBuffer.java +++ b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/IVertexBuffer.java @@ -1,7 +1,5 @@ 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.platform.graphics.api.shader.states.DrawMode; 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 { Element current(); IVertexBuffer next(); - IVertexBuffer finish(); - List results(); + BufferResult finish(); default IVertexBuffer validate(Usage usage, GraphicsDataType type, int size) { return validate(this, usage, type, size); } diff --git a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/VertexBuilder.java b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/VertexBuilder.java index 1235042..dcbe372 100644 --- a/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/VertexBuilder.java +++ b/src/graphics/java/speiger/src/coreengine/platform/graphics/api/vertex/builder/VertexBuilder.java @@ -1,13 +1,9 @@ package speiger.src.coreengine.platform.graphics.api.vertex.builder; import java.nio.ByteBuffer; -import java.util.List; 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.vertex.VertexLayout; import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Element; @@ -24,7 +20,6 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable { int vertexBytes; int elementBytes; int lastVertecies = 0; - ObjectList results; public VertexBuilder(int size) { this(MemoryUtil.memAlloc(size)); @@ -40,6 +35,7 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable { } public VertexBuilder start(DrawMode mode, VertexLayout layout) { + if(index != 0) throw new IllegalStateException("Can't change Layout mid Writing"); this.mode = mode; this.layout = layout; return this; @@ -52,10 +48,10 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable { totalStoredBytes = 0; vertexBytes = 0; lastVertecies = 0; - results = null; return this; } + public boolean hasVertecies() { return lastVertecies < vertecies; } public boolean is(DrawMode mode, VertexLayout layout) { return this.mode == mode && this.layout == layout; } public DrawMode mode() { return mode; } public VertexLayout getFormat() { return layout; } @@ -73,16 +69,10 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable { } @Override - public IVertexBuffer finish() { - if(results == null) results = new ObjectArrayList<>(); - results.add(new BufferResult(mode, lastVertecies, vertecies)); + public BufferResult finish() { + BufferResult result = new BufferResult(mode, lastVertecies, vertecies); lastVertecies = vertecies; - return this; - } - - @Override - public List results() { - return results == null ? ObjectLists.empty() : results.unmodifiable(); + return result; } @Override @@ -93,12 +83,8 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable { elementBytes = 0; if(index == 0) { vertecies++; - if(mode == DrawMode.LINES || mode == DrawMode.LINE_STRIP) { - buffer.put(totalStoredBytes, buffer, totalStoredBytes - vertexBytes, vertexBytes); - vertecies++; - } vertexBytes = 0; - ensureCapacity(totalStoredBytes + layout.bytes()); + ensureCapacity(totalStoredBytes + (layout.bytes() * mode.primitiveLength())); } return this; } @@ -136,8 +122,6 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable { return vertecies; } - - public VertexBuilder putBulk(byte[] source) { if(index != 0) throw new IllegalStateException("Can't do bulk iterations when mid Building"); ensureCapacity(source.length + layout.bytes()); diff --git a/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLImmidateCommandBuffer.java b/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLImmidateCommandBuffer.java index 0b341e1..0f92b03 100644 --- a/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLImmidateCommandBuffer.java +++ b/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLImmidateCommandBuffer.java @@ -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.core.GraphicsCommandBuffer; 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.DepthTarget; 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.texture.Texture; 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.opengl.buffer.GLVertexBuffer; import speiger.src.coreengine.platform.graphics.opengl.mesh.GLMesh; @@ -118,15 +118,14 @@ public class GLImmidateCommandBuffer implements GraphicsCommandBuffer { } @Override - public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) { + public GraphicsCommandBuffer texture(int binding, SampledTexture texture) { Objects.requireNonNull(texture); - Objects.requireNonNull(sampler); ensureDrawing(); Objects.requireNonNull(shader, "No Pipeline found"); Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found"); GLStates states = device.states; - states.textures.bind(binding, ((GLTexture)texture).id()); - states.samplers.bind(binding, ((GLSampler)sampler).id()); + states.textures.bind(binding, ((GLTexture)texture.texture()).id()); + states.samplers.bind(binding, ((GLSampler)texture.sampler()).id()); recorded++; return this; } diff --git a/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLRecordingCommandBuffer.java b/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLRecordingCommandBuffer.java index 7d0686d..6747325 100644 --- a/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLRecordingCommandBuffer.java +++ b/src/graphics/java/speiger/src/coreengine/platform/graphics/opengl/core/GLRecordingCommandBuffer.java @@ -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.core.GraphicsCommandBuffer; 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.DepthTarget; 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.texture.Texture; 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.NoOp; import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer; @@ -110,13 +110,12 @@ public class GLRecordingCommandBuffer implements GraphicsCommandBuffer { } @Override - public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) { + public GraphicsCommandBuffer texture(int binding, SampledTexture texture) { Objects.requireNonNull(texture); - Objects.requireNonNull(sampler); ensureDrawing(); Objects.requireNonNull(shader, "No Pipeline 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; } diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/component/base/GuiComponent.java b/src/gui/java/speiger/src/coreengine/ui/gui/component/base/GuiComponent.java index 7932e0d..1491ac2 100644 --- a/src/gui/java/speiger/src/coreengine/ui/gui/component/base/GuiComponent.java +++ b/src/gui/java/speiger/src/coreengine/ui/gui/component/base/GuiComponent.java @@ -94,14 +94,14 @@ public abstract non-sealed class GuiComponent extends FlagObject implements ICas if(!comp.isVisible()) return false; comp.updateAnimations(partialTicks); if(comp.isScissored()) { - if(!renderer.isInScissors(comp.getBox())) return false; - renderer.pushScissors(comp.getBox()); + if(!renderer.isClipping(comp.getBox())) return false; + renderer.pushClip(comp.getBox()); if(comp.renderer != null) { comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks); comp.renderChildren(renderer, mouseX, mouseY, partialTicks); } else comp.renderComponent(renderer, mouseX, mouseY, partialTicks); - renderer.popScissors(); + renderer.popClip(); } else if(comp.renderer != null) { comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks); diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/IGuiBox.java b/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/IGuiBox.java index 82b93c7..cf60e0a 100644 --- a/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/IGuiBox.java +++ b/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/IGuiBox.java @@ -16,6 +16,8 @@ public interface IGuiBox extends IScreenBox 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 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(float padding) { return GuiBox.clonePadded(this, padding); } diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/ParentBox.java b/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/ParentBox.java index 29a3c31..2fab719 100644 --- a/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/ParentBox.java +++ b/src/gui/java/speiger/src/coreengine/ui/gui/layout/box/ParentBox.java @@ -22,7 +22,7 @@ public class ParentBox implements IGuiBox maxY = -value; } - public ParentBox(float paddingTop, float paddingLeft, float paddingBottom, float paddingRight) { + public ParentBox(float paddingLeft, float paddingTop, float paddingRight, float paddingBottom) { minX = paddingLeft; minY = paddingTop; maxX = paddingRight; diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/renderer/IUIRenderer.java b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/IUIRenderer.java index c13ca8b..1091926 100644 --- a/src/gui/java/speiger/src/coreengine/ui/gui/renderer/IUIRenderer.java +++ b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/IUIRenderer.java @@ -1,24 +1,38 @@ package speiger.src.coreengine.ui.gui.renderer; 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.utils.Align; public interface IUIRenderer { - public boolean isInScissors(IGuiBox box); - public void pushScissors(IGuiBox box); - public void popScissors(); + boolean isClipping(IGuiBox box); + void pushClip(IGuiBox box); + void popClip(); - public void flush(); + void pushTransform(); + void popTransform(); - public void pushTransform(); - public void popTransform(); + void translate(float z); + void translate(float x, float y); - public void translate(float z); - public void translate(float x, float y); - public void translate(float x, float y, float z); + void scale(float scale); + void scale(float x, float y); - public void scale(float scale); - public void scale(float x, float y); + void rotate(Quaternion rotation); - 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); } diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/renderer/LayerType.java b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/LayerType.java new file mode 100644 index 0000000..5aaa209 --- /dev/null +++ b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/LayerType.java @@ -0,0 +1,7 @@ +package speiger.src.coreengine.ui.gui.renderer; + +public enum LayerType { + COMPONENT, + COMPONENT_STACK, + WINDOW; +} \ No newline at end of file diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIDrawer.java b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIDrawer.java new file mode 100644 index 0000000..3806f99 --- /dev/null +++ b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIDrawer.java @@ -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); +} \ No newline at end of file diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIRenderer.java b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIRenderer.java new file mode 100644 index 0000000..819eb62 --- /dev/null +++ b/src/gui/java/speiger/src/coreengine/ui/gui/renderer/UIRenderer.java @@ -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 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) {} +} diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/utils/Align.java b/src/gui/java/speiger/src/coreengine/ui/gui/utils/Align.java new file mode 100644 index 0000000..bb37da1 --- /dev/null +++ b/src/gui/java/speiger/src/coreengine/ui/gui/utils/Align.java @@ -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; + }; + } +} diff --git a/src/gui/java/speiger/src/coreengine/ui/gui/utils/UIConstants.java b/src/gui/java/speiger/src/coreengine/ui/gui/utils/UIConstants.java new file mode 100644 index 0000000..601281d --- /dev/null +++ b/src/gui/java/speiger/src/coreengine/ui/gui/utils/UIConstants.java @@ -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(); +} diff --git a/src/main/java/speiger/src/coreengine/NewRenderEngineTest.java b/src/main/java/speiger/src/coreengine/NewRenderEngineTest.java index d4bfc10..8ca8f18 100644 --- a/src/main/java/speiger/src/coreengine/NewRenderEngineTest.java +++ b/src/main/java/speiger/src/coreengine/NewRenderEngineTest.java @@ -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.SampleMode; 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.ShaderType; 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.TextureType; 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.Usage; import speiger.src.coreengine.platform.graphics.api.vertex.builder.VertexBuilder; @@ -84,7 +86,7 @@ public class NewRenderEngineTest { .build(); 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(1F, 1F).rgba(-1); builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1); @@ -123,7 +125,7 @@ public class NewRenderEngineTest { queue.begin() .pipeline(pipeline) .mesh(mesh) - .texture(0, texture, sampler) + .texture(0, new SampledTexture(texture, sampler)) .uniform(0, buffer) .drawArrays(0, 6) .end(); diff --git a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIShader.java b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIShader.java index a688dec..bfaa689 100644 --- a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIShader.java +++ b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIShader.java @@ -1,27 +1,27 @@ -package speiger.src.coreengine.rendering.gui.renderer; - -import speiger.src.coreengine.assets.AssetLocation; -import speiger.src.coreengine.assets.base.IAssetProvider; -import speiger.src.coreengine.math.vector.floats.Vec4f; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; -import speiger.src.coreengine.rendering.shader.SimpleShader; -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.TextureUniform; -import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform; -import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform; - -public class SimpleUIShader extends SimpleShader { - public BufferUniform camera = uniforms.addBuffer("cameraTransform", 0); - public Matrix4fUniform modelMatrix = uniforms.addMat("modelMatrix", new Matrix4f()); - public TextureUniform texture = uniforms.addTexture("texture", 0); - public FloatUniform useTexture = uniforms.addFloat("use_texture", 0); - public Vec4fUniform bounds = uniforms.addVec4("bounds", Vec4f.ZERO); - public FloatUniform roundness = uniforms.addFloat("roundness", 0); - - - 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"); - } - -} +package speiger.src.coreengine.rendering.gui.renderer; + +import speiger.src.coreengine.assets.AssetLocation; +import speiger.src.coreengine.assets.base.IAssetProvider; +import speiger.src.coreengine.math.vector.floats.Vec4f; +import speiger.src.coreengine.math.vector.matrix.Matrix4f; +import speiger.src.coreengine.rendering.shader.SimpleShader; +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.TextureUniform; +import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform; +import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform; + +public class SimpleUIShader extends SimpleShader { + public BufferUniform camera = uniforms.addBuffer("cameraTransform", 0); + public Matrix4fUniform modelMatrix = uniforms.addMat("modelMatrix", new Matrix4f()); + public TextureUniform texture = uniforms.addTexture("texture", 0); + public FloatUniform useTexture = uniforms.addFloat("use_texture", 0); + public Vec4fUniform bounds = uniforms.addVec4("bounds", Vec4f.ZERO); + public FloatUniform roundness = uniforms.addFloat("roundness", 0); + + + 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"); + } + +} diff --git a/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/GuiShader.java b/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/GuiShader.java index 80a576d..8c6c8e7 100644 --- a/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/GuiShader.java +++ b/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/GuiShader.java @@ -1,50 +1,50 @@ - -package speiger.src.coreengine.rendering.guiOld.renderer; - -import speiger.src.coreengine.assets.AssetLocation; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; -import speiger.src.coreengine.rendering.models.buffers.UniformBuffer; -import speiger.src.coreengine.rendering.shaderOld.ShaderProgram; -import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformBufferBlock; -import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformFloat; -import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformMatrix; -import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformTexture; -import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformVec4f; - -public class GuiShader extends ShaderProgram -{ - public UniformBufferBlock proViewMatrix = new UniformBufferBlock("cameraTransform", 1); - public UniformMatrix modelMatrix = new UniformMatrix("modelMatrix"); - public UniformTexture texture = new UniformTexture("texture", 0); - public UniformFloat useTexture = new UniformFloat("use_texture"); - public UniformFloat roundeness = new UniformFloat("roundness"); - public UniformVec4f bounds = new UniformVec4f("bounds"); - - public GuiShader(AssetLocation vertex, AssetLocation fragment, String...args) - { - super(vertex, fragment, args); - addUniforms(proViewMatrix, modelMatrix, texture, useTexture, roundeness, bounds); - } - - 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"); - } - - public void bind(UniformBuffer view) - { - if(isShaderRunning()) return; - startShader(); - proViewMatrix.bindBuffer(view); - } - - @Override - public GuiShader init() - { - startShader(); - modelMatrix.storeData(new Matrix4f()); - bounds.storeData(0F, 0F, 0F, 0F); - stopShader(); - return this; - } + +package speiger.src.coreengine.rendering.guiOld.renderer; + +import speiger.src.coreengine.assets.AssetLocation; +import speiger.src.coreengine.math.vector.matrix.Matrix4f; +import speiger.src.coreengine.rendering.models.buffers.UniformBuffer; +import speiger.src.coreengine.rendering.shaderOld.ShaderProgram; +import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformBufferBlock; +import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformFloat; +import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformMatrix; +import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformTexture; +import speiger.src.coreengine.rendering.shaderOld.uniforms.UniformVec4f; + +public class GuiShader extends ShaderProgram +{ + public UniformBufferBlock proViewMatrix = new UniformBufferBlock("cameraTransform", 1); + public UniformMatrix modelMatrix = new UniformMatrix("modelMatrix"); + public UniformTexture texture = new UniformTexture("texture", 0); + public UniformFloat useTexture = new UniformFloat("use_texture"); + public UniformFloat roundeness = new UniformFloat("roundness"); + public UniformVec4f bounds = new UniformVec4f("bounds"); + + public GuiShader(AssetLocation vertex, AssetLocation fragment, String...args) + { + super(vertex, fragment, args); + addUniforms(proViewMatrix, modelMatrix, texture, useTexture, roundeness, bounds); + } + + 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"); + } + + public void bind(UniformBuffer view) + { + if(isShaderRunning()) return; + startShader(); + proViewMatrix.bindBuffer(view); + } + + @Override + public GuiShader init() + { + startShader(); + modelMatrix.storeData(new Matrix4f()); + bounds.storeData(0F, 0F, 0F, 0F); + stopShader(); + return this; + } } \ No newline at end of file diff --git a/src/main/java/speiger/src/coreengine/rendering/shader/uniform/UniformManager.java b/src/main/java/speiger/src/coreengine/rendering/shader/uniform/UniformManager.java index 71831f8..33d17ee 100644 --- a/src/main/java/speiger/src/coreengine/rendering/shader/uniform/UniformManager.java +++ b/src/main/java/speiger/src/coreengine/rendering/shader/uniform/UniformManager.java @@ -1,111 +1,111 @@ -package speiger.src.coreengine.rendering.shader.uniform; - -import java.util.List; - -import speiger.src.collections.objects.lists.ObjectArrayList; -import speiger.src.coreengine.math.vector.floats.Vec2f; -import speiger.src.coreengine.math.vector.floats.Vec3f; -import speiger.src.coreengine.math.vector.floats.Vec4f; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; -import speiger.src.coreengine.rendering.shader.ShaderProgram; -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.FloatUniform; -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.vec.Matrix4fUniform; -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.Vec4fUniform; -import speiger.src.coreengine.rendering.utils.GLStateTracker; - -public class UniformManager { - List uniforms = new ObjectArrayList<>(); - List autoUniforms = new ObjectArrayList<>(); - ShaderProgram owner; - - public UniformManager(ShaderProgram owner) { - this.owner = owner; - } - - public T addGlobalUniform(String name) { - return addUniform(GLStateTracker.instance().uniforms.get(name)); - } - - public T addGlobalUniform(String name, T defaultValue) { - return addUniform(GLStateTracker.instance().uniforms.getOrDefault(name, defaultValue)); - } - - public BoolUniform addBool(String name, boolean defaultValue) { - return addUniform(new BoolUniform(name, defaultValue)); - } - - public IntUniform addInt(String name, int defaultValue) { - return addUniform(new IntUniform(name, defaultValue)); - } - - public FloatUniform addFloat(String name, float defaultValue) { - return addUniform(new FloatUniform(name, defaultValue)); - } - - public Vec2fUniform addVec2(String name, Vec2f defaultValue) { - return addUniform(new Vec2fUniform(name, defaultValue.copyAsMutable())); - } - - public Vec3fUniform addVec3(String name, Vec3f defaultValue) { - return addUniform(new Vec3fUniform(name, defaultValue.copyAsMutable())); - } - - public Vec4fUniform addVec4(String name, Vec4f defaultValue) { - return addUniform(new Vec4fUniform(name, defaultValue.copyAsMutable())); - } - - public Matrix4fUniform addMat(String name, Matrix4f defaultValue) { - return addUniform(new Matrix4fUniform(name, new Matrix4f(defaultValue))); - } - - public BufferUniform addBuffer(String name, int slot) { - return addUniform(new BufferUniform(name, slot)); - } - - public TextureUniform addTexture(String name, int unit) { - return addUniform(new TextureUniform(name, unit)); - } - - public T addUniform(T uniform) { - uniforms.add(uniform); - uniform.registerShader(owner); - if(uniform instanceof IAutoUniform auto) { - autoUniforms.add(auto); - } - return uniform; - } - - @SuppressWarnings("unchecked") - public T getUniform(String name) { - for(int i = 0,m=uniforms.size();i uniforms = new ObjectArrayList<>(); + List autoUniforms = new ObjectArrayList<>(); + ShaderProgram owner; + + public UniformManager(ShaderProgram owner) { + this.owner = owner; + } + + public T addGlobalUniform(String name) { + return addUniform(GLStateTracker.instance().uniforms.get(name)); + } + + public T addGlobalUniform(String name, T defaultValue) { + return addUniform(GLStateTracker.instance().uniforms.getOrDefault(name, defaultValue)); + } + + public BoolUniform addBool(String name, boolean defaultValue) { + return addUniform(new BoolUniform(name, defaultValue)); + } + + public IntUniform addInt(String name, int defaultValue) { + return addUniform(new IntUniform(name, defaultValue)); + } + + public FloatUniform addFloat(String name, float defaultValue) { + return addUniform(new FloatUniform(name, defaultValue)); + } + + public Vec2fUniform addVec2(String name, Vec2f defaultValue) { + return addUniform(new Vec2fUniform(name, defaultValue.copyAsMutable())); + } + + public Vec3fUniform addVec3(String name, Vec3f defaultValue) { + return addUniform(new Vec3fUniform(name, defaultValue.copyAsMutable())); + } + + public Vec4fUniform addVec4(String name, Vec4f defaultValue) { + return addUniform(new Vec4fUniform(name, defaultValue.copyAsMutable())); + } + + public Matrix4fUniform addMat(String name, Matrix4f defaultValue) { + return addUniform(new Matrix4fUniform(name, new Matrix4f(defaultValue))); + } + + public BufferUniform addBuffer(String name, int slot) { + return addUniform(new BufferUniform(name, slot)); + } + + public TextureUniform addTexture(String name, int unit) { + return addUniform(new TextureUniform(name, unit)); + } + + public T addUniform(T uniform) { + uniforms.add(uniform); + uniform.registerShader(owner); + if(uniform instanceof IAutoUniform auto) { + autoUniforms.add(auto); + } + return uniform; + } + + @SuppressWarnings("unchecked") + public T getUniform(String name) { + for(int i = 0,m=uniforms.size();i { - public UniformMatrix(String id) { - super(id); - } - - public void storeData(Matrix4f data) { - if (hasChanged(data)) { - GL20.glUniformMatrix4fv(getPosition(), false, data.getData()); - AllocationTracker.INSTANCE.addGPUBytes(64L); - } - } - - @Override - protected Matrix4f setValue(Matrix4f oldValue, Matrix4f newValue) { - if (oldValue != null) { - return oldValue.load(newValue); - } - return new Matrix4f(newValue); - } -} +package speiger.src.coreengine.rendering.shaderOld.uniforms; + +import org.lwjgl.opengl.GL20; + +import speiger.src.coreengine.math.vector.matrix.Matrix4f; +import speiger.src.coreengine.rendering.utils.AllocationTracker; + +public class UniformMatrix extends UniformBase { + public UniformMatrix(String id) { + super(id); + } + + public void storeData(Matrix4f data) { + if (hasChanged(data)) { + GL20.glUniformMatrix4fv(getPosition(), false, data.getData()); + AllocationTracker.INSTANCE.addGPUBytes(64L); + } + } + + @Override + protected Matrix4f setValue(Matrix4f oldValue, Matrix4f newValue) { + if (oldValue != null) { + return oldValue.load(newValue); + } + return new Matrix4f(newValue); + } +} diff --git a/src/main/java/speiger/src/coreengine/utils/helpers/InternalThreadPools.java b/src/main/java/speiger/src/coreengine/utils/helpers/InternalThreadPools.java index 4475cb1..1bcd605 100644 --- a/src/main/java/speiger/src/coreengine/utils/helpers/InternalThreadPools.java +++ b/src/main/java/speiger/src/coreengine/utils/helpers/InternalThreadPools.java @@ -1,12 +1,12 @@ -package speiger.src.coreengine.utils.helpers; - -import speiger.src.coreengine.math.vector.floats.Vec2f; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; -import speiger.src.coreengine.utils.collections.pools.IPool; -import speiger.src.coreengine.utils.collections.pools.ThreadPool; - -public class InternalThreadPools -{ - public static final IPool MATRIX = new ThreadPool(100, Matrix4f::new); - public static final IPool VEC2F = new ThreadPool(100, Vec2f::mutable); -} +package speiger.src.coreengine.utils.helpers; + +import speiger.src.coreengine.math.vector.floats.Vec2f; +import speiger.src.coreengine.math.vector.matrix.Matrix4f; +import speiger.src.coreengine.utils.collections.pools.IPool; +import speiger.src.coreengine.utils.collections.pools.ThreadPool; + +public class InternalThreadPools +{ + public static final IPool MATRIX = new ThreadPool(100, Matrix4f::new); + public static final IPool VEC2F = new ThreadPool(100, Vec2f::mutable); +} diff --git a/src/math/java/speiger/src/coreengine/math/vector/floats/Vec3f.java b/src/math/java/speiger/src/coreengine/math/vector/floats/Vec3f.java index 93e856c..6c02997 100644 --- a/src/math/java/speiger/src/coreengine/math/vector/floats/Vec3f.java +++ b/src/math/java/speiger/src/coreengine/math/vector/floats/Vec3f.java @@ -1,236 +1,236 @@ -package speiger.src.coreengine.math.vector.floats; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -import speiger.src.coreengine.math.MathUtils; -import speiger.src.coreengine.math.vector.bytes.Vec3b; -import speiger.src.coreengine.math.vector.doubles.Vec3d; -import speiger.src.coreengine.math.vector.ints.Vec3i; -import speiger.src.coreengine.math.vector.longs.Vec3l; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; -import speiger.src.coreengine.math.vector.shorts.Vec3s; - -public interface Vec3f extends Vecf { - public static final Vec3f ZERO = of(); - public static final Vec3f MINUS_ONE = of(-1F); - public static final Vec3f ONE = of(1F); - - public static Vec3f mutable() { return new Vec3fMutable(); } - 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(Vec3f vec) { return mutable(vec.x(), vec.y(), vec.z()); } - public static Vec3f of() { return new Vec3fImmutable(); } - 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(Vec3f vec) { return of(vec.x(), vec.y(), vec.z()); } - - public float x(); - public float y(); - public float z(); - public Vec3f x(float x); - public Vec3f y(float y); - public Vec3f z(float z); - - @Override - public default float[] asArray() { return new float[] {x(), y(), z()}; } - @Override - public Vec3f copy(); - @Override - public default Vec3f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z())); } - @Override - public default Vec3f negate() { return set(0F, 0F, 0F); } - @Override - public default Vec3f invert() { return set(-x(), -y(), -z()); } - public default Vec3f normalize() { - float l = length(); - return l == 0F ? this : multiply(1.0F / l); - } - - @Override - 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(float x, float y, float z) { return set(x() + x, y() + y, z() + z); } - @Override - 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(float x, float y, float z) { return set(x() - x, y() - y, z() - z); } - @Override - 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(float x, float y, float z) { return set(x() * x, y() * y, z() * z); } - @Override - 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(float x, float y, float z) { return set(x() / x, y() / y, z() / z); } - @Override - 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 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(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(float x, float y, float z) { - double xPos = x() - x; - double yPos = y() - y; - double zPos = z() - z; - return (xPos * xPos) + (yPos * yPos) + (zPos * zPos); - } - - @Override - 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(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(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(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(float x, float y, float z) { - double myLength = (x() * x()) + (y() * y()) + (z() * z()); - double otherLength = (x * x) + (y * y) + (z * z); - float dot = (x() * x) + (y() * y) + (z() * z); - 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, 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, 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, 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, Vec3f result) { - double dot = dotProduct(x, y, z) * 2D; - 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, 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, Vec3f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double dot = dotProduct(x, y, z); - 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 zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin; - 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, Vec3f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double y = y() * cos + z() * sin; - double z = z() * cos - y() * sin; - return result.set(x(), (float)y, (float)z); - } - - public default Vec3f rotateY(float angle) { return rotateY(angle, this); } - public default Vec3f rotateY(float angle, Vec3f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double x = x() * cos + z() * sin; - double z = z() * cos - x() * sin; - return result.set((float)x, y(), (float)z); - } - - public default Vec3f rotateZ(float angle) { return rotateZ(angle, this); } - public default Vec3f rotateZ(float angle, Vec3f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double x = cos * x() - sin * y(); - double y = sin * x() + cos * y(); - return result.set((float)x, (float)y, z()); - } - - 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 transform(Matrix4f matrix, boolean pos, Vec3f result) { - if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) { - return result.set(this); - } - if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) { - float w = pos ? 1F : 0F; - return result.set( - 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.M02, Matrix4f.M12, Matrix4f.M22, Matrix4f.M32, x(), y(), z(), w)); - } - if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) { - if(pos) return set( - 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.M02), z(), matrix.get(Matrix4f.M32))); - 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)); - 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(float x, float y, float z, float progress, Vec3f result) { - float t2 = progress * progress; - float t3 = t2 * progress; - 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 zPos = ((z() + z() - z - z) * t3 + (3.0F * z - 3.0F * z()) * t2 + z() * progress + z()); - return result.set(xPos, yPos, zPos); - } - - 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(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 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(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 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(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); } - @Override - 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); } - @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, 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 - public default Vec3f store(ByteBuffer buffer) { - buffer.putFloat(x()).putFloat(y()).putFloat(z()); - return this; - } - - @Override - public default Vec3f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } - - @Override - public default Vec3f store(FloatBuffer buffer) { - buffer.put(x()).put(y()).put(z()); - return this; - } - - @Override - public default Vec3f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get()); } - @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())); } - @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())); } - @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())); } - @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())); } - @Override - public default Vec3d asDouble() { return isMutable() ? Vec3d.mutable(x(), y(), z()) : Vec3d.of(x(), y(), z()); } - @Override - public default Vec3f asMutable() { return isMutable() ? this : mutable(this); } - @Override - public default Vec3f asImmutable() { return isMutable() ? of(this) : this; } - @Override - public default Vec3f copyAsMutable() { return mutable(this); } - @Override - public default Vec3f copyAsImmutable() { return of(this); } -} +package speiger.src.coreengine.math.vector.floats; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import speiger.src.coreengine.math.MathUtils; +import speiger.src.coreengine.math.vector.bytes.Vec3b; +import speiger.src.coreengine.math.vector.doubles.Vec3d; +import speiger.src.coreengine.math.vector.ints.Vec3i; +import speiger.src.coreengine.math.vector.longs.Vec3l; +import speiger.src.coreengine.math.vector.matrix.Matrix4f; +import speiger.src.coreengine.math.vector.shorts.Vec3s; + +public interface Vec3f extends Vecf { + public static final Vec3f ZERO = of(); + public static final Vec3f MINUS_ONE = of(-1F); + public static final Vec3f ONE = of(1F); + + public static Vec3f mutable() { return new Vec3fMutable(); } + 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(Vec3f vec) { return mutable(vec.x(), vec.y(), vec.z()); } + public static Vec3f of() { return new Vec3fImmutable(); } + 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(Vec3f vec) { return of(vec.x(), vec.y(), vec.z()); } + + public float x(); + public float y(); + public float z(); + public Vec3f x(float x); + public Vec3f y(float y); + public Vec3f z(float z); + + @Override + public default float[] asArray() { return new float[] {x(), y(), z()}; } + @Override + public Vec3f copy(); + @Override + public default Vec3f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z())); } + @Override + public default Vec3f negate() { return set(0F, 0F, 0F); } + @Override + public default Vec3f invert() { return set(-x(), -y(), -z()); } + public default Vec3f normalize() { + float l = length(); + return l == 0F ? this : multiply(1.0F / l); + } + + @Override + 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(float x, float y, float z) { return set(x() + x, y() + y, z() + z); } + @Override + 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(float x, float y, float z) { return set(x() - x, y() - y, z() - z); } + @Override + 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(float x, float y, float z) { return set(x() * x, y() * y, z() * z); } + @Override + 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(float x, float y, float z) { return set(x() / x, y() / y, z() / z); } + @Override + 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 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(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(float x, float y, float z) { + double xPos = x() - x; + double yPos = y() - y; + double zPos = z() - z; + return (xPos * xPos) + (yPos * yPos) + (zPos * zPos); + } + + @Override + 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(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(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(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(float x, float y, float z) { + double myLength = (x() * x()) + (y() * y()) + (z() * z()); + double otherLength = (x * x) + (y * y) + (z * z); + float dot = (x() * x) + (y() * y) + (z() * z); + 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, 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, 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, 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, Vec3f result) { + double dot = dotProduct(x, y, z) * 2D; + 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, 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, Vec3f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double dot = dotProduct(x, y, z); + 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 zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin; + 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, Vec3f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double y = y() * cos + z() * sin; + double z = z() * cos - y() * sin; + return result.set(x(), (float)y, (float)z); + } + + public default Vec3f rotateY(float angle) { return rotateY(angle, this); } + public default Vec3f rotateY(float angle, Vec3f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double x = x() * cos + z() * sin; + double z = z() * cos - x() * sin; + return result.set((float)x, y(), (float)z); + } + + public default Vec3f rotateZ(float angle) { return rotateZ(angle, this); } + public default Vec3f rotateZ(float angle, Vec3f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double x = cos * x() - sin * y(); + double y = sin * x() + cos * y(); + return result.set((float)x, (float)y, z()); + } + + 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 transform(Matrix4f matrix, boolean pos, Vec3f result) { + if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) { + return result.set(this); + } + if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) { + float w = pos ? 1F : 0F; + return result.set( + 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.M02, Matrix4f.M12, Matrix4f.M22, Matrix4f.M32, x(), y(), z(), w)); + } + if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) { + if(pos) return set( + 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.M02), z(), matrix.get(Matrix4f.M32))); + 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)); + 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(float x, float y, float z, float progress, Vec3f result) { + float t2 = progress * progress; + float t3 = t2 * progress; + 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 zPos = ((z() + z() - z - z) * t3 + (3.0F * z - 3.0F * z()) * t2 + z() * progress + z()); + return result.set(xPos, yPos, zPos); + } + + 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(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 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(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 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(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); } + @Override + 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); } + @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, 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 + public default Vec3f store(ByteBuffer buffer) { + buffer.putFloat(x()).putFloat(y()).putFloat(z()); + return this; + } + + @Override + public default Vec3f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } + + @Override + public default Vec3f store(FloatBuffer buffer) { + buffer.put(x()).put(y()).put(z()); + return this; + } + + @Override + public default Vec3f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get()); } + @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())); } + @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())); } + @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())); } + @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())); } + @Override + public default Vec3d asDouble() { return isMutable() ? Vec3d.mutable(x(), y(), z()) : Vec3d.of(x(), y(), z()); } + @Override + public default Vec3f asMutable() { return isMutable() ? this : mutable(this); } + @Override + public default Vec3f asImmutable() { return isMutable() ? of(this) : this; } + @Override + public default Vec3f copyAsMutable() { return mutable(this); } + @Override + public default Vec3f copyAsImmutable() { return of(this); } +} diff --git a/src/math/java/speiger/src/coreengine/math/vector/floats/Vec4f.java b/src/math/java/speiger/src/coreengine/math/vector/floats/Vec4f.java index d35ed11..ad1f2b1 100644 --- a/src/math/java/speiger/src/coreengine/math/vector/floats/Vec4f.java +++ b/src/math/java/speiger/src/coreengine/math/vector/floats/Vec4f.java @@ -1,226 +1,226 @@ -package speiger.src.coreengine.math.vector.floats; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -import speiger.src.coreengine.math.MathUtils; -import speiger.src.coreengine.math.vector.bytes.Vec4b; -import speiger.src.coreengine.math.vector.doubles.Vec4d; -import speiger.src.coreengine.math.vector.ints.Vec4i; -import speiger.src.coreengine.math.vector.longs.Vec4l; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; -import speiger.src.coreengine.math.vector.shorts.Vec4s; - -public interface Vec4f extends Vecf { - public static final Vec4f ZERO = of(); - public static final Vec4f MINUS_ONE = of(-1F); - public static final Vec4f ONE = of(1F); - - public static Vec4f mutable() { return new Vec4fMutable(); } - 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(Vec4f vec) { return mutable(vec.x(), vec.y(), vec.z(), vec.w()); } - public static Vec4f of() { return new Vec4fImmutable(); } - 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(Vec4f vec) { return of(vec.x(), vec.y(), vec.z(), vec.w()); } - - public float x(); - public float y(); - public float z(); - public float w(); - public Vec4f x(float x); - public Vec4f y(float y); - public Vec4f z(float z); - public Vec4f w(float w); - - @Override - public default float[] asArray() { return new float[] {x(), y(), z(), w()}; } - @Override - public Vec4f copy(); - @Override - public default Vec4f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z()), Math.abs(w())); } - @Override - public default Vec4f negate() { return set(0F, 0F, 0F, 0F); } - @Override - public default Vec4f invert() { return set(-x(), -y(), -z(), -w()); } - public default Vec4f normalize() { - float l = length(); - return l == 0F ? this : multiply(1.0F / l); - } - - public default Vec4f normalize3D() { - float value = (x() * x()) + (y() * y()) + (z() * z()); - return value == 0F ? this : multiply(1F / value); - } - - @Override - 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(float x, float y, float z, float w) { return set(x() + x, y() + y, z() + z, w() + w); } - @Override - 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(float x, float y, float z, float w) { return set(x() - x, y() - y, z() - z, w() - w); } - @Override - 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(float x, float y, float z, float w) { return set(x() * x, y() * y, z() * z, w() * w); } - @Override - 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(float x, float y, float z, float w) { return set(x() / x, y() / y, z() / z, w() / w); } - @Override - 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 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(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(float x, float y, float z, float w) { - double xPos = x() - x; - double yPos = y() - y; - double zPos = z() - z; - double wPos = w() - w; - return (xPos * xPos) + (yPos * yPos) + (zPos * zPos) + (wPos * wPos); - } - - @Override - 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(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(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(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(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, 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, Vec4f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double dot = dotProduct(x, y, z, w); - 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 zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin; - 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, Vec4f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double y = y() * cos + z() * sin; - double z = z() * cos - y() * sin; - 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, Vec4f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double x = x() * cos + z() * sin; - double z = z() * cos - x() * sin; - 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, Vec4f result) { - double cos = MathUtils.cos(angle); - double sin = MathUtils.sin(angle); - double x = cos * x() - sin * y(); - double y = sin * x() + cos * y(); - 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, Vec4f result) { - if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) { - return result.set(this); - } - if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) { - return result.set( - 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.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())); - } - if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) { - return set( - 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.M02), z(), matrix.get(Matrix4f.M32)), - 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)); - } - - 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) { - float t2 = progress * progress; - float t3 = t2 * progress; - 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 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()); - return result.set(xPos, yPos, zPos, wPos); - } - - 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(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 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(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 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(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); } - @Override - 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); } - @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, 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 - public default Vec4f store(ByteBuffer buffer) { - buffer.putFloat(x()).putFloat(y()).putFloat(z()).putFloat(w()); - return this; - } - - @Override - public default Vec4f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } - - @Override - public default Vec4f store(FloatBuffer buffer) { - buffer.put(x()).put(y()).put(z()).put(w()); - return this; - } - - @Override - public default Vec4f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); } - - @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())); } - @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())); } - @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())); } - @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())); } - @Override - public default Vec4d asDouble() { return isMutable() ? Vec4d.mutable(x(), y(), z(), w()) : Vec4d.of(x(), y(), z(), w()); } - @Override - public default Vec4f asMutable() { return isMutable() ? this : mutable(this); } - @Override - public default Vec4f asImmutable() { return isMutable() ? of(this) : this; } - @Override - public default Vec4f copyAsMutable() { return mutable(this); } - @Override - public default Vec4f copyAsImmutable() { return of(this); } -} +package speiger.src.coreengine.math.vector.floats; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import speiger.src.coreengine.math.MathUtils; +import speiger.src.coreengine.math.vector.bytes.Vec4b; +import speiger.src.coreengine.math.vector.doubles.Vec4d; +import speiger.src.coreengine.math.vector.ints.Vec4i; +import speiger.src.coreengine.math.vector.longs.Vec4l; +import speiger.src.coreengine.math.vector.matrix.Matrix4f; +import speiger.src.coreengine.math.vector.shorts.Vec4s; + +public interface Vec4f extends Vecf { + public static final Vec4f ZERO = of(); + public static final Vec4f MINUS_ONE = of(-1F); + public static final Vec4f ONE = of(1F); + + public static Vec4f mutable() { return new Vec4fMutable(); } + 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(Vec4f vec) { return mutable(vec.x(), vec.y(), vec.z(), vec.w()); } + public static Vec4f of() { return new Vec4fImmutable(); } + 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(Vec4f vec) { return of(vec.x(), vec.y(), vec.z(), vec.w()); } + + public float x(); + public float y(); + public float z(); + public float w(); + public Vec4f x(float x); + public Vec4f y(float y); + public Vec4f z(float z); + public Vec4f w(float w); + + @Override + public default float[] asArray() { return new float[] {x(), y(), z(), w()}; } + @Override + public Vec4f copy(); + @Override + public default Vec4f abs() { return set(Math.abs(x()), Math.abs(y()), Math.abs(z()), Math.abs(w())); } + @Override + public default Vec4f negate() { return set(0F, 0F, 0F, 0F); } + @Override + public default Vec4f invert() { return set(-x(), -y(), -z(), -w()); } + public default Vec4f normalize() { + float l = length(); + return l == 0F ? this : multiply(1.0F / l); + } + + public default Vec4f normalize3D() { + float value = (x() * x()) + (y() * y()) + (z() * z()); + return value == 0F ? this : multiply(1F / value); + } + + @Override + 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(float x, float y, float z, float w) { return set(x() + x, y() + y, z() + z, w() + w); } + @Override + 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(float x, float y, float z, float w) { return set(x() - x, y() - y, z() - z, w() - w); } + @Override + 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(float x, float y, float z, float w) { return set(x() * x, y() * y, z() * z, w() * w); } + @Override + 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(float x, float y, float z, float w) { return set(x() / x, y() / y, z() / z, w() / w); } + @Override + 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 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(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(float x, float y, float z, float w) { + double xPos = x() - x; + double yPos = y() - y; + double zPos = z() - z; + double wPos = w() - w; + return (xPos * xPos) + (yPos * yPos) + (zPos * zPos) + (wPos * wPos); + } + + @Override + 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(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(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(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(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, 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, Vec4f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double dot = dotProduct(x, y, z, w); + 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 zPos = z * dot * (1D - cos) + (z() * cos) + (-y * x() + x * y()) * sin; + 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, Vec4f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double y = y() * cos + z() * sin; + double z = z() * cos - y() * sin; + 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, Vec4f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double x = x() * cos + z() * sin; + double z = z() * cos - x() * sin; + 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, Vec4f result) { + double cos = MathUtils.cos(angle); + double sin = MathUtils.sin(angle); + double x = cos * x() - sin * y(); + double y = sin * x() + cos * y(); + 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, Vec4f result) { + if((matrix.properties() & Matrix4f.PROPERTY_IDENTITY) != 0) { + return result.set(this); + } + if((matrix.properties() & Matrix4f.PROPERTY_ROTATION) != 0) { + return result.set( + 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.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())); + } + if((matrix.properties() & Matrix4f.PROPERTY_SCALE) != 0) { + return set( + 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.M02), z(), matrix.get(Matrix4f.M32)), + 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)); + } + + 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) { + float t2 = progress * progress; + float t3 = t2 * progress; + 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 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()); + return result.set(xPos, yPos, zPos, wPos); + } + + 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(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 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(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 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(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); } + @Override + 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); } + @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, 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 + public default Vec4f store(ByteBuffer buffer) { + buffer.putFloat(x()).putFloat(y()).putFloat(z()).putFloat(w()); + return this; + } + + @Override + public default Vec4f load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } + + @Override + public default Vec4f store(FloatBuffer buffer) { + buffer.put(x()).put(y()).put(z()).put(w()); + return this; + } + + @Override + public default Vec4f load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); } + + @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())); } + @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())); } + @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())); } + @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())); } + @Override + public default Vec4d asDouble() { return isMutable() ? Vec4d.mutable(x(), y(), z(), w()) : Vec4d.of(x(), y(), z(), w()); } + @Override + public default Vec4f asMutable() { return isMutable() ? this : mutable(this); } + @Override + public default Vec4f asImmutable() { return isMutable() ? of(this) : this; } + @Override + public default Vec4f copyAsMutable() { return mutable(this); } + @Override + public default Vec4f copyAsImmutable() { return of(this); } +} diff --git a/src/math/java/speiger/src/coreengine/math/vector/matrix/ITransformOutput.java b/src/math/java/speiger/src/coreengine/math/vector/matrix/ITransformOutput.java index 3221bcd..3019a0b 100644 --- a/src/math/java/speiger/src/coreengine/math/vector/matrix/ITransformOutput.java +++ b/src/math/java/speiger/src/coreengine/math/vector/matrix/ITransformOutput.java @@ -1,5 +1,5 @@ -package speiger.src.coreengine.math.vector.matrix; - -public interface ITransformOutput { - public void accept(float...output); -} +package speiger.src.coreengine.math.vector.matrix; + +public interface ITransformOutput { + public void accept(float x, float y, float z); +} diff --git a/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java b/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java index 4c8d5d6..5987ee9 100644 --- a/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java +++ b/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java @@ -16,7 +16,6 @@ public class Matrix4f { public static final int PROPERTY_TRANSLATION = 1 << 2; public static final int PROPERTY_SCALE = 1 << 3; 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 M01 = 1; @@ -137,13 +136,13 @@ public class Matrix4f { } public Matrix4f setIdentity() { - if(properties == PROPERTY_DEFAULT) return this; + if((properties & PROPERTY_IDENTITY) == PROPERTY_IDENTITY) return this; Arrays.fill(data, 0F); data[M00] = 1F; data[M11] = 1F; data[M22] = 1F; data[M33] = 1F; - properties = PROPERTY_DEFAULT; + properties = PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_AFFINE; return this; } @@ -190,22 +189,9 @@ public class Matrix4f { } public Matrix4f flip() { - data[M00] = -data[M00]; - data[M01] = -data[M01]; - 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]; + for(int i = 0;i<16;i++) { + data[i] = -data[i]; + } return evaluateProps(); } @@ -215,42 +201,16 @@ public class Matrix4f { } public Matrix4f add(Matrix4f other) { - data[M00] += other.data[M00]; - data[M01] += other.data[M01]; - 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]; + for(int i = 0;i<16;i++) { + data[i] += other.data[i]; + } return evaluateProps(); } public Matrix4f sub(Matrix4f other) { - data[M00] -= other.data[M00]; - data[M01] -= other.data[M01]; - 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]; + for(int i = 0;i<16;i++) { + data[i] -= other.data[i]; + } return evaluateProps(); } @@ -371,6 +331,10 @@ public class Matrix4f { data[M32] += z; return evaluateProps(); } + if((properties & PROPERTY_ROTATION) == 0) { + data[M32] += data[M22] * z; + evaluateProps(); + } data[M30] += data[M20] * z; data[M31] += data[M21] * z; data[M32] += data[M22] * z; @@ -385,6 +349,11 @@ public class Matrix4f { data[M31] += y; 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[M31] += data[M01] * x + data[M11] * y; data[M32] += data[M02] * x + data[M12] * y; @@ -401,6 +370,12 @@ public class Matrix4f { properties |= PROPERTY_TRANSLATION; 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[M31] += data[M01] * x + data[M11] * y + data[M21] * z; data[M32] += data[M02] * x + data[M12] * y + data[M22] * z; @@ -614,28 +589,20 @@ public class Matrix4f { return this; } - public void transform(Vec4f input, FloatBuffer buffer) { - 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) { + public void transformOffset(float x, float y, float z, float xOff, float yOff, float zOff, ITransformOutput output) { if((properties & PROPERTY_IDENTITY) != 0) { - output.accept(x, y, z, w); + output.accept(x + xOff, y + yOff, z + zOff); return; } 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; } 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; } - 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) { diff --git a/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java b/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java index 2b4433f..73be206 100644 --- a/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java +++ b/src/math/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java @@ -1,31 +1,31 @@ -package speiger.src.coreengine.math.vector.matrix; - -import speiger.src.collections.objects.lists.ObjectArrayList; -import speiger.src.collections.utils.Stack; - -public class Matrix4fStack extends Matrix4f { - Stack stack = new ObjectArrayList<>(); - - public Matrix4f push() { - Matrix4f matrix = new Matrix4f(this); - stack.push(matrix); - return matrix; - } - - public void pop() { - load(stack.pop()); - } - - public void popRoot() { - load(stack.peek(stack.size()-1)); - stack.clear(); - } - - public int size() { - return stack.size(); - } - - public Matrix4f copyCurrent() { - return new Matrix4f(this); - } -} +package speiger.src.coreengine.math.vector.matrix; + +import speiger.src.collections.objects.lists.ObjectArrayList; +import speiger.src.collections.utils.Stack; + +public class Matrix4fStack extends Matrix4f { + Stack stack = new ObjectArrayList<>(); + + public Matrix4f push() { + Matrix4f matrix = new Matrix4f(this); + stack.push(matrix); + return matrix; + } + + public void pop() { + load(stack.pop()); + } + + public void popRoot() { + load(stack.peek(stack.size()-1)); + stack.clear(); + } + + public int size() { + return stack.size(); + } + + public Matrix4f copyCurrent() { + return new Matrix4f(this); + } +} diff --git a/src/math/java/speiger/src/coreengine/math/vector/quaternion/Quaternion.java b/src/math/java/speiger/src/coreengine/math/vector/quaternion/Quaternion.java index d949d6e..f79323e 100644 --- a/src/math/java/speiger/src/coreengine/math/vector/quaternion/Quaternion.java +++ b/src/math/java/speiger/src/coreengine/math/vector/quaternion/Quaternion.java @@ -1,191 +1,191 @@ -package speiger.src.coreengine.math.vector.quaternion; - -import java.nio.ByteBuffer; -import java.nio.FloatBuffer; - -import speiger.src.coreengine.math.MathUtils; -import speiger.src.coreengine.math.vector.floats.Vec4f; -import speiger.src.coreengine.math.vector.matrix.Matrix4f; - -public interface Quaternion { - public static final Quaternion ZERO = of(0F, 0F, 0F, 0F); - public static final Quaternion IDENTITY = of(); - - 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(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 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(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 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 double acos(double v) { return v < -1D ? 3.141592653589793D : (v > 1D ? 0D : Math.acos(v)); } - - public Quaternion setX(float x); - public Quaternion setY(float y); - public Quaternion setZ(float z); - public Quaternion setW(float w); - public float getX(); - public float getY(); - public float getZ(); - public float 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 invert() { return set(-getX(), -getY(), -getZ(), -getW()); } - public default Quaternion normalize() { return scale(1.0F / length()); } - public default Quaternion conjugate() { return set(-getX(), -getY(), -getZ(), getW()); } - 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 scale(float scale) { return set(getX() * scale, getY() * scale, getZ() * scale, getW() * scale); } - public default Quaternion rotateX(float angle) { - angle = (float)Math.toRadians(angle); - float sin = MathUtils.sin(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); - } - - public default Quaternion rotateY(float angle) { - angle = (float)Math.toRadians(angle); - float sin = MathUtils.sin(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); - } - - public default Quaternion rotateZ(float angle) { - angle = (float)Math.toRadians(angle); - float sin = MathUtils.sin(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); - } - - 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(Matrix4f matrix) { - float tr = matrix.get(0, 0) + matrix.get(1, 1) + matrix.get(2, 2); - if(tr >= 0.0D) { - float s = (float)Math.sqrt(tr + 1.0D); - float w = s * 0.5F; - s = 0.5F / s; - float x = (matrix.get(2, 1) - matrix.get(1, 2)) * s; - float y = (matrix.get(0, 2) - matrix.get(2, 0)) * s; - float z = (matrix.get(1, 0) - matrix.get(0, 1)) * s; - return set(x, y, z, w); - } - else { - float max = Math.max(Math.max(matrix.get(0, 0), matrix.get(1, 1)), matrix.get(2, 2)); - 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 x = s * 0.5F; - s = 0.5F / s; - float y = (matrix.get(0, 1) + matrix.get(1, 0)) * s; - float z = (matrix.get(2, 0) + matrix.get(0, 2)) * s; - float w = (matrix.get(2, 1) - matrix.get(1, 2)) * s; - return set(x, y, z, w); - } - 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 y = s * 0.5F; - s = 0.5F / s; - float z = (matrix.get(1, 2) + matrix.get(2, 1)) * s; - float x = (matrix.get(0, 1) + matrix.get(1, 0)) * s; - float w = (matrix.get(0, 2) - matrix.get(2, 0)) * s; - return set(x, y, z, w); - } - else { - float s = (float)Math.sqrt(matrix.get(2, 2) - (matrix.get(0, 0) + matrix.get(1, 1)) + 1.0D); - float z = s * 0.5F; - s = 0.5F / s; - float x = (matrix.get(2, 0) + matrix.get(0, 2)) * s; - float y = (matrix.get(1, 2) + matrix.get(2, 1)) * s; - float w = (matrix.get(1, 0) - matrix.get(0, 1)) * s; - return set(x, y, z, w); - } - } - } - - public default Quaternion setAxisRad(float x, float y, float z, float angle) { - float sin = MathUtils.sin(angle * 0.5D); - float cos = MathUtils.cos(angle * 0.5D); - return set(x * sin, y * sin, z * sin, cos); - } - - public default Quaternion setAxisDeg(float x, float y, float z, float angle) { - angle = (float)Math.toRadians(angle); - float sin = MathUtils.sin(angle * 0.5D); - float cos = MathUtils.cos(angle * 0.5D); - return set(x * sin, y * sin, z * sin, cos); - } - - 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 Quaternion difference(Quaternion other) { return difference(other, this); } - public default Quaternion difference(Quaternion other, Quaternion result) { - float invNorm = 1.0F / (getX() * getX() + getY() * getY() + getZ() * getZ() + getW() * getW()); - float x = -getX() * invNorm; - float y = -getY() * invNorm; - float z = -getZ() * 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()); - } - - public default Quaternion lerp(Quaternion other, float progress) { return lerp(other, progress, this); } - 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 absCosom = Math.abs(cosom); - float scale1; - float scale0; - if(1.0F - absCosom > 1.0E-006F) { - float sinSqr = 1.0F - absCosom * absCosom; - float sinom = (float)(1.0D / Math.sqrt(sinSqr)); - float omega = (float)Math.atan2(sinSqr * sinom, absCosom); - scale0 = MathUtils.sin((1.0D - progress) * omega) * sinom; - scale1 = MathUtils.sin(progress * omega) * sinom; - } - else { - scale0 = 1.0F - progress; - scale1 = progress; - } - 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()); - } - - public default float length() { return (float)Math.sqrt(lengthSquared()); } - public default double lengthSquared() { return (getX() * getX()) + (getY() * getY()) + (getZ() * getZ()) + (getW() * getW()); } - public default Matrix4f asRotationMatrix() { return new Matrix4f().rotate(this); } - public default Vec4f toAxisDegreeRotation() { return toAxisDegreeRotation(Vec4f.mutable()); } - public default Vec4f toAxisDegreeRotation(Vec4f input) { - 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)); - } - - public default Vec4f toAxisRotation() { return toAxisRotation(Vec4f.mutable()); } - public default Vec4f toAxisRotation(Vec4f input) { - 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); - } - - public default Quaternion store(ByteBuffer buffer) { - buffer.putFloat(getX()).putFloat(getY()).putFloat(getZ()).putFloat(getW()); - return this; - } - - public default Quaternion load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } - - public default Quaternion store(FloatBuffer buffer) { - buffer.put(getX()).put(getY()).put(getZ()).put(getW()); - return this; - } - - public default Quaternion load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); } - - public Quaternion copy(); - public boolean isMutable(); - public default Quaternion asMutable() { return isMutable() ? this : of(this); } - public default Quaternion asImmutable() { return isMutable() ? mutable(this) : this; } - public default Quaternion copyAsMutable() { return mutable(this); } - public default Quaternion copyAsImmutable() { return of(this); } -} +package speiger.src.coreengine.math.vector.quaternion; + +import java.nio.ByteBuffer; +import java.nio.FloatBuffer; + +import speiger.src.coreengine.math.MathUtils; +import speiger.src.coreengine.math.vector.floats.Vec4f; +import speiger.src.coreengine.math.vector.matrix.Matrix4f; + +public interface Quaternion { + public static final Quaternion ZERO = of(0F, 0F, 0F, 0F); + public static final Quaternion IDENTITY = of(); + + 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(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 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(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 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 double acos(double v) { return v < -1D ? 3.141592653589793D : (v > 1D ? 0D : Math.acos(v)); } + + public Quaternion setX(float x); + public Quaternion setY(float y); + public Quaternion setZ(float z); + public Quaternion setW(float w); + public float getX(); + public float getY(); + public float getZ(); + public float 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 invert() { return set(-getX(), -getY(), -getZ(), -getW()); } + public default Quaternion normalize() { return scale(1.0F / length()); } + public default Quaternion conjugate() { return set(-getX(), -getY(), -getZ(), getW()); } + 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 scale(float scale) { return set(getX() * scale, getY() * scale, getZ() * scale, getW() * scale); } + public default Quaternion rotateX(float angle) { + angle = (float)Math.toRadians(angle); + float sin = MathUtils.sin(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); + } + + public default Quaternion rotateY(float angle) { + angle = (float)Math.toRadians(angle); + float sin = MathUtils.sin(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); + } + + public default Quaternion rotateZ(float angle) { + angle = (float)Math.toRadians(angle); + float sin = MathUtils.sin(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); + } + + 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(Matrix4f matrix) { + float tr = matrix.get(0, 0) + matrix.get(1, 1) + matrix.get(2, 2); + if(tr >= 0.0D) { + float s = (float)Math.sqrt(tr + 1.0D); + float w = s * 0.5F; + s = 0.5F / s; + float x = (matrix.get(2, 1) - matrix.get(1, 2)) * s; + float y = (matrix.get(0, 2) - matrix.get(2, 0)) * s; + float z = (matrix.get(1, 0) - matrix.get(0, 1)) * s; + return set(x, y, z, w); + } + else { + float max = Math.max(Math.max(matrix.get(0, 0), matrix.get(1, 1)), matrix.get(2, 2)); + 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 x = s * 0.5F; + s = 0.5F / s; + float y = (matrix.get(0, 1) + matrix.get(1, 0)) * s; + float z = (matrix.get(2, 0) + matrix.get(0, 2)) * s; + float w = (matrix.get(2, 1) - matrix.get(1, 2)) * s; + return set(x, y, z, w); + } + 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 y = s * 0.5F; + s = 0.5F / s; + float z = (matrix.get(1, 2) + matrix.get(2, 1)) * s; + float x = (matrix.get(0, 1) + matrix.get(1, 0)) * s; + float w = (matrix.get(0, 2) - matrix.get(2, 0)) * s; + return set(x, y, z, w); + } + else { + float s = (float)Math.sqrt(matrix.get(2, 2) - (matrix.get(0, 0) + matrix.get(1, 1)) + 1.0D); + float z = s * 0.5F; + s = 0.5F / s; + float x = (matrix.get(2, 0) + matrix.get(0, 2)) * s; + float y = (matrix.get(1, 2) + matrix.get(2, 1)) * s; + float w = (matrix.get(1, 0) - matrix.get(0, 1)) * s; + return set(x, y, z, w); + } + } + } + + public default Quaternion setAxisRad(float x, float y, float z, float angle) { + float sin = MathUtils.sin(angle * 0.5D); + float cos = MathUtils.cos(angle * 0.5D); + return set(x * sin, y * sin, z * sin, cos); + } + + public default Quaternion setAxisDeg(float x, float y, float z, float angle) { + angle = (float)Math.toRadians(angle); + float sin = MathUtils.sin(angle * 0.5D); + float cos = MathUtils.cos(angle * 0.5D); + return set(x * sin, y * sin, z * sin, cos); + } + + 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 Quaternion difference(Quaternion other) { return difference(other, this); } + public default Quaternion difference(Quaternion other, Quaternion result) { + float invNorm = 1.0F / (getX() * getX() + getY() * getY() + getZ() * getZ() + getW() * getW()); + float x = -getX() * invNorm; + float y = -getY() * invNorm; + float z = -getZ() * 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()); + } + + public default Quaternion lerp(Quaternion other, float progress) { return lerp(other, progress, this); } + 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 absCosom = Math.abs(cosom); + float scale1; + float scale0; + if(1.0F - absCosom > 1.0E-006F) { + float sinSqr = 1.0F - absCosom * absCosom; + float sinom = (float)(1.0D / Math.sqrt(sinSqr)); + float omega = (float)Math.atan2(sinSqr * sinom, absCosom); + scale0 = MathUtils.sin((1.0D - progress) * omega) * sinom; + scale1 = MathUtils.sin(progress * omega) * sinom; + } + else { + scale0 = 1.0F - progress; + scale1 = progress; + } + 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()); + } + + public default float length() { return (float)Math.sqrt(lengthSquared()); } + public default double lengthSquared() { return (getX() * getX()) + (getY() * getY()) + (getZ() * getZ()) + (getW() * getW()); } + public default Matrix4f asRotationMatrix() { return new Matrix4f().rotate(this); } + public default Vec4f toAxisDegreeRotation() { return toAxisDegreeRotation(Vec4f.mutable()); } + public default Vec4f toAxisDegreeRotation(Vec4f input) { + 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)); + } + + public default Vec4f toAxisRotation() { return toAxisRotation(Vec4f.mutable()); } + public default Vec4f toAxisRotation(Vec4f input) { + 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); + } + + public default Quaternion store(ByteBuffer buffer) { + buffer.putFloat(getX()).putFloat(getY()).putFloat(getZ()).putFloat(getW()); + return this; + } + + public default Quaternion load(ByteBuffer buffer) { return set(buffer.getFloat(), buffer.getFloat(), buffer.getFloat(), buffer.getFloat()); } + + public default Quaternion store(FloatBuffer buffer) { + buffer.put(getX()).put(getY()).put(getZ()).put(getW()); + return this; + } + + public default Quaternion load(FloatBuffer buffer) { return set(buffer.get(), buffer.get(), buffer.get(), buffer.get()); } + + public Quaternion copy(); + public boolean isMutable(); + public default Quaternion asMutable() { return isMutable() ? this : of(this); } + public default Quaternion asImmutable() { return isMutable() ? mutable(this) : this; } + public default Quaternion copyAsMutable() { return mutable(this); } + public default Quaternion copyAsImmutable() { return of(this); } +}